From a86c6240f45963adb4f6421942f149c6312e2c43 Mon Sep 17 00:00:00 2001 From: Prakash Date: Fri, 20 Mar 2026 18:09:06 +0530 Subject: [PATCH 01/33] @uppy: upgrade esbuild from "^0.25.0" -> "^0.27.0" (#6235) this should fix CI error in bundlers workflow , more context : https://transloadit.slack.com/archives/C0FMW9PSB/p1773989607853769?thread_ts=1773336079.954969&cid=C0FMW9PSB --- .changeset/swift-papayas-greet.md | 5 + packages/uppy/package.json | 4 +- yarn.lock | 283 +++++++++++++++++++++++++++++- 3 files changed, 284 insertions(+), 8 deletions(-) create mode 100644 .changeset/swift-papayas-greet.md diff --git a/.changeset/swift-papayas-greet.md b/.changeset/swift-papayas-greet.md new file mode 100644 index 000000000..701a2e903 --- /dev/null +++ b/.changeset/swift-papayas-greet.md @@ -0,0 +1,5 @@ +--- +"uppy": patch +--- + +upgrade esbuild in uppy to "^0.27.0" diff --git a/packages/uppy/package.json b/packages/uppy/package.json index 353f7ec3f..e13b4074c 100644 --- a/packages/uppy/package.json +++ b/packages/uppy/package.json @@ -85,14 +85,14 @@ "chalk": "^5.0.0", "concat-stream": "^2.0.0", "cssnano": "^7.0.7", - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "mime-types": "^2.1.26", "npm-packlist": "^5.0.0", "pacote": "^13.0.0", "postcss": "^8.5.6", "postcss-cli": "^11.0.1", "sass": "^1.89.2", - "tar": "^7.5.8", + "tar": "^7.5.7", "typescript": "^5.8.3" } } diff --git a/yarn.lock b/yarn.lock index f2246134c..e5ae52e94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4064,6 +4064,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/aix-ppc64@npm:0.27.4" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/android-arm64@npm:0.25.4" @@ -4078,6 +4085,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm64@npm:0.27.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/android-arm@npm:0.25.4" @@ -4092,6 +4106,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm@npm:0.27.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/android-x64@npm:0.25.4" @@ -4106,6 +4127,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-x64@npm:0.27.4" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/darwin-arm64@npm:0.25.4" @@ -4120,6 +4148,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-arm64@npm:0.27.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/darwin-x64@npm:0.25.4" @@ -4134,6 +4169,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-x64@npm:0.27.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/freebsd-arm64@npm:0.25.4" @@ -4148,6 +4190,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-arm64@npm:0.27.4" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/freebsd-x64@npm:0.25.4" @@ -4162,6 +4211,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-x64@npm:0.27.4" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-arm64@npm:0.25.4" @@ -4176,6 +4232,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm64@npm:0.27.4" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-arm@npm:0.25.4" @@ -4190,6 +4253,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm@npm:0.27.4" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-ia32@npm:0.25.4" @@ -4204,6 +4274,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ia32@npm:0.27.4" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-loong64@npm:0.25.4" @@ -4218,6 +4295,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-loong64@npm:0.27.4" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-mips64el@npm:0.25.4" @@ -4232,6 +4316,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-mips64el@npm:0.27.4" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-ppc64@npm:0.25.4" @@ -4246,6 +4337,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ppc64@npm:0.27.4" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-riscv64@npm:0.25.4" @@ -4260,6 +4358,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-riscv64@npm:0.27.4" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-s390x@npm:0.25.4" @@ -4274,6 +4379,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-s390x@npm:0.27.4" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/linux-x64@npm:0.25.4" @@ -4288,6 +4400,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-x64@npm:0.27.4" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/netbsd-arm64@npm:0.25.4" @@ -4302,6 +4421,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-arm64@npm:0.27.4" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/netbsd-x64@npm:0.25.4" @@ -4316,6 +4442,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-x64@npm:0.27.4" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/openbsd-arm64@npm:0.25.4" @@ -4330,6 +4463,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-arm64@npm:0.27.4" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/openbsd-x64@npm:0.25.4" @@ -4344,6 +4484,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-x64@npm:0.27.4" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.25.9": version: 0.25.9 resolution: "@esbuild/openharmony-arm64@npm:0.25.9" @@ -4351,6 +4498,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openharmony-arm64@npm:0.27.4" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/sunos-x64@npm:0.25.4" @@ -4365,6 +4519,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/sunos-x64@npm:0.27.4" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/win32-arm64@npm:0.25.4" @@ -4379,6 +4540,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-arm64@npm:0.27.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/win32-ia32@npm:0.25.4" @@ -4393,6 +4561,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-ia32@npm:0.27.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/win32-x64@npm:0.25.4" @@ -4407,6 +4582,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-x64@npm:0.27.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.7.0 resolution: "@eslint-community/eslint-utils@npm:4.7.0" @@ -13833,6 +14015,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.27.0": + version: 0.27.4 + resolution: "esbuild@npm:0.27.4" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.4" + "@esbuild/android-arm": "npm:0.27.4" + "@esbuild/android-arm64": "npm:0.27.4" + "@esbuild/android-x64": "npm:0.27.4" + "@esbuild/darwin-arm64": "npm:0.27.4" + "@esbuild/darwin-x64": "npm:0.27.4" + "@esbuild/freebsd-arm64": "npm:0.27.4" + "@esbuild/freebsd-x64": "npm:0.27.4" + "@esbuild/linux-arm": "npm:0.27.4" + "@esbuild/linux-arm64": "npm:0.27.4" + "@esbuild/linux-ia32": "npm:0.27.4" + "@esbuild/linux-loong64": "npm:0.27.4" + "@esbuild/linux-mips64el": "npm:0.27.4" + "@esbuild/linux-ppc64": "npm:0.27.4" + "@esbuild/linux-riscv64": "npm:0.27.4" + "@esbuild/linux-s390x": "npm:0.27.4" + "@esbuild/linux-x64": "npm:0.27.4" + "@esbuild/netbsd-arm64": "npm:0.27.4" + "@esbuild/netbsd-x64": "npm:0.27.4" + "@esbuild/openbsd-arm64": "npm:0.27.4" + "@esbuild/openbsd-x64": "npm:0.27.4" + "@esbuild/openharmony-arm64": "npm:0.27.4" + "@esbuild/sunos-x64": "npm:0.27.4" + "@esbuild/win32-arm64": "npm:0.27.4" + "@esbuild/win32-ia32": "npm:0.27.4" + "@esbuild/win32-x64": "npm:0.27.4" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/32b46ec22ef78bae6cc141145022a4c0209852c07151f037fbefccc2033ca54e7f33705f8fca198eb7026f400142f64c2dbc9f0d0ce9c0a638ebc472a04abc4a + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -22750,16 +23021,16 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.5.8": - version: 7.5.9 - resolution: "tar@npm:7.5.9" +"tar@npm:^7.5.7": + version: 7.5.12 + resolution: "tar@npm:7.5.12" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10/1213cdde9c22d6acf8809ba5d2a025212ce3517bc99c4a4c6981b7dc0489bf3b164db9c826c9517680889194c9ba57448c8ff0da35eca9a60bb7689bf0b3897d + checksum: 10/a72114d28ab9b4878eeebaae8987692a577c390683c13f150d8330e139237038cc46fbb0be6983b02acf5a31b01d74776436ba03790f320a59efb44b8ac39e39 languageName: node linkType: hard @@ -23524,14 +23795,14 @@ __metadata: chalk: "npm:^5.0.0" concat-stream: "npm:^2.0.0" cssnano: "npm:^7.0.7" - esbuild: "npm:^0.25.0" + esbuild: "npm:^0.27.0" mime-types: "npm:^2.1.26" npm-packlist: "npm:^5.0.0" pacote: "npm:^13.0.0" postcss: "npm:^8.5.6" postcss-cli: "npm:^11.0.1" sass: "npm:^1.89.2" - tar: "npm:^7.5.8" + tar: "npm:^7.5.7" typescript: "npm:^5.8.3" languageName: unknown linkType: soft From 1b4c246034531becd913281aef8517286f1cf1e7 Mon Sep 17 00:00:00 2001 From: Prakash Date: Sat, 21 Mar 2026 11:45:17 +0530 Subject: [PATCH 02/33] @uppy/examples: update transloadit example (#6238) discovered while testing the `@uppy/transloadit` plugin ideally these examples should have been updated in https://github.com/transloadit/uppy/commit/c4455ebba --- examples/transloadit/main.js | 40 ++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/examples/transloadit/main.js b/examples/transloadit/main.js index 7853376a3..88720ac57 100644 --- a/examples/transloadit/main.js +++ b/examples/transloadit/main.js @@ -50,9 +50,11 @@ const formUppy = new Uppy({ }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -100,9 +102,11 @@ const formUppyWithDashboard = new Uppy({ }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -129,9 +133,11 @@ const dashboard = new Uppy({ .use(ImageEditor, { target: Dashboard }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -151,9 +157,11 @@ const dashboardModal = new Uppy({ .use(ImageEditor, { target: Dashboard }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -182,9 +190,11 @@ const uppyWithoutUI = new Uppy({ }, }).use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) From 2f6849d4daa23d52a4318682775b405b32a8402e Mon Sep 17 00:00:00 2001 From: Prakash Date: Wed, 25 Mar 2026 20:18:18 +0530 Subject: [PATCH 03/33] add missing changeset for #6156 (#6242) context : https://transloadit.slack.com/archives/C0FMW9PSB/p1774438325564219 is this the right way to add missing changeset ? --- .changeset/giant-eyes-run.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/giant-eyes-run.md diff --git a/.changeset/giant-eyes-run.md b/.changeset/giant-eyes-run.md new file mode 100644 index 000000000..932d9e94a --- /dev/null +++ b/.changeset/giant-eyes-run.md @@ -0,0 +1,5 @@ +--- +"@uppy/transloadit": patch +--- + +Fix allowMultipleUploadBatches to prevent adding/removing files while an upload is in progress (#6156) From dabd878b87c03731e6f63b23f648f0a5fb689ec7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:59:50 +0530 Subject: [PATCH 04/33] [ci] release (#6170) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @uppy/utils@7.2.0 ### Minor Changes - 6b1abaa: Introduce modern, minimal TaskQueue to replace RateLimitedQueue ## @uppy/xhr-upload@5.2.0 ### Minor Changes - 6b1abaa: Introduce modern, minimal TaskQueue to replace RateLimitedQueue ### Patch Changes - Updated dependencies [6b1abaa] - @uppy/utils@7.2.0 ## @uppy/companion@6.2.2 ### Patch Changes - 49db42d: Fix bug with 429 not returning JSON response with message - 4652dc6: upgrade @aws-sdk/ deps in @uppy/companion ## @uppy/transloadit@5.5.1 ### Patch Changes - 4787960: Add type re-export for `AssemblyInstructionsInput` - 2f6849d: Fix allowMultipleUploadBatches to prevent adding/removing files while an upload is in progress (#6156) - 29d2772: remove monkey patch from uppy bundle package - Updated dependencies [6b1abaa] - @uppy/utils@7.2.0 ## uppy@5.2.4 ### Patch Changes - 29d2772: remove monkey patch from uppy bundle package - a86c624: upgrade esbuild in uppy to "^0.27.0" - Updated dependencies [6b1abaa] - Updated dependencies [4787960] - Updated dependencies [2f6849d] - Updated dependencies [29d2772] - @uppy/xhr-upload@5.2.0 - @uppy/transloadit@5.5.1 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/bumpy-cougars-open.md | 6 ------ .changeset/clever-crabs-worry.md | 5 ----- .changeset/giant-eyes-run.md | 5 ----- .changeset/good-chicken-brake.md | 5 ----- .changeset/rich-emus-arrive.md | 5 ----- .changeset/silly-parrots-knock.md | 6 ------ .changeset/swift-papayas-greet.md | 5 ----- BUNDLE-README.md | 2 +- README.md | 6 +++--- packages/@uppy/companion/CHANGELOG.md | 7 +++++++ packages/@uppy/companion/package.json | 2 +- packages/@uppy/transloadit/CHANGELOG.md | 10 ++++++++++ packages/@uppy/transloadit/package.json | 2 +- packages/@uppy/utils/CHANGELOG.md | 6 ++++++ packages/@uppy/utils/package.json | 2 +- packages/@uppy/xhr-upload/CHANGELOG.md | 11 +++++++++++ packages/@uppy/xhr-upload/package.json | 2 +- packages/uppy/CHANGELOG.md | 13 +++++++++++++ packages/uppy/package.json | 2 +- 19 files changed, 56 insertions(+), 46 deletions(-) delete mode 100644 .changeset/bumpy-cougars-open.md delete mode 100644 .changeset/clever-crabs-worry.md delete mode 100644 .changeset/giant-eyes-run.md delete mode 100644 .changeset/good-chicken-brake.md delete mode 100644 .changeset/rich-emus-arrive.md delete mode 100644 .changeset/silly-parrots-knock.md delete mode 100644 .changeset/swift-papayas-greet.md diff --git a/.changeset/bumpy-cougars-open.md b/.changeset/bumpy-cougars-open.md deleted file mode 100644 index ba7f4c611..000000000 --- a/.changeset/bumpy-cougars-open.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@uppy/xhr-upload": minor -"@uppy/utils": minor ---- - -Introduce modern, minimal TaskQueue to replace RateLimitedQueue diff --git a/.changeset/clever-crabs-worry.md b/.changeset/clever-crabs-worry.md deleted file mode 100644 index f0d2715a4..000000000 --- a/.changeset/clever-crabs-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/transloadit": patch ---- - -Add type re-export for `AssemblyInstructionsInput` diff --git a/.changeset/giant-eyes-run.md b/.changeset/giant-eyes-run.md deleted file mode 100644 index 932d9e94a..000000000 --- a/.changeset/giant-eyes-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/transloadit": patch ---- - -Fix allowMultipleUploadBatches to prevent adding/removing files while an upload is in progress (#6156) diff --git a/.changeset/good-chicken-brake.md b/.changeset/good-chicken-brake.md deleted file mode 100644 index 7341ac512..000000000 --- a/.changeset/good-chicken-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/companion": patch ---- - -Fix bug with 429 not returning JSON response with message diff --git a/.changeset/rich-emus-arrive.md b/.changeset/rich-emus-arrive.md deleted file mode 100644 index 72426dcef..000000000 --- a/.changeset/rich-emus-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/companion": patch ---- - -upgrade @aws-sdk/ deps in @uppy/companion diff --git a/.changeset/silly-parrots-knock.md b/.changeset/silly-parrots-knock.md deleted file mode 100644 index 9d07ade94..000000000 --- a/.changeset/silly-parrots-knock.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@uppy/transloadit": patch -"uppy": patch ---- - -remove monkey patch from uppy bundle package diff --git a/.changeset/swift-papayas-greet.md b/.changeset/swift-papayas-greet.md deleted file mode 100644 index 701a2e903..000000000 --- a/.changeset/swift-papayas-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"uppy": patch ---- - -upgrade esbuild in uppy to "^0.27.0" diff --git a/BUNDLE-README.md b/BUNDLE-README.md index de13cd256..ffc6fc6c0 100644 --- a/BUNDLE-README.md +++ b/BUNDLE-README.md @@ -2,7 +2,7 @@ Hi, thanks for trying out the bundled version of the Uppy File Uploader. You can use this from a CDN -(``) +(``) or bundle it with your webapp. Note that the recommended way to use Uppy is to install it with yarn/npm and use diff --git a/README.md b/README.md index 611aafed1..261e5ab0b 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ npm install @uppy/core @uppy/dashboard @uppy/tus ``` Add CSS -[uppy.min.css](https://releases.transloadit.com/uppy/v5.2.3/uppy.min.css), +[uppy.min.css](https://releases.transloadit.com/uppy/v5.2.4/uppy.min.css), either to your HTML page’s `` or include in JS, if your bundler of choice supports it. @@ -117,7 +117,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. ```html @@ -128,7 +128,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. Uppy, Dashboard, Tus, - } from 'https://releases.transloadit.com/uppy/v5.2.3/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v5.2.4/uppy.min.mjs' const uppy = new Uppy() uppy.use(Dashboard, { target: '#files-drag-drop' }) diff --git a/packages/@uppy/companion/CHANGELOG.md b/packages/@uppy/companion/CHANGELOG.md index 94eea31b9..70f07e8a2 100644 --- a/packages/@uppy/companion/CHANGELOG.md +++ b/packages/@uppy/companion/CHANGELOG.md @@ -1,5 +1,12 @@ # @uppy/companion +## 6.2.2 + +### Patch Changes + +- 49db42d: Fix bug with 429 not returning JSON response with message +- 4652dc6: upgrade @aws-sdk/ deps in @uppy/companion + ## 6.2.1 ### Patch Changes diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 5917e5da8..4ebebb19a 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -1,6 +1,6 @@ { "name": "@uppy/companion", - "version": "6.2.1", + "version": "6.2.2", "description": "OAuth helper and remote fetcher for Uppy's (https://uppy.io) extensible file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox and Google Drive, S3 and more :dog:", "types": "lib/companion.d.ts", "author": "Transloadit.com", diff --git a/packages/@uppy/transloadit/CHANGELOG.md b/packages/@uppy/transloadit/CHANGELOG.md index 85be5f038..abb888e8a 100644 --- a/packages/@uppy/transloadit/CHANGELOG.md +++ b/packages/@uppy/transloadit/CHANGELOG.md @@ -1,5 +1,15 @@ # @uppy/transloadit +## 5.5.1 + +### Patch Changes + +- 4787960: Add type re-export for `AssemblyInstructionsInput` +- 2f6849d: Fix allowMultipleUploadBatches to prevent adding/removing files while an upload is in progress (#6156) +- 29d2772: remove monkey patch from uppy bundle package +- Updated dependencies [6b1abaa] + - @uppy/utils@7.2.0 + ## 5.5.0 ### Minor Changes diff --git a/packages/@uppy/transloadit/package.json b/packages/@uppy/transloadit/package.json index 123aaf629..44e087655 100644 --- a/packages/@uppy/transloadit/package.json +++ b/packages/@uppy/transloadit/package.json @@ -1,7 +1,7 @@ { "name": "@uppy/transloadit", "description": "The Transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and more", - "version": "5.5.0", + "version": "5.5.1", "license": "MIT", "type": "module", "sideEffects": false, diff --git a/packages/@uppy/utils/CHANGELOG.md b/packages/@uppy/utils/CHANGELOG.md index 31f5eb95c..9ee5d9d27 100644 --- a/packages/@uppy/utils/CHANGELOG.md +++ b/packages/@uppy/utils/CHANGELOG.md @@ -1,5 +1,11 @@ # @uppy/utils +## 7.2.0 + +### Minor Changes + +- 6b1abaa: Introduce modern, minimal TaskQueue to replace RateLimitedQueue + ## 7.1.5 ### Patch Changes diff --git a/packages/@uppy/utils/package.json b/packages/@uppy/utils/package.json index 77ead056b..aaba91511 100644 --- a/packages/@uppy/utils/package.json +++ b/packages/@uppy/utils/package.json @@ -1,7 +1,7 @@ { "name": "@uppy/utils", "description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.", - "version": "7.1.5", + "version": "7.2.0", "license": "MIT", "type": "module", "sideEffects": false, diff --git a/packages/@uppy/xhr-upload/CHANGELOG.md b/packages/@uppy/xhr-upload/CHANGELOG.md index a9e7e367d..be839990e 100644 --- a/packages/@uppy/xhr-upload/CHANGELOG.md +++ b/packages/@uppy/xhr-upload/CHANGELOG.md @@ -1,5 +1,16 @@ # @uppy/xhr-upload +## 5.2.0 + +### Minor Changes + +- 6b1abaa: Introduce modern, minimal TaskQueue to replace RateLimitedQueue + +### Patch Changes + +- Updated dependencies [6b1abaa] + - @uppy/utils@7.2.0 + ## 5.1.1 ### Patch Changes diff --git a/packages/@uppy/xhr-upload/package.json b/packages/@uppy/xhr-upload/package.json index 66650a2eb..8b06983ac 100644 --- a/packages/@uppy/xhr-upload/package.json +++ b/packages/@uppy/xhr-upload/package.json @@ -1,7 +1,7 @@ { "name": "@uppy/xhr-upload", "description": "Plain and simple classic HTML multipart form uploads with Uppy, as well as uploads using the HTTP PUT method.", - "version": "5.1.1", + "version": "5.2.0", "license": "MIT", "type": "module", "sideEffects": false, diff --git a/packages/uppy/CHANGELOG.md b/packages/uppy/CHANGELOG.md index 2a91e5431..80c2e85d7 100644 --- a/packages/uppy/CHANGELOG.md +++ b/packages/uppy/CHANGELOG.md @@ -1,5 +1,18 @@ # uppy +## 5.2.4 + +### Patch Changes + +- 29d2772: remove monkey patch from uppy bundle package +- a86c624: upgrade esbuild in uppy to "^0.27.0" +- Updated dependencies [6b1abaa] +- Updated dependencies [4787960] +- Updated dependencies [2f6849d] +- Updated dependencies [29d2772] + - @uppy/xhr-upload@5.2.0 + - @uppy/transloadit@5.5.1 + ## 5.2.3 ### Patch Changes diff --git a/packages/uppy/package.json b/packages/uppy/package.json index e13b4074c..88d580041 100644 --- a/packages/uppy/package.json +++ b/packages/uppy/package.json @@ -1,7 +1,7 @@ { "name": "uppy", "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:", - "version": "5.2.3", + "version": "5.2.4", "license": "MIT", "main": "lib/index.js", "module": "lib/index.js", From 71a34b9b378660291a1019150cfee1c86ce66261 Mon Sep 17 00:00:00 2001 From: Prakash Date: Wed, 8 Apr 2026 17:35:59 +0530 Subject: [PATCH 05/33] remove stale heroku job (#6254) context : https://transloadit.slack.com/archives/C0FMW9PSB/p1774888069486179 --- .github/workflows/companion-deploy.yml | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/.github/workflows/companion-deploy.yml b/.github/workflows/companion-deploy.yml index 97ebed0c8..b7696d1b1 100644 --- a/.github/workflows/companion-deploy.yml +++ b/.github/workflows/companion-deploy.yml @@ -69,25 +69,4 @@ jobs: platforms: linux/amd64,linux/arm64 file: Dockerfile tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} - - heroku: - name: Heroku - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v6 - - name: Alter dockerfile - run: | - sed -i 's/^EXPOSE 3020$/EXPOSE $PORT/g' Dockerfile - # https://github.com/AkhileshNS/heroku-deploy/issues/188 - - name: Install Heroku CLI - run: | - curl https://cli-assets.heroku.com/install.sh | sh - - name: Deploy to heroku - uses: akhileshns/heroku-deploy@e3eb99d45a8e2ec5dca08735e089607befa4bf28 # v3.14.15 - with: - heroku_api_key: ${{secrets.HEROKU_API_KEY}} - heroku_app_name: companion-demo - heroku_email: ${{secrets.HEROKU_EMAIL}} - usedocker: true + labels: ${{ steps.docker_meta.outputs.labels }} \ No newline at end of file From b9253f797a3a782cfc9d1a5ec84e5c3716642d5c Mon Sep 17 00:00:00 2001 From: Enver <39167353+EnverUsta@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:30:02 +0300 Subject: [PATCH 06/33] @uppy/dashboard: My Device button respects fileManagerSelectionType (#6258) Fixes #6256 ## Problem When `fileManagerSelectionType` is set to `'folders'`, clicking the **My Device** tab/button still opens the file picker instead of the folder picker. The inline "browse" link in the tagline correctly respects the setting, but `renderMyDeviceAcquirer` in `AddFiles.tsx` always called `triggerFileInputClick` regardless of the `fileManagerSelectionType` prop. ## Solution `renderMyDeviceAcquirer` now reads `fileManagerSelectionType` and calls `triggerFolderInputClick` when set to `'folders'`, or `triggerFileInputClick` for `'files'` and `'both'`. For `'both'` mode, the button defaults to file selection because a single HTML `` cannot handle both files and folders simultaneously (`webkitdirectory` is all-or-nothing). The folder picker remains accessible via the tagline's "browse folders" link. --------- Co-authored-by: Prakash --- .changeset/few-plants-pump.md | 5 + .../dashboard/src/components/AddFiles.tsx | 9 +- packages/@uppy/dashboard/src/index.test.ts | 102 ++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 .changeset/few-plants-pump.md diff --git a/.changeset/few-plants-pump.md b/.changeset/few-plants-pump.md new file mode 100644 index 000000000..a094e2988 --- /dev/null +++ b/.changeset/few-plants-pump.md @@ -0,0 +1,5 @@ +--- +"@uppy/dashboard": patch +--- + +fix "My Device" button in dashboard, it now respects the fileManagerSelectionType. diff --git a/packages/@uppy/dashboard/src/components/AddFiles.tsx b/packages/@uppy/dashboard/src/components/AddFiles.tsx index bbfd6ac95..643170295 100644 --- a/packages/@uppy/dashboard/src/components/AddFiles.tsx +++ b/packages/@uppy/dashboard/src/components/AddFiles.tsx @@ -106,6 +106,13 @@ class AddFiles extends Component { } private renderMyDeviceAcquirer = () => { + // Cannot select both files and folders at once (webkitdirectory is all-or-nothing), + // so in 'both' mode the folder picker remains accessible via the tagline browse link. + const triggerMyDeviceInputClick = + this.props.fileManagerSelectionType === 'folders' + ? this.triggerFolderInputClick + : this.triggerFileInputClick + return (
{ role="tab" tabIndex={0} data-uppy-super-focusable - onClick={this.triggerFileInputClick} + onClick={triggerMyDeviceInputClick} >
{ core.destroy() }) + + describe('My Device acquirer respects fileManagerSelectionType', () => { + // `showNativePhotoCameraButton: true` is used to force the My Device tab + // to render — Dashboard hides it when it would be the only entry in the list + // (see `hasOnlyMyDevice` in AddFiles.tsx). + const mountDashboard = ( + fileManagerSelectionType: 'files' | 'folders' | 'both', + ) => { + document.body.innerHTML = '' + const core = new Core() + core.use(DashboardPlugin, { + inline: true, + target: 'body', + fileManagerSelectionType, + showNativePhotoCameraButton: true, + }) + return core + } + + const getInputs = () => { + const fileInput = document.querySelector( + '.uppy-Dashboard-input:not([webkitdirectory])', + )! + const folderInput = document.querySelector( + '.uppy-Dashboard-input[webkitdirectory]', + )! + return { fileInput, folderInput } + } + + const clickMyDeviceTab = () => { + const tab = document.querySelector( + '[data-uppy-acquirer-id="MyDevice"] button[role="tab"]', + )! + tab.click() + } + + it('triggers the folder input when set to "folders"', () => { + const core = mountDashboard('folders') + const { fileInput, folderInput } = getInputs() + + let fileClicked = false + let folderClicked = false + fileInput.addEventListener('click', () => { + fileClicked = true + }) + folderInput.addEventListener('click', () => { + folderClicked = true + }) + + clickMyDeviceTab() + + expect(folderClicked).toBe(true) + expect(fileClicked).toBe(false) + + core.destroy() + }) + + it('triggers the file input when set to "files"', () => { + const core = mountDashboard('files') + const { fileInput, folderInput } = getInputs() + + let fileClicked = false + let folderClicked = false + fileInput.addEventListener('click', () => { + fileClicked = true + }) + folderInput.addEventListener('click', () => { + folderClicked = true + }) + + clickMyDeviceTab() + + expect(fileClicked).toBe(true) + expect(folderClicked).toBe(false) + + core.destroy() + }) + + // `both` mode intentionally falls back to the file picker because a single + // HTML @@ -21,64 +23,73 @@ const closePageHtml = (origin) => ` Authentication failed. ` -/** - * - * @param {object} req - * @param {object} res - * @param {Function} next - */ -export default function callback(req, res, next) { - const { providerName } = req.params - - const grant = req.session.grant || {} +export default function callback( + req: Request, + res: Response, + next: NextFunction, +): void { + const providerName = req.params['providerName'] + if (providerName == null || providerName.length === 0) { + res.sendStatus(400) + return + } + const secret = req.companion.options.secret const grantDynamic = oAuthState.getGrantDynamicFromRequest(req) const origin = grantDynamic.state && - oAuthState.getFromState( - grantDynamic.state, - 'origin', - req.companion.options.secret, - ) + oAuthState.getFromState(grantDynamic.state, 'origin', secret) + const originString = typeof origin === 'string' ? origin : undefined - if (!grant.response?.access_token) { + const accessToken = req.session?.grant?.response?.access_token + const refreshToken = req.session?.grant?.response?.refresh_token + + if (!accessToken) { logger.debug( `Did not receive access token for provider ${providerName}`, - null, + undefined, req.id, ) - logger.debug(grant.response, 'callback.oauth.resp', req.id) - return res.status(400).send(closePageHtml(origin)) + logger.debug(req.session?.grant?.response, 'callback.oauth.resp', req.id) + res.status(400).send(closePageHtml(originString)) + return } - const { access_token: accessToken, refresh_token: refreshToken } = - grant.response + const { providerClass } = req.companion + if (!providerClass) { + res.sendStatus(400) + return + } req.companion.providerUserSession = { accessToken, refreshToken, // might be undefined for some providers - ...req.companion.providerClass.grantDynamicToUserSession({ grantDynamic }), + ...providerClass.grantDynamicToUserSession({ grantDynamic }), } logger.debug( `Generating auth token for provider ${providerName}. refreshToken: ${refreshToken ? 'yes' : 'no'}`, - null, + undefined, req.id, ) const uppyAuthToken = tokenService.generateEncryptedAuthToken( { [providerName]: req.companion.providerUserSession }, - req.companion.options.secret, - req.companion.providerClass.authStateExpiry, + secret, + providerClass.authStateExpiry, ) tokenService.addToCookiesIfNeeded( req, res, uppyAuthToken, - req.companion.providerClass.authStateExpiry, + providerClass.authStateExpiry, ) - return res.redirect( + if (!req.companion.buildURL) { + res.sendStatus(500) + return + } + res.redirect( req.companion.buildURL( `/${providerName}/send-token?uppyAuthToken=${uppyAuthToken}`, true, diff --git a/packages/@uppy/companion/src/server/controllers/connect.js b/packages/@uppy/companion/src/server/controllers/connect.ts similarity index 62% rename from packages/@uppy/companion/src/server/controllers/connect.js rename to packages/@uppy/companion/src/server/controllers/connect.ts index 36bcadf2b..2d62c4d95 100644 --- a/packages/@uppy/companion/src/server/controllers/connect.js +++ b/packages/@uppy/companion/src/server/controllers/connect.ts @@ -1,13 +1,16 @@ +import type { CorsOptions } from 'cors' +import type { NextFunction, Request, Response } from 'express' import * as oAuthState from '../helpers/oauth-state.js' +import { isRecord } from '../helpers/type-guards.js' /** * Derived from `cors` npm package. * @see https://github.com/expressjs/cors/blob/791983ebc0407115bc8ae8e64830d440da995938/lib/index.js#L19-L34 - * @param {string} origin - * @param {*} allowedOrigins - * @returns {boolean} */ -function isOriginAllowed(origin, allowedOrigins) { +function isOriginAllowed( + origin: string, + allowedOrigins: CorsOptions['origin'], +): boolean { if (Array.isArray(allowedOrigins)) { return allowedOrigins.some((allowedOrigin) => isOriginAllowed(origin, allowedOrigin), @@ -16,33 +19,55 @@ function isOriginAllowed(origin, allowedOrigins) { if (typeof allowedOrigins === 'string') { return origin === allowedOrigins } - return allowedOrigins.test?.(origin) ?? !!allowedOrigins + if (allowedOrigins instanceof RegExp) { + return allowedOrigins.test(origin) + } + return !!allowedOrigins } -const queryString = (params, prefix = '?') => { +const queryString = (params: Record, prefix = '?'): string => { const str = new URLSearchParams(params).toString() return str ? `${prefix}${str}` : '' } -function encodeStateAndRedirect(req, res, stateObj) { +function encodeStateAndRedirect( + req: Request, + res: Response, + stateObj: oAuthState.OAuthState, +): void { const { secret } = req.companion.options const state = oAuthState.encodeState(stateObj, secret) const { providerClass, providerGrantConfig } = req.companion + if (!providerClass || !req.companion.buildURL) { + res.sendStatus(400) + return + } // pass along grant's dynamic config (if specified for the provider in its grant config `dynamic` section) // this is needed for things like custom oauth domain (e.g. webdav) + const dynamicKeys = providerGrantConfig?.dynamic ?? [] const grantDynamicConfig = Object.fromEntries( - providerGrantConfig.dynamic?.flatMap((dynamicKey) => { + dynamicKeys.flatMap((dynamicKey) => { const queryValue = req.query[dynamicKey] + const queryValueString = + typeof queryValue === 'string' + ? queryValue + : Array.isArray(queryValue) && typeof queryValue[0] === 'string' + ? queryValue[0] + : undefined // note: when using credentialsURL (dynamic oauth credentials), dynamic has ['key', 'secret', 'redirect_uri'] // but in that case, query string is empty, so we need to only fetch these parameters from QS if they exist. - if (!queryValue) return [] - return [[dynamicKey, queryValue]] - }) || [], + if (!queryValueString) return [] + return [[dynamicKey, queryValueString]] + }), ) const { oauthProvider } = providerClass + if (oauthProvider == null || oauthProvider.length === 0) { + res.sendStatus(400) + return + } const qs = queryString({ ...grantDynamicConfig, state, @@ -52,10 +77,13 @@ function encodeStateAndRedirect(req, res, stateObj) { res.redirect(req.companion.buildURL(`/connect/${oauthProvider}${qs}`, true)) } -function getClientOrigin(base64EncodedState) { +function getClientOrigin(base64EncodedState: unknown): string | undefined { + if (typeof base64EncodedState !== 'string') return undefined try { - const { origin } = JSON.parse(atob(base64EncodedState)) - return origin + const parsed: unknown = JSON.parse(atob(base64EncodedState)) + if (!isRecord(parsed)) return undefined + const origin = parsed['origin'] + return typeof origin === 'string' ? origin : undefined } catch { return undefined } @@ -78,39 +106,44 @@ function getClientOrigin(base64EncodedState) { * That's why we use the client-provided base64-encoded parameter, check if it * matches origin(s) allowed in `corsOrigins` Companion option, and use that as * our `targetOrigin` for the `window.postMessage()` call (see `send-token.js`). - * - * @param {object} req - * @param {object} res */ -export default function connect(req, res, next) { +export default function connect( + req: Request, + res: Response, + next: NextFunction, +): void { const stateObj = oAuthState.generateState() - if (req.companion.options.server.oauthDomain) { + if (req.companion.options.server.oauthDomain && req.companion.buildURL) { stateObj.companionInstance = req.companion.buildURL('', true) } - if (req.query.uppyPreAuthToken) { - stateObj.preAuthToken = req.query.uppyPreAuthToken + const preAuthTokenValue = req.query['uppyPreAuthToken'] + if (typeof preAuthTokenValue === 'string') { + stateObj.preAuthToken = preAuthTokenValue } // Get the computed header generated by `cors` in a previous middleware. stateObj.origin = res.getHeader('Access-Control-Allow-Origin') - let clientOrigin + let clientOrigin: string | undefined if (!stateObj.origin) { - clientOrigin = getClientOrigin(req.query.state) + clientOrigin = getClientOrigin(req.query['state']) } if (!stateObj.origin && clientOrigin) { const { corsOrigins } = req.companion.options if (typeof corsOrigins === 'function') { corsOrigins(clientOrigin, (err, finalOrigin) => { - if (err) next(err) + if (err) { + next(err) + return + } stateObj.origin = finalOrigin encodeStateAndRedirect(req, res, stateObj) }) return } - if (isOriginAllowed(clientOrigin, req.companion.options.corsOrigins)) { + if (isOriginAllowed(clientOrigin, req.companion.options['corsOrigins'])) { stateObj.origin = clientOrigin } } diff --git a/packages/@uppy/companion/src/server/controllers/deauth-callback.js b/packages/@uppy/companion/src/server/controllers/deauth-callback.ts similarity index 55% rename from packages/@uppy/companion/src/server/controllers/deauth-callback.js rename to packages/@uppy/companion/src/server/controllers/deauth-callback.ts index c73b1bd01..6ec962f8c 100644 --- a/packages/@uppy/companion/src/server/controllers/deauth-callback.js +++ b/packages/@uppy/companion/src/server/controllers/deauth-callback.ts @@ -1,21 +1,28 @@ +import type { NextFunction, Request, Response } from 'express' import { respondWithError } from '../provider/error.js' export default async function deauthCallback( - { body, companion, headers }, - res, - next, -) { + req: Request, + res: Response, + next: NextFunction, +): Promise { + const { body, companion, headers } = req + const { provider } = companion + if (!provider) { + res.sendStatus(400) + return + } // we need the provider instance to decide status codes because // this endpoint does not cater to a uniform client. // It doesn't respond to Uppy client like other endpoints. // Instead it responds to the providers themselves. try { - const { data, status } = await companion.provider.deauthorizationCallback({ + const { data, status } = await provider.deauthorizationCallback({ companion, body, headers, }) - res.status(status || 200).json(data) + res.status(status ?? 200).json(data) } catch (err) { if (respondWithError(err, res)) return next(err) diff --git a/packages/@uppy/companion/src/server/controllers/get.js b/packages/@uppy/companion/src/server/controllers/get.js deleted file mode 100644 index b5316ebfb..000000000 --- a/packages/@uppy/companion/src/server/controllers/get.js +++ /dev/null @@ -1,24 +0,0 @@ -import { startDownUpload } from '../helpers/upload.js' -import logger from '../logger.js' -import { respondWithError } from '../provider/error.js' - -export default async function get(req, res) { - const { id } = req.params - const { providerUserSession } = req.companion - const { provider } = req.companion - - async function getSize() { - return provider.size({ id, providerUserSession, query: req.query }) - } - - const download = () => - provider.download({ id, providerUserSession, query: req.query }) - - try { - await startDownUpload({ req, res, getSize, download }) - } catch (err) { - logger.error(err, 'controller.get.error', req.id) - if (respondWithError(err, res)) return - res.status(500).json({ message: 'Failed to download file' }) - } -} diff --git a/packages/@uppy/companion/src/server/controllers/get.ts b/packages/@uppy/companion/src/server/controllers/get.ts new file mode 100644 index 000000000..e54270d24 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/get.ts @@ -0,0 +1,37 @@ +import type { Request, Response } from 'express' +import { startDownUpload } from '../helpers/upload.js' +import logger from '../logger.js' +import { respondWithError } from '../provider/error.js' + +export default async function get(req: Request, res: Response): Promise { + const id = req.params['id'] + if (typeof id !== 'string' || id.length === 0) { + res.sendStatus(400) + return + } + const { providerUserSession } = req.companion + const { provider } = req.companion + if (!provider) { + res.sendStatus(400) + return + } + + const getSize = async () => + provider.size({ id, providerUserSession, query: req.query }) + + const download = () => + provider.download({ + id, + providerUserSession, + query: req.query, + companion: req.companion, + }) + + try { + await startDownUpload({ req, res, getSize, download }) + } catch (err) { + logger.error(err, 'controller.get.error', req.id) + if (respondWithError(err, res)) return + res.status(500).json({ message: 'Failed to download file' }) + } +} diff --git a/packages/@uppy/companion/src/server/controllers/googlePicker.js b/packages/@uppy/companion/src/server/controllers/googlePicker.js deleted file mode 100644 index a020d7d0d..000000000 --- a/packages/@uppy/companion/src/server/controllers/googlePicker.js +++ /dev/null @@ -1,49 +0,0 @@ -import assert from 'node:assert' -import express from 'express' -import { downloadURL } from '../download.js' -import { validateURL } from '../helpers/request.js' -import { startDownUpload } from '../helpers/upload.js' -import logger from '../logger.js' -import { respondWithError } from '../provider/error.js' -import { streamGoogleFile } from '../provider/google/drive/index.js' - -const getAuthHeader = (token) => ({ authorization: `Bearer ${token}` }) - -/** - * - * @param {object} req expressJS request object - * @param {object} res expressJS response object - */ -const get = async (req, res) => { - try { - logger.debug('Google Picker file import handler running', null, req.id) - - const allowLocalUrls = false - - const { accessToken, platform, fileId } = req.body - - assert(platform === 'drive' || platform === 'photos') - - if (platform === 'photos' && !validateURL(req.body.url, allowLocalUrls)) { - res.status(400).json({ error: 'Invalid URL' }) - return - } - - const download = () => { - if (platform === 'drive') { - return streamGoogleFile({ token: accessToken, id: fileId }) - } - return downloadURL(req.body.url, allowLocalUrls, req.id, { - headers: getAuthHeader(accessToken), - }) - } - - await startDownUpload({ req, res, download, getSize: undefined }) - } catch (err) { - logger.error(err, 'controller.googlePicker.error', req.id) - if (respondWithError(err, res)) return - res.status(500).json({ message: 'failed to fetch Google Picker URL' }) - } -} - -export default () => express.Router().post('/get', express.json(), get) diff --git a/packages/@uppy/companion/src/server/controllers/googlePicker.ts b/packages/@uppy/companion/src/server/controllers/googlePicker.ts new file mode 100644 index 000000000..28fde95e6 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/googlePicker.ts @@ -0,0 +1,69 @@ +import type { Request, Response } from 'express' +import express from 'express' +import { z } from 'zod' +import { downloadURL } from '../download.js' +import { validateURL } from '../helpers/request.js' +import { startDownUpload } from '../helpers/upload.js' +import logger from '../logger.js' +import { respondWithError } from '../provider/error.js' +import { streamGoogleFile } from '../provider/google/drive/index.js' + +const getAuthHeader = (token: string): { authorization: string } => ({ + authorization: `Bearer ${token}`, +}) + +const googlePickerBodySchema = z.discriminatedUnion('platform', [ + z.object({ + platform: z.literal('drive'), + accessToken: z.string().min(1), + fileId: z.string().min(1), + }), + z.object({ + platform: z.literal('photos'), + accessToken: z.string().min(1), + url: z.string().min(1), + }), +]) + +const get = async (req: Request, res: Response): Promise => { + try { + logger.debug('Google Picker file import handler running', undefined, req.id) + + const allowLocalUrls = false + + const parsedBody = googlePickerBodySchema.safeParse(req.body) + if (!parsedBody.success) { + res.status(400).json({ error: 'Invalid request body' }) + return + } + const { accessToken, platform } = parsedBody.data + + if ( + platform === 'photos' && + !validateURL(parsedBody.data.url, allowLocalUrls) + ) { + res.status(400).json({ error: 'Invalid URL' }) + return + } + + const download = () => { + if (platform === 'drive') { + return streamGoogleFile({ + token: accessToken, + id: parsedBody.data.fileId, + }) + } + return downloadURL(parsedBody.data.url, allowLocalUrls, req.id, { + headers: getAuthHeader(accessToken), + }) + } + + await startDownUpload({ req, res, download, getSize: undefined }) + } catch (err) { + logger.error(err, 'controller.googlePicker.error', req.id) + if (respondWithError(err, res)) return + res.status(500).json({ message: 'failed to fetch Google Picker URL' }) + } +} + +export default () => express.Router().post('/get', express.json(), get) diff --git a/packages/@uppy/companion/src/server/controllers/index.js b/packages/@uppy/companion/src/server/controllers/index.ts similarity index 100% rename from packages/@uppy/companion/src/server/controllers/index.js rename to packages/@uppy/companion/src/server/controllers/index.ts diff --git a/packages/@uppy/companion/src/server/controllers/list.js b/packages/@uppy/companion/src/server/controllers/list.js deleted file mode 100644 index 723d9015d..000000000 --- a/packages/@uppy/companion/src/server/controllers/list.js +++ /dev/null @@ -1,18 +0,0 @@ -import { respondWithError } from '../provider/error.js' - -export default async function list({ query, params, companion }, res, next) { - const { providerUserSession } = companion - - try { - const data = await companion.provider.list({ - companion, - providerUserSession, - directory: params.id, - query, - }) - res.json(data) - } catch (err) { - if (respondWithError(err, res)) return - next(err) - } -} diff --git a/packages/@uppy/companion/src/server/controllers/list.ts b/packages/@uppy/companion/src/server/controllers/list.ts new file mode 100644 index 000000000..f6acfa4d3 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/list.ts @@ -0,0 +1,28 @@ +import type { NextFunction, Request, Response } from 'express' +import { respondWithError } from '../provider/error.js' + +export default async function list( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const { query, params, companion } = req + const { providerUserSession, provider } = companion + if (!provider) { + res.sendStatus(400) + return + } + + try { + const data = await provider.list({ + companion, + providerUserSession, + directory: params['id'], + query, + }) + res.json(data) + } catch (err) { + if (respondWithError(err, res)) return + next(err) + } +} diff --git a/packages/@uppy/companion/src/server/controllers/logout.js b/packages/@uppy/companion/src/server/controllers/logout.js deleted file mode 100644 index c170e45e9..000000000 --- a/packages/@uppy/companion/src/server/controllers/logout.js +++ /dev/null @@ -1,42 +0,0 @@ -import * as tokenService from '../helpers/jwt.js' -import { respondWithError } from '../provider/error.js' - -/** - * - * @param {object} req - * @param {object} res - */ -export default async function logout(req, res, next) { - const cleanSession = () => { - if (req.session.grant) { - req.session.grant.state = null - req.session.grant.dynamic = null - } - } - const { companion } = req - const { providerUserSession } = companion - - if (!providerUserSession) { - cleanSession() - res.json({ ok: true, revoked: false }) - return - } - - try { - const data = await companion.provider.logout({ - providerUserSession, - companion, - }) - delete companion.providerUserSession - tokenService.removeFromCookies( - res, - companion.options, - companion.providerClass.oauthProvider, - ) - cleanSession() - res.json({ ok: true, ...data }) - } catch (err) { - if (respondWithError(err, res)) return - next(err) - } -} diff --git a/packages/@uppy/companion/src/server/controllers/logout.ts b/packages/@uppy/companion/src/server/controllers/logout.ts new file mode 100644 index 000000000..7c6527282 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/logout.ts @@ -0,0 +1,47 @@ +import type { NextFunction, Request, Response } from 'express' +import * as tokenService from '../helpers/jwt.js' +import { respondWithError } from '../provider/error.js' + +export default async function logout( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const cleanSession = (): void => { + const grant = req.session?.grant + if (grant) { + grant['state'] = null + grant['dynamic'] = null + } + } + const { companion } = req + const { providerUserSession, provider, providerClass } = companion + + if (!providerUserSession) { + cleanSession() + res.json({ ok: true, revoked: false }) + return + } + if (!provider) { + cleanSession() + res.sendStatus(400) + return + } + + try { + const out = await provider.logout({ + providerUserSession, + companion, + }) + delete companion.providerUserSession + const oauthProvider = providerClass?.oauthProvider + if (oauthProvider != null) { + tokenService.removeFromCookies(res, companion.options, oauthProvider) + } + cleanSession() + res.json({ ok: true, ...out }) + } catch (err) { + if (respondWithError(err, res)) return + next(err) + } +} diff --git a/packages/@uppy/companion/src/server/controllers/oauth-redirect.js b/packages/@uppy/companion/src/server/controllers/oauth-redirect.js deleted file mode 100644 index 5a9279e5f..000000000 --- a/packages/@uppy/companion/src/server/controllers/oauth-redirect.js +++ /dev/null @@ -1,43 +0,0 @@ -import qs from 'node:querystring' -import { URL } from 'node:url' -import * as oAuthState from '../helpers/oauth-state.js' -import { hasMatch } from '../helpers/utils.js' - -/** - * - * @param {object} req - * @param {object} res - */ -export default function oauthRedirect(req, res) { - const params = qs.stringify(req.query) - const { oauthProvider } = req.companion.providerClass - if (!req.companion.options.server.oauthDomain) { - res.redirect( - req.companion.buildURL( - `/connect/${oauthProvider}/callback?${params}`, - true, - ), - ) - return - } - - const { state } = oAuthState.getGrantDynamicFromRequest(req) - if (!state) { - res.status(400).send('Cannot find state in session') - return - } - const handler = oAuthState.getFromState( - state, - 'companionInstance', - req.companion.options.secret, - ) - const handlerHostName = new URL(handler).host - - if (hasMatch(handlerHostName, req.companion.options.server.validHosts)) { - const url = `${handler}/connect/${oauthProvider}/callback?${params}` - res.redirect(url) - return - } - - res.status(400).send('Invalid Host in state') -} diff --git a/packages/@uppy/companion/src/server/controllers/oauth-redirect.ts b/packages/@uppy/companion/src/server/controllers/oauth-redirect.ts new file mode 100644 index 000000000..cb177d88a --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/oauth-redirect.ts @@ -0,0 +1,58 @@ +import qs from 'node:querystring' +import { URL } from 'node:url' +import type { Request, Response } from 'express' +import * as oAuthState from '../helpers/oauth-state.js' +import { hasMatch } from '../helpers/utils.js' + +export default function oauthRedirect(req: Request, res: Response): void { + const secret = req.companion.options.secret + const queryParams: Record = {} + for (const [key, value] of Object.entries(req.query)) { + if (typeof value === 'string') { + queryParams[key] = value + continue + } + if (Array.isArray(value) && value.every((i) => typeof i === 'string')) { + queryParams[key] = value + } + } + const params = qs.stringify(queryParams) + const { providerClass, buildURL } = req.companion + const oauthProvider = providerClass?.oauthProvider + if (!buildURL) { + res.sendStatus(500) + return + } + if (!req.companion.options.server.oauthDomain) { + res.redirect(buildURL(`/connect/${oauthProvider}/callback?${params}`, true)) + return + } + + const { state } = oAuthState.getGrantDynamicFromRequest(req) + if (!state) { + res.status(400).send('Cannot find state in session') + return + } + const handler = oAuthState.getFromState(state, 'companionInstance', secret) + if (typeof handler !== 'string' || handler.length === 0) { + res.status(400).send('Invalid Host in state') + return + } + let handlerHostName: string + try { + handlerHostName = new URL(handler).host + } catch { + res.status(400).send('Invalid Host in state') + return + } + + if ( + hasMatch(handlerHostName, req.companion.options.server.validHosts ?? []) + ) { + const url = `${handler}/connect/${oauthProvider}/callback?${params}` + res.redirect(url) + return + } + + res.status(400).send('Invalid Host in state') +} diff --git a/packages/@uppy/companion/src/server/controllers/preauth.js b/packages/@uppy/companion/src/server/controllers/preauth.js deleted file mode 100644 index ff21d67d3..000000000 --- a/packages/@uppy/companion/src/server/controllers/preauth.js +++ /dev/null @@ -1,21 +0,0 @@ -import * as tokenService from '../helpers/jwt.js' -import logger from '../logger.js' - -export default function preauth(req, res) { - if (!req.body || !req.body.params) { - logger.info('invalid request data received', 'preauth.bad') - return res.sendStatus(400) - } - - const providerConfig = - req.companion.options.providerOptions[req.params.providerName] - if (!providerConfig?.credentialsURL) { - return res.sendStatus(501) - } - - const preAuthToken = tokenService.generateEncryptedToken( - req.body.params, - req.companion.options.preAuthSecret, - ) - return res.json({ token: preAuthToken }) -} diff --git a/packages/@uppy/companion/src/server/controllers/preauth.ts b/packages/@uppy/companion/src/server/controllers/preauth.ts new file mode 100644 index 000000000..e3b30a226 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/preauth.ts @@ -0,0 +1,39 @@ +import type { Request, Response } from 'express' +import * as tokenService from '../helpers/jwt.js' +import { isRecord } from '../helpers/type-guards.js' +import logger from '../logger.js' + +export default function preauth(req: Request, res: Response): void { + const body = isRecord(req.body) ? req.body : undefined + const params = + body && Object.hasOwn(body, 'params') ? body['params'] : undefined + if (!params) { + logger.info('invalid request data received', 'preauth.bad') + res.sendStatus(400) + return + } + + const providerName = req.params['providerName'] + if (providerName == null || providerName.length === 0) { + res.sendStatus(400) + return + } + + const credentialsURL = + req.companion.options.providerOptions[providerName]?.credentialsURL + if (!credentialsURL) { + res.sendStatus(501) + return + } + + const { preAuthSecret } = req.companion.options + if (preAuthSecret == null) { + res.sendStatus(500) + return + } + const preAuthToken = tokenService.generateEncryptedToken( + params, + preAuthSecret, + ) + res.json({ token: preAuthToken }) +} diff --git a/packages/@uppy/companion/src/server/controllers/refresh-token.js b/packages/@uppy/companion/src/server/controllers/refresh-token.ts similarity index 56% rename from packages/@uppy/companion/src/server/controllers/refresh-token.js rename to packages/@uppy/companion/src/server/controllers/refresh-token.ts index 2ff2124cd..c6d5ab5ac 100644 --- a/packages/@uppy/companion/src/server/controllers/refresh-token.js +++ b/packages/@uppy/companion/src/server/controllers/refresh-token.ts @@ -1,3 +1,4 @@ +import type { NextFunction, Request, Response } from 'express' import * as tokenService from '../helpers/jwt.js' import logger from '../logger.js' import { respondWithError } from '../provider/error.js' @@ -5,27 +6,39 @@ import { respondWithError } from '../provider/error.js' // https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Get-refresh-token-from-access-token/td-p/596739 // https://developers.dropbox.com/oauth-guide // https://github.com/simov/grant/issues/149 -export default async function refreshToken(req, res, next) { - const { providerName } = req.params +export default async function refreshToken( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const providerName = req.params['providerName'] + if (providerName == null) { + res.sendStatus(400) + return + } + const { secret } = req.companion.options - const { key: clientId, secret: clientSecret } = req.companion.options - .providerOptions[providerName] ?? { __proto__: null } - const { redirect_uri: redirectUri } = req.companion.providerGrantConfig + const providerConfig = req.companion.options.providerOptions?.[providerName] + const clientId = providerConfig?.key + const clientSecret = providerConfig?.secret + const redirectUri = req.companion.providerGrantConfig?.redirect_uri + const { provider, providerClass } = req.companion const { providerUserSession } = req.companion // not all providers have refresh tokens - if ( - providerUserSession.refreshToken == null || - providerUserSession.refreshToken === '' - ) { + if (!providerUserSession?.refreshToken) { logger.warn('Tried to refresh token without having a token') res.sendStatus(401) return } + if (!provider || !providerClass) { + res.sendStatus(400) + return + } try { - const data = await req.companion.provider.refreshToken({ + const { accessToken } = await provider.refreshToken({ redirectUri, clientId, clientSecret, @@ -34,25 +47,25 @@ export default async function refreshToken(req, res, next) { req.companion.providerUserSession = { ...providerUserSession, - accessToken: data.accessToken, + accessToken, } logger.debug( `Generating refreshed auth token for provider ${providerName}`, - null, + undefined, req.id, ) const uppyAuthToken = tokenService.generateEncryptedAuthToken( { [providerName]: req.companion.providerUserSession }, - req.companion.options.secret, - req.companion.providerClass.authStateExpiry, + secret, + providerClass.authStateExpiry, ) tokenService.addToCookiesIfNeeded( req, res, uppyAuthToken, - req.companion.providerClass.authStateExpiry, + providerClass.authStateExpiry, ) res.send({ uppyAuthToken }) diff --git a/packages/@uppy/companion/src/server/controllers/s3.js b/packages/@uppy/companion/src/server/controllers/s3.ts similarity index 79% rename from packages/@uppy/companion/src/server/controllers/s3.js rename to packages/@uppy/companion/src/server/controllers/s3.ts index 3210c829b..dcfd4c4a1 100644 --- a/packages/@uppy/companion/src/server/controllers/s3.js +++ b/packages/@uppy/companion/src/server/controllers/s3.ts @@ -1,3 +1,4 @@ +import type { Part, S3Client } from '@aws-sdk/client-s3' import { AbortMultipartUploadCommand, CompleteMultipartUploadCommand, @@ -8,14 +9,29 @@ import { import { GetFederationTokenCommand, STSClient } from '@aws-sdk/client-sts' import { createPresignedPost } from '@aws-sdk/s3-presigned-post' import { getSignedUrl } from '@aws-sdk/s3-request-presigner' +import type { NextFunction, Request, Response, Router } from 'express' import express from 'express' +import type { CompanionRuntimeOptions } from '../../types/companion-options.js' +import { isRecord } from '../helpers/type-guards.js' import { getBucket, rfc2047EncodeMetadata, truncateFilename, } from '../helpers/utils.js' -export default function s3(config) { +export default function s3( + config: Pick< + CompanionRuntimeOptions['s3'], + | 'acl' + | 'getKey' + | 'expires' + | 'conditions' + | 'bucket' + | 'region' + | 'key' + | 'secret' + >, +): Router { if (typeof config.acl !== 'string' && config.acl != null) { throw new TypeError('s3: The `acl` option must be a string or null') } @@ -23,10 +39,11 @@ export default function s3(config) { throw new TypeError('s3: The `getKey` option must be a function') } - function getS3Client(req, res, createPresignedPostMode = false) { - /** - * @type {import('@aws-sdk/client-s3').S3Client} - */ + function getS3Client( + req: Request, + res: Response, + createPresignedPostMode = false, + ): S3Client | undefined { const client = createPresignedPostMode ? req.companion.s3ClientCreatePresignedPost : req.companion.s3Client @@ -52,11 +69,18 @@ export default function s3(config) { * - url - The URL to upload to. * - fields - Form fields to send along. */ - function getUploadParameters(req, res, next) { - const client = getS3Client(req, res) + function getUploadParameters( + req: Request, + res: Response, + next: NextFunction, + ) { + const client = getS3Client(req, res, true) if (!client) return - const { metadata = {}, filename } = req.query + const filename = req.query['filename'] + const metadata = isRecord(req.query['metadata']) + ? req.query['metadata'] + : {} // Validate filename is provided and non-empty if (typeof filename !== 'string' || filename === '') { @@ -88,17 +112,23 @@ export default function s3(config) { return } - const fields = { + const fields: Record = { success_action_status: '201', - 'content-type': req.query.type, + ...(typeof req.query['type'] === 'string' && { + 'content-type': req.query['type'], + }), } - if (config.acl != null) fields.acl = config.acl + if (config.acl != null) fields['acl'] = config.acl - Object.keys(metadata).forEach((metadataKey) => { - fields[`x-amz-meta-${metadataKey}`] = metadata[metadataKey] + Object.entries(metadata).forEach(([metadataKey, value]) => { + if (typeof value !== 'string') return + fields[`x-amz-meta-${metadataKey}`] = value }) + // `createPresignedPost` sometimes pulls in a nested copy of `@aws-sdk/client-s3`, + // which makes the `S3Client` type nominally incompatible. The instance is still + // compatible at runtime. createPresignedPost(client, { Bucket: bucket, Expires: config.expires, @@ -129,11 +159,21 @@ export default function s3(config) { * - key - The object key in the S3 bucket. * - uploadId - The ID of this multipart upload, to be used in later requests. */ - function createMultipartUpload(req, res, next) { + function createMultipartUpload( + req: Request, + res: Response, + next: NextFunction, + ) { const client = getS3Client(req, res) if (!client) return - const { type, metadata = {}, filename } = req.body + const { + type, + filename, + metadata: maybeMetadata, + }: { type: unknown; filename: unknown; metadata: unknown } = req.body + + const metadata = isRecord(maybeMetadata) ? maybeMetadata : {} // Validate filename is provided and non-empty if (typeof filename !== 'string' || filename === '') { @@ -149,8 +189,6 @@ export default function s3(config) { req.companion.options.maxFilenameLength, ) - const key = config.getKey({ req, filename: truncatedFilename, metadata }) - const bucket = getBucket({ bucketOrFn: config.bucket, req, @@ -158,6 +196,8 @@ export default function s3(config) { metadata, }) + const key = config.getKey({ req, filename: truncatedFilename, metadata }) + if (typeof key !== 'string') { res.status(500).json({ error: 's3: filename returned from `getKey` must be a string', @@ -174,10 +214,9 @@ export default function s3(config) { Key: key, ContentType: type, Metadata: rfc2047EncodeMetadata(metadata), + ...(config.acl != null && { ACL: config.acl }), } - if (config.acl != null) params.ACL = config.acl - client.send(new CreateMultipartUploadCommand(params)).then((data) => { res.json({ key: data.Key, @@ -200,9 +239,10 @@ export default function s3(config) { * - ETag - a hash of this part's contents, used to refer to it. * - Size - size of this part. */ - function getUploadedParts(req, res, next) { + function getUploadedParts(req: Request, res: Response, next: NextFunction) { const client = getS3Client(req, res) if (!client) return + const s3Client = client const { uploadId } = req.params const { key } = req.query @@ -214,17 +254,18 @@ export default function s3(config) { }) return } + const keyStr = key const bucket = getBucket({ bucketOrFn: config.bucket, req }) - const parts = [] + const parts: Part[] = [] - function listPartsPage(startAt) { - client + function listPartsPage(startAt?: string) { + s3Client .send( new ListPartsCommand({ Bucket: bucket, - Key: key, + Key: keyStr, UploadId: uploadId, PartNumberMarker: startAt, }), @@ -254,13 +295,18 @@ export default function s3(config) { * Response JSON: * - url - The URL to upload to, including signed query parameters. */ - function signPartUpload(req, res, next) { + function signPartUpload(req: Request, res: Response, next: NextFunction) { const client = getS3Client(req, res) if (!client) return - const { uploadId, partNumber } = req.params - const { key } = req.query + const uploadId = req.params['uploadId'] + const partNumber = req.params['partNumber'] + const key = req.query['key'] + if (uploadId == null || uploadId.length === 0) { + res.status(400).json({ error: 's3: uploadId must be provided.' }) + return + } if (typeof key !== 'string') { res.status(400).json({ error: @@ -268,7 +314,7 @@ export default function s3(config) { }) return } - if (!parseInt(partNumber, 10)) { + if (partNumber == null || !parseInt(partNumber, 10)) { res.status(400).json({ error: 's3: the part number must be a number between 1 and 10000.', }) @@ -283,7 +329,7 @@ export default function s3(config) { Bucket: bucket, Key: key, UploadId: uploadId, - PartNumber: partNumber, + PartNumber: Number(partNumber), Body: '', }), { expiresIn: config.expires }, @@ -305,12 +351,22 @@ export default function s3(config) { * - presignedUrls - The URLs to upload to, including signed query parameters, * in an object mapped to part numbers. */ - function batchSignPartsUpload(req, res, next) { + function batchSignPartsUpload( + req: Request, + res: Response, + next: NextFunction, + ) { const client = getS3Client(req, res) if (!client) return - const { uploadId } = req.params - const { key, partNumbers } = req.query + const uploadId = req.params['uploadId'] + const key = req.query['key'] + const partNumbers = req.query['partNumbers'] + + if (uploadId == null || uploadId.length === 0) { + res.status(400).json({ error: 's3: uploadId must be provided.' }) + return + } if (typeof key !== 'string') { res.status(400).json({ @@ -354,9 +410,12 @@ export default function s3(config) { }), ) .then((urls) => { - const presignedUrls = Object.create(null) + const presignedUrls: Record = Object.create(null) for (let index = 0; index < partNumbersArray.length; index++) { - presignedUrls[partNumbersArray[index]] = urls[index] + const partNumber = partNumbersArray[index] + const url = urls[index] + if (!partNumber || !url) continue + presignedUrls[partNumber] = url } res.json({ presignedUrls }) }) @@ -373,7 +432,11 @@ export default function s3(config) { * Response JSON: * Empty. */ - function abortMultipartUpload(req, res, next) { + function abortMultipartUpload( + req: Request, + res: Response, + next: NextFunction, + ) { const client = getS3Client(req, res) if (!client) return @@ -413,13 +476,17 @@ export default function s3(config) { * Response JSON: * - location - The full URL to the object in the S3 bucket. */ - function completeMultipartUpload(req, res, next) { + function completeMultipartUpload( + req: Request, + res: Response, + next: NextFunction, + ) { const client = getS3Client(req, res) if (!client) return const { uploadId } = req.params const { key } = req.query - const { parts } = req.body + const { parts }: { parts: unknown } = req.body if (typeof key !== 'string') { res.status(400).json({ @@ -479,8 +546,11 @@ export default function s3(config) { ], } - let stsClient - function getSTSClient() { + let stsClient: STSClient | undefined + function getSTSClient(): STSClient | null { + if (config.region == null || config.key == null || config.secret == null) { + return null + } if (stsClient == null) { stsClient = new STSClient({ region: config.region, @@ -506,8 +576,20 @@ export default function s3(config) { * - bucket: the S3 bucket name. * - region: the region where that bucket is stored. */ - function getTemporarySecurityCredentials(req, res, next) { - getSTSClient() + function getTemporarySecurityCredentials( + req: Request, + res: Response, + next: NextFunction, + ) { + const sts = getSTSClient() + if (!sts || typeof config.bucket !== 'string') { + res.status(400).json({ + error: 'This Companion server does not support STS credentials', + }) + return + } + + sts .send( new GetFederationTokenCommand({ // Name of the federated user. The name is used as an identifier for the diff --git a/packages/@uppy/companion/src/server/controllers/search.js b/packages/@uppy/companion/src/server/controllers/search.js deleted file mode 100644 index c888ed059..000000000 --- a/packages/@uppy/companion/src/server/controllers/search.js +++ /dev/null @@ -1,17 +0,0 @@ -import { respondWithError } from '../provider/error.js' - -export default async function search({ query, companion }, res, next) { - const { providerUserSession } = companion - - try { - const data = await companion.provider.search({ - companion, - providerUserSession, - query, - }) - res.json(data) - } catch (err) { - if (respondWithError(err, res)) return - next(err) - } -} diff --git a/packages/@uppy/companion/src/server/controllers/search.ts b/packages/@uppy/companion/src/server/controllers/search.ts new file mode 100644 index 000000000..c0a8cb304 --- /dev/null +++ b/packages/@uppy/companion/src/server/controllers/search.ts @@ -0,0 +1,34 @@ +import type { NextFunction, Request, Response } from 'express' +import { respondWithError } from '../provider/error.js' + +export default async function search( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const { query, companion } = req + const { providerUserSession, provider } = companion + if (!provider) { + res.sendStatus(400) + return + } + + const buildURL = companion.buildURL + const q = query['q'] + if (buildURL == null || typeof q !== 'string') { + res.sendStatus(500) + return + } + + try { + const data = await provider.search({ + companion: { buildURL }, + providerUserSession, + query: { ...query, q }, + }) + res.json(data) + } catch (err) { + if (respondWithError(err, res)) return + next(err) + } +} diff --git a/packages/@uppy/companion/src/server/controllers/send-token.js b/packages/@uppy/companion/src/server/controllers/send-token.ts similarity index 74% rename from packages/@uppy/companion/src/server/controllers/send-token.js rename to packages/@uppy/companion/src/server/controllers/send-token.ts index 389cd31fe..b0396fa28 100644 --- a/packages/@uppy/companion/src/server/controllers/send-token.js +++ b/packages/@uppy/companion/src/server/controllers/send-token.ts @@ -1,13 +1,9 @@ +import type { NextFunction, Request, Response } from 'express' import serialize from 'serialize-javascript' import * as oAuthState from '../helpers/oauth-state.js' import { isOriginAllowed } from './connect.js' -/** - * - * @param {string} token uppy auth token - * @param {string} origin url string - */ -const htmlContent = (token, origin) => { +const htmlContent = (token: string, origin: string): string => { return ` @@ -44,40 +40,39 @@ const htmlContent = (token, origin) => { ` } -/** - * - * @param {import('express').Request} req - * @param {import('express').Response} res - * @param {import('express').NextFunction} next - */ -export default function sendToken(req, res, next) { - // @ts-expect-error untyped - const { companion } = req +export default function sendToken( + req: Request, + res: Response, + next: NextFunction, +): void { + const companion = req.companion const uppyAuthToken = companion.authToken + const { secret } = companion.options const { state } = oAuthState.getGrantDynamicFromRequest(req) - if (!state) { - return next() + next() + return } - const clientOrigin = oAuthState.getFromState( - state, - 'origin', - companion.options.secret, - ) + const clientOrigin = oAuthState.getFromState(state, 'origin', secret) + if (typeof clientOrigin !== 'string' || clientOrigin.length === 0) { + next() + return + } const customerDefinedAllowedOrigins = oAuthState.getFromState( state, 'customerDefinedAllowedOrigins', - companion.options.secret, + secret, ) if ( customerDefinedAllowedOrigins && !isOriginAllowed(clientOrigin, customerDefinedAllowedOrigins) ) { - return next() + next() + return } - return res.send(htmlContent(uppyAuthToken, clientOrigin)) + res.send(htmlContent(`${uppyAuthToken}`, clientOrigin)) } diff --git a/packages/@uppy/companion/src/server/controllers/simple-auth.js b/packages/@uppy/companion/src/server/controllers/simple-auth.ts similarity index 53% rename from packages/@uppy/companion/src/server/controllers/simple-auth.js rename to packages/@uppy/companion/src/server/controllers/simple-auth.ts index f95ccc65d..c1171356c 100644 --- a/packages/@uppy/companion/src/server/controllers/simple-auth.js +++ b/packages/@uppy/companion/src/server/controllers/simple-auth.ts @@ -1,12 +1,27 @@ +import type { NextFunction, Request, Response } from 'express' import * as tokenService from '../helpers/jwt.js' import logger from '../logger.js' import { respondWithError } from '../provider/error.js' -export default async function simpleAuth(req, res, next) { - const { providerName } = req.params +export default async function simpleAuth( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const providerName = req.params['providerName'] + if (providerName == null || providerName.length === 0) { + res.sendStatus(400) + return + } + const { secret } = req.companion.options + const { provider, providerClass } = req.companion + if (!provider || !providerClass) { + res.sendStatus(400) + return + } try { - const simpleAuthResponse = await req.companion.provider.simpleAuth({ + const simpleAuthResponse = await provider.simpleAuth({ requestBody: req.body, }) @@ -17,20 +32,20 @@ export default async function simpleAuth(req, res, next) { logger.debug( `Generating simple auth token for provider ${providerName}`, - null, + undefined, req.id, ) const uppyAuthToken = tokenService.generateEncryptedAuthToken( { [providerName]: req.companion.providerUserSession }, - req.companion.options.secret, - req.companion.providerClass.authStateExpiry, + secret, + providerClass.authStateExpiry, ) tokenService.addToCookiesIfNeeded( req, res, uppyAuthToken, - req.companion.providerClass.authStateExpiry, + providerClass.authStateExpiry, ) res.send({ uppyAuthToken }) diff --git a/packages/@uppy/companion/src/server/controllers/thumbnail.js b/packages/@uppy/companion/src/server/controllers/thumbnail.ts similarity index 57% rename from packages/@uppy/companion/src/server/controllers/thumbnail.js rename to packages/@uppy/companion/src/server/controllers/thumbnail.ts index a2978e31e..bae18cafd 100644 --- a/packages/@uppy/companion/src/server/controllers/thumbnail.js +++ b/packages/@uppy/companion/src/server/controllers/thumbnail.ts @@ -1,13 +1,21 @@ +import type { NextFunction, Request, Response } from 'express' import { respondWithError } from '../provider/error.js' -/** - * - * @param {object} req - * @param {object} res - */ -async function thumbnail(req, res, next) { - const { id } = req.params +async function thumbnail( + req: Request, + res: Response, + next: NextFunction, +): Promise { + const id = req.params['id'] + if (id == null) { + res.sendStatus(400) + return + } const { provider, providerUserSession } = req.companion + if (!provider) { + res.sendStatus(400) + return + } try { const { stream, contentType } = await provider.thumbnail({ diff --git a/packages/@uppy/companion/src/server/controllers/url.js b/packages/@uppy/companion/src/server/controllers/url.ts similarity index 70% rename from packages/@uppy/companion/src/server/controllers/url.js rename to packages/@uppy/companion/src/server/controllers/url.ts index e34900878..7a72ff013 100644 --- a/packages/@uppy/companion/src/server/controllers/url.js +++ b/packages/@uppy/companion/src/server/controllers/url.ts @@ -1,3 +1,4 @@ +import type { Request, Response } from 'express' import express from 'express' import { downloadURL } from '../download.js' import { getURLMeta, validateURL } from '../helpers/request.js' @@ -6,25 +7,16 @@ import logger from '../logger.js' import { respondWithError } from '../provider/error.js' /** - * @callback downloadCallback - * @param {Error} err - * @param {string | Buffer | Buffer[]} chunk + * Fetch the size and content type of a URL. */ - -/** - * Fetches the size and content type of a URL - * - * @param {object} req expressJS request object - * @param {object} res expressJS response object - */ -const meta = async (req, res) => { +const meta = async (req: Request, res: Response): Promise => { try { - logger.debug('URL file import handler running', null, req.id) + logger.debug('URL file import handler running', undefined, req.id) const { allowLocalUrls } = req.companion.options if (!validateURL(req.body.url, allowLocalUrls)) { logger.debug( 'Invalid request body detected. Exiting url meta handler.', - null, + undefined, req.id, ) res.status(400).json({ error: 'Invalid request body' }) @@ -41,19 +33,15 @@ const meta = async (req, res) => { } /** - * Handles the reques of import a file from a remote URL, and then - * subsequently uploading it to the specified destination. - * - * @param {object} req expressJS request object - * @param {object} res expressJS response object + * Import a file from a remote URL, then upload it to the specified destination. */ -const get = async (req, res) => { - logger.debug('URL file import handler running', null, req.id) +const get = async (req: Request, res: Response): Promise => { + logger.debug('URL file import handler running', undefined, req.id) const { allowLocalUrls } = req.companion.options if (!validateURL(req.body.url, allowLocalUrls)) { logger.debug( 'Invalid request body detected. Exiting url import handler.', - null, + undefined, req.id, ) res.status(400).json({ error: 'Invalid request body' }) diff --git a/packages/@uppy/companion/src/server/download.js b/packages/@uppy/companion/src/server/download.ts similarity index 52% rename from packages/@uppy/companion/src/server/download.js rename to packages/@uppy/companion/src/server/download.ts index d69d0f4ed..7333c81b2 100644 --- a/packages/@uppy/companion/src/server/download.js +++ b/packages/@uppy/companion/src/server/download.ts @@ -1,17 +1,21 @@ +import type { Readable } from 'node:stream' import { getProtectedGot } from './helpers/request.js' import { prepareStream } from './helpers/utils.js' import logger from './logger.js' /** - * Downloads the content in the specified url, and passes the data - * to the callback chunk by chunk. + * Downloads the content at the given URL. * - * @param {string} url - * @param {boolean} allowLocalIPs - * @param {string} traceId - * @returns {Promise} + * @param url - URL to download. + * @param allowLocalIPs - Whether to allow local/private IPs (disables SSRF protection). + * @param traceId - Request trace id for logging. */ -export const downloadURL = async (url, allowLocalIPs, traceId, options) => { +export const downloadURL = async ( + url: string, + allowLocalIPs: boolean, + traceId?: string, + options: Record = {}, +): Promise<{ stream: Readable; size: number | undefined }> => { try { const protectedGot = getProtectedGot({ allowLocalIPs }) const stream = protectedGot.stream.get(url, { diff --git a/packages/@uppy/companion/src/server/emitter/default-emitter.js b/packages/@uppy/companion/src/server/emitter/default-emitter.js deleted file mode 100644 index f8dfc739a..000000000 --- a/packages/@uppy/companion/src/server/emitter/default-emitter.js +++ /dev/null @@ -1,5 +0,0 @@ -import { EventEmitter } from 'node:events' - -export default function defaultEmitter() { - return new EventEmitter() -} diff --git a/packages/@uppy/companion/src/server/emitter/default-emitter.ts b/packages/@uppy/companion/src/server/emitter/default-emitter.ts new file mode 100644 index 000000000..2c0fe15c4 --- /dev/null +++ b/packages/@uppy/companion/src/server/emitter/default-emitter.ts @@ -0,0 +1,6 @@ +import { EventEmitter } from 'node:events' +import type { EmitterLike } from './index.js' + +export default function defaultEmitter(): EmitterLike { + return new EventEmitter() +} diff --git a/packages/@uppy/companion/src/server/emitter/index.js b/packages/@uppy/companion/src/server/emitter/index.js deleted file mode 100644 index 9521f1a6f..000000000 --- a/packages/@uppy/companion/src/server/emitter/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import nodeEmitter from './default-emitter.js' -import redisEmitter from './redis-emitter.js' - -let emitter - -/** - * Singleton event emitter that is shared between modules throughout the lifetime of the server. - * Used to transmit events (such as progress, upload completion) from controllers, - * such as the Google Drive 'get' controller, along to the client. - */ -export default function getEmitter(redisClient, redisPubSubScope) { - if (!emitter) { - emitter = redisClient - ? redisEmitter(redisClient, redisPubSubScope) - : nodeEmitter() - } - - return emitter -} diff --git a/packages/@uppy/companion/src/server/emitter/index.ts b/packages/@uppy/companion/src/server/emitter/index.ts new file mode 100644 index 000000000..94323c81f --- /dev/null +++ b/packages/@uppy/companion/src/server/emitter/index.ts @@ -0,0 +1,34 @@ +import type { Redis } from 'ioredis' +import nodeEmitter from './default-emitter.js' +import redisEmitter from './redis-emitter.js' + +type Listener = (...args: unknown[]) => void + +export interface EmitterLike { + on: (eventName: string, handler: Listener) => unknown + once: (eventName: string, handler: Listener) => unknown + off?: (eventName: string, handler: Listener) => unknown + emit: (eventName: string, ...args: unknown[]) => unknown + removeListener: (eventName: string, handler: Listener) => unknown + removeAllListeners: (eventName: string) => unknown +} + +let emitter: EmitterLike | undefined + +/** + * Singleton event emitter that is shared between modules throughout the lifetime of the server. + * Used to transmit events (such as progress, upload completion) from controllers, + * such as the Google Drive 'get' controller, along to the client. + */ +export default function getEmitter( + redisClient?: Redis | undefined, + redisPubSubScope?: string, +): EmitterLike { + if (!emitter) { + emitter = redisClient + ? redisEmitter(redisClient, redisPubSubScope) + : nodeEmitter() + } + + return emitter +} diff --git a/packages/@uppy/companion/src/server/emitter/redis-emitter.js b/packages/@uppy/companion/src/server/emitter/redis-emitter.ts similarity index 66% rename from packages/@uppy/companion/src/server/emitter/redis-emitter.js rename to packages/@uppy/companion/src/server/emitter/redis-emitter.ts index 49014ea03..b2f7d9f0a 100644 --- a/packages/@uppy/companion/src/server/emitter/redis-emitter.js +++ b/packages/@uppy/companion/src/server/emitter/redis-emitter.ts @@ -1,8 +1,10 @@ import { EventEmitter } from 'node:events' import safeStringify from 'fast-safe-stringify' +import type { Redis } from 'ioredis' import * as logger from '../logger.js' +import type { EmitterLike } from './index.js' -function replacer(key, value) { +function replacer(key: string, value: unknown): unknown { // Remove the circular structure and internal ones return key[0] === '_' || value === '[Circular]' ? undefined : value } @@ -12,16 +14,18 @@ function replacer(key, value) { * This is useful for when companion is running on multiple instances and events need * to be distributed across. * - * @param {import('ioredis').Redis} redisClient - * @param {string} redisPubSubScope - * @returns + * @param redisClient + * @param redisPubSubScope */ -export default function redisEmitter(redisClient, redisPubSubScope) { +export default function redisEmitter( + redisClient: Redis, + redisPubSubScope?: string, +): EmitterLike { const prefix = redisPubSubScope ? `${redisPubSubScope}:` : '' - const getPrefixedEventName = (eventName) => `${prefix}${eventName}` + const getPrefixedEventName = (eventName: string) => `${prefix}${eventName}` const errorEmitter = new EventEmitter() - const handleError = (err) => errorEmitter.emit('error', err) + const handleError = (err: unknown) => errorEmitter.emit('error', err) async function makeRedis() { const publisher = redisClient.duplicate({ lazyConnect: true }) @@ -42,9 +46,11 @@ export default function redisEmitter(redisClient, redisPubSubScope) { /** * - * @param {(a: Awaited) => void} fn + * @param fn */ - async function runWhenConnected(fn) { + async function runWhenConnected( + fn: (clients: { subscriber: Redis; publisher: Redis }) => unknown, + ): Promise { try { await fn(await redisPromise) } catch (err) { @@ -53,16 +59,23 @@ export default function redisEmitter(redisClient, redisPubSubScope) { } // because each event can have multiple listeners, we need to keep track of them - /** @type {Map unknown, () => unknown>>} */ - const handlersByEventName = new Map() + const handlersByEventName: Map< + string, + Map< + (...args: unknown[]) => unknown, + (pattern: string, _channel: string, message: string) => unknown + > + > = new Map() /** * Remove an event listener * - * @param {string} eventName name of the event - * @param {any} handler the handler of the event to remove + * @param eventName name of the event + * @param handler the handler of the event to remove */ - async function removeListener(eventName, handler) { + type Handler = (...args: unknown[]) => unknown + + async function removeListener(eventName: string, handler: Handler) { if (eventName === 'error') { errorEmitter.removeListener('error', handler) return @@ -91,26 +104,34 @@ export default function redisEmitter(redisClient, redisPubSubScope) { /** * - * @param {string} eventName - * @param {*} handler - * @param {*} _once + * @param eventName + * @param handler + * @param _once */ - async function addListener(eventName, handler, _once = false) { + async function addListener( + eventName: string, + handler: Handler, + _once = false, + ) { if (eventName === 'error') { if (_once) errorEmitter.once('error', handler) else errorEmitter.addListener('error', handler) return } - function actualHandler(pattern, channel, message) { + function actualHandler(pattern: string, _channel: string, message: string) { if (pattern !== getPrefixedEventName(eventName)) { return } if (_once) removeListener(eventName, handler) - let args + let args: unknown[] try { - args = JSON.parse(message) + const parsed: unknown = JSON.parse(message) + if (!Array.isArray(parsed)) { + throw new Error('Expected JSON array') + } + args = parsed } catch (_ex) { handleError( new Error( @@ -139,39 +160,39 @@ export default function redisEmitter(redisClient, redisPubSubScope) { /** * Add an event listener * - * @param {string} eventName name of the event - * @param {any} handler the handler of the event + * @param eventName name of the event + * @param handler the handler of the event */ - async function on(eventName, handler) { + async function on(eventName: string, handler: Handler) { await addListener(eventName, handler) } /** * Remove an event listener * - * @param {string} eventName name of the event - * @param {any} handler the handler of the event + * @param eventName name of the event + * @param handler the handler of the event */ - async function off(eventName, handler) { + async function off(eventName: string, handler: Handler) { await removeListener(eventName, handler) } /** * Add an event listener (will be triggered at most once) * - * @param {string} eventName name of the event - * @param {any} handler the handler of the event + * @param eventName name of the event + * @param handler the handler of the event */ - async function once(eventName, handler) { + async function once(eventName: string, handler: Handler) { await addListener(eventName, handler, true) } /** * Announce the occurrence of an event * - * @param {string} eventName name of the event + * @param eventName name of the event */ - async function emit(eventName, ...args) { + async function emit(eventName: string, ...args: unknown[]) { await runWhenConnected(async ({ publisher }) => publisher.publish( getPrefixedEventName(eventName), @@ -183,9 +204,9 @@ export default function redisEmitter(redisClient, redisPubSubScope) { /** * Remove all listeners of an event * - * @param {string} eventName name of the event + * @param eventName name of the event */ - async function removeAllListeners(eventName) { + async function removeAllListeners(eventName: string) { if (eventName === 'error') { errorEmitter.removeAllListeners(eventName) return diff --git a/packages/@uppy/companion/src/server/header-blacklist.js b/packages/@uppy/companion/src/server/header-blacklist.ts similarity index 70% rename from packages/@uppy/companion/src/server/header-blacklist.js rename to packages/@uppy/companion/src/server/header-blacklist.ts index 275dc11cb..15ed47492 100644 --- a/packages/@uppy/companion/src/server/header-blacklist.js +++ b/packages/@uppy/companion/src/server/header-blacklist.ts @@ -34,10 +34,10 @@ const forbiddenRegex = [/^proxy-.*$/, /^sec-.*$/] /** * Check if the header in parameter is a forbidden header. * - * @param {string} header Header to check + * @param header Header to check * @returns True if header is forbidden, false otherwise. */ -const isForbiddenHeader = (header) => { +const isForbiddenHeader = (header: string): boolean => { const headerLower = header.toLowerCase() const forbidden = forbiddenNames.indexOf(headerLower) >= 0 || @@ -49,7 +49,9 @@ const isForbiddenHeader = (header) => { return forbidden } -export default function headerBlacklist(headers) { +export default function headerBlacklist( + headers: Record | undefined, +): Record { if ( headers == null || typeof headers !== 'object' || @@ -58,11 +60,11 @@ export default function headerBlacklist(headers) { return {} } - const headersCloned = { ...headers } - Object.keys(headersCloned).forEach((header) => { - if (isForbiddenHeader(header)) { - delete headersCloned[header] - } - }) - return headersCloned + const out: Record = {} + for (const [header, value] of Object.entries(headers)) { + if (isForbiddenHeader(header)) continue + if (typeof value !== 'string') continue + out[header] = value + } + return out } diff --git a/packages/@uppy/companion/src/server/helpers/jwt.js b/packages/@uppy/companion/src/server/helpers/jwt.ts similarity index 57% rename from packages/@uppy/companion/src/server/helpers/jwt.js rename to packages/@uppy/companion/src/server/helpers/jwt.ts index e410516fd..7d3ef4b0e 100644 --- a/packages/@uppy/companion/src/server/helpers/jwt.js +++ b/packages/@uppy/companion/src/server/helpers/jwt.ts @@ -1,4 +1,7 @@ +import type { Request, Response } from 'express' import jwt from 'jsonwebtoken' +import type { CompanionRuntimeOptions } from '../../types/companion-options.js' +import { isRecord } from './type-guards.js' import { decrypt, encrypt } from './utils.js' // The Uppy auth token is an encrypted JWT & JSON encoded container. @@ -19,74 +22,72 @@ import { decrypt, encrypt } from './utils.js' // With 400 days, there's still a theoretical possibility but very low. export const MAX_AGE_REFRESH_TOKEN = 60 * 60 * 24 * 400 export const MAX_AGE_24H = 60 * 60 * 24 -/** - * - * @param {*} data - * @param {string} secret - * @param {number} maxAge - */ -const generateToken = (data, secret, maxAge) => { + +type EncryptionSecret = string | Buffer + +const generateToken = ( + data: unknown, + secret: EncryptionSecret, + maxAge: number, +): string => { return jwt.sign({ data }, secret, { expiresIn: maxAge }) } -/** - * - * @param {string} token - * @param {string} secret - */ -const verifyToken = (token, secret) => { - // @ts-ignore - return jwt.verify(token, secret, {}).data +const verifyJwtToken = (token: string, secret: EncryptionSecret) => { + const decoded = jwt.verify(token, secret, {}) + if (!decoded || typeof decoded !== 'object' || !('data' in decoded)) { + throw new Error('Invalid token payload') + } + return decoded.data } -/** - * - * @param {*} payload - * @param {string} secret - */ export const generateEncryptedToken = ( - payload, - secret, + payload: unknown, + secret: EncryptionSecret, maxAge = MAX_AGE_24H, -) => { +): string => { // return payload // for easier debugging return encrypt(generateToken(payload, secret, maxAge), secret) } -/** - * @param {*} payload - * @param {string} secret - */ -export const generateEncryptedAuthToken = (payload, secret, maxAge) => { +export const generateEncryptedAuthToken = ( + payload: unknown, + secret: EncryptionSecret, + maxAge?: number, +): string => { return generateEncryptedToken(JSON.stringify(payload), secret, maxAge) } -/** - * - * @param {string} token - * @param {string} secret - */ -export const verifyEncryptedToken = (token, secret) => { - const ret = verifyToken(decrypt(token, secret), secret) +export const verifyEncryptedToken = ( + token: string, + secret: EncryptionSecret, +) => { + const ret = verifyJwtToken(decrypt(token, secret), secret) if (!ret) throw new Error('No payload') return ret } -/** - * - * @param {string} token - * @param {string} secret - */ -export const verifyEncryptedAuthToken = (token, secret, providerName) => { +export const verifyEncryptedAuthToken = >( + token: string, + secret: EncryptionSecret, + providerName: string, +): T => { const json = verifyEncryptedToken(token, secret) - const tokens = JSON.parse(json) - if (!tokens[providerName]) + if (typeof json !== 'string') { + throw new Error('Invalid token payload: expected string') + } + const tokens: T = JSON.parse(json) + if (!isRecord(tokens) || !Object.hasOwn(tokens, providerName)) throw new Error(`Missing token payload for provider ${providerName}`) return tokens } -function getCommonCookieOptions({ companionOptions }) { - const cookieOptions = { +function getCommonCookieOptions({ + companionOptions, +}: { + companionOptions: CompanionRuntimeOptions +}): Record { + const cookieOptions: Record = { httpOnly: true, } @@ -95,18 +96,20 @@ function getCommonCookieOptions({ companionOptions }) { // Note that sameSite cookies also require secure (which needs https), so thumbnails don't work from localhost // to test locally, you can manually find the URL of the image and open it in a separate browser tab if (companionOptions.server && companionOptions.server.protocol === 'https') { - cookieOptions.sameSite = 'none' - cookieOptions.secure = true + cookieOptions['sameSite'] = 'none' + cookieOptions['secure'] = true } - if (companionOptions.cookieDomain) { - cookieOptions.domain = companionOptions.cookieDomain + const cookieDomain = companionOptions['cookieDomain'] + if (cookieDomain != null) { + cookieOptions['domain'] = cookieDomain } return cookieOptions } -const getCookieName = (oauthProvider) => `uppyAuthToken--${oauthProvider}` +const getCookieName = (oauthProvider: string): string => + `uppyAuthToken--${oauthProvider}` const addToCookies = ({ res, @@ -114,7 +117,13 @@ const addToCookies = ({ companionOptions, oauthProvider, maxAge = MAX_AGE_24H, -}) => { +}: { + res: Response + token: string + companionOptions: CompanionRuntimeOptions + oauthProvider: string + maxAge?: number +}): void => { const cookieOptions = { ...getCommonCookieOptions({ companionOptions }), maxAge: maxAge * 1000, @@ -124,26 +133,32 @@ const addToCookies = ({ res.cookie(getCookieName(oauthProvider), token, cookieOptions) } -export const addToCookiesIfNeeded = (req, res, uppyAuthToken, maxAge) => { +export const addToCookiesIfNeeded = ( + req: Request, + res: Response, + uppyAuthToken: string, + maxAge?: number, +): void => { // some providers need the token in cookies for thumbnail/image requests - if (req.companion.provider.needsCookieAuth) { - addToCookies({ + if (req.companion.provider?.needsCookieAuth) { + const oauthProvider = req.companion.providerClass?.oauthProvider + if (oauthProvider == null) return + const args = { res, token: uppyAuthToken, companionOptions: req.companion.options, - oauthProvider: req.companion.providerClass.oauthProvider, - maxAge, - }) + oauthProvider, + ...(maxAge != null && { maxAge }), + } + addToCookies(args) } } -/** - * - * @param {object} res - * @param {object} companionOptions - * @param {string} oauthProvider - */ -export const removeFromCookies = (res, companionOptions, oauthProvider) => { +export const removeFromCookies = ( + res: Response, + companionOptions: CompanionRuntimeOptions, + oauthProvider: string, +): void => { // options must be identical to those given to res.cookie(), excluding expires and maxAge. // https://expressjs.com/en/api.html#res.clearCookie const cookieOptions = getCommonCookieOptions({ companionOptions }) diff --git a/packages/@uppy/companion/src/server/helpers/oauth-state.js b/packages/@uppy/companion/src/server/helpers/oauth-state.js deleted file mode 100644 index 0482ee4d5..000000000 --- a/packages/@uppy/companion/src/server/helpers/oauth-state.js +++ /dev/null @@ -1,26 +0,0 @@ -import crypto from 'node:crypto' -import { decrypt, encrypt } from './utils.js' - -export const encodeState = (state, secret) => { - const encodedState = Buffer.from(JSON.stringify(state)).toString('base64') - return encrypt(encodedState, secret) -} - -export const decodeState = (state, secret) => { - const encodedState = decrypt(state, secret) - return JSON.parse(atob(encodedState)) -} - -export const generateState = () => { - return { - id: crypto.randomBytes(10).toString('hex'), - } -} - -export const getFromState = (state, name, secret) => { - return decodeState(state, secret)[name] -} - -export const getGrantDynamicFromRequest = (req) => { - return req.session.grant?.dynamic ?? {} -} diff --git a/packages/@uppy/companion/src/server/helpers/oauth-state.ts b/packages/@uppy/companion/src/server/helpers/oauth-state.ts new file mode 100644 index 000000000..a1080ce79 --- /dev/null +++ b/packages/@uppy/companion/src/server/helpers/oauth-state.ts @@ -0,0 +1,56 @@ +import crypto from 'node:crypto' +import type { CompanionSession } from '../../types/express.js' +import { isRecord } from './type-guards.js' +import { decrypt, encrypt } from './utils.js' + +export type OAuthState = { + id: string + origin?: string | string[] | number | boolean | undefined // weird type because this is what express's res.getHeader and cors callback combined can possibly return + preAuthToken?: string + companionInstance?: string + customerDefinedAllowedOrigins?: string[] +} + +export const encodeState = ( + state: OAuthState, + secret: string | Buffer, +): string => { + const encodedState = Buffer.from(JSON.stringify(state)).toString('base64') + return encrypt(encodedState, secret) +} + +export const decodeState = ( + state: string, + secret: string | Buffer, +): OAuthState => { + const encodedState = decrypt(state, secret) + const parsed: unknown = JSON.parse(atob(encodedState)) + if (!isOAuthState(parsed)) { + throw new Error('Invalid OAuth state payload') + } + return parsed +} + +export const generateState = (): OAuthState => { + return { + id: crypto.randomBytes(10).toString('hex'), + } +} + +function isOAuthState(value: unknown): value is OAuthState { + return isRecord(value) && typeof value['id'] === 'string' +} + +export const getFromState = ( + state: string, + name: T, + secret: string | Buffer, +): OAuthState[T] | undefined => { + return decodeState(state, secret)[name] +} + +export const getGrantDynamicFromRequest = (req: { + session?: CompanionSession +}) => { + return req.session?.grant?.dynamic ?? {} +} diff --git a/packages/@uppy/companion/src/server/helpers/request.js b/packages/@uppy/companion/src/server/helpers/request.ts similarity index 53% rename from packages/@uppy/companion/src/server/helpers/request.js rename to packages/@uppy/companion/src/server/helpers/request.ts index 311fc4bda..babf5ff07 100644 --- a/packages/@uppy/companion/src/server/helpers/request.js +++ b/packages/@uppy/companion/src/server/helpers/request.ts @@ -1,9 +1,11 @@ import dns from 'node:dns' import http from 'node:http' import https from 'node:https' +import type { LookupFunction } from 'node:net' import path from 'node:path' +import type { Duplex } from 'node:stream' import contentDisposition from 'content-disposition' -import got from 'got' +import got, { type Response } from 'got' import ipaddr from 'ipaddr.js' import validator from 'validator' @@ -12,16 +14,19 @@ export const FORBIDDEN_IP_ADDRESS = 'Forbidden IP address' // Example scary IPs that should return false (ipv6-to-ipv4 mapped): // ::FFFF:127.0.0.1 // ::ffff:7f00:1 -const isDisallowedIP = (ipAddress) => +const isDisallowedIP = (ipAddress: string): boolean => ipaddr.parse(ipAddress).range() !== 'unicast' /** - * Validates that the download URL is secure + * Validates that the download URL is secure. * - * @param {string} url the url to validate - * @param {boolean} allowLocalUrls whether to allow local addresses + * @param url - The URL to validate. + * @param allowLocalUrls - Whether to allow local addresses. */ -const validateURL = (url, allowLocalUrls) => { +const validateURL = ( + url: string | null | undefined, + allowLocalUrls: boolean, +): boolean => { if (!url) { return false } @@ -43,8 +48,35 @@ export { validateURL } /** * Returns http Agent that will prevent requests to private IPs (to prevent SSRF) */ -const getProtectedHttpAgent = ({ protocol, allowLocalIPs }) => { - function dnsLookup(hostname, options, callback) { +function getProtectedHttpAgent({ + protocol, + allowLocalIPs, +}: { + protocol: 'http' + allowLocalIPs: boolean +}): typeof http.Agent +function getProtectedHttpAgent({ + protocol, + allowLocalIPs, +}: { + protocol: 'https' + allowLocalIPs: boolean +}): typeof https.Agent +function getProtectedHttpAgent({ + protocol, + allowLocalIPs, +}: { + protocol: string + allowLocalIPs: boolean +}): typeof http.Agent | typeof https.Agent +function getProtectedHttpAgent({ + protocol, + allowLocalIPs, +}: { + protocol: string + allowLocalIPs: boolean +}): typeof http.Agent | typeof https.Agent { + const dnsLookup: LookupFunction = (hostname, options, callback) => { dns.lookup(hostname, options, (err, addresses, maybeFamily) => { if (err) { callback(err, addresses, maybeFamily) @@ -53,7 +85,8 @@ const getProtectedHttpAgent = ({ protocol, allowLocalIPs }) => { const toValidate = Array.isArray(addresses) ? addresses - : [{ address: addresses }] + : [{ address: addresses, family: maybeFamily }] + // because dns.lookup seems to be called with option `all: true`, if we are on an ipv6 system, // `addresses` could contain a list of ipv4 addresses as well as ipv6 mapped addresses (rfc6052) which we cannot allow // however we should still allow any valid ipv4 addresses, so we filter out the invalid addresses @@ -61,8 +94,9 @@ const getProtectedHttpAgent = ({ protocol, allowLocalIPs }) => { ? toValidate : toValidate.filter(({ address }) => !isDisallowedIP(address)) + const [firstValidAddress] = validAddresses // and check if there's anything left after we filtered: - if (validAddresses.length === 0) { + if (firstValidAddress == null) { callback( new Error( `Forbidden resolved IP address ${hostname} -> ${toValidate.map(({ address }) => address).join(', ')}`, @@ -75,23 +109,43 @@ const getProtectedHttpAgent = ({ protocol, allowLocalIPs }) => { const ret = Array.isArray(addresses) ? validAddresses - : validAddresses[0].address + : firstValidAddress.address callback(err, ret, maybeFamily) }) } - return class HttpAgent extends (protocol.startsWith('https') ? https : http) - .Agent { - createConnection(options, callback) { - if ( - ipaddr.isValid(options.host) && - !allowLocalIPs && - isDisallowedIP(options.host) - ) { - callback(new Error(FORBIDDEN_IP_ADDRESS)) - return undefined + const shouldBlockHost = (host: string | null | undefined): host is string => + host != null && ipaddr.isValid(host) && isDisallowedIP(host) + + if (protocol.startsWith('https')) { + return class HttpsAgent extends https.Agent { + override createConnection( + options: http.ClientRequestArgs, + callback?: (err: Error | null, stream: Duplex) => void, + ): Duplex { + if (!allowLocalIPs && shouldBlockHost(options.host)) { + const socket = undefined as unknown as Duplex // not sure about this but it's how it always worked + callback?.(new Error(FORBIDDEN_IP_ADDRESS), socket) + return socket + } + return super.createConnection( + { ...options, lookup: dnsLookup }, + callback, + ) + } + } + } + + return class HttpAgent extends http.Agent { + override createConnection( + options: http.ClientRequestArgs, + callback?: (err: Error | null, stream: Duplex) => void, + ): Duplex { + if (!allowLocalIPs && shouldBlockHost(options.host)) { + const socket = undefined as unknown as Duplex // not sure about this but it's how it always worked + callback?.(new Error(FORBIDDEN_IP_ADDRESS), socket) + return socket } - // @ts-ignore return super.createConnection({ ...options, lookup: dnsLookup }, callback) } } @@ -99,7 +153,7 @@ const getProtectedHttpAgent = ({ protocol, allowLocalIPs }) => { export { getProtectedHttpAgent } -function getProtectedGot({ allowLocalIPs }) { +function getProtectedGot({ allowLocalIPs }: { allowLocalIPs: boolean }) { const HttpAgent = getProtectedHttpAgent({ protocol: 'http', allowLocalIPs }) const HttpsAgent = getProtectedHttpAgent({ protocol: 'https', @@ -108,7 +162,6 @@ function getProtectedGot({ allowLocalIPs }) { const httpAgent = new HttpAgent() const httpsAgent = new HttpsAgent() - // @ts-ignore return got.extend({ agent: { http: httpAgent, https: httpsAgent } }) } @@ -117,16 +170,23 @@ export { getProtectedGot } /** * Gets the size and content type of a url's content * - * @param {string} url - * @param {boolean} allowLocalIPs - * @returns {Promise<{name: string, type: string, size: number}>} + * @param url - The URL to inspect. + * @param allowLocalIPs - Whether to allow local addresses (disables SSRF protection). + * @param options - Extra request options passed to got. */ export async function getURLMeta( - url, + url: string, allowLocalIPs = false, - options = undefined, + options: Record | undefined = undefined, ) { - async function requestWithMethod(method) { + type UrlMetaWithStatus = { + name: string + type: string | undefined + size: number | null + statusCode: number + } + + async function requestWithMethod(method: 'HEAD' | 'GET') { const protectedGot = getProtectedGot({ allowLocalIPs }) const stream = protectedGot.stream(url, { method, @@ -134,18 +194,30 @@ export async function getURLMeta( ...options, }) - return new Promise((resolve, reject) => + return new Promise((resolve, reject) => stream - .on('response', (response) => { + .on('response', (response: Response) => { // Can be undefined for unknown length URLs, e.g. transfer-encoding: chunked - const contentLength = parseInt(response.headers['content-length'], 10) + const contentLengthHeader = response.headers['content-length'] + const contentLength = + contentLengthHeader != null + ? parseInt(contentLengthHeader, 10) + : NaN // If Content-Disposition with file name is missing, fallback to the URL path for the name, // but if multiple files are served via query params like foo.com?file=file-1, foo.com?file=file-2, // we add random string to avoid duplicate files - const filename = response.headers['content-disposition'] - ? contentDisposition.parse(response.headers['content-disposition']) - .parameters.filename - : path.basename(`${response.request.requestUrl}`) + const contentDispositionHeader = + response.headers['content-disposition'] + let filename: string | undefined + if (contentDispositionHeader != null) { + const parsed = contentDisposition.parse(contentDispositionHeader) + const maybeFilename = parsed.parameters['filename'] + if (maybeFilename != null) { + filename = maybeFilename + } + } + if (!filename) + filename = path.basename(`${response.request.requestUrl}`) // No need to get the rest of the response, as we only want header (not really relevant for HEAD, but why not) stream.destroy() diff --git a/packages/@uppy/companion/src/server/helpers/type-guards.ts b/packages/@uppy/companion/src/server/helpers/type-guards.ts new file mode 100644 index 000000000..a3716c044 --- /dev/null +++ b/packages/@uppy/companion/src/server/helpers/type-guards.ts @@ -0,0 +1,9 @@ +export function isRecord(value: unknown): value is Record { + return value != null && typeof value === 'object' && !Array.isArray(value) +} + +export function toError(err: unknown): Error { + if (err instanceof Error) return err + if (typeof err === 'string') return new Error(err) + return new Error('Unknown error') +} diff --git a/packages/@uppy/companion/src/server/helpers/upload.js b/packages/@uppy/companion/src/server/helpers/upload.ts similarity index 64% rename from packages/@uppy/companion/src/server/helpers/upload.js rename to packages/@uppy/companion/src/server/helpers/upload.ts index 56ccb1252..72b477ba8 100644 --- a/packages/@uppy/companion/src/server/helpers/upload.js +++ b/packages/@uppy/companion/src/server/helpers/upload.ts @@ -1,19 +1,28 @@ +import type { Readable } from 'node:stream' +import type { Request, Response } from 'express' import logger from '../logger.js' import Uploader from '../Uploader.js' -export async function startDownUpload({ req, res, getSize, download }) { - logger.debug('Starting download stream.', null, req.id) +export async function startDownUpload({ + req, + res, + getSize, + download, +}: { + req: Request + res: Response + getSize?: (() => Promise) | undefined + download: () => Promise<{ stream: Readable; size: number | undefined }> +}): Promise { + logger.debug('Starting download stream.', undefined, req.id) const { stream, size: maybeSize } = await download() - let size // if we already know the size from the GET response content-length header, we can use that - if ( - typeof maybeSize === 'number' && - !Number.isNaN(maybeSize) && - maybeSize > 0 - ) { - size = maybeSize - } + let size: number | null | undefined = + maybeSize != null && !Number.isNaN(maybeSize) && maybeSize > 0 + ? maybeSize + : undefined + // if not, we may need to explicitly get the size // note that getSize might also return undefined/null, which is usually fine, it just means that // the size is unknown and we cannot send the size to the Uploader @@ -22,8 +31,8 @@ export async function startDownUpload({ req, res, getSize, download }) { } const { clientSocketConnectTimeout } = req.companion.options - logger.debug('Instantiating uploader.', null, req.id) - const uploader = new Uploader(Uploader.reqToOptions(req, size)) + logger.debug('Instantiating uploader.', undefined, req.id) + const uploader = new Uploader(Uploader.reqToOptions(req, size ?? undefined)) // "Forking" off the upload operation to background, so we can return the http request: ;(async () => { @@ -31,13 +40,13 @@ export async function startDownUpload({ req, res, getSize, download }) { // the download, so that the client can receive all download/upload progress. logger.debug( 'Waiting for socket connection before beginning remote download/upload.', - null, + undefined, req.id, ) await uploader.awaitReady(clientSocketConnectTimeout) logger.debug( 'Socket connection received. Starting remote download/upload.', - null, + undefined, req.id, ) diff --git a/packages/@uppy/companion/src/server/helpers/utils.js b/packages/@uppy/companion/src/server/helpers/utils.js deleted file mode 100644 index 8e58adfb6..000000000 --- a/packages/@uppy/companion/src/server/helpers/utils.js +++ /dev/null @@ -1,285 +0,0 @@ -import crypto from 'node:crypto' - -const authTagLength = 16 -const nonceLength = 16 -const encryptionKeyLength = 32 -const ivLength = 12 - -/** - * - * @param {string} value - * @param {string[]} criteria - * @returns {boolean} - */ -export const hasMatch = (value, criteria) => { - return criteria.some((i) => { - return value === i || new RegExp(i).test(value) - }) -} - -/** - * - * @param {object} data - * @returns {string} - */ -export const jsonStringify = (data) => { - const cache = [] - return JSON.stringify(data, (key, value) => { - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - // Circular reference found, discard key - return undefined - } - cache.push(value) - } - return value - }) -} - -// all paths are assumed to be '/' prepended -/** - * Returns a url builder - * - * @param {object} options companion options - */ -export function getURLBuilder(options) { - /** - * Builds companion targeted url - * - * @param {string} subPath the tail path of the url - * @param {boolean} isExternal if the url is for the external world - * @param {boolean} [excludeHost] if the server domain and protocol should be included - */ - const buildURL = (subPath, isExternal, excludeHost) => { - let path = '' - - if (isExternal && options.server.implicitPath) { - path += options.server.implicitPath - } - - if (options.server.path) { - path += options.server.path - } - - path += subPath - - if (excludeHost) { - return path - } - - return `${options.server.protocol}://${options.server.host}${path}` - } - - return buildURL -} - -export const getRedirectPath = (providerName) => `/${providerName}/redirect` - -/** - * Create an AES-CCM encryption key and initialization vector from the provided secret - * and a random nonce. - * - * @param {string|Buffer} secret - * @param {Buffer|undefined} nonce - */ -function createSecrets(secret, nonce) { - const key = crypto.hkdfSync( - 'sha256', - secret, - new Uint8Array(32), - nonce, - encryptionKeyLength + ivLength, - ) - const buf = Buffer.from(key) - return { - key: buf.subarray(0, encryptionKeyLength), - iv: buf.subarray(encryptionKeyLength, encryptionKeyLength + ivLength), - } -} - -/** - * Encrypt a buffer or string with AES256 and a random iv. - * - * @param {string} input - * @param {string|Buffer} secret - * @returns {string} Ciphertext as a hex string, prefixed with 32 hex characters containing the iv. - */ -export const encrypt = (input, secret) => { - const nonce = crypto.randomBytes(nonceLength) - const { key, iv } = createSecrets(secret, nonce) - const cipher = crypto.createCipheriv('aes-256-ccm', key, iv, { - authTagLength, - }) - const encrypted = Buffer.concat([ - cipher.update(input, 'utf8'), - cipher.final(), - cipher.getAuthTag(), - ]) - // add nonce to encrypted string to use for decryption - return `${nonce.toString('hex')}${encrypted.toString('base64url')}` -} - -/** - * Decrypt an iv-prefixed or string with AES256. The iv should be in the first 32 hex characters. - * - * @param {string} encrypted hex encoded string of encrypted data - * @param {string|Buffer} secret - * @returns {string} Decrypted value. - */ -export const decrypt = (encrypted, secret) => { - const nonceHexLength = nonceLength * 2 // because hex encoding uses 2 bytes per byte - - // NOTE: The first 32 characters are the nonce, in hex format. - const nonce = Buffer.from(encrypted.slice(0, nonceHexLength), 'hex') - // The rest is the encrypted string, in base64url format. - const encryptionWithoutNonce = Buffer.from( - encrypted.slice(nonceHexLength), - 'base64url', - ) - // The last 16 bytes of the rest is the authentication tag - const authTag = encryptionWithoutNonce.subarray(-authTagLength) - // and the rest (from beginning) is the encrypted data - const encryptionWithoutNonceAndTag = encryptionWithoutNonce.subarray( - 0, - -authTagLength, - ) - - if (nonce.length < nonceLength) { - throw new Error( - 'Invalid encrypted value. Maybe it was generated with an old Companion version?', - ) - } - - const { key, iv } = createSecrets(secret, nonce) - - const decipher = crypto.createDecipheriv('aes-256-ccm', key, iv, { - authTagLength, - }) - decipher.setAuthTag(authTag) - - const decrypted = Buffer.concat([ - decipher.update(encryptionWithoutNonceAndTag), - decipher.final(), - ]) - return decrypted.toString('utf8') -} - -export const defaultGetKey = ({ filename }) => { - return `${crypto.randomUUID()}-${filename}` -} - -/** - * Our own HttpError in cases where we can't use `got`'s `HTTPError` - */ -export class HttpError extends Error { - statusCode - - responseJson - - constructor({ statusCode, responseJson }) { - super(`Request failed with status ${statusCode}`) - this.statusCode = statusCode - this.responseJson = responseJson - this.name = 'HttpError' - } -} - -export const prepareStream = async (stream) => - new Promise((resolve, reject) => { - stream - .on('response', (response) => { - const contentLengthStr = response.headers['content-length'] - const contentLength = parseInt(contentLengthStr, 10) - const size = - !Number.isNaN(contentLength) && contentLength >= 0 - ? contentLength - : undefined - // Don't allow any more data to flow yet. - // https://github.com/request/request/issues/1990#issuecomment-184712275 - stream.pause() - resolve({ size }) - }) - .on('error', (err) => { - // In this case the error object is not a normal GOT HTTPError where json is already parsed, - // we use our own HttpError error for this scenario. - if ( - typeof err.response?.body === 'string' && - typeof err.response?.statusCode === 'number' - ) { - let responseJson - try { - responseJson = JSON.parse(err.response.body) - } catch (_err2) { - reject(err) - return - } - - reject( - new HttpError({ - statusCode: err.response.statusCode, - responseJson, - }), - ) - return - } - - reject(err) - }) - }) - -export const getBasicAuthHeader = (key, secret) => { - const base64 = Buffer.from(`${key}:${secret}`, 'binary').toString('base64') - return `Basic ${base64}` -} - -const rfc2047Encode = (dataIn) => { - const data = `${dataIn}` - // biome-ignore lint/suspicious/noControlCharactersInRegex: leave it for now - if (/^[\x00-\x7F]*$/.test(data)) return data // we return ASCII as is - return `=?UTF-8?B?${Buffer.from(data).toString('base64')}?=` // We encode non-ASCII strings -} - -export const rfc2047EncodeMetadata = (metadata) => - Object.fromEntries( - Object.entries(metadata).map((entry) => entry.map(rfc2047Encode)), - ) - -/** - * - * @param {{ - * bucketOrFn: string | ((a: { - * req: import('express').Request, - * metadata: Record, - * filename: string | undefined, - * }) => string), - * req: import('express').Request, - * metadata?: Record, - * filename?: string, - * }} param0 - * @returns - */ -export const getBucket = ({ bucketOrFn, req, metadata, filename }) => { - const bucket = - typeof bucketOrFn === 'function' - ? bucketOrFn({ req, metadata, filename }) - : bucketOrFn - - if (typeof bucket !== 'string' || bucket === '') { - // This means a misconfiguration or bug - throw new TypeError( - 's3: bucket key must be a string or a function resolving the bucket string', - ) - } - return bucket -} - -/** - * Truncate filename to a maximum length. - * - * @param {string} filename - * @param {number} maxFilenameLength - * @returns {string} - */ -export const truncateFilename = (filename, maxFilenameLength) => { - return filename.slice(maxFilenameLength * -1) -} diff --git a/packages/@uppy/companion/src/server/helpers/utils.ts b/packages/@uppy/companion/src/server/helpers/utils.ts new file mode 100644 index 000000000..8d9d87021 --- /dev/null +++ b/packages/@uppy/companion/src/server/helpers/utils.ts @@ -0,0 +1,300 @@ +import crypto from 'node:crypto' +import type { Request } from 'express' +import type { GetBucketFn } from '../../schemas/companion.js' + +const authTagLength = 16 +const nonceLength = 16 +const encryptionKeyLength = 32 +const ivLength = 12 + +export const hasMatch = ( + value: string, + criteria: ReadonlyArray, +): boolean => { + return criteria.some((i) => { + if (i instanceof RegExp) return i.test(value) + return value === i || new RegExp(i).test(value) + }) +} + +export const jsonStringify = (data: unknown): string => { + const cache: unknown[] = [] + return JSON.stringify(data, (_key, value) => { + if (typeof value === 'object' && value !== null) { + if (cache.indexOf(value) !== -1) { + // Circular reference found, discard key + return undefined + } + cache.push(value) + } + return value + }) +} + +// all paths are assumed to be '/' prepended + +/** + * Returns a URL builder. + * + * The returned function builds Companion-targeted URLs, optionally including the + * server protocol/host for external use. + */ +export function getURLBuilder(options: { + server?: { + protocol?: string | undefined + host?: string | undefined + path?: string | undefined + implicitPath?: string | undefined + } +}) { + return ( + subPath: string, + isExternal: boolean, + excludeHost?: boolean, + ): string => { + const server = options.server ?? {} + let path = '' + + if (isExternal && server.implicitPath) path += server.implicitPath + if (server.path) path += server.path + path += subPath + + if (excludeHost) return path + + return `${server.protocol}://${server.host}${path}` + } +} + +export const getRedirectPath = (providerName: string): string => + `/${providerName}/redirect` + +/** + * Create an AES-CCM encryption key and initialization vector from the provided + * secret and a random nonce. + */ +function createSecrets( + secret: string | Buffer, + nonce: Buffer | undefined, +): { key: Buffer; iv: Buffer } { + const key = crypto.hkdfSync( + 'sha256', + secret, + new Uint8Array(32), + nonce ?? new Uint8Array(0), + encryptionKeyLength + ivLength, + ) + const buf = Buffer.from(key) + return { + key: buf.subarray(0, encryptionKeyLength), + iv: buf.subarray(encryptionKeyLength, encryptionKeyLength + ivLength), + } +} + +/** + * Encrypt a string with AES-256-CCM and a random nonce. + * Ciphertext as a hex string, prefixed with 32 hex characters containing the iv. + * + * The returned ciphertext is prefixed with the nonce (hex), followed by the + * encrypted data (base64url). + */ +export const encrypt = (input: string, secret: string | Buffer): string => { + const nonce = crypto.randomBytes(nonceLength) + const { key, iv } = createSecrets(secret, nonce) + const cipher = crypto.createCipheriv('aes-256-ccm', key, iv, { + authTagLength, + }) + const encrypted = Buffer.concat([ + cipher.update(input, 'utf8'), + cipher.final(), + cipher.getAuthTag(), + ]) + return `${nonce.toString('hex')}${encrypted.toString('base64url')}` +} + +/** + * Decrypt a nonce-prefixed ciphertext produced by {@link encrypt}. + * The iv should be in the first 32 hex characters. + */ +export const decrypt = (encrypted: string, secret: string | Buffer): string => { + const nonceHexLength = nonceLength * 2 // because hex encoding uses 2 bytes per byte + // NOTE: The first 32 characters are the nonce, in hex format. + const nonce = Buffer.from(encrypted.slice(0, nonceHexLength), 'hex') + // The rest is the encrypted string, in base64url format. + const encryptionWithoutNonce = Buffer.from( + encrypted.slice(nonceHexLength), + 'base64url', + ) + // The last 16 bytes of the rest is the authentication tag + const authTag = encryptionWithoutNonce.subarray(-authTagLength) + // and the rest (from beginning) is the encrypted data + const encryptionWithoutNonceAndTag = encryptionWithoutNonce.subarray( + 0, + -authTagLength, + ) + + if (nonce.length < nonceLength) { + throw new Error( + 'Invalid encrypted value. Maybe it was generated with an old Companion version?', + ) + } + + const { key, iv } = createSecrets(secret, nonce) + + const decipher = crypto.createDecipheriv('aes-256-ccm', key, iv, { + authTagLength, + }) + decipher.setAuthTag(authTag) + + const decrypted = Buffer.concat([ + decipher.update(encryptionWithoutNonceAndTag), + decipher.final(), + ]) + return decrypted.toString('utf8') +} + +export const defaultGetKey = ({ filename }: { filename: string }): string => { + return `${crypto.randomUUID()}-${filename}` +} + +/** + * Our own HttpError in cases where we can't use `got`'s `HTTPError`. + */ +export class HttpError extends Error { + statusCode: number + + responseJson: unknown + + constructor({ + statusCode, + responseJson, + }: { statusCode: number; responseJson: unknown }) { + super(`Request failed with status ${statusCode}`) + this.statusCode = statusCode + this.responseJson = responseJson + this.name = 'HttpError' + } +} + +type ResponseLike = { headers: Record } +type StreamLike = NodeJS.ReadableStream & { + pause: () => void + on: { + (event: 'response', handler: (response: ResponseLike) => void): StreamLike + (event: 'error', handler: (err: unknown) => void): StreamLike + } +} + +export const prepareStream = async ( + stream: StreamLike, +): Promise<{ size: number | undefined }> => + new Promise((resolve, reject) => { + stream + .on('response', (response) => { + const contentLengthStr = response.headers['content-length'] + const contentLength = + typeof contentLengthStr === 'string' + ? parseInt(contentLengthStr, 10) + : NaN + const size = + !Number.isNaN(contentLength) && contentLength >= 0 + ? contentLength + : undefined + // Don't allow any more data to flow yet. + stream.pause() + resolve({ size }) + }) + .on('error', (err) => { + if (!err || typeof err !== 'object' || !('response' in err)) { + reject(err) + return + } + + const response = err.response + if (!response || typeof response !== 'object') { + reject(err) + return + } + + const body = (response as { body?: unknown }).body + const statusCode = (response as { statusCode?: unknown }).statusCode + if (typeof body === 'string' && typeof statusCode === 'number') { + // In this case the error object is not a normal GOT HTTPError where json is already parsed, + // we use our own HttpError error for this scenario. + try { + const responseJson: unknown = JSON.parse(body) + reject(new HttpError({ statusCode, responseJson })) + return + } catch { + reject(err) + return + } + } + + reject(err) + }) + }) + +export const getBasicAuthHeader = ( + key: string | undefined, + secret: string | undefined, +): string => { + const base64 = Buffer.from(`${key}:${secret}`, 'binary').toString('base64') + return `Basic ${base64}` +} + +const rfc2047Encode = (dataIn: unknown): string => { + const data = String(dataIn) + // biome-ignore lint/suspicious/noControlCharactersInRegex: leave it for now + if (/^[\x00-\x7F]*$/.test(data)) return data // we return ASCII as is + return `=?UTF-8?B?${Buffer.from(data).toString('base64')}?=` // We encode non-ASCII strings +} + +export const rfc2047EncodeMetadata = ( + metadata: Record, +): Record => + Object.fromEntries( + Object.entries(metadata).map(([key, value]) => [ + rfc2047Encode(key), + rfc2047Encode(value), + ]), + ) + +export const getBucket = ({ + bucketOrFn, + req, + metadata, + filename, +}: { + bucketOrFn: string | GetBucketFn | undefined + req: Request + metadata?: Record + filename?: string +}): string => { + const bucket = + typeof bucketOrFn === 'function' + ? bucketOrFn({ req, metadata: metadata ?? {}, filename }) + : bucketOrFn + + if (typeof bucket !== 'string' || bucket === '') { + // This means a misconfiguration or bug + throw new TypeError( + 's3: bucket key must be a string or a function resolving the bucket string', + ) + } + return bucket +} + +export const truncateFilename = ( + filename: string, + maxFilenameLength?: number, +): string => { + if ( + maxFilenameLength == null || + !Number.isFinite(maxFilenameLength) || + maxFilenameLength <= 0 + ) { + // Historically, passing `undefined` resulted in no truncation (slice(0)). + return filename + } + return filename.slice(maxFilenameLength * -1) +} diff --git a/packages/@uppy/companion/src/server/jobs.js b/packages/@uppy/companion/src/server/jobs.ts similarity index 82% rename from packages/@uppy/companion/src/server/jobs.js rename to packages/@uppy/companion/src/server/jobs.ts index 5da2a045d..87c00712c 100644 --- a/packages/@uppy/companion/src/server/jobs.js +++ b/packages/@uppy/companion/src/server/jobs.ts @@ -3,10 +3,11 @@ import path from 'node:path' import { setTimeout as sleep } from 'node:timers/promises' import got from 'got' import schedule from 'node-schedule' +import { isRecord } from './helpers/type-guards.js' import * as logger from './logger.js' import Uploader from './Uploader.js' -const cleanUpFinishedUploads = (dirPath) => { +const cleanUpFinishedUploads = (dirPath: string): void => { logger.info( `running clean up job for path: ${dirPath}`, 'jobs.cleanup.progress.read', @@ -34,8 +35,7 @@ const cleanUpFinishedUploads = (dirPath) => { // we still delete the file if we can't get the stats // but we also log the error logger.error(err2, 'jobs.cleanup.stat.error') - // @ts-ignore - } else if (Date.now() - stats.mtime < twelveHoursAgo) { + } else if (Date.now() - stats.mtime.getTime() < twelveHoursAgo) { logger.info(`skipping file ${file}`, 'jobs.cleanup.skip') return } @@ -52,15 +52,23 @@ const cleanUpFinishedUploads = (dirPath) => { /** * Runs a function every 24 hours, to clean up stale, upload related files. * - * @param {string} dirPath path to the directory which you want to clean + * @param dirPath path to the directory which you want to clean */ -export function startCleanUpJob(dirPath) { +export function startCleanUpJob(dirPath: string): void { logger.info('starting clean up job', 'jobs.cleanup.start') // run once a day schedule.scheduleJob('0 23 * * *', () => cleanUpFinishedUploads(dirPath)) } -async function runPeriodicPing({ urls, payload, requestTimeout }) { +async function runPeriodicPing({ + urls, + payload, + requestTimeout, +}: { + urls: string[] + payload: Record + requestTimeout: number +}): Promise { // Run requests in parallel await Promise.all( urls.map(async (url) => { @@ -85,7 +93,14 @@ export async function startPeriodicPingJob({ staticPayload = {}, version, processId, -}) { +}: { + urls: string[] + interval?: number | undefined + count?: number | undefined + staticPayload?: unknown | undefined + version: string + processId: string +}): Promise { if (urls.length === 0) return logger.info('Starting periodic ping job', 'jobs.periodic.ping.start') @@ -122,11 +137,12 @@ export async function startPeriodicPingJob({ try { requesting = true + const safeStaticPayload = isRecord(staticPayload) ? staticPayload : {} const payload = { version, processId, service: 'companion', - ...staticPayload, + ...safeStaticPayload, } await runPeriodicPing({ urls, payload, requestTimeout }) } finally { diff --git a/packages/@uppy/companion/src/server/logger.js b/packages/@uppy/companion/src/server/logger.js deleted file mode 100644 index a2d197f50..000000000 --- a/packages/@uppy/companion/src/server/logger.js +++ /dev/null @@ -1,132 +0,0 @@ -import util from 'node:util' -import escapeStringRegexp from 'escape-string-regexp' -import supportsColors from 'supports-color' - -let valuesToMask = [] -/** - * Adds a list of strings that should be masked by the logger. - * This function can only be called once through out the life of the server. - * - * @param {Array} maskables a list of strings to be masked - */ -export function setMaskables(maskables) { - valuesToMask = maskables.map((i) => escapeStringRegexp(i)) -} - -/** - * Mask the secret content of a message - * - * @param {string} msg the message whose content should be masked - * @returns {string} - */ -function maskMessage(msg) { - let out = msg - for (const toBeMasked of valuesToMask) { - const toBeReplaced = new RegExp(toBeMasked, 'gi') - out = out.replace(toBeReplaced, '******') - } - return out -} - -let processName = 'companion' - -export function setProcessName(newProcessName) { - processName = newProcessName -} - -const styleText = - typeof util.styleText === 'function' && supportsColors.stderr - ? util.styleText - : (style, text) => text - -/** - * message log - * - * @typedef {import('node:util').styleText} styleText - * @typedef {Parameters[0]} Colors - * - * @param {object} params - * @param {string | Error} params.arg the message or error to log - * @param {string} params.tag a unique tag to easily search for this message - * @param {string} params.level error | info | debug - * @param {string} [params.traceId] a unique id to easily trace logs tied to a request - * @param {Colors} [params.color] Format(s) that can be passed to `util.styleText`. - */ -const log = ({ arg, tag = '', level, traceId = '', color = [] }) => { - const time = new Date().toISOString() - const whitespace = tag && traceId ? ' ' : '' - - function msgToString() { - // We don't need to log stack trace on special errors that we ourselves have produced - // (to reduce log noise) - // @ts-ignore - if ( - arg instanceof Error && - arg.name === 'ProviderApiError' && - typeof arg.message === 'string' - ) { - return arg.message - } - if (typeof arg === 'string') return arg - return util.inspect(arg) - } - - const msgString = msgToString() - const masked = maskMessage(msgString) - console.log( - styleText( - color, - `${processName}: ${time} [${level}] ${traceId}${whitespace}${tag}`, - ), - styleText(color, masked), - ) -} - -/** - * INFO level log - * - * @param {string} msg the message to log - * @param {string} [tag] a unique tag to easily search for this message - * @param {string} [traceId] a unique id to easily trace logs tied to a request - */ -export function info(msg, tag, traceId) { - log({ arg: msg, tag, level: 'info', traceId }) -} - -/** - * WARN level log - * - * @param {string} msg the message to log - * @param {string} [tag] a unique tag to easily search for this message - * @param {string} [traceId] a unique id to easily trace logs tied to a request - */ -export function warn(msg, tag, traceId) { - log({ arg: msg, tag, level: 'warn', traceId, color: ['bold', 'yellow'] }) -} - -/** - * ERROR level log - * - * @param {string | Error} msg the message to log - * @param {string} [tag] a unique tag to easily search for this message - * @param {string} [traceId] a unique id to easily trace logs tied to a request - */ -export function error(msg, tag, traceId) { - log({ arg: msg, tag, level: 'error', traceId, color: ['bold', 'red'] }) -} - -/** - * DEBUG level log - * - * @param {string} msg the message to log - * @param {string} [tag] a unique tag to easily search for this message - * @param {string} [traceId] a unique id to easily trace logs tied to a request - */ -export function debug(msg, tag, traceId) { - if (process.env.NODE_ENV !== 'production') { - log({ arg: msg, tag, level: 'debug', traceId, color: ['bold', 'blue'] }) - } -} - -const logger = { setMaskables, setProcessName, info, warn, error, debug } -export default logger diff --git a/packages/@uppy/companion/src/server/logger.ts b/packages/@uppy/companion/src/server/logger.ts new file mode 100644 index 000000000..ea14e5055 --- /dev/null +++ b/packages/@uppy/companion/src/server/logger.ts @@ -0,0 +1,148 @@ +import util from 'node:util' +import escapeStringRegexp from 'escape-string-regexp' +import supportsColors from 'supports-color' + +type StyleTextFn = ( + style: Parameters>[0], + text: string, +) => string +type Colors = Parameters[0] +type LogLevel = 'error' | 'info' | 'warn' | 'debug' + +let valuesToMask: string[] = [] + +/** + * Adds a list of strings that should be masked by the logger. + * This is expected to be set during startup and not updated continuously. + */ +export function setMaskables(maskables: readonly string[]): void { + valuesToMask = maskables.map((i) => escapeStringRegexp(i)) +} + +/** + * Mask secret values in a log message. + */ +function maskMessage(msg: string): string { + let out = msg + for (const toBeMasked of valuesToMask) { + const toBeReplaced = new RegExp(toBeMasked, 'gi') + out = out.replace(toBeReplaced, '******') + } + return out +} + +let processName = 'companion' + +export function setProcessName(newProcessName: string): void { + processName = newProcessName +} + +const styleText: StyleTextFn = + typeof util.styleText === 'function' && supportsColors.stderr + ? (style, text) => util.styleText(style, text) + : (_style, text) => text + +/** + * Logs a message. + * + * @param params.arg - The message or error to log. + * @param params.tag - A tag to easily search for this message. + * @param params.level - Log level. + * @param params.traceId - A unique id to correlate logs tied to a request. + * @param params.color - Format(s) that can be passed to `util.styleText`. + */ +function log(params: { + arg: unknown + tag?: string + level: LogLevel + traceId?: string + color?: Colors +}): void { + const { arg, level } = params + const tag = params.tag ?? '' + const traceId = params.traceId ?? '' + const color = params.color ?? [] + + const time = new Date().toISOString() + const whitespace = tag && traceId ? ' ' : '' + + function msgToString(): string { + // We don't need to log stack trace on special errors that we ourselves have produced + // (to reduce log noise). + if ( + arg instanceof Error && + arg.name === 'ProviderApiError' && + typeof arg.message === 'string' + ) { + return arg.message + } + if (typeof arg === 'string') return arg + return util.inspect(arg) + } + + const msgString = msgToString() + const masked = maskMessage(msgString) + console.log( + styleText( + color, + `${processName}: ${time} [${level}] ${traceId}${whitespace}${tag}`, + ), + styleText(color, masked), + ) +} + +/** + * INFO level log. + */ +export function info(msg: unknown, tag?: string, traceId?: string): void { + log({ + arg: msg, + level: 'info', + ...(tag != null && { tag }), + ...(traceId != null && { traceId }), + }) +} + +/** + * WARN level log. + */ +export function warn(msg: unknown, tag?: string, traceId?: string): void { + log({ + arg: msg, + level: 'warn', + color: ['bold', 'yellow'], + ...(tag != null && { tag }), + ...(traceId != null && { traceId }), + }) +} + +/** + * ERROR level log. + */ +export function error(msg: unknown, tag?: string, traceId?: string): void { + log({ + arg: msg, + level: 'error', + color: ['bold', 'red'], + ...(tag != null && { tag }), + ...(traceId != null && { traceId }), + }) +} + +/** + * DEBUG level log. + */ +export function debug(msg: unknown, tag?: string, traceId?: string): void { + if (process.env['NODE_ENV'] !== 'production') { + log({ + arg: msg, + level: 'debug', + color: ['bold', 'blue'], + ...(tag != null && { tag }), + ...(traceId != null && { traceId }), + }) + } +} + +const logger = { setMaskables, setProcessName, info, warn, error, debug } +export default logger diff --git a/packages/@uppy/companion/src/server/middlewares.js b/packages/@uppy/companion/src/server/middlewares.ts similarity index 57% rename from packages/@uppy/companion/src/server/middlewares.js rename to packages/@uppy/companion/src/server/middlewares.ts index eea47ee2b..4dd3103b6 100644 --- a/packages/@uppy/companion/src/server/middlewares.js +++ b/packages/@uppy/companion/src/server/middlewares.ts @@ -1,18 +1,21 @@ import corsImport from 'cors' +import type { NextFunction, Request, RequestHandler, Response } from 'express' import promBundle from 'express-prom-bundle' import packageJson from '../../package.json' with { type: 'json' } +import type { CompanionRuntimeOptions } from '../types/companion-options.js' +import type { ProviderUserSession } from '../types/express.js' import * as tokenService from './helpers/jwt.js' import { getURLBuilder } from './helpers/utils.js' import * as logger from './logger.js' import { isOAuthProvider } from './provider/Provider.js' import getS3Client from './s3-client.js' -export const hasSessionAndProvider = (req, res, next) => { +export const hasSessionAndProvider: RequestHandler = (req, res, next) => { if (!req.session) { logger.debug( 'No session attached to req object. Exiting dispatcher.', - null, + undefined, req.id, ) return res.sendStatus(400) @@ -21,7 +24,7 @@ export const hasSessionAndProvider = (req, res, next) => { if (!req.companion.provider) { logger.debug( 'No provider/provider-handler found. Exiting dispatcher.', - null, + undefined, req.id, ) return res.sendStatus(400) @@ -30,38 +33,38 @@ export const hasSessionAndProvider = (req, res, next) => { return next() } -const isOAuthProviderReq = (req) => - isOAuthProvider(req.companion.providerClass.oauthProvider) -const isSimpleAuthProviderReq = (req) => - !!req.companion.providerClass.hasSimpleAuth +const isOAuthProviderReq = (req: Request) => + isOAuthProvider(req.companion.providerClass?.oauthProvider) +const isSimpleAuthProviderReq = (req: Request) => + !!req.companion.providerClass?.hasSimpleAuth /** * Middleware can be used to verify that the current request is to an OAuth provider * This is because not all requests are supported by non-oauth providers (formerly known as SearchProviders) */ -export const hasOAuthProvider = (req, res, next) => { +export const hasOAuthProvider: RequestHandler = (req, res, next) => { if (!isOAuthProviderReq(req)) { - logger.debug('Provider does not support OAuth.', null, req.id) + logger.debug('Provider does not support OAuth.', undefined, req.id) return res.sendStatus(400) } return next() } -export const hasSimpleAuthProvider = (req, res, next) => { +export const hasSimpleAuthProvider: RequestHandler = (req, res, next) => { if (!isSimpleAuthProviderReq(req)) { - logger.debug('Provider does not support simple auth.', null, req.id) + logger.debug('Provider does not support simple auth.', undefined, req.id) return res.sendStatus(400) } return next() } -export const hasBody = (req, res, next) => { +export const hasBody: RequestHandler = (req, res, next) => { if (!req.body) { logger.debug( 'No body attached to req object. Exiting dispatcher.', - null, + undefined, req.id, ) return res.sendStatus(400) @@ -70,8 +73,8 @@ export const hasBody = (req, res, next) => { return next() } -export const hasSearchQuery = (req, res, next) => { - if (typeof req.query.q !== 'string') { +export const hasSearchQuery: RequestHandler = (req, res, next) => { + if (typeof req.query['q'] !== 'string') { logger.debug( 'search request has no search query', 'search.query.check', @@ -83,7 +86,7 @@ export const hasSearchQuery = (req, res, next) => { return next() } -export const verifyToken = (req, res, next) => { +export const verifyToken: RequestHandler = (req, res, next) => { if (isOAuthProviderReq(req) || isSimpleAuthProviderReq(req)) { // For OAuth / simple auth provider, we find the encrypted auth token from the header: const token = req.companion.authToken @@ -92,16 +95,23 @@ export const verifyToken = (req, res, next) => { res.sendStatus(401) return } - const { providerName } = req.params + const { secret } = req.companion.options + const providerName = req.params['providerName'] + if (providerName == null || providerName.length === 0) { + res.sendStatus(400) + return + } try { - const payload = tokenService.verifyEncryptedAuthToken( - token, - req.companion.options.secret, - providerName, - ) + const payload = tokenService.verifyEncryptedAuthToken< + Record + >(token, secret, providerName) req.companion.providerUserSession = payload[providerName] } catch (err) { - logger.error(err.message, 'token.verify.error', req.id) + logger.error( + err instanceof Error ? err.message : String(err), + 'token.verify.error', + req.id, + ) res.sendStatus(401) return } @@ -112,8 +122,10 @@ export const verifyToken = (req, res, next) => { // for non auth providers, we just load the static key from options if (!isOAuthProviderReq(req)) { const { providerOptions } = req.companion.options - const { providerName } = req.params - const key = providerOptions[providerName]?.key + const providerName = req.params['providerName'] + const providerOption = + providerName != null ? providerOptions?.[providerName] : undefined + const key = providerOption?.key if (!key) { logger.info( `unconfigured credentials for ${providerName}`, @@ -132,31 +144,44 @@ export const verifyToken = (req, res, next) => { } // does not fail if token is invalid -export const gentleVerifyToken = (req, res, next) => { - const { providerName } = req.params - if (req.companion.authToken) { +export const gentleVerifyToken: RequestHandler = (req, res, next) => { + const providerName = req.params['providerName'] + if (providerName == null || providerName.length === 0) { + next() + return + } + const { secret } = req.companion.options + if (req.companion.authToken != null) { try { - const payload = tokenService.verifyEncryptedAuthToken( - req.companion.authToken, - req.companion.options.secret, - providerName, - ) + const payload = tokenService.verifyEncryptedAuthToken< + Record + >(req.companion.authToken, secret, providerName) req.companion.providerUserSession = payload[providerName] } catch (err) { - logger.error(err.message, 'token.gentle.verify.error', req.id) + logger.error( + err instanceof Error ? err.message : String(err), + 'token.gentle.verify.error', + req.id, + ) } } next() } -export const cookieAuthToken = (req, res, next) => { - req.companion.authToken = - req.cookies[`uppyAuthToken--${req.companion.providerClass.oauthProvider}`] +export const cookieAuthToken: RequestHandler = (req, res, next) => { + const oauthProvider = req.companion.providerClass?.oauthProvider + if (oauthProvider == null || oauthProvider.length === 0) { + return next() + } + req.companion.authToken = req.cookies[`uppyAuthToken--${oauthProvider}`] return next() } export const cors = - (options = {}) => + (options: { + corsOrigins?: CompanionRuntimeOptions['corsOrigins'] + sendSelfEndpoint?: CompanionRuntimeOptions['sendSelfEndpoint'] + }): RequestHandler => (req, res, next) => { // HTTP headers are not case sensitive, and express always handles them in lower case, so that's why we lower case them. // I believe that HTTP verbs are case sensitive, and should be uppercase. @@ -168,7 +193,10 @@ export const cors = ?.map((method) => method.trim().toLowerCase()), ) - if (options.sendSelfEndpoint) exposeHeadersSet.add('i-am') + const sendSelfEndpoint = options['sendSelfEndpoint'] + if (sendSelfEndpoint != null) { + exposeHeadersSet.add('i-am') + } // Needed for basic operation: https://github.com/transloadit/uppy/issues/3021 const allowedHeaders = [ @@ -208,19 +236,33 @@ export const cors = // Because we need to merge with existing headers, we need to call cors inside our own middleware return corsImport({ credentials: true, - origin, methods: Array.from(allowMethodsSet), allowedHeaders: Array.from(allowHeadersSet).join(','), exposedHeaders: Array.from(exposeHeadersSet).join(','), + ...(origin !== undefined && { origin }), })(req, res, next) } -export const metrics = ({ path = undefined } = {}) => { +function hasPromClient(mw: unknown): mw is RequestHandler & { + promClient: { + collectDefaultMetrics: (opts: unknown) => void + Gauge: new (opts: unknown) => { set: (n: number) => void } + register: unknown + } +} { + return !!mw && typeof mw === 'function' && 'promClient' in mw +} + +export const metrics = ({ + path = undefined, +}: { + path?: string +} = {}): RequestHandler => { const metricsMiddleware = promBundle({ includeMethod: true, - metricsPath: path ? `${path}/metrics` : undefined, + ...(path && { metricsPath: `${path}/metrics` }), }) - // @ts-ignore Not in the typings, but it does exist + if (!hasPromClient(metricsMiddleware)) return metricsMiddleware const { promClient } = metricsMiddleware const { collectDefaultMetrics } = promClient collectDefaultMetrics({ register: promClient.register }) @@ -235,23 +277,21 @@ export const metrics = ({ path = undefined } = {}) => { return metricsMiddleware } -/** - * - * @param {object} options - */ -export const getCompanionMiddleware = (options) => { - /** - * @param {object} req - * @param {object} res - * @param {Function} next - */ - const middleware = (req, res, next) => { +export const getCompanionMiddleware = ( + options: CompanionRuntimeOptions, +): RequestHandler => { + const middleware = (req: Request, _res: Response, next: NextFunction) => { + const s3Client = getS3Client(options, false) + const s3ClientCreatePresignedPost = getS3Client(options, true) + const authToken = + req.header('uppy-auth-token') || req.query['uppyAuthToken'] + req.companion = { options, - s3Client: getS3Client(options, false), - s3ClientCreatePresignedPost: getS3Client(options, true), - authToken: req.header('uppy-auth-token') || req.query.uppyAuthToken, buildURL: getURLBuilder(options), + ...(s3Client && { s3Client }), + ...(s3ClientCreatePresignedPost && { s3ClientCreatePresignedPost }), + ...(typeof authToken === 'string' && { authToken }), } next() } diff --git a/packages/@uppy/companion/src/server/provider/Provider.js b/packages/@uppy/companion/src/server/provider/Provider.js deleted file mode 100644 index 8250f8548..000000000 --- a/packages/@uppy/companion/src/server/provider/Provider.js +++ /dev/null @@ -1,129 +0,0 @@ -import { MAX_AGE_24H } from '../helpers/jwt.js' - -/** - * Provider interface defines the specifications of any provider implementation - */ -export default class Provider { - /** - * - * @param {{providerName: string, allowLocalUrls: boolean, providerGrantConfig?: object, secret: string}} options - */ - constructor({ allowLocalUrls, providerGrantConfig, secret }) { - // Some providers might need cookie auth for the thumbnails fetched via companion - this.needsCookieAuth = false - this.allowLocalUrls = allowLocalUrls - this.providerGrantConfig = providerGrantConfig - this.secret = secret - // biome-ignore lint/correctness/noConstructorReturn: ... - return this - } - - /** - * config to extend the grant config - */ - static getExtraGrantConfig() { - return {} - } - - /** - * list the files and folders in the provider account - * - * @param {object} options - * @returns {Promise} - */ - async list(options) { - throw new Error('method not implemented') - } - - /** - * search for files/folders in the provider account - * - * @param {object} options - * @returns {Promise} - */ - async search(options) { - throw new Error('method not implemented') - } - - /** - * download a certain file from the provider account - * - * @param {object} options - * @returns {Promise} - */ - async download(options) { - throw new Error('method not implemented') - } - - /** - * return a thumbnail for a provider file - * - * @param {object} options - * @returns {Promise} - */ - async thumbnail(options) { - throw new Error('method not implemented') - } - - /** - * first Companion will try to get the size from the content-length response header, - * if that fails, it will call this method to get the size. - * So if your provider has a different method for getting the size, you can return the size here - * - * @param {object} options - * @returns {Promise} - */ - async size(options) { - return undefined - } - - /** - * handle deauthorization notification from oauth providers - * - * @param {object} options - * @returns {Promise} - */ - async deauthorizationCallback(options) { - throw new Error('method not implemented') - } - - /** - * Generate a new access token based on the refresh token - */ - async refreshToken(options) { - throw new Error('method not implemented') - } - - /** - * @param {any} param0 - * @returns {Promise} - */ - async simpleAuth({ requestBody }) { - throw new Error('method not implemented') - } - - /** - * Name of the OAuth provider (passed to Grant). Return empty string if no OAuth provider is needed. - * - * @returns {string} - */ - static get oauthProvider() { - return undefined - } - - static grantDynamicToUserSession({ grantDynamic }) { - return {} - } - - static get hasSimpleAuth() { - return false - } - - static get authStateExpiry() { - return MAX_AGE_24H - } -} - -// OAuth providers are those that have an `oauthProvider` set. It means they require OAuth authentication to work -export const isOAuthProvider = (oauthProvider) => - typeof oauthProvider === 'string' && oauthProvider.length > 0 diff --git a/packages/@uppy/companion/src/server/provider/Provider.ts b/packages/@uppy/companion/src/server/provider/Provider.ts new file mode 100644 index 000000000..2a9f7b73d --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/Provider.ts @@ -0,0 +1,210 @@ +import type { Readable } from 'node:stream' +import type { + BuildUrl, + CompanionContext, + GrantDynamic, + ProviderGrantConfig, +} from '../../types/express.js' +import { MAX_AGE_24H } from '../helpers/jwt.js' + +// from express: +export interface Query { + [key: string]: undefined | string | string[] | Query | Query[] +} + +export type CompanionLike = Pick< + CompanionContext, + 'getProviderCredentials' | 'options' +> + +export interface ProviderListItem { + isFolder: boolean + icon: string | null | undefined + id: string + name?: string | undefined + requestPath: string + modifiedDate?: string | undefined + mimeType?: string | null | undefined + size?: number | null | undefined + thumbnail?: string | null | undefined +} + +// todo use these types in the Uppy client +export interface ProviderListResponse { + items: ProviderListItem[] + nextPagePath?: string | null | undefined + username?: string | null | undefined +} + +export type ProviderSearchResponse = ProviderListResponse + +/** + * Provider interface defines the specifications of any provider implementation + */ +export default class Provider { + needsCookieAuth: boolean + + allowLocalUrls: boolean + + providerGrantConfig: ProviderGrantConfig | undefined + + constructor({ + allowLocalUrls, + providerGrantConfig, + }: { + allowLocalUrls: boolean + providerGrantConfig?: ProviderGrantConfig + }) { + // Some providers might need cookie auth for the thumbnails fetched via companion + this.needsCookieAuth = false + this.allowLocalUrls = allowLocalUrls + this.providerGrantConfig = providerGrantConfig + // biome-ignore lint/correctness/noConstructorReturn: ... + return this + } + + /** + * config to extend the grant config + */ + static getExtraGrantConfig(): Record { + return {} + } + + /** + * List the files and folders in the provider account. + * + * This method should be overridden by provider implementations. + */ + async list(options: { + companion: CompanionContext + directory?: string | undefined + providerUserSession: US + query?: Query + }): Promise { + throw new Error('method not implemented') + } + + /** + * Search for files and folders in the provider account. + * + * This method should be overridden by provider implementations. + */ + async search(options: { + providerUserSession: US + query: { q: string; path?: string; [k: string]: unknown } + companion: { buildURL: BuildUrl } + }): Promise { + throw new Error('method not implemented') + } + + /** + * Download a certain file from the provider account. + * + * This method should be overridden by provider implementations. + */ + async download(options: { + companion: CompanionLike + id: string + providerUserSession: US + query: Query + }): Promise<{ stream: Readable; size: number | undefined }> { + throw new Error('method not implemented') + } + + /** + * Return a thumbnail for a provider file. + * + * This method should be overridden by provider implementations. + */ + async thumbnail(options: { + id: string + providerUserSession: US + }): Promise<{ stream: Readable; contentType?: string }> { + throw new Error('method not implemented') + } + + /** + * first Companion will try to get the size from the content-length response header, + * if that fails, it will call this method to get the size. + * So if your provider has a different method for getting the size, you can return the size here + */ + async size(options: { + id: string + providerUserSession: US + query: unknown + }): Promise { + return undefined + } + + /** + * Handle deauthorization notification from OAuth providers. + * + * This method should be overridden by provider implementations. + */ + async deauthorizationCallback(options: { + companion: CompanionLike + body: unknown + headers: Record + }): Promise<{ data?: unknown; status?: number }> { + throw new Error('method not implemented') + } + + /** + * Generate a new access token based on the refresh token + */ + async refreshToken(options: { + redirectUri: string | undefined + clientId: string | undefined + clientSecret: string | undefined + refreshToken: string + }): Promise<{ accessToken: string }> { + throw new Error('method not implemented') + } + + /** + * Revoke/logout for a provider session (if supported). + * + * This method should be overridden by provider implementations. + */ + async logout(options: { + providerUserSession: US + companion: CompanionLike + }): Promise<{ revoked: boolean; manual_revoke_url?: string }> { + throw new Error('method not implemented') + } + + async simpleAuth({ requestBody }: { requestBody: unknown }): Promise { + throw new Error('method not implemented') + } + + /** + * Name of the OAuth provider (passed to Grant). Return empty string if no OAuth provider is needed. + */ + static get oauthProvider(): string | undefined { + return undefined + } + + static grantDynamicToUserSession({ + grantDynamic, + }: { + grantDynamic: GrantDynamic + }): Record { + return {} + } + + static get hasSimpleAuth(): boolean { + return false + } + + static get authStateExpiry(): number { + return MAX_AGE_24H + } +} + +export type ProviderCtor = typeof Provider + +// OAuth providers are those that have an `oauthProvider` set. It means they require OAuth authentication to work +export const isOAuthProvider = ( + oauthProvider: string | undefined, +): oauthProvider is string => + typeof oauthProvider === 'string' && oauthProvider.length > 0 diff --git a/packages/@uppy/companion/src/server/provider/box/adapter.js b/packages/@uppy/companion/src/server/provider/box/adapter.js deleted file mode 100644 index 8c02a5af2..000000000 --- a/packages/@uppy/companion/src/server/provider/box/adapter.js +++ /dev/null @@ -1,77 +0,0 @@ -import querystring from 'node:querystring' -import mime from 'mime-types' - -const isFolder = (item) => { - return item.type === 'folder' -} - -const getItemSize = (item) => { - return item.size -} - -const getItemIcon = (item) => { - return item.type -} - -const getItemSubList = (item) => { - return item.entries -} - -const getItemName = (item) => { - return item.name || '' -} - -const getMimeType = (item) => { - return mime.lookup(getItemName(item)) || null -} - -const getItemId = (item) => { - return item.id -} - -const getItemRequestPath = (item) => { - return item.id -} - -const getItemModifiedDate = (item) => { - return item.modified_at -} - -const getItemThumbnailUrl = (item) => { - return `/box/thumbnail/${getItemRequestPath(item)}` -} - -const getNextPagePath = (data) => { - if ( - data.total_count < data.limit || - data.offset + data.limit > data.total_count - ) { - return null - } - const query = { cursor: data.offset + data.limit } - return `?${querystring.stringify(query)}` -} - -const adaptData = function adaptData(res, username, companion) { - const data = { username, items: [] } - const items = getItemSubList(res) - items.forEach((item) => { - data.items.push({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item), - mimeType: getMimeType(item), - id: getItemId(item), - thumbnail: companion.buildURL(getItemThumbnailUrl(item), true), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - size: getItemSize(item), - }) - }) - - data.nextPagePath = getNextPagePath(res) - - return data -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/box/adapter.ts b/packages/@uppy/companion/src/server/provider/box/adapter.ts new file mode 100644 index 000000000..7671d14fe --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/box/adapter.ts @@ -0,0 +1,99 @@ +import querystring from 'node:querystring' +import mime from 'mime-types' +import type { BuildUrl } from '../../../types/express.js' + +type BoxItem = { + type?: string + size?: number + entries?: BoxItem[] + name?: string + id: string + modified_at?: string +} + +type BoxListResponse = { + entries: BoxItem[] + total_count: number + limit: number + offset: number +} + +type CompanionLike = { + buildURL?: BuildUrl +} + +const isFolder = (item: BoxItem): boolean => { + return item.type === 'folder' +} + +const getItemSize = (item: BoxItem): number | undefined => { + return item.size +} + +const getItemIcon = (item: BoxItem): string | undefined => { + return item.type +} + +const getItemSubList = (item: BoxListResponse): BoxItem[] => { + return item.entries +} + +const getItemName = (item: BoxItem): string => { + return item.name || '' +} + +const getMimeType = (item: BoxItem): string | null => { + const mt = mime.lookup(getItemName(item)) + return typeof mt === 'string' ? mt : null +} + +const getItemId = (item: BoxItem): string => { + return item.id +} + +const getItemRequestPath = (item: BoxItem): string => { + return item.id +} + +const getItemModifiedDate = (item: BoxItem): string | undefined => { + return item.modified_at +} + +const getItemThumbnailUrl = (item: BoxItem): string => { + return `/box/thumbnail/${getItemRequestPath(item)}` +} + +const getNextPagePath = (data: BoxListResponse): string | null => { + if ( + data.total_count < data.limit || + data.offset + data.limit > data.total_count + ) { + return null + } + const query = { cursor: data.offset + data.limit } + return `?${querystring.stringify(query)}` +} + +const adaptData = function adaptData( + res: BoxListResponse, + username: string | undefined, + companion: CompanionLike, +) { + const items = getItemSubList(res).map((item) => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item), + mimeType: getMimeType(item), + id: getItemId(item), + thumbnail: companion.buildURL?.(getItemThumbnailUrl(item), true), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + size: getItemSize(item), + })) + + const nextPagePath = getNextPagePath(res) + + return { username, items, nextPagePath } +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/box/index.js b/packages/@uppy/companion/src/server/provider/box/index.ts similarity index 52% rename from packages/@uppy/companion/src/server/provider/box/index.js rename to packages/@uppy/companion/src/server/provider/box/index.ts index 942182fcc..c13537c9d 100644 --- a/packages/@uppy/companion/src/server/provider/box/index.js +++ b/packages/@uppy/companion/src/server/provider/box/index.ts @@ -1,13 +1,25 @@ +import type { Readable } from 'node:stream' import got from 'got' +import type { ProviderOptions } from '../../../schemas/companion.js' +import type { BuildUrl } from '../../../types/express.js' +import { isRecord } from '../../helpers/type-guards.js' import { prepareStream } from '../../helpers/utils.js' -import Provider from '../Provider.js' +import Provider, { type ProviderListResponse, type Query } from '../Provider.js' import { withProviderErrorHandling } from '../providerErrors.js' import adaptData from './adapter.js' const BOX_FILES_FIELDS = 'id,modified_at,name,permissions,size,type' const BOX_THUMBNAIL_SIZE = 256 -const getClient = ({ token }) => +type BoxUserSession = { accessToken: string } +type CompanionLike = { + buildURL?: BuildUrl + options: { + providerOptions: Record> + } +} + +const getClient = ({ token }: { token: string }) => got.extend({ prefixUrl: 'https://api.box.com/2.0', headers: { @@ -15,53 +27,74 @@ const getClient = ({ token }) => }, }) -async function getUserInfo({ token }) { - return getClient({ token }).get('users/me', { responseType: 'json' }).json() +async function getUserInfo({ + token, +}: { + token: string +}): Promise<{ login?: string }> { + return getClient({ token }) + .get('users/me', { responseType: 'json' }) + .json<{ login?: string }>() } -async function list({ directory, query, token }) { +async function list({ + directory, + query, + token, +}: { + directory: string | undefined + query?: Query | undefined + token: string +}): Promise[0]> { const rootFolderID = '0' + const cursor = + typeof query?.['cursor'] === 'string' ? query?.['cursor'] : undefined return getClient({ token }) .get(`folders/${directory || rootFolderID}/items`, { searchParams: { fields: BOX_FILES_FIELDS, - offset: query.cursor, + offset: cursor, limit: 1000, }, responseType: 'json', }) - .json() + .json[0]>() } /** * Adapter for API https://developer.box.com/reference/ */ -export default class Box extends Provider { - constructor(options) { +export default class Box extends Provider { + constructor(options: ConstructorParameters[0]) { super(options) // needed for the thumbnails fetched via companion this.needsCookieAuth = true } - static get oauthProvider() { + static override get oauthProvider() { return 'box' } /** * Lists files and folders from Box API * - * @param {object} options - * @param {string} options.directory - * @param {any} options.query - * @param {{ accessToken: string }} options.providerUserSession - * @param {unknown} options.companion + * @param options + * @param options.directory + * @param options.query + * @param options.providerUserSession + * @param options.companion */ - async list({ + override async list({ directory, providerUserSession: { accessToken: token }, query, companion, - }) { + }: { + directory?: string | undefined + providerUserSession: BoxUserSession + query?: Query + companion: CompanionLike + }): Promise { return this.#withErrorHandling('provider.box.list.error', async () => { const [userInfo, files] = await Promise.all([ getUserInfo({ token }), @@ -72,7 +105,13 @@ export default class Box extends Provider { }) } - async download({ id, providerUserSession: { accessToken: token } }) { + override async download({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: BoxUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { return this.#withErrorHandling('provider.box.download.error', async () => { const stream = getClient({ token }).stream.get(`files/${id}/content`, { responseType: 'json', @@ -83,7 +122,13 @@ export default class Box extends Provider { }) } - async thumbnail({ id, providerUserSession: { accessToken: token } }) { + override async thumbnail({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: BoxUserSession + }): Promise<{ stream: Readable; contentType: string }> { return this.#withErrorHandling('provider.box.thumbnail.error', async () => { const extension = 'jpg' // you can set this to png to more easily reproduce http 202 retry-after @@ -112,18 +157,37 @@ export default class Box extends Provider { }) } - async size({ id, providerUserSession: { accessToken: token } }) { + override async size({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: BoxUserSession + }): Promise { return this.#withErrorHandling('provider.box.size.error', async () => { - const { size } = await getClient({ token }) + const file = await getClient({ token }) .get(`files/${id}`, { responseType: 'json' }) - .json() - return parseInt(size, 10) + .json>() + const sizeValue = file['size'] + const sizeStr = + typeof sizeValue === 'string' + ? sizeValue + : typeof sizeValue === 'number' + ? `${sizeValue}` + : '0' + return parseInt(sizeStr, 10) }) } - logout({ companion, providerUserSession: { accessToken: token } }) { + override async logout({ + companion, + providerUserSession: { accessToken: token }, + }: { + companion: CompanionLike + providerUserSession: BoxUserSession + }): Promise<{ revoked: true }> { return this.#withErrorHandling('provider.box.logout.error', async () => { - const { key, secret } = companion.options.providerOptions.box + const { key, secret } = companion.options.providerOptions['box']! await getClient({ token }).post('oauth2/revoke', { prefixUrl: 'https://api.box.com', form: { @@ -138,13 +202,17 @@ export default class Box extends Provider { }) } - async #withErrorHandling(tag, fn) { + async #withErrorHandling(tag: string, fn: () => Promise): Promise { return withProviderErrorHandling({ fn, tag, providerName: Box.oauthProvider, isAuthError: (response) => response.statusCode === 401, - getJsonErrorMessage: (body) => body?.message, + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const msg = body['message'] + return typeof msg === 'string' ? msg : undefined + }, }) } } diff --git a/packages/@uppy/companion/src/server/provider/credentials.js b/packages/@uppy/companion/src/server/provider/credentials.js deleted file mode 100644 index 92abcc7c3..000000000 --- a/packages/@uppy/companion/src/server/provider/credentials.js +++ /dev/null @@ -1,242 +0,0 @@ -import { htmlEscape } from 'escape-goat' -import got from 'got' -import * as tokenService from '../helpers/jwt.js' -import * as oAuthState from '../helpers/oauth-state.js' -import { getRedirectPath, getURLBuilder } from '../helpers/utils.js' -import logger from '../logger.js' -// biome-ignore lint/correctness/noUnusedImports: It is used as a type -import Provider from './Provider.js' - -/** - * @param {string} url - * @param {string} providerName - * @param {object|null} credentialRequestParams - null asks for default credentials. - */ -async function fetchKeys(url, providerName, credentialRequestParams) { - try { - const { credentials } = await got - .post(url, { - json: { provider: providerName, parameters: credentialRequestParams }, - }) - .json() - - if (!credentials) throw new Error('Received no remote credentials') - return credentials - } catch (err) { - logger.error(err, 'credentials.fetch.fail') - throw err - } -} - -/** - * Fetches for a providers OAuth credentials. If the config for that provider allows fetching - * of the credentials via http, and the `credentialRequestParams` argument is provided, the oauth - * credentials will be fetched via http. Otherwise, the credentials provided via companion options - * will be used instead. - * - * @param {string} providerName the name of the provider whose oauth keys we want to fetch (e.g onedrive) - * @param {object} companionOptions the companion options object - * @param {object} credentialRequestParams the params that should be sent if an http request is required. - */ -async function fetchProviderKeys( - providerName, - companionOptions, - credentialRequestParams, -) { - let providerConfig = companionOptions.providerOptions[providerName] - if (!providerConfig) { - providerConfig = companionOptions.customProviders[providerName]?.config - } - - if (!providerConfig) { - return null - } - - if (!providerConfig.credentialsURL) { - return providerConfig - } - - // If a default key is configured, do not ask the credentials endpoint for it. - // In a future version we could make this an XOR thing, providing either an endpoint or global keys, - // but not both. - if (!credentialRequestParams && providerConfig.key) { - return providerConfig - } - - return fetchKeys( - providerConfig.credentialsURL, - providerName, - credentialRequestParams || null, - ) -} - -/** - * Returns a request middleware function that can be used to pre-fetch a provider's - * Oauth credentials before the request is passed to the Oauth handler (https://github.com/simov/grant in this case). - * - * @param {Record} providers provider classes enabled for this server - * @param {object} companionOptions companion options object - * @returns {import('express').RequestHandler} - */ -export const getCredentialsOverrideMiddleware = ( - providers, - companionOptions, -) => { - return async (req, res, next) => { - try { - const { oauthProvider, override } = req.params - const [providerName] = Object.keys(providers).filter( - (name) => providers[name].oauthProvider === oauthProvider, - ) - if (!providerName) { - next() - return - } - - if (!companionOptions.providerOptions[providerName]?.credentialsURL) { - next() - return - } - - const grantDynamic = oAuthState.getGrantDynamicFromRequest(req) - // only use state via session object if user isn't making intial "connect" request. - // override param indicates subsequent requests from the oauth flow - const state = override ? grantDynamic.state : req.query.state - if (!state) { - next() - return - } - - const preAuthToken = oAuthState.getFromState( - state, - 'preAuthToken', - companionOptions.secret, - ) - if (!preAuthToken) { - next() - return - } - - let payload - try { - payload = tokenService.verifyEncryptedToken( - preAuthToken, - companionOptions.preAuthSecret, - ) - } catch (_err) { - next() - return - } - - const credentials = await fetchProviderKeys( - providerName, - companionOptions, - payload, - ) - - // Besides the key and secret the fetched credentials can also contain `origins`, - // which is an array of strings of allowed origins to prevent any origin from getting the OAuth - // token through window.postMessage (see comment in connect.js). - // postMessage happens in send-token.js, which is a different request, so we need to put the allowed origins - // on the encrypted session state to access it later there. - if ( - Array.isArray(credentials.origins) && - credentials.origins.length > 0 - ) { - const decodedState = oAuthState.decodeState( - state, - companionOptions.secret, - ) - decodedState.customerDefinedAllowedOrigins = credentials.origins - const newState = oAuthState.encodeState( - decodedState, - companionOptions.secret, - ) - // @ts-expect-error untyped - req.session.grant = { - // @ts-expect-error untyped - ...req.session.grant, - dynamic: { - // @ts-expect-error untyped - ...req.session.grant?.dynamic, - state: newState, - }, - } - } - - res.locals.grant = { - dynamic: { - key: credentials.key, - secret: credentials.secret, - origins: credentials.origins, - }, - } - - if (credentials.transloadit_gateway) { - const redirectPath = getRedirectPath(providerName) - const fullRedirectPath = getURLBuilder(companionOptions)( - redirectPath, - true, - true, - ) - const redirectUri = new URL( - fullRedirectPath, - credentials.transloadit_gateway, - ).toString() - logger.info('Using redirect URI from transloadit_gateway', redirectUri) - res.locals.grant.dynamic.redirect_uri = redirectUri - } - - next() - } catch (keyErr) { - res.send(` - - - - - - -

Could not fetch credentials

-

- This is probably an Uppy configuration issue. Check that your Transloadit key is correct, and that the configured credentialsName for this remote provider matches the name you gave it in the Template Credentials setup on the Transloadit side. -

-

Internal error message: ${htmlEscape(keyErr.message)}

- - - `) - } - } -} - -/** - * Returns a request scoped function that can be used to get a provider's oauth credentials - * through out the lifetime of the request. - * - * @param {string} providerName the name of the provider attached to the scope of the request - * @param {object} companionOptions the companion options object - * @param {object} req the express request object for the said request - * @returns {(providerName: string, companionOptions: object, credentialRequestParams?: object) => Promise} - */ -export const getCredentialsResolver = (providerName, companionOptions, req) => { - const credentialsResolver = () => { - const encodedCredentialsParams = req.header('uppy-credentials-params') - let credentialRequestParams = null - if (encodedCredentialsParams) { - try { - credentialRequestParams = JSON.parse( - atob(encodedCredentialsParams), - ).params - } catch (error) { - logger.error(error, 'credentials.resolve.fail', req.id) - } - } - - return fetchProviderKeys( - providerName, - companionOptions, - credentialRequestParams, - ) - } - - return credentialsResolver -} diff --git a/packages/@uppy/companion/src/server/provider/credentials.ts b/packages/@uppy/companion/src/server/provider/credentials.ts new file mode 100644 index 000000000..5dab60fca --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/credentials.ts @@ -0,0 +1,266 @@ +import { htmlEscape } from 'escape-goat' +import type { NextFunction, Request, Response } from 'express' +import got from 'got' +import type { CredentialsFetchResponse } from '../../schemas/companion.js' +import type { CompanionRuntimeOptions } from '../../types/companion-options.js' +import type { CompanionExpressLocals } from '../../types/express.js' +import * as tokenService from '../helpers/jwt.js' +import * as oAuthState from '../helpers/oauth-state.js' +import { isRecord, toError } from '../helpers/type-guards.js' +import { getRedirectPath, getURLBuilder } from '../helpers/utils.js' +import logger from '../logger.js' +import type Provider from './Provider.js' + +/** + * @param url + * @param providerName + * @param credentialRequestParams - null asks for default credentials. + */ +async function fetchKeys( + url: string, + providerName: string, + credentialRequestParams: unknown | null, +) { + try { + const { credentials } = await got + .post(url, { + json: { provider: providerName, parameters: credentialRequestParams }, + }) + .json<{ credentials?: CredentialsFetchResponse }>() + + if (!isRecord(credentials)) + throw new Error('Received no remote credentials') + + return credentials + } catch (err) { + logger.error(err, 'credentials.fetch.fail') + throw err + } +} + +/** + * Fetches for a providers OAuth credentials. If the config for that provider allows fetching + * of the credentials via http, and the `credentialRequestParams` argument is provided, the oauth + * credentials will be fetched via http. Otherwise, the credentials provided via companion options + * will be used instead. + * + * @param providerName the name of the provider whose oauth keys we want to fetch (e.g onedrive) + * @param companionOptions the companion options object + * @param credentialRequestParams the params that should be sent if an http request is required. + */ +async function fetchProviderKeys( + providerName: string, + companionOptions: CompanionRuntimeOptions, + credentialRequestParams: unknown, +): Promise { + let providerConfig = companionOptions.providerOptions[providerName] + if (!providerConfig) { + providerConfig = companionOptions.customProviders?.[providerName]?.config + } + + if (!providerConfig) { + return null + } + + // If a default key is configured, do not ask the credentials endpoint for it. + // In a future version we could make this an XOR thing, providing either an endpoint or global keys, + // but not both. + const key = providerConfig.key + if (!credentialRequestParams && key != null) { + return providerConfig + } + + const credentialsURL = providerConfig.credentialsURL + if (credentialsURL == null) { + return providerConfig + } + + return fetchKeys( + credentialsURL, + providerName, + credentialRequestParams || null, + ) +} + +/** + * Returns a request middleware function that can be used to pre-fetch a provider's + * Oauth credentials before the request is passed to the Oauth handler (https://github.com/simov/grant in this case). + * + * @param providers provider classes enabled for this server + * @param companionOptions companion options object + */ +export const getCredentialsOverrideMiddleware = ( + providers: Record, + companionOptions: CompanionRuntimeOptions, +) => { + return async ( + req: Request, + res: Response, + next: NextFunction, + ) => { + try { + const { oauthProvider, override } = req.params + if (oauthProvider == null || oauthProvider.length === 0) { + next() + return + } + const [providerName] = Object.keys(providers).filter( + (name) => providers[name]?.oauthProvider === oauthProvider, + ) + if ( + !providerName || + !companionOptions.providerOptions[providerName]?.credentialsURL + ) { + next() + return + } + + const grantDynamic = oAuthState.getGrantDynamicFromRequest(req) + // only use state via session object if user isn't making intial "connect" request. + // override param indicates subsequent requests from the oauth flow + + const state = override ? grantDynamic.state : req.query['state'] + if (!state || typeof state !== 'string') { + next() + return + } + + const { secret, preAuthSecret } = companionOptions + if (preAuthSecret == null) { + next() + return + } + + const preAuthToken = oAuthState.getFromState( + state, + 'preAuthToken', + secret, + ) + if (preAuthToken == null) { + next() + return + } + + let payload: unknown + try { + payload = tokenService.verifyEncryptedToken(preAuthToken, preAuthSecret) + } catch (_err) { + next() + return + } + + const credentials = await fetchProviderKeys( + providerName, + companionOptions, + payload, + ) + if (!credentials) { + next() + return + } + + // Besides the key and secret the fetched credentials can also contain `origins`, + // which is an array of strings of allowed origins to prevent any origin from getting the OAuth + // token through window.postMessage (see comment in connect.js). + // postMessage happens in send-token.js, which is a different request, so we need to put the allowed origins + // on the encrypted session state to access it later there. + const { origins } = credentials + if (Array.isArray(origins) && origins.length > 0) { + const decodedState = oAuthState.decodeState(state, secret) + decodedState['customerDefinedAllowedOrigins'] = origins + const newState = oAuthState.encodeState(decodedState, secret) + if (req.session != null) { + req.session.grant = { + ...req.session.grant, + dynamic: { + ...req.session.grant?.dynamic, + state: newState, + }, + } + } + } + + const dynamic: Record = {} + const fetchedKey = credentials.key + const fetchedSecret = credentials.secret + if (fetchedKey != null) dynamic['key'] = fetchedKey + if (fetchedSecret != null) dynamic['secret'] = fetchedSecret + if (origins != null) dynamic['origins'] = origins + + res.locals['grant'] = { dynamic } + + const gateway = credentials.transloadit_gateway + if (typeof gateway === 'string') { + const redirectPath = getRedirectPath(providerName) + const fullRedirectPath = getURLBuilder(companionOptions)( + redirectPath, + true, + true, + ) + const redirectUri = new URL(fullRedirectPath, gateway).toString() + logger.info('Using redirect URI from transloadit_gateway', redirectUri) + const grant = res.locals['grant'] + if (isRecord(grant) && isRecord(grant['dynamic'])) { + grant['dynamic']['redirect_uri'] = redirectUri + } + } + + next() + } catch (keyErr) { + const error = toError(keyErr) + res.send(` + + + + + + +

Could not fetch credentials

+

+ This is probably an Uppy configuration issue. Check that your Transloadit key is correct, and that the configured credentialsName for this remote provider matches the name you gave it in the Template Credentials setup on the Transloadit side. +

+

Internal error message: ${htmlEscape(error.message)}

+ + + `) + } + } +} + +/** + * Returns a request scoped function that can be used to get a provider's oauth credentials + * through out the lifetime of the request. + * + * @param providerName the name of the provider attached to the scope of the request + * @param companionOptions the companion options object + * @param req the express request object for the said request + */ +export const getCredentialsResolver = ( + providerName: string, + companionOptions: CompanionRuntimeOptions, + req: Request, +): (() => Promise) => { + const credentialsResolver = () => { + const encodedCredentialsParams = req.header('uppy-credentials-params') + let credentialRequestParams: unknown = null + if (encodedCredentialsParams) { + try { + const parsed: unknown = JSON.parse(atob(encodedCredentialsParams)) + credentialRequestParams = + isRecord(parsed) && Object.hasOwn(parsed, 'params') + ? parsed['params'] + : null + } catch (error) { + logger.error(error, 'credentials.resolve.fail', req.id) + } + } + + return fetchProviderKeys( + providerName, + companionOptions, + credentialRequestParams, + ) + } + + return credentialsResolver +} diff --git a/packages/@uppy/companion/src/server/provider/dropbox/adapter.js b/packages/@uppy/companion/src/server/provider/dropbox/adapter.js deleted file mode 100644 index 2dccf3484..000000000 --- a/packages/@uppy/companion/src/server/provider/dropbox/adapter.js +++ /dev/null @@ -1,73 +0,0 @@ -import querystring from 'node:querystring' -import mime from 'mime-types' - -const isFolder = (item) => { - return item['.tag'] === 'folder' -} - -const getItemSize = (item) => { - return item.size -} - -const getItemIcon = (item) => { - return item['.tag'] -} - -const getItemSubList = (item) => { - return item.entries -} - -const getItemName = (item) => { - return item.name || '' -} - -const getMimeType = (item) => { - return mime.lookup(getItemName(item)) || null -} - -const getItemId = (item) => { - return item.id -} - -const getItemRequestPath = (item) => { - return encodeURIComponent(item.path_lower) -} - -const getItemModifiedDate = (item) => { - return item.server_modified -} - -const getItemThumbnailUrl = (item) => { - return `/dropbox/thumbnail/${getItemRequestPath(item)}` -} - -const getNextPagePath = (data) => { - if (!data.has_more) { - return null - } - const query = { cursor: data.cursor } - return `?${querystring.stringify(query)}` -} - -const adaptData = (res, email, buildURL) => { - const items = getItemSubList(res).map((item) => ({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item), - mimeType: getMimeType(item), - id: getItemId(item), - thumbnail: buildURL(getItemThumbnailUrl(item), true), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - size: getItemSize(item), - })) - items.sort((a, b) => a.name.localeCompare(b.name, 'en-US', { numeric: true })) - - return { - username: email, - items, - nextPagePath: getNextPagePath(res), - } -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/dropbox/adapter.ts b/packages/@uppy/companion/src/server/provider/dropbox/adapter.ts new file mode 100644 index 000000000..733ad4a5a --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/dropbox/adapter.ts @@ -0,0 +1,108 @@ +import querystring from 'node:querystring' +import mime from 'mime-types' +import type { BuildUrl } from '../../../types/express.js' + +type DropboxItem = { + '.tag'?: string + size?: number + name?: string + id: string + path_lower: string + server_modified?: string +} + +type DropboxListResponse = { + entries: DropboxItem[] + has_more: boolean + cursor?: string +} + +const isFolder = (item: DropboxItem): boolean => { + return item['.tag'] === 'folder' +} + +const getItemSize = (item: DropboxItem): number | undefined => { + return item.size +} + +const getItemIcon = (item: DropboxItem): string | undefined => { + return item['.tag'] +} + +const getItemSubList = (item: DropboxListResponse): DropboxItem[] => { + return item.entries +} + +const getItemName = (item: DropboxItem): string => { + return item.name || '' +} + +const getMimeType = (item: DropboxItem): string | null => { + const mt = mime.lookup(getItemName(item)) + return typeof mt === 'string' ? mt : null +} + +const getItemId = (item: DropboxItem): string => { + return item.id +} + +const getItemRequestPath = (item: DropboxItem): string => { + return encodeURIComponent(item.path_lower) +} + +const getItemModifiedDate = (item: DropboxItem): string | undefined => { + return item.server_modified +} + +const getItemThumbnailUrl = (item: DropboxItem): string => { + return `/dropbox/thumbnail/${getItemRequestPath(item)}` +} + +const getNextPagePath = (data: DropboxListResponse): string | null => { + if (!data.has_more) { + return null + } + const query = { cursor: data.cursor } + return `?${querystring.stringify(query)}` +} + +const adaptData = ( + res: DropboxListResponse, + email: string | undefined, + buildURL: BuildUrl, +): { + username: string | undefined + items: Array<{ + isFolder: boolean + icon: string | undefined + name: string + mimeType: string | null + id: string + thumbnail: string + requestPath: string + modifiedDate: string | undefined + size: number | undefined + }> + nextPagePath: string | null +} => { + const items = getItemSubList(res).map((item) => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item), + mimeType: getMimeType(item), + id: getItemId(item), + thumbnail: buildURL(getItemThumbnailUrl(item), true), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + size: getItemSize(item), + })) + items.sort((a, b) => a.name.localeCompare(b.name, 'en-US', { numeric: true })) + + return { + username: email, + items, + nextPagePath: getNextPagePath(res), + } +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/dropbox/index.js b/packages/@uppy/companion/src/server/provider/dropbox/index.ts similarity index 56% rename from packages/@uppy/companion/src/server/provider/dropbox/index.js rename to packages/@uppy/companion/src/server/provider/dropbox/index.ts index 804c6b4f9..4a2da703d 100644 --- a/packages/@uppy/companion/src/server/provider/dropbox/index.js +++ b/packages/@uppy/companion/src/server/provider/dropbox/index.ts @@ -2,29 +2,57 @@ // // This function is simple and has OK performance compared to more // complicated ones: http://jsperf.com/json-escape-unicode/4 + +import type { Readable } from 'node:stream' import got from 'got' +import type { BuildUrl } from '../../../types/express.js' import { MAX_AGE_REFRESH_TOKEN } from '../../helpers/jwt.js' +import { isRecord } from '../../helpers/type-guards.js' import { prepareStream } from '../../helpers/utils.js' import logger from '../../logger.js' -import Provider from '../Provider.js' +import Provider, { + type ProviderListResponse, + type ProviderSearchResponse, + type Query, +} from '../Provider.js' import { withProviderErrorHandling } from '../providerErrors.js' import adaptData from './adapter.js' const charsToEncode = /[\u007f-\uffff]/g -function httpHeaderSafeJson(v) { +function httpHeaderSafeJson(v: unknown): string { return JSON.stringify(v).replace(charsToEncode, (c) => { return `\\u${`000${c.charCodeAt(0).toString(16)}`.slice(-4)}` }) } -async function getUserInfo({ client }) { - return client - .post('users/get_current_account', { responseType: 'json' }) - .json() +type DropboxClient = ReturnType + +type DropboxUserInfo = { + email?: string + root_info?: { + root_namespace_id?: string + home_namespace_id?: string + } } -async function getClient({ token, namespaced }) { - const makeClient = (namespace) => +async function getUserInfo({ + client, +}: { + client: DropboxClient +}): Promise { + return client + .post('users/get_current_account', { responseType: 'json' }) + .json() +} + +async function getClient({ + token, + namespaced, +}: { + token: string + namespaced: boolean +}): Promise<{ client: DropboxClient; userInfo: DropboxUserInfo }> { + const makeClient = (namespace?: string) => got.extend({ prefixUrl: 'https://api.dropboxapi.com/2', headers: { @@ -48,17 +76,14 @@ async function getClient({ token, namespaced }) { // https://www.dropboxforum.com/discussions/101000014/how-to-list-the-contents-of-a-team-folder/258310 // https://developers.dropbox.com/dbx-team-files-guide#namespaces // https://www.dropbox.com/developers/reference/path-root-header-modes + const rootInfo = userInfo.root_info if ( namespaced && - userInfo.root_info != null && - userInfo.root_info.root_namespace_id !== - userInfo.root_info.home_namespace_id + rootInfo != null && + rootInfo.root_namespace_id !== rootInfo.home_namespace_id ) { - logger.debug( - 'using root_namespace_id', - userInfo.root_info.root_namespace_id, - ) - client = makeClient(userInfo.root_info.root_namespace_id) + logger.debug('using root_namespace_id', rootInfo.root_namespace_id) + client = makeClient(rootInfo.root_namespace_id) } return { @@ -72,19 +97,34 @@ const getOauthClient = () => prefixUrl: 'https://api.dropboxapi.com/oauth2', }) -async function list({ client, directory, query }) { - if (query.cursor) { +async function list({ + client, + directory, + query, +}: { + client: DropboxClient + directory?: string | undefined + query?: Query | undefined +}): Promise[0]> { + if (query?.['cursor']) { return client .post('files/list_folder/continue', { - json: { cursor: query.cursor }, + json: { cursor: query['cursor'] }, responseType: 'json', }) - .json() + .json[0]>() + } + + const searchParams: Record = {} + if (query != null) { + for (const [k, v] of Object.entries(query)) { + if (typeof v === 'string') searchParams[k] = v + } } return client .post('files/list_folder', { - searchParams: query, + searchParams, json: { path: `${directory || ''}`, include_non_downloadable_files: false, @@ -93,13 +133,27 @@ async function list({ client, directory, query }) { }, responseType: 'json', }) - .json() + .json[0]>() } -async function fetchSearchEntries({ client, query }) { +async function fetchSearchEntries({ + client, + query, +}: { + client: DropboxClient + query: { q: string; path?: string; [k: string]: unknown } +}): Promise[0]> { const scopePath = typeof query.path === 'string' ? decodeURIComponent(query.path) : undefined + type DropboxSearchResponse = { + matches: Array<{ + metadata: { metadata: Parameters[0]['entries'][number] } + }> + has_more: boolean + cursor?: string + } + const searchRes = await client .post('files/search_v2', { json: { @@ -113,37 +167,45 @@ async function fetchSearchEntries({ client, query }) { }, responseType: 'json', }) - .json() + .json() const entries = searchRes.matches.map((m) => m.metadata.metadata) return { entries, has_more: searchRes.has_more, - cursor: searchRes.cursor, + ...(searchRes.cursor != null && { cursor: searchRes.cursor }), } } +interface DropboxUserSession { + accessToken: string +} + /** * Adapter for API https://www.dropbox.com/developers/documentation/http/documentation */ -export default class Dropbox extends Provider { - constructor(options) { +export default class Dropbox extends Provider { + constructor(options: ConstructorParameters[0]) { super(options) this.needsCookieAuth = true } - static get oauthProvider() { + static override get oauthProvider() { return 'dropbox' } - static get authStateExpiry() { + static override get authStateExpiry() { return MAX_AGE_REFRESH_TOKEN } /** * Search entries */ - async search(options) { + override async search(options: { + providerUserSession: DropboxUserSession + query: { q: string; path?: string; [k: string]: unknown } + companion: { buildURL: BuildUrl } + }): Promise { return this.#withErrorHandling( 'provider.dropbox.search.error', async () => { @@ -153,7 +215,6 @@ export default class Dropbox extends Provider { }) const stats = await fetchSearchEntries({ client, query: options.query }) - console.log(stats) const { email } = userInfo // we don't really need email, but let's mimic `list` response shape for consistency return adaptData(stats, email, options.companion.buildURL) @@ -164,20 +225,35 @@ export default class Dropbox extends Provider { /** * List folder entries */ - async list(options) { + override async list(options: { + directory?: string | undefined + providerUserSession: DropboxUserSession + query?: Query + companion: { buildURL?: BuildUrl } + }): Promise { return this.#withErrorHandling('provider.dropbox.list.error', async () => { const { client, userInfo } = await getClient({ token: options.providerUserSession.accessToken, namespaced: true, }) + if (options.companion.buildURL == null) { + throw new Error('companion.buildURL is required for Dropbox provider') + } + const stats = await list({ ...options, client }) const { email } = userInfo return adaptData(stats, email, options.companion.buildURL) }) } - async download({ id, providerUserSession: { accessToken: token } }) { + override async download({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: DropboxUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { return this.#withErrorHandling( 'provider.dropbox.download.error', async () => { @@ -199,7 +275,13 @@ export default class Dropbox extends Provider { ) } - async thumbnail({ id, providerUserSession: { accessToken: token } }) { + override async thumbnail({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: DropboxUserSession + }): Promise<{ stream: Readable; contentType: string }> { return this.#withErrorHandling( 'provider.dropbox.thumbnail.error', async () => { @@ -224,21 +306,36 @@ export default class Dropbox extends Provider { ) } - async size({ id, providerUserSession: { accessToken: token } }) { + override async size({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: DropboxUserSession + }): Promise { return this.#withErrorHandling('provider.dropbox.size.error', async () => { - const { size } = await ( - await getClient({ token, namespaced: true }) - ).client + const meta = await (await getClient({ token, namespaced: true })).client .post('files/get_metadata', { json: { path: id }, responseType: 'json', }) - .json() - return parseInt(size, 10) + .json<{ size?: unknown }>() + const sizeValue = meta?.size + const sizeStr = + typeof sizeValue === 'string' + ? sizeValue + : typeof sizeValue === 'number' + ? String(sizeValue) + : '' + return parseInt(sizeStr, 10) }) } - async logout({ providerUserSession: { accessToken: token } }) { + override async logout({ + providerUserSession: { accessToken: token }, + }: { + providerUserSession: DropboxUserSession + }): Promise<{ revoked: true }> { return this.#withErrorHandling( 'provider.dropbox.logout.error', async () => { @@ -251,11 +348,19 @@ export default class Dropbox extends Provider { ) } - async refreshToken({ clientId, clientSecret, refreshToken }) { + override async refreshToken({ + clientId, + clientSecret, + refreshToken, + }: { + clientId: string | undefined + clientSecret: string | undefined + refreshToken: string + }): Promise<{ accessToken: string }> { return this.#withErrorHandling( 'provider.dropbox.token.refresh.error', async () => { - const { access_token: accessToken } = await getOauthClient() + const tokenRes = await getOauthClient() .post('token', { form: { refresh_token: refreshToken, @@ -264,19 +369,27 @@ export default class Dropbox extends Provider { client_secret: clientSecret, }, }) - .json() + .json<{ access_token?: unknown }>() + const accessToken = tokenRes.access_token + if (typeof accessToken !== 'string' || accessToken.length === 0) { + throw new Error('Missing access_token') + } return { accessToken } }, ) } - async #withErrorHandling(tag, fn) { + async #withErrorHandling(tag: string, fn: () => Promise): Promise { return withProviderErrorHandling({ fn, tag, providerName: Dropbox.oauthProvider, isAuthError: (response) => response.statusCode === 401, - getJsonErrorMessage: (body) => body?.error_summary, + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const summary = body['error_summary'] + return typeof summary === 'string' ? summary : undefined + }, }) } } diff --git a/packages/@uppy/companion/src/server/provider/error.js b/packages/@uppy/companion/src/server/provider/error.js deleted file mode 100644 index ed37c9b18..000000000 --- a/packages/@uppy/companion/src/server/provider/error.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * ProviderApiError is error returned when an adapter encounters - * an http error while communication with its corresponding provider - */ -export class ProviderApiError extends Error { - /** - * @param {string} message error message - * @param {number} statusCode the http status code from the provider api - */ - constructor(message, statusCode) { - super(`HTTP ${statusCode}: ${message}`) // Include statusCode to make it easier to debug - this.name = 'ProviderApiError' - this.statusCode = statusCode - this.isAuthError = false - } -} - -export class ProviderUserError extends ProviderApiError { - /** - * @param {object} json arbitrary JSON.stringify-able object that will be passed to the client - */ - constructor(json) { - super('User error', undefined) - this.name = 'ProviderUserError' - this.json = json - } -} - -/** - * AuthError is error returned when an adapter encounters - * an authorization error while communication with its corresponding provider - * this signals to the client that the access token is invalid and needs to be - * refreshed or the user needs to re-authenticate - */ -export class ProviderAuthError extends ProviderApiError { - constructor() { - super('invalid access token detected by Provider', 401) - this.name = 'AuthError' - this.isAuthError = true - } -} - -export function parseHttpError(err) { - if (err?.name === 'HTTPError') { - return { - statusCode: err.response?.statusCode, - body: err.response?.body, - } - } - if (err?.name === 'HttpError') { - return { - statusCode: err.statusCode, - body: err.responseJson, - } - } - return undefined -} - -/** - * Convert an error instance to an http response if possible - * - * @param {Error | ProviderApiError} err the error instance to convert to an http json response - * @returns {object | undefined} an object with a code and json field if the error can be converted to a response - */ -function errorToResponse(err) { - // @ts-ignore - if (err?.isAuthError) { - return { code: 401, json: { message: err.message } } - } - - if (err?.name === 'ValidationError') { - return { code: 400, json: { message: err.message } } - } - - if (err?.name === 'ProviderUserError') { - // @ts-ignore - return { code: 400, json: err.json } - } - - if (err?.name === 'ProviderApiError') { - // @ts-ignore - if (err.statusCode >= 500) { - // bad gateway i.e the provider APIs gateway - return { code: 502, json: { message: err.message } } - } - - // @ts-ignore - if (err.statusCode === 429) { - return { code: 429, json: { message: err.message } } - } - - // @ts-ignore - if (err.statusCode >= 400) { - // 424 Failed Dependency - return { code: 424, json: { message: err.message } } - } - } - - const httpError = parseHttpError(err) - if (httpError) { - // We proxy the response purely for ease of debugging - return { - code: 500, - json: { statusCode: httpError.statusCode, body: httpError.body }, - } - } - - return undefined -} - -export function respondWithError(err, res) { - const errResp = errorToResponse(err) - if (errResp) { - res.status(errResp.code).json(errResp.json) - return true - } - return false -} diff --git a/packages/@uppy/companion/src/server/provider/error.ts b/packages/@uppy/companion/src/server/provider/error.ts new file mode 100644 index 000000000..9ad57ae83 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/error.ts @@ -0,0 +1,141 @@ +import { isRecord } from '../helpers/type-guards.js' + +type HttpErrorLike = { + statusCode: number | undefined + body: unknown +} + +/** + * Error thrown when an adapter encounters an HTTP error while communicating + * with its corresponding provider. + */ +export class ProviderApiError extends Error { + statusCode: number | undefined + + isAuthError: boolean + + constructor(message: string, statusCode: number | undefined) { + super(`HTTP ${statusCode}: ${message}`) // Include statusCode to make it easier to debug + this.name = 'ProviderApiError' + this.statusCode = statusCode + this.isAuthError = false + } +} + +/** + * Error thrown when the provider response should be forwarded to the client + * as-is (e.g. user-facing validation errors). + */ +export class ProviderUserError extends ProviderApiError { + json: unknown // arbitrary JSON.stringify-able object that will be passed to the client + + constructor(json: unknown) { + super('User error', undefined) + this.name = 'ProviderUserError' + this.json = json + } +} + +/** + * Error thrown when an adapter encounters an authorization error while + * communicating with its provider. This signals to the client that the access + * token is invalid and needs to be refreshed or the user needs to re-authenticate. + */ +export class ProviderAuthError extends ProviderApiError { + constructor() { + super('invalid access token detected by Provider', 401) + this.name = 'AuthError' + this.isAuthError = true + } +} + +export function parseHttpError(err: unknown): HttpErrorLike | undefined { + if (!isRecord(err)) return undefined + + const name = err['name'] + if (name === 'HTTPError') { + const responseCandidate = err['response'] + const response = isRecord(responseCandidate) ? responseCandidate : undefined + const statusCode = + response && typeof response['statusCode'] === 'number' + ? response['statusCode'] + : undefined + const body = response ? response['body'] : undefined + return { statusCode, body } + } + + if (name === 'HttpError') { + const statusCode = + typeof err['statusCode'] === 'number' ? err['statusCode'] : undefined + const body = err['responseJson'] + return { statusCode, body } + } + + return undefined +} + +/** + * Convert an error instance to an HTTP response if possible. + */ +function errorToResponse( + err: unknown, +): { code: number; json: Record } | undefined { + if (!isRecord(err)) return undefined + + if (err['isAuthError'] === true) { + return { code: 401, json: { message: err['message'] } } + } + + const name = err['name'] + + if (name === 'ValidationError') { + return { code: 400, json: { message: err['message'] } } + } + + if (name === 'ProviderUserError') { + const json = err['json'] as Record + return { + code: 400, + json, + } + } + + if (name === 'ProviderApiError') { + const statusCode = + typeof err['statusCode'] === 'number' ? err['statusCode'] : undefined + if (statusCode != null && statusCode >= 500) { + // bad gateway i.e the provider APIs gateway + return { code: 502, json: { message: err['message'] } } + } + if (statusCode === 429) { + return { code: 429, json: { message: err['message'] } } + } + if (statusCode != null && statusCode >= 400) { + // 424 Failed Dependency + return { code: 424, json: { message: err['message'] } } + } + } + + const httpError = parseHttpError(err) + if (httpError) { + // We proxy the response purely for ease of debugging + return { + code: 500, + json: { statusCode: httpError.statusCode, body: httpError.body }, + } + } + + return undefined +} + +export function respondWithError( + err: unknown, + res: { status: (n: number) => { json: (v: unknown) => void } }, +): boolean { + const errResp = errorToResponse(err) + if (errResp) { + res.status(errResp.code).json(errResp.json) + return true + } + return false +} diff --git a/packages/@uppy/companion/src/server/provider/facebook/adapter.js b/packages/@uppy/companion/src/server/provider/facebook/adapter.js deleted file mode 100644 index ab05390a8..000000000 --- a/packages/@uppy/companion/src/server/provider/facebook/adapter.js +++ /dev/null @@ -1,75 +0,0 @@ -import querystring from 'node:querystring' - -const isFolder = (item) => { - return !!item.type -} - -export const sortImages = (images) => { - // sort in ascending order of dimension - return images.slice().sort((a, b) => a.width - b.width) -} - -const getItemIcon = (item) => { - if (isFolder(item)) { - return 'folder' - } - return sortImages(item.images)[0].source -} - -const getItemSubList = (item) => { - return item.data -} - -const getItemName = (item) => { - return item.name || `${item.id} ${item.created_time}` -} - -const getMimeType = (item) => { - return isFolder(item) ? null : 'image/jpeg' -} - -const getItemId = (item) => { - return `${item.id}` -} - -const getItemRequestPath = (item) => { - return `${item.id}` -} - -const getItemModifiedDate = (item) => { - return item.created_time -} - -const getItemThumbnailUrl = (item) => { - return isFolder(item) ? null : sortImages(item.images)[0].source -} - -const getNextPagePath = (data, currentQuery, currentPath) => { - if (!data.paging || !data.paging.cursors) { - return null - } - - const query = { ...currentQuery, cursor: data.paging.cursors.after } - return `${currentPath || ''}?${querystring.stringify(query)}` -} - -export const adaptData = (res, username, directory, currentQuery) => { - const data = { username, items: [] } - const items = getItemSubList(res) - items.forEach((item) => { - data.items.push({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item), - mimeType: getMimeType(item), - size: null, - id: getItemId(item), - thumbnail: getItemThumbnailUrl(item), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - }) - }) - - data.nextPagePath = getNextPagePath(res, currentQuery, directory) - return data -} diff --git a/packages/@uppy/companion/src/server/provider/facebook/adapter.ts b/packages/@uppy/companion/src/server/provider/facebook/adapter.ts new file mode 100644 index 000000000..97c5084cf --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/facebook/adapter.ts @@ -0,0 +1,110 @@ +import querystring from 'node:querystring' + +type FacebookImage = { width: number; source: string } + +type FacebookAlbum = { + type?: string + id: string | number + name?: string + created_time?: string +} + +type FacebookPhoto = { + id: string | number + name?: string + created_time?: string + images: FacebookImage[] +} + +type FacebookItem = FacebookAlbum | FacebookPhoto + +export type FacebookListResponse = { + data: FacebookItem[] + paging?: { + cursors?: { + after?: string + } + } +} + +const isFolder = (item: FacebookItem): item is FacebookAlbum => { + return 'type' in item && typeof item.type === 'string' +} + +export const sortImages = (images: FacebookImage[]): FacebookImage[] => { + // sort in ascending order of dimension + return images.slice().sort((a, b) => a.width - b.width) +} + +const getItemIcon = (item: FacebookItem): string | undefined => { + if (isFolder(item)) { + return 'folder' + } + return sortImages(item.images)[0]?.source +} + +const getItemSubList = (item: FacebookListResponse): FacebookItem[] => { + return item.data +} + +const getItemName = (item: FacebookItem): string => { + return item.name || `${item.id} ${item.created_time}` +} + +const getMimeType = (item: FacebookItem): string | null => { + return isFolder(item) ? null : 'image/jpeg' +} + +const getItemId = (item: FacebookItem): string => { + return `${item.id}` +} + +const getItemRequestPath = (item: FacebookItem): string => { + return `${item.id}` +} + +const getItemModifiedDate = (item: FacebookItem): string | undefined => { + return item.created_time +} + +const getItemThumbnailUrl = (item: FacebookItem): string | null => { + return isFolder(item) ? null : (sortImages(item.images)[0]?.source ?? null) +} + +const getNextPagePath = ( + data: FacebookListResponse, + currentQuery: Record, + currentPath: string | undefined, +): string | null => { + if (!data.paging || !data.paging.cursors) { + return null + } + + const after = data.paging.cursors.after + if (after == null || after.length === 0) return null + + const query = { ...currentQuery, cursor: after } + return `${currentPath || ''}?${querystring.stringify(query)}` +} + +export const adaptData = ( + res: FacebookListResponse, + username: string | undefined, + directory: string | undefined, + currentQuery: Record, +) => { + const items = getItemSubList(res).map((item) => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item), + mimeType: getMimeType(item), + size: null, + id: getItemId(item), + thumbnail: getItemThumbnailUrl(item), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + })) + + const nextPagePath = getNextPagePath(res, currentQuery, directory) + return { username, items, nextPagePath } +} diff --git a/packages/@uppy/companion/src/server/provider/facebook/index.js b/packages/@uppy/companion/src/server/provider/facebook/index.js deleted file mode 100644 index 8d84fa14d..000000000 --- a/packages/@uppy/companion/src/server/provider/facebook/index.js +++ /dev/null @@ -1,150 +0,0 @@ -import crypto from 'node:crypto' -import got from 'got' -import { HttpError, prepareStream } from '../../helpers/utils.js' -import logger from '../../logger.js' -import Provider from '../Provider.js' -import { withProviderErrorHandling } from '../providerErrors.js' -import { adaptData, sortImages } from './adapter.js' - -async function runRequestBatch({ secret, token, requests }) { - // https://developers.facebook.com/docs/facebook-login/security/#appsecret - // couldn't get `appsecret_time` working, but it seems to be working without it - // const time = Math.floor(Date.now() / 1000) - const appSecretProof = crypto - .createHmac('sha256', secret) - // .update(`${token}|${time}`) - .update(token) - .digest('hex') - - const form = { - access_token: token, - appsecret_proof: appSecretProof, - // appsecret_time: String(time), - batch: JSON.stringify(requests), - } - - const responsesRaw = await got - .post('https://graph.facebook.com', { form }) - .json() - - const responses = responsesRaw.map((response) => ({ - ...response, - body: JSON.parse(response.body), - })) - - const errorResponse = responses.find((response) => response.code !== 200) - if (errorResponse) { - throw new HttpError({ - statusCode: errorResponse.code, - responseJson: errorResponse.body, - }) - } - - return responses -} - -async function getMediaUrl({ secret, token, id }) { - const [{ body }] = await runRequestBatch({ - secret, - token, - requests: [ - { - method: 'GET', - relative_url: `${id}?${new URLSearchParams({ fields: 'images' }).toString()}`, - }, - ], - }) - - const sortedImages = sortImages(body.images) - return sortedImages[sortedImages.length - 1].source -} - -/** - * Adapter for API https://developers.facebook.com/docs/graph-api/using-graph-api/ - */ -export default class Facebook extends Provider { - static get oauthProvider() { - return 'facebook' - } - - async list({ - directory, - providerUserSession: { accessToken: token }, - query = { cursor: null }, - }) { - return this.#withErrorHandling('provider.facebook.list.error', async () => { - const qs = { fields: 'name,cover_photo,created_time,type' } - - if (query.cursor) qs.after = query.cursor - - let path = 'me/albums' - if (directory) { - path = `${directory}/photos` - qs.fields = 'icon,images,name,width,height,created_time' - } - - const [response1, response2] = await runRequestBatch({ - secret: this.secret, - token, - requests: [ - { - method: 'GET', - relative_url: `me?${new URLSearchParams({ fields: 'email' }).toString()}`, - }, - { method: 'GET', relative_url: `${path}?${new URLSearchParams(qs)}` }, - ], - }) - - const { email } = response1.body - const list = response2.body - return adaptData(list, email, directory, query) - }) - } - - async download({ id, providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling( - 'provider.facebook.download.error', - async () => { - const url = await getMediaUrl({ secret: this.secret, token, id }) - const stream = got.stream.get(url, { responseType: 'json' }) - const { size } = await prepareStream(stream) - return { stream, size } - }, - ) - } - - async thumbnail() { - // not implementing this because a public thumbnail from facebook will be used instead - logger.error( - 'call to thumbnail is not implemented', - 'provider.facebook.thumbnail.error', - ) - throw new Error('call to thumbnail is not implemented') - } - - async logout({ providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling( - 'provider.facebook.logout.error', - async () => { - await runRequestBatch({ - secret: this.secret, - token, - requests: [{ method: 'DELETE', relative_url: 'me/permissions' }], - }) - - return { revoked: true } - }, - ) - } - - async #withErrorHandling(tag, fn) { - return withProviderErrorHandling({ - fn, - tag, - providerName: Facebook.oauthProvider, - isAuthError: (response) => - typeof response.body === 'object' && response.body?.error?.code === 190, // Invalid OAuth 2.0 Access Token - getJsonErrorMessage: (body) => body?.error?.message, - }) - } -} diff --git a/packages/@uppy/companion/src/server/provider/facebook/index.ts b/packages/@uppy/companion/src/server/provider/facebook/index.ts new file mode 100644 index 000000000..f2bf22cbf --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/facebook/index.ts @@ -0,0 +1,265 @@ +import crypto from 'node:crypto' +import type { Readable } from 'node:stream' +import got from 'got' +import { isRecord } from '../../helpers/type-guards.js' +import { HttpError, prepareStream } from '../../helpers/utils.js' +import logger from '../../logger.js' +import Provider, { + type CompanionLike, + type ProviderListResponse, + type Query, +} from '../Provider.js' +import { withProviderErrorHandling } from '../providerErrors.js' +import { adaptData, type FacebookListResponse, sortImages } from './adapter.js' + +type FacebookBatchRequest = { + method: string + relative_url: string +} + +type FacebookBatchResponse = { code: number; body: unknown } + +interface FacebookUserSession { + accessToken: string +} + +async function runRequestBatch({ + secret, + token, + requests, +}: { + secret: string + token: string + requests: FacebookBatchRequest[] +}): Promise { + // https://developers.facebook.com/docs/facebook-login/security/#appsecret + // couldn't get `appsecret_time` working, but it seems to be working without it + // const time = Math.floor(Date.now() / 1000) + const appSecretProof = crypto + .createHmac('sha256', secret) + // .update(`${token}|${time}`) + .update(token) + .digest('hex') + + const form = { + access_token: token, + appsecret_proof: appSecretProof, + // appsecret_time: String(time), + batch: JSON.stringify(requests), + } + + const responsesRaw = await got + .post('https://graph.facebook.com', { form }) + .json<{ code: number; body: string }[]>() + + const responses = responsesRaw.map((response) => ({ + ...response, + body: (() => { + const parsed: unknown = JSON.parse(response.body) + return parsed + })(), + })) + + const errorResponse = responses.find((response) => response.code !== 200) + if (errorResponse) { + throw new HttpError({ + statusCode: errorResponse.code, + responseJson: errorResponse.body, + }) + } + + return responses +} + +async function getMediaUrl({ + secret, + token, + id, +}: { + secret: string + token: string + id: string +}): Promise { + const batch = await runRequestBatch({ + secret, + token, + requests: [ + { + method: 'GET', + relative_url: `${id}?${new URLSearchParams({ fields: 'images' }).toString()}`, + }, + ], + }) + + const first = batch[0] + if (!first) throw new Error('Unexpected Facebook response: missing body') + const body = first.body + + const imagesValue = isRecord(body) ? body['images'] : undefined + + const isFbImage = ( + value: unknown, + ): value is { width: number; source: string } => + isRecord(value) && + typeof value['width'] === 'number' && + typeof value['source'] === 'string' + + const images = Array.isArray(imagesValue) ? imagesValue.filter(isFbImage) : [] + const sortedImages = sortImages(images) + const largest = sortedImages[sortedImages.length - 1] + if (!largest) { + throw new Error('Unexpected Facebook response: missing images') + } + return largest.source +} + +/** + * Adapter for API https://developers.facebook.com/docs/graph-api/using-graph-api/ + */ +export default class Facebook extends Provider { + static override get oauthProvider() { + return 'facebook' + } + + override async list({ + directory, + providerUserSession: { accessToken: token }, + query, + companion, + }: { + directory?: string | undefined + providerUserSession: FacebookUserSession + query?: Query | undefined + companion: CompanionLike + }): Promise { + return this.#withErrorHandling('provider.facebook.list.error', async () => { + const qs: Record = { + fields: 'name,cover_photo,created_time,type', + } + + const cursor = query?.['cursor'] ?? null + + if (typeof cursor === 'string') { + qs['after'] = cursor + } + + let path = 'me/albums' + if (directory) { + path = `${directory}/photos` + qs['fields'] = 'icon,images,name,width,height,created_time' + } + + const { secret } = (await companion.getProviderCredentials?.())! + if (secret == null) { + throw new Error('Facebook provider secret is not configured') + } + + const responses = await runRequestBatch({ + secret, + token, + requests: [ + { + method: 'GET', + relative_url: `me?${new URLSearchParams({ fields: 'email' }).toString()}`, + }, + { method: 'GET', relative_url: `${path}?${new URLSearchParams(qs)}` }, + ], + }) + const response1 = responses[0] + const response2 = responses[1] + if (!response1 || !response2) { + throw new Error('Unexpected Facebook response: missing batch result') + } + + const { email } = response1.body as { email?: string } + + const list = response2.body as FacebookListResponse + + const currentQuery: Record = {} + if (typeof cursor === 'string') currentQuery['cursor'] = cursor + return adaptData(list, email, directory, currentQuery) + }) + } + + override async download({ + companion, + id, + providerUserSession: { accessToken: token }, + }: { + companion: CompanionLike + id: string + providerUserSession: FacebookUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.#withErrorHandling( + 'provider.facebook.download.error', + async () => { + const { secret } = (await companion.getProviderCredentials?.())! + + if (secret == null) { + throw new Error('Facebook provider secret is not configured') + } + const url = await getMediaUrl({ secret, token, id }) + const stream = got.stream.get(url, { responseType: 'json' }) + const { size } = await prepareStream(stream) + return { stream, size } + }, + ) + } + + override async thumbnail(): Promise<{ + stream: Readable + contentType: string + }> { + // not implementing this because a public thumbnail from facebook will be used instead + logger.error( + 'call to thumbnail is not implemented', + 'provider.facebook.thumbnail.error', + ) + throw new Error('call to thumbnail is not implemented') + } + + override async logout({ + companion, + providerUserSession: { accessToken: token }, + }: { + companion: CompanionLike + providerUserSession: FacebookUserSession + }): Promise<{ revoked: true }> { + return this.#withErrorHandling( + 'provider.facebook.logout.error', + async () => { + const { secret } = (await companion.getProviderCredentials?.())! + if (secret == null) { + throw new Error('Facebook provider secret is not configured') + } + + await runRequestBatch({ + secret, + token, + requests: [{ method: 'DELETE', relative_url: 'me/permissions' }], + }) + + return { revoked: true } + }, + ) + } + + async #withErrorHandling(tag: string, fn: () => Promise): Promise { + return withProviderErrorHandling({ + fn, + tag, + providerName: Facebook.oauthProvider, + isAuthError: (response) => + isRecord(response.body) && + isRecord(response.body['error']) && + response.body['error']['code'] === 190, // Invalid OAuth 2.0 Access Token + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const error = body['error'] + if (!isRecord(error)) return undefined + const message = error['message'] + return typeof message === 'string' ? message : undefined + }, + }) + } +} diff --git a/packages/@uppy/companion/src/server/provider/google/drive/adapter.js b/packages/@uppy/companion/src/server/provider/google/drive/adapter.ts similarity index 53% rename from packages/@uppy/companion/src/server/provider/google/drive/adapter.js rename to packages/@uppy/companion/src/server/provider/google/drive/adapter.ts index 401dde7f1..bcc768f94 100644 --- a/packages/@uppy/companion/src/server/provider/google/drive/adapter.js +++ b/packages/@uppy/companion/src/server/provider/google/drive/adapter.ts @@ -1,43 +1,82 @@ import querystring from 'node:querystring' +import type { Query } from '../../Provider.js' -const getUsername = (data) => { - return data.user.emailAddress +export type DriveItem = { + kind?: string + mimeType?: string + files?: DriveItem[] + id: string + name?: string + size?: string + thumbnailLink?: string + iconLink?: string + backgroundImageLink?: string + modifiedTime?: string + shortcutDetails?: { targetMimeType?: string } + imageMediaMetadata?: { + height?: number + width?: number + rotation?: number + date?: string + } + videoMediaMetadata?: { + height?: number + width?: number + durationMillis?: number + } } -export const isGsuiteFile = (mimeType) => { - return mimeType?.startsWith('application/vnd.google') +export type DriveListResponse = { + files?: DriveItem[] + nextPageToken?: string +} +export type DriveSharedDrivesResponse = { + drives?: DriveItem[] + nextPageToken?: unknown +} +export type DriveAbout = { user?: { emailAddress?: string } } + +const getUsername = (data: DriveAbout) => { + return data.user?.emailAddress } -const isSharedDrive = (item) => { +export const isGsuiteFile = (mimeType: string | undefined) => + mimeType?.startsWith('application/vnd.google') + +const isSharedDrive = (item: DriveItem): boolean => { return item.kind === 'drive#drive' } -const isFolder = (item) => { +const isFolder = (item: DriveItem): boolean => { return ( item.mimeType === 'application/vnd.google-apps.folder' || isSharedDrive(item) ) } -export const isShortcut = (mimeType) => { +export const isShortcut = (mimeType: string | undefined): boolean => { return mimeType === 'application/vnd.google-apps.shortcut' } -const getItemSize = (item) => { - return parseInt(item.size, 10) +const getItemSize = (item: DriveItem): number => { + const size = item.size != null ? parseInt(item.size, 10) : NaN + return Number.isFinite(size) ? size : 0 } -const getItemIcon = (item) => { +const getItemIcon = (item: DriveItem): string | undefined => { if (isSharedDrive(item)) { const size = '=w16-h16-n' const sizeParamRegex = /=[-whncsp0-9]*$/ - return item.backgroundImageLink.match(sizeParamRegex) - ? item.backgroundImageLink.replace(sizeParamRegex, size) - : `${item.backgroundImageLink}${size}` + const background = item.backgroundImageLink + if (background == null) return undefined + return background.match(sizeParamRegex) + ? background.replace(sizeParamRegex, size) + : `${background}${size}` } if ( item.thumbnailLink && + item.mimeType != null && !item.mimeType.startsWith('application/vnd.google') ) { const smallerThumbnailLink = item.thumbnailLink.replace('s220', 's40') @@ -47,7 +86,7 @@ const getItemIcon = (item) => { return item.iconLink } -const getItemSubList = (item) => { +const getItemSubList = (item: DriveListResponse): DriveItem[] => { const allowedGSuiteTypes = [ 'application/vnd.google-apps.document', 'application/vnd.google-apps.drawing', @@ -57,17 +96,18 @@ const getItemSubList = (item) => { 'application/vnd.google-apps.shortcut', ] - return item.files.filter((i) => { + const files = item.files ?? [] + return files.filter((i) => { return ( isFolder(i) || !isGsuiteFile(i.mimeType) || - allowedGSuiteTypes.includes(i.mimeType) + (i.mimeType != null && allowedGSuiteTypes.includes(i.mimeType)) ) }) } -const getItemName = (item) => { - const extensionMaps = { +const getItemName = (item: DriveItem): string => { + const extensionMaps: Record = { 'application/vnd.google-apps.document': '.docx', 'application/vnd.google-apps.drawing': '.png', 'application/vnd.google-apps.script': '.json', @@ -75,7 +115,7 @@ const getItemName = (item) => { 'application/vnd.google-apps.presentation': '.ppt', } - const extension = extensionMaps[item.mimeType] + const extension = item.mimeType ? extensionMaps[item.mimeType] : undefined if (extension && item.name && !item.name.endsWith(extension)) { return item.name + extension } @@ -83,8 +123,8 @@ const getItemName = (item) => { return item.name ? item.name : '/' } -export const getGsuiteExportType = (mimeType) => { - const typeMaps = { +export const getGsuiteExportType = (mimeType: string): string => { + const typeMaps: Record = { 'application/vnd.google-apps.document': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.google-apps.drawing': 'image/png', @@ -99,37 +139,41 @@ export const getGsuiteExportType = (mimeType) => { return typeMaps[mimeType] || 'application/pdf' } -function getMimeType2(mimeType) { +function getMimeType2(mimeType: string | undefined) { if (isGsuiteFile(mimeType)) { - return getGsuiteExportType(mimeType) + return getGsuiteExportType(mimeType ?? '') } return mimeType } -const getMimeType = (item) => { +const getMimeType = (item: DriveItem) => { if (isShortcut(item.mimeType)) { - return getMimeType2(item.shortcutDetails.targetMimeType) + return getMimeType2(item.shortcutDetails?.targetMimeType) } return getMimeType2(item.mimeType) } -const getItemId = (item) => { +const getItemId = (item: DriveItem) => { return item.id } -const getItemRequestPath = (item) => { +const getItemRequestPath = (item: DriveItem) => { return item.id } -const getItemModifiedDate = (item) => { +const getItemModifiedDate = (item: DriveItem) => { return item.modifiedTime } -const getItemThumbnailUrl = (item) => { +const getItemThumbnailUrl = (item: DriveItem) => { return item.thumbnailLink } -const getNextPagePath = (data, currentQuery, currentPath) => { +const getNextPagePath = ( + data: DriveListResponse, + currentQuery: Query | undefined, + currentPath: string | undefined, +): string | null => { if (!data.nextPageToken) { return null } @@ -137,32 +181,33 @@ const getNextPagePath = (data, currentQuery, currentPath) => { return `${currentPath}?${querystring.stringify(query)}` } -const getImageHeight = (item) => item.imageMediaMetadata?.height +const getImageHeight = (item: DriveItem) => item.imageMediaMetadata?.height -const getImageWidth = (item) => item.imageMediaMetadata?.width +const getImageWidth = (item: DriveItem) => item.imageMediaMetadata?.width -const getImageRotation = (item) => item.imageMediaMetadata?.rotation +const getImageRotation = (item: DriveItem) => item.imageMediaMetadata?.rotation -const getImageDate = (item) => item.imageMediaMetadata?.date +const getImageDate = (item: DriveItem) => item.imageMediaMetadata?.date -const getVideoHeight = (item) => item.videoMediaMetadata?.height +const getVideoHeight = (item: DriveItem) => item.videoMediaMetadata?.height -const getVideoWidth = (item) => item.videoMediaMetadata?.width +const getVideoWidth = (item: DriveItem) => item.videoMediaMetadata?.width -const getVideoDurationMillis = (item) => item.videoMediaMetadata?.durationMillis +const getVideoDurationMillis = (item: DriveItem) => + item.videoMediaMetadata?.durationMillis // Hopefully this name will not be used by Google export const VIRTUAL_SHARED_DIR = 'shared-with-me' export const adaptData = ( - listFilesResp, - sharedDrivesResp, - directory, - query, - showSharedWithMe, - about, + listFilesResp: DriveListResponse, + sharedDrivesResp: DriveSharedDrivesResponse | null | undefined, + directory: string | undefined, + query: Query | undefined, + showSharedWithMe: boolean, + about: DriveAbout, ) => { - const adaptItem = (item) => ({ + const adaptItem = (item: DriveItem) => ({ isFolder: isFolder(item), icon: getItemIcon(item), name: getItemName(item), diff --git a/packages/@uppy/companion/src/server/provider/google/drive/index.js b/packages/@uppy/companion/src/server/provider/google/drive/index.ts similarity index 61% rename from packages/@uppy/companion/src/server/provider/google/drive/index.js rename to packages/@uppy/companion/src/server/provider/google/drive/index.ts index 83211de6d..7c743e219 100644 --- a/packages/@uppy/companion/src/server/provider/google/drive/index.js +++ b/packages/@uppy/companion/src/server/provider/google/drive/index.ts @@ -1,13 +1,21 @@ +import type { Readable } from 'node:stream' import got from 'got' import { MAX_AGE_REFRESH_TOKEN } from '../../../helpers/jwt.js' +import { isRecord } from '../../../helpers/type-guards.js' import { prepareStream } from '../../../helpers/utils.js' import logger from '../../../logger.js' import { ProviderAuthError } from '../../error.js' -import Provider from '../../Provider.js' +import Provider, { + type ProviderListResponse, + type Query, +} from '../../Provider.js' import { withGoogleErrorHandling } from '../../providerErrors.js' import { logout, refreshToken } from '../index.js' import { adaptData, + type DriveAbout, + type DriveListResponse, + type DriveSharedDrivesResponse, getGsuiteExportType, isGsuiteFile, isShortcut, @@ -18,7 +26,7 @@ import { // first run a download with mockAccessTokenExpiredError = true // then when you want to test expiry, set to mockAccessTokenExpiredError to the logged access token // This will trigger companion/nodemon to restart, and it will respond with a simulated invalid token response -const mockAccessTokenExpiredError = undefined +const mockAccessTokenExpiredError: string | true | undefined = undefined // const mockAccessTokenExpiredError = true // const mockAccessTokenExpiredError = '' @@ -28,7 +36,7 @@ const DRIVE_FILES_FIELDS = `kind,nextPageToken,incompleteSearch,files(${DRIVE_FI // using wildcard to get all 'drive' fields because specifying fields seems no to work for the /drives endpoint const SHARED_DRIVE_FIELDS = '*' -const getClient = ({ token }) => +const getClient = ({ token }: { token: string }) => got.extend({ prefixUrl: 'https://www.googleapis.com/drive/v3', headers: { @@ -36,31 +44,58 @@ const getClient = ({ token }) => }, }) -async function getStats({ id, token }) { +type DriveFileStats = { + mimeType?: unknown + id?: unknown + exportLinks?: unknown + shortcutDetails?: unknown +} & Record + +async function getStats({ id, token }: { id: string; token: string }) { const client = getClient({ token }) - const getStatsInner = async (statsOfId) => + const getStatsInner = async (statsOfId: string) => client .get(`files/${encodeURIComponent(statsOfId)}`, { searchParams: { fields: DRIVE_FILE_FIELDS, supportsAllDrives: true }, responseType: 'json', }) - .json() + .json() const stats = await getStatsInner(id) // If it is a shortcut, we need to get stats again on the target - if (isShortcut(stats.mimeType)) - return getStatsInner(stats.shortcutDetails.targetId) + const mimeType = + typeof stats.mimeType === 'string' ? stats.mimeType : undefined + if (mimeType && isShortcut(mimeType)) { + const shortcutDetails = stats.shortcutDetails + if ( + isRecord(shortcutDetails) && + typeof shortcutDetails['targetId'] === 'string' + ) { + return getStatsInner(shortcutDetails['targetId']) + } + } return stats } -export async function streamGoogleFile({ token, id: idIn }) { +export async function streamGoogleFile({ + token, + id: idIn, +}: { + token: string + id: string +}) { const client = getClient({ token }) - const { mimeType, id, exportLinks } = await getStats({ id: idIn, token }) + const stats = await getStats({ id: idIn, token }) + const mimeType = typeof stats.mimeType === 'string' ? stats.mimeType : '' + const id = typeof stats.id === 'string' ? stats.id : `${idIn}` + const exportLinks = isRecord(stats.exportLinks) + ? stats.exportLinks + : undefined - let stream + let stream: Readable if (isGsuiteFile(mimeType)) { const mimeType2 = getGsuiteExportType(mimeType) @@ -73,7 +108,10 @@ export async function streamGoogleFile({ token, id: idIn }) { // Error message: "This file is too large to be exported.". // Issue logged in Google APIs: https://github.com/googleapis/google-api-nodejs-client/issues/3446 // Implemented based on the answer from StackOverflow: https://stackoverflow.com/a/59168288 - const mimeTypeExportLink = exportLinks?.[mimeType2] + const mimeTypeExportLink = + exportLinks && typeof exportLinks[mimeType2] === 'string' + ? exportLinks[mimeType2] + : undefined if (mimeTypeExportLink) { stream = got.stream.get(mimeTypeExportLink, { headers: { @@ -98,36 +136,64 @@ export async function streamGoogleFile({ token, id: idIn }) { return { stream, size } } +interface DriveUserSession { + accessToken: string +} + /** * Adapter for API https://developers.google.com/drive/api/v3/ */ -export class Drive extends Provider { - static get oauthProvider() { +export class Drive extends Provider { + static override get oauthProvider() { return 'googledrive' } - static get authStateExpiry() { + static override get authStateExpiry() { return MAX_AGE_REFRESH_TOKEN } - async list(options) { + // Define these as real methods (not prototype assignment), so we don't risk + // instance fields shadowing the prototype in downlevel transpiles. + override logout(args: Parameters[0]) { + return logout(args) + } + + override refreshToken(args: { + redirectUri: string | undefined + clientId: string | undefined + clientSecret: string | undefined + refreshToken: string + }) { + return refreshToken(args) + } + + override async list({ + directory: directoryIn, + providerUserSession: { accessToken: token }, + query, + }: { + directory?: string | undefined + providerUserSession: DriveUserSession + query?: Query | undefined + }): Promise { return withGoogleErrorHandling( Drive.oauthProvider, 'provider.drive.list.error', async () => { - const directory = options.directory || 'root' - const query = options.query || {} - const { - providerUserSession: { accessToken: token }, - } = options + const cursor = + typeof query?.['cursor'] === 'string' ? query['cursor'] : undefined + + const directory = directoryIn || 'root' const isRoot = directory === 'root' const isVirtualSharedDirRoot = directory === VIRTUAL_SHARED_DIR const client = getClient({ token }) - async function fetchSharedDrives(pageToken = null) { - const shouldListSharedDrives = isRoot && !query.cursor + async function fetchSharedDrives( + pageToken: string | null = null, + ): Promise { + const shouldListSharedDrives = isRoot && !cursor if (!shouldListSharedDrives) return undefined const response = await client @@ -139,15 +205,21 @@ export class Drive extends Provider { }, responseType: 'json', }) - .json() + .json() - const { nextPageToken } = response + const nextPageToken = + typeof response.nextPageToken === 'string' + ? response.nextPageToken + : undefined if (nextPageToken) { const nextResponse = await fetchSharedDrives(nextPageToken) if (!nextResponse) return response return { ...nextResponse, - drives: [...response.drives, ...nextResponse.drives], + drives: [ + ...(response.drives ?? []), + ...(nextResponse.drives ?? []), + ], } } @@ -162,7 +234,7 @@ export class Drive extends Provider { const searchParams = { fields: DRIVE_FILES_FIELDS, - pageToken: query.cursor, + pageToken: cursor, q, // We can only do a page size of 1000 because we do not request permissions in DRIVE_FILES_FIELDS. // Otherwise we are limited to 100. Instead we get the user info from `this.user()` @@ -174,7 +246,7 @@ export class Drive extends Provider { return client .get('files', { searchParams, responseType: 'json' }) - .json() + .json() } async function fetchAbout() { @@ -182,7 +254,7 @@ export class Drive extends Provider { return client .get('about', { searchParams, responseType: 'json' }) - .json() + .json() } const [sharedDrives, filesResponse, about] = await Promise.all([ @@ -196,14 +268,20 @@ export class Drive extends Provider { sharedDrives, directory, query, - isRoot && !query.cursor, // we can only show it on the first page request, or else we will have duplicates of it + isRoot && !cursor, // we can only show it on the first page request, or else we will have duplicates of it about, ) }, ) } - async download({ id, providerUserSession: { accessToken: token } }) { + override async download({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: DriveUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { if (mockAccessTokenExpiredError != null) { logger.warn(`Access token: ${token}`) @@ -222,6 +300,3 @@ export class Drive extends Provider { ) } } - -Drive.prototype.logout = logout -Drive.prototype.refreshToken = refreshToken diff --git a/packages/@uppy/companion/src/server/provider/google/index.js b/packages/@uppy/companion/src/server/provider/google/index.ts similarity index 64% rename from packages/@uppy/companion/src/server/provider/google/index.js rename to packages/@uppy/companion/src/server/provider/google/index.ts index 40d5fc26f..f9d72f746 100644 --- a/packages/@uppy/companion/src/server/provider/google/index.js +++ b/packages/@uppy/companion/src/server/provider/google/index.ts @@ -14,12 +14,16 @@ export async function refreshToken({ clientId, clientSecret, refreshToken: theRefreshToken, -}) { +}: { + clientId: string | undefined + clientSecret: string | undefined + refreshToken: string +}): Promise<{ accessToken: string }> { return withGoogleErrorHandling( 'google', 'provider.google.token.refresh.error', async () => { - const { access_token: accessToken } = await getOauthClient() + const tokenRes = await getOauthClient() .post('token', { responseType: 'json', form: { @@ -29,13 +33,21 @@ export async function refreshToken({ client_secret: clientSecret, }, }) - .json() + .json<{ access_token?: unknown }>() + const accessToken = tokenRes.access_token + if (typeof accessToken !== 'string' || accessToken.length === 0) { + throw new Error('Missing access_token') + } return { accessToken } }, ) } -export async function logout({ providerUserSession: { accessToken: token } }) { +export async function logout({ + providerUserSession: { accessToken: token }, +}: { + providerUserSession: { accessToken: string } +}): Promise<{ revoked: true }> { return withGoogleErrorHandling( 'google', 'provider.google.logout.error', diff --git a/packages/@uppy/companion/src/server/provider/index.js b/packages/@uppy/companion/src/server/provider/index.js deleted file mode 100644 index cce45c1b1..000000000 --- a/packages/@uppy/companion/src/server/provider/index.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @module provider - */ - -import { getRedirectPath, getURLBuilder } from '../helpers/utils.js' -import * as logger from '../logger.js' -import box from './box/index.js' -import { getCredentialsResolver } from './credentials.js' -import dropbox from './dropbox/index.js' -import facebook from './facebook/index.js' -import { Drive } from './google/drive/index.js' -import instagram from './instagram/graph/index.js' -import onedrive from './onedrive/index.js' -// biome-ignore lint/correctness/noUnusedImports: It's used as a type -import Provider, { isOAuthProvider } from './Provider.js' -import unsplash from './unsplash/index.js' -import webdav from './webdav/index.js' -import zoom from './zoom/index.js' - -/** - * - * @param {{server: object}} options - */ -const validOptions = (options) => { - return options.server.host && options.server.protocol -} - -/** - * adds the desired provider module to the request object, - * based on the providerName parameter specified - * - * @param {Record} providers - */ -export function getProviderMiddleware(providers, grantConfig) { - /** - * - * @param {object} req - * @param {object} res - * @param {Function} next - * @param {string} providerName - */ - const middleware = (req, res, next, providerName) => { - const ProviderClass = providers[providerName] - if (ProviderClass && validOptions(req.companion.options)) { - const { allowLocalUrls, providerOptions } = req.companion.options - const { oauthProvider } = ProviderClass - - let providerGrantConfig - if (isOAuthProvider(oauthProvider)) { - req.companion.getProviderCredentials = getCredentialsResolver( - providerName, - req.companion.options, - req, - ) - providerGrantConfig = grantConfig[oauthProvider] - req.companion.providerGrantConfig = providerGrantConfig - } - - const secret = providerOptions[providerName]?.secret - req.companion.provider = new ProviderClass({ - secret, - providerName, - providerGrantConfig, - allowLocalUrls, - }) - req.companion.providerName = providerName - req.companion.providerClass = ProviderClass - } else { - logger.warn( - 'invalid provider options detected. Provider will not be loaded', - 'provider.middleware.invalid', - req.id, - ) - } - next() - } - - return middleware -} - -/** - * @returns {Record} - */ -export function getDefaultProviders() { - const providers = { - dropbox, - box, - drive: Drive, - facebook, - onedrive, - zoom, - instagram, - unsplash, - webdav, - } - - return providers -} - -/** - * - * @typedef {{'module': typeof Provider, config: Record}} CustomProvider - * - * @param {Record} customProviders - * @param {Record} providers - * @param {object} grantConfig - */ -export function addCustomProviders(customProviders, providers, grantConfig) { - Object.keys(customProviders).forEach((providerName) => { - const customProvider = customProviders[providerName] - - providers[providerName] = customProvider.module - const { oauthProvider } = customProvider.module - - if (isOAuthProvider(oauthProvider)) { - grantConfig[oauthProvider] = { - ...customProvider.config, - // todo: consider setting these options from a universal point also used - // by official providers. It'll prevent these from getting left out if the - // requirement changes. - callback: `/${providerName}/callback`, - transport: 'session', - } - } - }) -} - -/** - * - * @param {{server: object, providerOptions: object}} companionOptions - * @param {object} grantConfig - * @param {(a: string) => string} getOauthProvider - */ -export function addProviderOptions( - companionOptions, - grantConfig, - getOauthProvider, -) { - const { server, providerOptions } = companionOptions - if (!validOptions({ server })) { - logger.warn( - 'invalid provider options detected. Providers will not be loaded', - 'provider.options.invalid', - ) - return - } - - grantConfig.defaults = { - host: server.host, - protocol: server.protocol, - path: server.path, - } - - const { oauthDomain } = server - const keys = Object.keys(providerOptions).filter((key) => key !== 'server') - keys.forEach((providerName) => { - const oauthProvider = getOauthProvider?.(providerName) - - if (isOAuthProvider(oauthProvider) && grantConfig[oauthProvider]) { - // explicitly add providerOptions so users don't override other providerOptions. - grantConfig[oauthProvider].key = providerOptions[providerName].key - grantConfig[oauthProvider].secret = providerOptions[providerName].secret - if (providerOptions[providerName].credentialsURL) { - grantConfig[oauthProvider].dynamic = [ - 'key', - 'secret', - 'redirect_uri', - 'origins', - ] - } - - const provider = getDefaultProviders()[providerName] - Object.assign(grantConfig[oauthProvider], provider.getExtraGrantConfig()) - - // override grant.js redirect uri with companion's custom redirect url - const isExternal = !!server.implicitPath - const redirectPath = getRedirectPath(providerName) - grantConfig[oauthProvider].redirect_uri = getURLBuilder(companionOptions)( - redirectPath, - isExternal, - ) - if (oauthDomain) { - const fullRedirectPath = getURLBuilder(companionOptions)( - redirectPath, - isExternal, - true, - ) - grantConfig[oauthProvider].redirect_uri = - `${server.protocol}://${oauthDomain}${fullRedirectPath}` - } - - if (server.implicitPath) { - // no url builder is used for this because grant internally adds the path - grantConfig[oauthProvider].callback = - `${server.implicitPath}${grantConfig[oauthProvider].callback}` - } else if (server.path) { - grantConfig[oauthProvider].callback = - `${server.path}${grantConfig[oauthProvider].callback}` - } - } - }) -} diff --git a/packages/@uppy/companion/src/server/provider/index.ts b/packages/@uppy/companion/src/server/provider/index.ts new file mode 100644 index 000000000..31b28fe1a --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/index.ts @@ -0,0 +1,253 @@ +import type { NextFunction, Request, Response } from 'express' +import type { GrantProviderStaticConfig } from '../../config/grant.js' +import { getRedirectPath, getURLBuilder } from '../helpers/utils.js' +import * as logger from '../logger.js' +import box from './box/index.js' +import { getCredentialsResolver } from './credentials.js' +import dropbox from './dropbox/index.js' +import facebook from './facebook/index.js' +import { Drive } from './google/drive/index.js' +import instagram from './instagram/graph/index.js' +import onedrive from './onedrive/index.js' +import { isOAuthProvider, type ProviderCtor } from './Provider.js' +import unsplash from './unsplash/index.js' +import webdav from './webdav/index.js' +import zoom from './zoom/index.js' + +export interface GrantConfigDefaults { + host?: string + protocol?: string + path?: string +} + +export interface GrantProviderConfig + extends GrantProviderStaticConfig, + GrantConfigDefaults { + key?: string | undefined + secret?: string | undefined + dynamic?: string[] + redirect_uri?: string | undefined +} + +export interface GrantConfig { + defaults?: GrantConfigDefaults + // keyed per provider: + [key: string]: GrantProviderConfig | undefined +} + +/** + * adds the desired provider module to the request object, + * based on the providerName parameter specified + */ +export function getProviderMiddleware( + providers: Record, + grantConfig: GrantConfig, +): ( + req: Request, + res: Response, + next: NextFunction, + providerName: string, +) => void { + const middleware = ( + req: Request, + _res: Response, + next: NextFunction, + providerName: string, + ): void => { + const ProviderClass = providers[providerName] + if ( + !ProviderClass || + !( + req.companion.options.server.host && + req.companion.options.server.protocol + ) + ) { + logger.warn( + 'invalid provider options detected. Provider will not be loaded', + 'provider.middleware.invalid', + req.id, + ) + return + } + + const { allowLocalUrls, providerOptions } = req.companion.options + const { oauthProvider } = ProviderClass + + let providerGrantConfig: GrantProviderConfig | undefined + if (isOAuthProvider(oauthProvider)) { + req.companion.getProviderCredentials = getCredentialsResolver( + providerName, + req.companion.options, + req, + ) + + providerGrantConfig = grantConfig[oauthProvider] + req.companion.providerGrantConfig = providerGrantConfig ?? {} + } + + const secret = providerOptions[providerName]?.secret + + const providerArgs = { + secret, + providerName, + allowLocalUrls, + ...(providerGrantConfig && { providerGrantConfig }), + } + req.companion.provider = new ProviderClass(providerArgs) + req.companion.providerName = providerName + req.companion.providerClass = ProviderClass + next() + } + + return middleware +} + +/** + * Return the default provider implementations. + */ +export function getDefaultProviders() { + return { + dropbox, + box, + drive: Drive, + facebook, + onedrive, + zoom, + instagram, + unsplash, + webdav, + } +} + +/** + * Register custom providers and extend Grant config for OAuth-based providers. + * + * @param customProviders - Map of provider name -> provider module + Grant config. + * @param providers - Provider registry to mutate. + * @param grantConfig - Grant config object to mutate. + */ +export function addCustomProviders( + customProviders: Record< + string, + { module: ProviderCtor; config: GrantProviderConfig } + >, + providers: Record, + grantConfig: GrantConfig, +): void { + Object.entries(customProviders).forEach(([providerName, customProvider]) => { + providers[providerName] = customProvider.module + const { oauthProvider } = customProvider.module + + if (isOAuthProvider(oauthProvider)) { + grantConfig[oauthProvider] = { + ...customProvider.config, + // todo: consider setting these options from a universal point also used + // by official providers. It'll prevent these from getting left out if the + // requirement changes. + callback: `/${providerName}/callback`, + transport: 'session', + } + } + }) +} + +export function addProviderOptions( + companionOptions: { + server?: { + host?: string | undefined + protocol?: string | undefined + path?: string | undefined + implicitPath?: string | undefined + oauthDomain?: string | undefined + } + providerOptions?: Record< + string, + { + key?: string | undefined + secret?: string | undefined + credentialsURL?: string | undefined + } + > + }, + grantConfig: GrantConfig, + getOauthProvider?: (providerName: string) => string | undefined, +): void { + const server = companionOptions.server ?? {} + const providerOptions = companionOptions.providerOptions ?? {} + const host = server.host + const protocol = server.protocol + if (!(host && protocol)) { + logger.warn( + 'invalid provider options detected. Provider will not be loaded', + 'provider.options.invalid', + ) + return + } + + grantConfig.defaults = { + host, + protocol, + ...(server.path != null && { path: server.path }), + } + + const { oauthDomain } = server + const keys = Object.keys(providerOptions).filter((key) => key !== 'server') + keys.forEach((providerName) => { + const oauthProvider = getOauthProvider?.(providerName) + + if (isOAuthProvider(oauthProvider) && grantConfig[oauthProvider]) { + const grantProviderConfig = grantConfig[oauthProvider] + const providerOption = providerOptions[providerName] + if (!providerOption) return + // explicitly add providerOptions so users don't override other providerOptions. + grantProviderConfig['key'] = providerOption.key + grantProviderConfig['secret'] = providerOption.secret + if (providerOption.credentialsURL) { + grantProviderConfig['dynamic'] = [ + 'key', + 'secret', + 'redirect_uri', + 'origins', + ] + } + + const provider = + getDefaultProviders()[ + providerName as keyof ReturnType + ] + if (provider) { + Object.assign(grantProviderConfig, provider.getExtraGrantConfig()) + } + + // override grant.js redirect uri with companion's custom redirect url + const isExternal = !!server.implicitPath + const redirectPath = getRedirectPath(providerName) + grantProviderConfig['redirect_uri'] = getURLBuilder(companionOptions)( + redirectPath, + isExternal, + ) + if (oauthDomain) { + const fullRedirectPath = getURLBuilder(companionOptions)( + redirectPath, + isExternal, + true, + ) + grantProviderConfig['redirect_uri'] = + `${protocol}://${oauthDomain}${fullRedirectPath}` + } + + if (server.implicitPath) { + // no url builder is used for this because grant internally adds the path + const cb = grantProviderConfig['callback'] + if (typeof cb === 'string') { + grantProviderConfig['callback'] = `${server.implicitPath}${cb}` + } + } else if (server.path) { + const cb = grantProviderConfig['callback'] + if (typeof cb === 'string') { + grantProviderConfig['callback'] = `${server.path}${cb}` + } + } + } + }) +} diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.js b/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.js deleted file mode 100644 index c85b9d201..000000000 --- a/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.js +++ /dev/null @@ -1,79 +0,0 @@ -import querystring from 'node:querystring' - -const MEDIA_TYPES = Object.freeze({ - video: 'VIDEO', - carousel: 'CAROUSEL_ALBUM', - image: 'IMAGE', -}) - -const isVideo = (item) => item.media_type === MEDIA_TYPES.video - -const isFolder = (item) => { - return false -} - -const getItemIcon = (item) => { - return isVideo(item) ? item.thumbnail_url : item.media_url -} - -const getItemSubList = (item) => { - const newItems = [] - item.data.forEach((subItem) => { - if (subItem.media_type === MEDIA_TYPES.carousel) { - subItem.children.data.forEach((i) => newItems.push(i)) - } else { - newItems.push(subItem) - } - }) - return newItems -} - -const getItemName = (item, index) => { - const ext = isVideo(item) ? 'mp4' : 'jpeg' - // adding index, so the name is unique - return `Instagram ${item.timestamp}${index}.${ext}` -} - -const getMimeType = (item) => { - return isVideo(item) ? 'video/mp4' : 'image/jpeg' -} - -const getItemId = (item) => item.id - -const getItemRequestPath = (item) => item.id - -const getItemModifiedDate = (item) => item.timestamp - -const getItemThumbnailUrl = (item) => getItemIcon(item) - -const getNextPagePath = (data, currentQuery, currentPath) => { - if (!data.paging || !data.paging.cursors) { - return null - } - - const query = { ...currentQuery, cursor: data.paging.cursors.after } - return `${currentPath || ''}?${querystring.stringify(query)}` -} - -const adaptData = (res, username, directory, currentQuery) => { - const data = { username, items: [] } - const items = getItemSubList(res) - items.forEach((item, i) => { - data.items.push({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item, i), - mimeType: getMimeType(item), - id: getItemId(item), - size: null, - thumbnail: getItemThumbnailUrl(item), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - }) - }) - - data.nextPagePath = getNextPagePath(res, currentQuery, directory) - return data -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts b/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts new file mode 100644 index 000000000..8779361d5 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts @@ -0,0 +1,103 @@ +import querystring from 'node:querystring' + +const MEDIA_TYPES = Object.freeze({ + video: 'VIDEO', + carousel: 'CAROUSEL_ALBUM', + image: 'IMAGE', +}) + +type InstagramMedia = { + id: string + media_type: string + media_url?: string + thumbnail_url?: string + timestamp: string + children?: { data: InstagramMedia[] } +} + +type InstagramListResponse = { + data: InstagramMedia[] + paging?: { cursors?: { after?: string } } +} + +const isVideo = (item: InstagramMedia): boolean => + item.media_type === MEDIA_TYPES.video + +const isFolder = (_item: InstagramMedia): boolean => { + return false +} + +const getItemIcon = (item: InstagramMedia): string | undefined => { + return isVideo(item) ? item.thumbnail_url : item.media_url +} + +const getItemSubList = (item: InstagramListResponse): InstagramMedia[] => { + const newItems: InstagramMedia[] = [] + item.data.forEach((subItem) => { + if (subItem.media_type === MEDIA_TYPES.carousel) { + subItem.children?.data.forEach((i) => newItems.push(i)) + } else { + newItems.push(subItem) + } + }) + return newItems +} + +const getItemName = (item: InstagramMedia, index: number): string => { + const ext = isVideo(item) ? 'mp4' : 'jpeg' + // adding index, so the name is unique + return `Instagram ${item.timestamp}${index}.${ext}` +} + +const getMimeType = (item: InstagramMedia): string => { + return isVideo(item) ? 'video/mp4' : 'image/jpeg' +} + +const getItemId = (item: InstagramMedia): string => item.id + +const getItemRequestPath = (item: InstagramMedia): string => item.id + +const getItemModifiedDate = (item: InstagramMedia): string => item.timestamp + +const getItemThumbnailUrl = (item: InstagramMedia): string | undefined => + getItemIcon(item) + +const getNextPagePath = ( + data: InstagramListResponse, + currentQuery: Record, + currentPath: string | undefined, +): string | null => { + if (!data.paging || !data.paging.cursors) { + return null + } + + const after = data.paging.cursors.after + if (after == null || after.length === 0) return null + + const query = { ...currentQuery, cursor: after } + return `${currentPath || ''}?${querystring.stringify(query)}` +} + +const adaptData = ( + res: InstagramListResponse, + username: string | null, + directory: string | undefined, + currentQuery: Record, +) => { + const items = getItemSubList(res).map((item, i) => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item, i), + mimeType: getMimeType(item), + id: getItemId(item), + size: null, + thumbnail: getItemThumbnailUrl(item), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + })) + + const nextPagePath = getNextPagePath(res, currentQuery, directory) + return { username, items, nextPagePath } +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/index.js b/packages/@uppy/companion/src/server/provider/instagram/graph/index.js deleted file mode 100644 index f9bb872a0..000000000 --- a/packages/@uppy/companion/src/server/provider/instagram/graph/index.js +++ /dev/null @@ -1,114 +0,0 @@ -import got from 'got' -import { prepareStream } from '../../../helpers/utils.js' -import logger from '../../../logger.js' -import Provider from '../../Provider.js' -import { withProviderErrorHandling } from '../../providerErrors.js' -import adaptData from './adapter.js' - -const getClient = ({ token }) => - got.extend({ - prefixUrl: 'https://graph.instagram.com', - headers: { - authorization: `Bearer ${token}`, - }, - }) - -async function getMediaUrl({ token, id }) { - const body = await getClient({ token }) - .get(String(id), { - searchParams: { fields: 'media_url' }, - responseType: 'json', - }) - .json() - return body.media_url -} - -/** - * Adapter for API https://developers.facebook.com/docs/instagram-api/overview - */ -export default class Instagram extends Provider { - // for "grant" - static getExtraGrantConfig() { - return { - protocol: 'https', - scope: ['user_profile', 'user_media'], - } - } - - static get oauthProvider() { - return 'instagram' - } - - async list({ - directory, - providerUserSession: { accessToken: token }, - query = { cursor: null }, - }) { - return this.#withErrorHandling( - 'provider.instagram.list.error', - async () => { - const qs = { - fields: - 'id,media_type,thumbnail_url,media_url,timestamp,children{media_type,media_url,thumbnail_url,timestamp}', - } - - if (query.cursor) qs.after = query.cursor - - const client = getClient({ token }) - - const [{ username }, list] = await Promise.all([ - client - .get('me', { - searchParams: { fields: 'username' }, - responseType: 'json', - }) - .json(), - client - .get('me/media', { searchParams: qs, responseType: 'json' }) - .json(), - ]) - return adaptData(list, username, directory, query) - }, - ) - } - - async download({ id, providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling( - 'provider.instagram.download.error', - async () => { - const url = await getMediaUrl({ token, id }) - const stream = got.stream.get(url, { responseType: 'json' }) - const { size } = await prepareStream(stream) - return { stream, size } - }, - ) - } - - async thumbnail() { - // not implementing this because a public thumbnail from instagram will be used instead - logger.error( - 'call to thumbnail is not implemented', - 'provider.instagram.thumbnail.error', - ) - throw new Error('call to thumbnail is not implemented') - } - - async logout() { - // access revoke is not supported by Instagram's API - return { - revoked: false, - manual_revoke_url: 'https://www.instagram.com/accounts/manage_access/', - } - } - - async #withErrorHandling(tag, fn) { - return withProviderErrorHandling({ - fn, - tag, - providerName: Instagram.oauthProvider, - isAuthError: (response) => - typeof response.body === 'object' && response.body?.error?.code === 190, // Invalid OAuth 2.0 Access Token - getJsonErrorMessage: (body) => body?.error?.message, - }) - } -} diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts b/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts new file mode 100644 index 000000000..791bd5008 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts @@ -0,0 +1,161 @@ +import type { Readable } from 'node:stream' +import got from 'got' +import { isRecord } from '../../../helpers/type-guards.js' +import { prepareStream } from '../../../helpers/utils.js' +import logger from '../../../logger.js' +import Provider, { + type ProviderListResponse, + type Query, +} from '../../Provider.js' +import { withProviderErrorHandling } from '../../providerErrors.js' +import adaptData from './adapter.js' + +type InstagramClient = ReturnType + +interface InstagramUserSession { + accessToken: string +} + +const getClient = ({ token }: { token: string }): InstagramClient => + got.extend({ + prefixUrl: 'https://graph.instagram.com', + headers: { + authorization: `Bearer ${token}`, + }, + }) + +async function getMediaUrl({ + token, + id, +}: { + token: string + id: string +}): Promise { + const body = await getClient({ token }) + .get(String(id), { + searchParams: { fields: 'media_url' }, + responseType: 'json', + }) + .json<{ media_url: string }>() + + return body.media_url +} + +/** + * Adapter for API https://developers.facebook.com/docs/instagram-api/overview + */ +export default class Instagram extends Provider { + // for "grant" + static override getExtraGrantConfig() { + return { + protocol: 'https', + scope: ['user_profile', 'user_media'], + } + } + + static override get oauthProvider() { + return 'instagram' + } + + override async list({ + directory, + providerUserSession: { accessToken: token }, + query, + }: { + directory?: string | undefined + providerUserSession: InstagramUserSession + query?: Query | undefined + }): Promise { + return this.#withErrorHandling( + 'provider.instagram.list.error', + async () => { + const qs: Record = { + fields: + 'id,media_type,thumbnail_url,media_url,timestamp,children{media_type,media_url,thumbnail_url,timestamp}', + } + + if (typeof query?.['cursor'] === 'string') { + qs['after'] = query['cursor'] + } + + const client = getClient({ token }) + + const [me, list] = await Promise.all([ + client + .get('me', { + searchParams: { fields: 'username' }, + responseType: 'json', + }) + .json<{ username?: string }>(), + client + .get('me/media', { searchParams: qs, responseType: 'json' }) + .json[0]>(), + ]) + + const username = me.username != null ? me.username : null + const currentQuery: Record = {} + if (typeof query?.['cursor'] === 'string') + currentQuery['cursor'] = query['cursor'] + return adaptData(list, username, directory, currentQuery) + }, + ) + } + + override async download({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: InstagramUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.#withErrorHandling( + 'provider.instagram.download.error', + async () => { + const url = await getMediaUrl({ token, id }) + const stream = got.stream.get(url, { responseType: 'json' }) + const { size } = await prepareStream(stream) + return { stream, size } + }, + ) + } + + override async thumbnail(): Promise<{ + stream: Readable + contentType: string + }> { + // not implementing this because a public thumbnail from instagram will be used instead + logger.error( + 'call to thumbnail is not implemented', + 'provider.instagram.thumbnail.error', + ) + throw new Error('call to thumbnail is not implemented') + } + + override async logout() { + // access revoke is not supported by Instagram's API + return { + revoked: false, + manual_revoke_url: 'https://www.instagram.com/accounts/manage_access/', + } + } + + async #withErrorHandling(tag: string, fn: () => Promise): Promise { + return withProviderErrorHandling({ + fn, + tag, + providerName: Instagram.oauthProvider, + isAuthError: (response) => { + const body = response.body + if (!isRecord(body)) return false + const err = body['error'] + return isRecord(err) && err['code'] === 190 + }, // Invalid OAuth 2.0 Access Token + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const err = body['error'] + if (!isRecord(err)) return undefined + return typeof err['message'] === 'string' ? err['message'] : undefined + }, + }) + } +} diff --git a/packages/@uppy/companion/src/server/provider/onedrive/adapter.js b/packages/@uppy/companion/src/server/provider/onedrive/adapter.js deleted file mode 100644 index a669b3974..000000000 --- a/packages/@uppy/companion/src/server/provider/onedrive/adapter.js +++ /dev/null @@ -1,86 +0,0 @@ -const isFolder = (item) => { - if (item.remoteItem) { - return !!item.remoteItem.folder - } - - return !!item.folder -} - -const getItemSize = (item) => { - return item.size -} - -const getItemThumbnailUrl = (item) => { - return item.thumbnails[0] ? item.thumbnails[0].medium.url : null -} - -const getItemIcon = (item) => { - return isFolder(item) ? 'folder' : getItemThumbnailUrl(item) -} - -const getItemSubList = (item) => { - return item.value -} - -const getItemName = (item) => { - return item.name || '' -} - -const getMimeType = (item) => { - return item.file ? item.file.mimeType : null -} - -const getItemId = (item) => { - if (item.remoteItem) { - return item.remoteItem.id - } - return item.id -} - -const getItemRequestPath = (item) => { - let query = `?driveId=${item.parentReference.driveId}` - if (item.remoteItem) { - query = `?driveId=${item.remoteItem.parentReference.driveId}` - } - return getItemId(item) + query -} - -const getItemModifiedDate = (item) => { - return item.lastModifiedDateTime -} - -const getNextPagePath = ({ res, query: currentQuery, directory }) => { - const nextLink = res['@odata.nextLink'] - if (!nextLink) { - return null - } - - const skipToken = new URL(nextLink).searchParams.get('$skiptoken') - - const query = { ...currentQuery, cursor: skipToken } - return `${directory ?? ''}?${new URLSearchParams(query).toString()}` -} - -const adaptData = (res, username, query, directory) => { - const data = { username, items: [] } - const items = getItemSubList(res) - items.forEach((item) => { - data.items.push({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item), - mimeType: getMimeType(item), - id: getItemId(item), - thumbnail: getItemThumbnailUrl(item), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - size: getItemSize(item), - }) - }) - - data.nextPagePath = getNextPagePath({ res, query, directory }) - - return data -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/onedrive/adapter.ts b/packages/@uppy/companion/src/server/provider/onedrive/adapter.ts new file mode 100644 index 000000000..947f6649f --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/onedrive/adapter.ts @@ -0,0 +1,123 @@ +type OneDriveParentReference = { driveId: string } + +type OneDriveRemoteItem = { + id: string + folder?: unknown + parentReference: OneDriveParentReference +} + +type OneDriveItem = { + id: string + name?: string + size?: number + file?: { mimeType?: string } + folder?: unknown + remoteItem?: OneDriveRemoteItem + thumbnails?: Array<{ medium?: { url?: string } }> + parentReference: OneDriveParentReference + lastModifiedDateTime?: string +} + +type OneDriveListResponse = { + value: OneDriveItem[] + '@odata.nextLink'?: string +} + +const isFolder = (item: OneDriveItem): boolean => { + if (item.remoteItem) { + return !!item.remoteItem.folder + } + + return !!item.folder +} + +const getItemSize = (item: OneDriveItem): number | undefined => { + return item.size +} + +const getItemThumbnailUrl = (item: OneDriveItem): string | null => { + const url = item.thumbnails?.[0]?.medium?.url + return typeof url === 'string' ? url : null +} + +const getItemIcon = (item: OneDriveItem): string | null => { + return isFolder(item) ? 'folder' : getItemThumbnailUrl(item) +} + +const getItemSubList = (item: OneDriveListResponse): OneDriveItem[] => { + return item.value +} + +const getItemName = (item: OneDriveItem): string => { + return item.name || '' +} + +const getMimeType = (item: OneDriveItem): string | null => { + const mimeType = item.file?.mimeType + return typeof mimeType === 'string' ? mimeType : null +} + +const getItemId = (item: OneDriveItem): string => { + if (item.remoteItem) { + return item.remoteItem.id + } + return item.id +} + +const getItemRequestPath = (item: OneDriveItem): string => { + let query = `?driveId=${item.parentReference.driveId}` + if (item.remoteItem) { + query = `?driveId=${item.remoteItem.parentReference.driveId}` + } + return getItemId(item) + query +} + +const getItemModifiedDate = (item: OneDriveItem): string | undefined => { + return item.lastModifiedDateTime +} + +const getNextPagePath = ({ + res, + query: currentQuery, + directory, +}: { + res: OneDriveListResponse + query: Record + directory: string | undefined +}): string | null => { + const nextLink = res['@odata.nextLink'] + if (!nextLink) { + return null + } + + const skipToken = new URL(nextLink).searchParams.get('$skiptoken') + if (skipToken == null || skipToken.length === 0) return null + + const query = { ...currentQuery, cursor: skipToken } + return `${directory ?? ''}?${new URLSearchParams(query).toString()}` +} + +const adaptData = ( + res: OneDriveListResponse, + username: string | undefined, + query: Record, + directory: string | undefined, +) => { + const items = getItemSubList(res).map((item) => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item), + mimeType: getMimeType(item), + id: getItemId(item), + thumbnail: getItemThumbnailUrl(item), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + size: getItemSize(item), + })) + + const nextPagePath = getNextPagePath({ res, query, directory }) + + return { username, items, nextPagePath } +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/onedrive/index.js b/packages/@uppy/companion/src/server/provider/onedrive/index.js deleted file mode 100644 index 6b5a13cac..000000000 --- a/packages/@uppy/companion/src/server/provider/onedrive/index.js +++ /dev/null @@ -1,148 +0,0 @@ -import got from 'got' -import { prepareStream } from '../../helpers/utils.js' -import logger from '../../logger.js' -import Provider from '../Provider.js' -import { withProviderErrorHandling } from '../providerErrors.js' -import adaptData from './adapter.js' - -const getClient = ({ token }) => - got.extend({ - prefixUrl: 'https://graph.microsoft.com/v1.0', - headers: { - authorization: `Bearer ${token}`, - }, - }) - -const getOauthClient = () => - got.extend({ - prefixUrl: 'https://login.live.com', - }) - -const getRootPath = (query) => - query.driveId ? `drives/${query.driveId}` : 'me/drive' - -/** - * Adapter for API https://docs.microsoft.com/en-us/onedrive/developer/rest-api/ - */ -export default class OneDrive extends Provider { - static get oauthProvider() { - return 'microsoft' - } - - /** - * Makes 2 requests in parallel - 1. to get files, 2. to get user email - * it then waits till both requests are done before proceeding with the callback - * - * @param {object} options - * @param {string} options.directory - * @param {any} options.query - * @param {{ accessToken: string }} options.providerUserSession - */ - async list({ - directory, - query, - providerUserSession: { accessToken: token }, - }) { - return this.#withErrorHandling('provider.onedrive.list.error', async () => { - const path = directory ? `items/${directory}` : 'root' - // https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter - const pageSize = 999 - // const pageSize = 20 // to test pagination easily - const qs = { $expand: 'thumbnails', $top: pageSize } - if (query.cursor) { - qs.$skiptoken = query.cursor - } - - const client = getClient({ token }) - - const [{ mail, userPrincipalName }, list] = await Promise.all([ - client.get('me', { responseType: 'json' }).json(), - client - .get(`${getRootPath(query)}/${path}/children`, { - searchParams: qs, - responseType: 'json', - }) - .json(), - ]) - - return adaptData(list, mail || userPrincipalName, query, directory) - }) - } - - async download({ id, providerUserSession: { accessToken: token }, query }) { - return this.#withErrorHandling( - 'provider.onedrive.download.error', - async () => { - const stream = getClient({ token }).stream.get( - `${getRootPath(query)}/items/${id}/content`, - { responseType: 'json' }, - ) - const { size } = await prepareStream(stream) - return { stream, size } - }, - ) - } - - async thumbnail() { - // not implementing this because a public thumbnail from onedrive will be used instead - logger.error( - 'call to thumbnail is not implemented', - 'provider.onedrive.thumbnail.error', - ) - throw new Error('call to thumbnail is not implemented') - } - - async size({ id, query, providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling('provider.onedrive.size.error', async () => { - const { size } = await getClient({ token }) - .get(`${getRootPath(query)}/items/${id}`, { responseType: 'json' }) - .json() - return size - }) - } - - async logout() { - // apparently M$ doesn't support programmatic oauth2 revoke - return { - revoked: false, - manual_revoke_url: 'https://account.live.com/consent/Manage', - } - } - - async refreshToken({ clientId, clientSecret, refreshToken, redirectUri }) { - return this.#withErrorHandling( - 'provider.onedrive.token.refresh.error', - async () => { - const { access_token: accessToken } = await getOauthClient() - .post('oauth20_token.srf', { - responseType: 'json', - form: { - refresh_token: refreshToken, - grant_type: 'refresh_token', - client_id: clientId, - client_secret: clientSecret, - redirect_uri: redirectUri, - }, - }) - .json() - return { accessToken } - }, - ) - } - - async #withErrorHandling(tag, fn) { - return withProviderErrorHandling({ - fn, - tag, - providerName: OneDrive.oauthProvider, - isAuthError: (response) => response.statusCode === 401, - isUserFacingError: (response) => [400, 403].includes(response.statusCode), - // onedrive gives some errors here that the user might want to know about - // e.g. these happen if you try to login to a users in an organization, - // without an Office365 licence or OneDrive account setup completed - // 400: Tenant does not have a SPO license - // 403: You do not have access to create this personal site or you do not have a valid license - getJsonErrorMessage: (body) => body?.error?.message, - }) - } -} diff --git a/packages/@uppy/companion/src/server/provider/onedrive/index.ts b/packages/@uppy/companion/src/server/provider/onedrive/index.ts new file mode 100644 index 000000000..f7f947800 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/onedrive/index.ts @@ -0,0 +1,223 @@ +import type { Readable } from 'node:stream' +import got from 'got' +import { isRecord } from '../../helpers/type-guards.js' +import { prepareStream } from '../../helpers/utils.js' +import logger from '../../logger.js' +import Provider, { type ProviderListResponse, type Query } from '../Provider.js' +import { withProviderErrorHandling } from '../providerErrors.js' +import adaptData from './adapter.js' + +type OneDriveClient = ReturnType + +const getClient = ({ token }: { token: string }): OneDriveClient => + got.extend({ + prefixUrl: 'https://graph.microsoft.com/v1.0', + headers: { + authorization: `Bearer ${token}`, + }, + }) + +const getOauthClient = () => + got.extend({ + prefixUrl: 'https://login.live.com', + }) + +function getQueryRecord(query: Query | undefined) { + const out: { driveId?: string; cursor?: string } = {} + const driveId = query?.['driveId'] + if (typeof driveId === 'string') out['driveId'] = driveId + const cursor = query?.['cursor'] + if (typeof cursor === 'string') out['cursor'] = cursor + return out +} + +const getRootPath = (query: Query): string => + query['driveId'] ? `drives/${query['driveId']}` : 'me/drive' + +interface OneDriveUserSession { + accessToken: string +} + +/** + * Adapter for API https://docs.microsoft.com/en-us/onedrive/developer/rest-api/ + */ +export default class OneDrive extends Provider { + static override get oauthProvider() { + return 'microsoft' + } + + /** + * Makes 2 requests in parallel - 1. to get files, 2. to get user email + * it then waits till both requests are done before proceeding with the callback + * + * @param options + * @param options.directory + * @param options.query + * @param options.providerUserSession + */ + override async list({ + directory, + providerUserSession: { accessToken: token }, + query, + }: { + directory?: string | undefined + providerUserSession: OneDriveUserSession + query?: Query | undefined + }): Promise { + return this.#withErrorHandling('provider.onedrive.list.error', async () => { + const queryRecord = getQueryRecord(query) + const path = directory ? `items/${directory}` : 'root' + // https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter + const pageSize = 999 + // const pageSize = 20 // to test pagination easily + const qs = new URLSearchParams({ + $expand: 'thumbnails', + $top: String(pageSize), + }) + const cursor = queryRecord['cursor'] + if (cursor != null) { + qs.set('$skiptoken', cursor) + } + + const client = getClient({ token }) + + const [{ mail, userPrincipalName }, list] = await Promise.all([ + client + .get('me', { responseType: 'json' }) + .json<{ mail?: string; userPrincipalName?: string }>(), + client + .get(`${getRootPath(queryRecord)}/${path}/children`, { + searchParams: qs, + responseType: 'json', + }) + .json[0]>(), + ]) + + return adaptData(list, mail || userPrincipalName, queryRecord, directory) + }) + } + + override async download({ + id, + providerUserSession: { accessToken: token }, + query, + }: { + id: string + providerUserSession: OneDriveUserSession + query: Query + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.#withErrorHandling( + 'provider.onedrive.download.error', + async () => { + const queryRecord = getQueryRecord(query) + const stream = getClient({ token }).stream.get( + `${getRootPath(queryRecord)}/items/${id}/content`, + { responseType: 'json' }, + ) + const { size } = await prepareStream(stream) + return { stream, size } + }, + ) + } + + override async thumbnail(): Promise<{ + stream: Readable + contentType: string + }> { + // not implementing this because a public thumbnail from onedrive will be used instead + logger.error( + 'call to thumbnail is not implemented', + 'provider.onedrive.thumbnail.error', + ) + throw new Error('call to thumbnail is not implemented') + } + + override async size({ + id, + query, + providerUserSession: { accessToken: token }, + }: { + id: string + query: Query + providerUserSession: OneDriveUserSession + }): Promise { + return this.#withErrorHandling('provider.onedrive.size.error', async () => { + const queryRecord = getQueryRecord(query) + const body = await getClient({ token }) + .get(`${getRootPath(queryRecord)}/items/${id}`, { + responseType: 'json', + }) + .json>() + const size = body['size'] + return typeof size === 'number' ? size : undefined + }) + } + + override async logout() { + // apparently M$ doesn't support programmatic oauth2 revoke + return { + revoked: false, + manual_revoke_url: 'https://account.live.com/consent/Manage', + } + } + + override async refreshToken({ + clientId, + clientSecret, + refreshToken, + redirectUri, + }: { + clientId: string | undefined + clientSecret: string | undefined + refreshToken: string + redirectUri: string + }): Promise<{ accessToken: string }> { + return this.#withErrorHandling( + 'provider.onedrive.token.refresh.error', + async () => { + const body = await getOauthClient() + .post('oauth20_token.srf', { + responseType: 'json', + form: { + refresh_token: refreshToken, + grant_type: 'refresh_token', + client_id: clientId, + client_secret: clientSecret, + redirect_uri: redirectUri, + }, + }) + .json>() + + const accessToken = + typeof body['access_token'] === 'string' ? body['access_token'] : null + if (!accessToken) { + throw new Error('Unexpected OneDrive token refresh response') + } + return { accessToken } + }, + ) + } + + async #withErrorHandling(tag: string, fn: () => Promise): Promise { + return withProviderErrorHandling({ + fn, + tag, + providerName: OneDrive.oauthProvider, + isAuthError: (response) => response.statusCode === 401, + isUserFacingError: (response) => + typeof response.statusCode === 'number' && + [400, 403].includes(response.statusCode), + // onedrive gives some errors here that the user might want to know about + // e.g. these happen if you try to login to a users in an organization, + // without an Office365 licence or OneDrive account setup completed + // 400: Tenant does not have a SPO license + // 403: You do not have access to create this personal site or you do not have a valid license + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const err = body['error'] + if (!isRecord(err)) return undefined + return typeof err['message'] === 'string' ? err['message'] : undefined + }, + }) + } +} diff --git a/packages/@uppy/companion/src/server/provider/providerErrors.js b/packages/@uppy/companion/src/server/provider/providerErrors.ts similarity index 50% rename from packages/@uppy/companion/src/server/provider/providerErrors.js rename to packages/@uppy/companion/src/server/provider/providerErrors.ts index a5cebe090..2e0c704ca 100644 --- a/packages/@uppy/companion/src/server/provider/providerErrors.js +++ b/packages/@uppy/companion/src/server/provider/providerErrors.ts @@ -1,3 +1,4 @@ +import { isRecord } from '../helpers/type-guards.js' import * as logger from '../logger.js' import { ProviderApiError, @@ -8,27 +9,32 @@ import { export { parseHttpError } +type ProviderHttpError = { + statusCode: number | undefined + body: unknown +} + +type ProviderErrorHandlingOptions = { + fn: () => Promise + tag: string + providerName: string + isAuthError?: (a: ProviderHttpError) => boolean + isUserFacingError?: (a: ProviderHttpError) => boolean + getJsonErrorMessage: (a: unknown) => string | undefined +} + /** - * - * @param {{ - * fn: () => any, - * tag: string, - * providerName: string, - * isAuthError?: (a: { statusCode: number, body?: object }) => boolean, - * isUserFacingError?: (a: { statusCode: number, body?: object }) => boolean, - * getJsonErrorMessage: (a: object) => string - * }} param0 - * @returns + * Wrap a provider call and normalize errors to Provider*Error instances. */ -export async function withProviderErrorHandling({ +export async function withProviderErrorHandling({ fn, tag, providerName, - isAuthError = () => false, - isUserFacingError = () => false, + isAuthError = (_: ProviderHttpError) => false, + isUserFacingError = (_: ProviderHttpError) => false, getJsonErrorMessage, -}) { - function getErrorMessage({ statusCode, body }) { +}: ProviderErrorHandlingOptions): Promise { + function getErrorMessage({ statusCode, body }: ProviderHttpError): string { if (typeof body === 'object') { const message = getJsonErrorMessage(body) if (message != null) return message @@ -49,7 +55,7 @@ export async function withProviderErrorHandling({ // Wrap all HTTP errors according to the provider's desired error handling if (httpError) { const { statusCode, body } = httpError - let knownErr + let knownErr: Error if (isAuthError({ statusCode, body })) { knownErr = new ProviderAuthError() } else if (isUserFacingError({ statusCode, body })) { @@ -73,14 +79,26 @@ export async function withProviderErrorHandling({ } } -export async function withGoogleErrorHandling(providerName, tag, fn) { - return withProviderErrorHandling({ +export async function withGoogleErrorHandling( + providerName: string, + tag: string, + fn: () => Promise, +): Promise { + return withProviderErrorHandling({ fn, tag, providerName, isAuthError: (response) => response.statusCode === 401 || - (response.statusCode === 400 && response.body?.error === 'invalid_grant'), // Refresh token has expired or been revoked - getJsonErrorMessage: (body) => body?.error?.message, + (response.statusCode === 400 && + isRecord(response.body) && + response.body['error'] === 'invalid_grant'), // Refresh token has expired or been revoked + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const error = body['error'] + if (!isRecord(error)) return undefined + const message = error['message'] + return typeof message === 'string' ? message : undefined + }, }) } diff --git a/packages/@uppy/companion/src/server/provider/unsplash/adapter.js b/packages/@uppy/companion/src/server/provider/unsplash/adapter.js deleted file mode 100644 index 491a16181..000000000 --- a/packages/@uppy/companion/src/server/provider/unsplash/adapter.js +++ /dev/null @@ -1,84 +0,0 @@ -import querystring from 'node:querystring' - -const isFolder = (item) => { - return false -} - -const getItemIcon = (item) => { - return item.urls.thumb -} - -const getItemSubList = (item) => { - return item.results -} - -const getItemName = (item) => { - const description = item.description || item.alt_description - if (description) { - return `${description.replace(/^([\S\s]{27})[\S\s]{3,}/, '$1...')}.jpg` - } - return undefined -} - -const getMimeType = (item) => { - return 'image/jpeg' -} - -const getItemId = (item) => { - return `${item.id}` -} - -const getItemRequestPath = (item) => { - return `${item.id}` -} - -const getItemModifiedDate = (item) => { - return item.created_at -} - -const getItemThumbnailUrl = (item) => { - return item.urls.thumb -} - -const getNextPageQuery = (currentQuery) => { - const newCursor = Number.parseInt(currentQuery.cursor || 1, 10) + 1 - const query = { - ...currentQuery, - cursor: newCursor, - } - - delete query.q - return querystring.stringify(query) -} - -const getAuthor = (item) => { - return { name: item.user.name, url: item.user.links.html } -} - -const adaptData = (body, currentQuery) => { - const { total_pages: pagesCount } = body - const { cursor, q } = currentQuery - const currentPage = Number(cursor || 1) - const hasNextPage = currentPage < pagesCount - const subList = getItemSubList(body) || [] - - return { - searchedFor: q, - username: null, - items: subList.map((item) => ({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item), - mimeType: getMimeType(item), - id: getItemId(item), - thumbnail: getItemThumbnailUrl(item), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - author: getAuthor(item), - size: null, - })), - nextPageQuery: hasNextPage ? getNextPageQuery(currentQuery) : null, - } -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/unsplash/adapter.ts b/packages/@uppy/companion/src/server/provider/unsplash/adapter.ts new file mode 100644 index 000000000..0f066838c --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/unsplash/adapter.ts @@ -0,0 +1,128 @@ +import querystring from 'node:querystring' +import type { Query } from '../Provider.js' + +type UnsplashPhoto = { + id: string + created_at?: string + description?: string | null + alt_description?: string | null + urls: { thumb: string } + user: { name: string; links: { html: string } } +} + +type UnsplashSearchResponse = { + total_pages: number + results?: UnsplashPhoto[] +} + +type UnsplashAdaptedItem = { + isFolder: boolean + icon: string + name: string | undefined + mimeType: string + id: string + thumbnail: string + requestPath: string + modifiedDate: string | undefined + author: { name: string; url: string } + size: null +} + +const isFolder = (_item: UnsplashPhoto): boolean => { + return false +} + +const getItemIcon = (item: UnsplashPhoto): string => { + return item.urls.thumb +} + +const getItemSubList = (item: UnsplashSearchResponse): UnsplashPhoto[] => { + return item.results ?? [] +} + +const getItemName = (item: UnsplashPhoto): string | undefined => { + const description = item.description || item.alt_description + if (description) { + return `${description.replace(/^([\S\s]{27})[\S\s]{3,}/, '$1...')}.jpg` + } + return undefined +} + +const getMimeType = (_item: UnsplashPhoto): string => { + return 'image/jpeg' +} + +const getItemId = (item: UnsplashPhoto): string => { + return `${item.id}` +} + +const getItemRequestPath = (item: UnsplashPhoto): string => { + return `${item.id}` +} + +const getItemModifiedDate = (item: UnsplashPhoto): string | undefined => { + return item.created_at +} + +const getItemThumbnailUrl = (item: UnsplashPhoto): string => { + return item.urls.thumb +} + +const getNextPageQuery = (currentQuery: Query | undefined): string => { + const newCursor = + parseInt( + typeof currentQuery?.['cursor'] === 'string' + ? currentQuery['cursor'] + : '1', + 10, + ) + 1 + const query: Query & { q?: string } = { + ...currentQuery, + cursor: String(newCursor), + } + + delete query['q'] + return querystring.stringify(query as Record) +} + +const getAuthor = ( + item: UnsplashPhoto, +): { + name: string + url: string +} => { + return { name: item.user.name, url: item.user.links.html } +} + +const adaptData = ( + body: UnsplashSearchResponse, + currentQuery: Query | undefined, +) => { + const { total_pages: pagesCount } = body + const { cursor, q } = currentQuery! + const currentPage = Number(cursor || 1) + const hasNextPage = currentPage < pagesCount + const subList = getItemSubList(body) || [] + + return { + searchedFor: q, + username: null, + items: subList.map( + (item): UnsplashAdaptedItem => ({ + isFolder: isFolder(item), + icon: getItemIcon(item), + name: getItemName(item), + mimeType: getMimeType(item), + id: getItemId(item), + thumbnail: getItemThumbnailUrl(item), + requestPath: getItemRequestPath(item), + modifiedDate: getItemModifiedDate(item), + author: getAuthor(item), + size: null, + }), + ), + nextPageQuery: hasNextPage ? getNextPageQuery(currentQuery) : null, + } +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/unsplash/index.js b/packages/@uppy/companion/src/server/provider/unsplash/index.js deleted file mode 100644 index ed6f02f2c..000000000 --- a/packages/@uppy/companion/src/server/provider/unsplash/index.js +++ /dev/null @@ -1,80 +0,0 @@ -import got from 'got' -import { prepareStream } from '../../helpers/utils.js' -import { ProviderApiError } from '../error.js' -import Provider from '../Provider.js' -import { withProviderErrorHandling } from '../providerErrors.js' -import adaptData from './adapter.js' - -const BASE_URL = 'https://api.unsplash.com' - -const getClient = ({ token }) => - got.extend({ - prefixUrl: BASE_URL, - headers: { - authorization: `Client-ID ${token}`, - }, - }) - -const getPhotoMeta = async (client, id) => - client.get(`photos/${id}`, { responseType: 'json' }).json() - -/** - * Adapter for API https://api.unsplash.com - */ -export default class Unsplash extends Provider { - async list({ - providerUserSession: { accessToken: token }, - query = { cursor: null, q: null }, - }) { - if (typeof query.q !== 'string') { - throw new ProviderApiError('Search query missing', 400) - } - - return this.#withErrorHandling('provider.unsplash.list.error', async () => { - const qs = { per_page: 40, query: query.q } - if (query.cursor) qs.page = query.cursor - - const response = await getClient({ token }) - .get('search/photos', { searchParams: qs, responseType: 'json' }) - .json() - return adaptData(response, query) - }) - } - - async download({ id, providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling( - 'provider.unsplash.download.error', - async () => { - const client = getClient({ token }) - - const { - links: { download: url, download_location: attributionUrl }, - } = await getPhotoMeta(client, id) - - const stream = got.stream.get(url, { responseType: 'json' }) - const { size } = await prepareStream(stream) - - // To attribute the author of the image, we call the `download_location` - // endpoint to increment the download count on Unsplash. - // https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download - await client.get(attributionUrl, { - prefixUrl: '', - responseType: 'json', - }) - - // finally, stream on! - return { stream, size } - }, - ) - } - - async #withErrorHandling(tag, fn) { - // @ts-ignore - return withProviderErrorHandling({ - fn, - tag, - providerName: 'Unsplash', - getJsonErrorMessage: (body) => body?.errors && String(body.errors), - }) - } -} diff --git a/packages/@uppy/companion/src/server/provider/unsplash/index.ts b/packages/@uppy/companion/src/server/provider/unsplash/index.ts new file mode 100644 index 000000000..30f828beb --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/unsplash/index.ts @@ -0,0 +1,113 @@ +import type { Readable } from 'node:stream' +import got from 'got' +import { isRecord } from '../../helpers/type-guards.js' +import { prepareStream } from '../../helpers/utils.js' +import { ProviderApiError } from '../error.js' +import Provider, { type ProviderListResponse, type Query } from '../Provider.js' +import { withProviderErrorHandling } from '../providerErrors.js' +import adaptData from './adapter.js' + +const BASE_URL = 'https://api.unsplash.com' + +type UnsplashClient = ReturnType + +const getClient = ({ token }: { token: string }): UnsplashClient => + got.extend({ + prefixUrl: BASE_URL, + headers: { + authorization: `Client-ID ${token}`, + }, + }) + +const getPhotoMeta = async (client: UnsplashClient, id: string) => + client + .get(`photos/${id}`, { responseType: 'json' }) + .json<{ links: { download?: string; download_location?: string } }>() + +interface UnsplashUserSession { + accessToken: string +} + +/** + * Adapter for API https://api.unsplash.com + */ +export default class Unsplash extends Provider { + override async list({ + providerUserSession: { accessToken: token }, + query, + }: { + providerUserSession: UnsplashUserSession + query?: Query | undefined + }): Promise { + const q = typeof query?.['q'] === 'string' ? query['q'] : undefined + if (!q) { + throw new ProviderApiError('Search query missing', 400) + } + + return this.#withErrorHandling('provider.unsplash.list.error', async () => { + const qs = new URLSearchParams({ per_page: '40', query: q }) + if (typeof query?.['cursor'] === 'string') { + qs.set('page', query['cursor']) + } + + const response = await getClient({ token }) + .get('search/photos', { searchParams: qs, responseType: 'json' }) + .json[0]>() + return adaptData(response, query) + }) + } + + override async download({ + id, + providerUserSession: { accessToken: token }, + }: { + id: string + providerUserSession: UnsplashUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.#withErrorHandling( + 'provider.unsplash.download.error', + async () => { + const client = getClient({ token }) + + const { + links: { download: url, download_location: attributionUrl }, + } = await getPhotoMeta(client, id) + + if (!url || !attributionUrl) { + throw new Error( + 'Unexpected Unsplash response: missing download links', + ) + } + + const stream = got.stream.get(url, { responseType: 'json' }) + const { size } = await prepareStream(stream) + + // To attribute the author of the image, we call the `download_location` + // endpoint to increment the download count on Unsplash. + // https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download + await client.get(attributionUrl, { + prefixUrl: '', + responseType: 'json', + }) + + // finally, stream on! + return { stream, size } + }, + ) + } + + async #withErrorHandling(tag: string, fn: () => Promise): Promise { + return withProviderErrorHandling({ + fn, + tag, + providerName: 'Unsplash', + getJsonErrorMessage: (body) => { + if (!isRecord(body)) return undefined + const errors = body['errors'] + if (typeof errors === 'string') return errors + if (Array.isArray(errors)) return errors.map(String).join(', ') + return undefined + }, + }) + } +} diff --git a/packages/@uppy/companion/src/server/provider/webdav/index.js b/packages/@uppy/companion/src/server/provider/webdav/index.js deleted file mode 100644 index 391ec6f51..000000000 --- a/packages/@uppy/companion/src/server/provider/webdav/index.js +++ /dev/null @@ -1,180 +0,0 @@ -import { AuthType, createClient } from 'webdav' -import { getProtectedHttpAgent, validateURL } from '../../helpers/request.js' -import logger from '../../logger.js' -import { - ProviderApiError, - ProviderAuthError, - ProviderUserError, -} from '../error.js' -import Provider from '../Provider.js' - -const defaultDirectory = '/' - -/** - * Adapter for WebDAV servers that support simple auth (non-OAuth). - */ -export default class WebdavProvider extends Provider { - static get hasSimpleAuth() { - return true - } - - isAuthenticated({ providerUserSession }) { - return providerUserSession.webdavUrl != null - } - - async getClient({ providerUserSession }) { - const webdavUrl = providerUserSession?.webdavUrl - const { allowLocalUrls } = this - if (!validateURL(webdavUrl, allowLocalUrls)) { - throw new Error('invalid public link url') - } - - // Is this an ownCloud or Nextcloud public link URL? e.g. https://example.com/s/kFy9Lek5sm928xP - // they have specific urls that we can identify - // todo not sure if this is the right way to support nextcloud and other webdavs - if (/\/s\/([^/]+)/.test(webdavUrl)) { - const [baseURL, publicLinkToken] = webdavUrl.split('/s/') - - return this.getClientHelper({ - url: `${baseURL.replace('/index.php', '')}/public.php/webdav/`, - authType: AuthType.Password, - username: publicLinkToken, - password: 'null', - }) - } - - // normal public WebDAV urls - return this.getClientHelper({ - url: webdavUrl, - authType: AuthType.None, - }) - } - - async logout() { - return { revoked: true } - } - - async simpleAuth({ requestBody }) { - try { - const providerUserSession = { webdavUrl: requestBody.form.webdavUrl } - - const client = await this.getClient({ providerUserSession }) - // call the list operation as a way to validate the url - await client.getDirectoryContents(defaultDirectory) - - return providerUserSession - } catch (err) { - logger.error(err, 'provider.webdav.error') - if (['ECONNREFUSED', 'ENOTFOUND'].includes(err.code)) { - throw new ProviderUserError({ message: 'Cannot connect to server' }) - } - throw err - } - } - - async getClientHelper({ url, ...options }) { - const { allowLocalUrls } = this - if (!validateURL(url, allowLocalUrls)) { - throw new Error('invalid webdav url') - } - const { protocol } = new URL(url) - const HttpAgentClass = getProtectedHttpAgent({ - protocol, - allowLocalIPs: !allowLocalUrls, - }) - - return createClient(url, { - ...options, - [`${protocol}Agent`]: new HttpAgentClass(), - }) - } - - async list({ directory, providerUserSession }) { - return this.withErrorHandling('provider.webdav.list.error', async () => { - // @ts-ignore - if (!this.isAuthenticated({ providerUserSession })) { - throw new ProviderAuthError() - } - - const data = { items: [] } - const client = await this.getClient({ providerUserSession }) - - /** @type {any} */ - const dir = await client.getDirectoryContents(directory || '/') - - dir.forEach((item) => { - const isFolder = item.type === 'directory' - const requestPath = encodeURIComponent( - `${directory || ''}/${item.basename}`, - ) - - let modifiedDate - try { - modifiedDate = new Date(item.lastmod).toISOString() - } catch (_e) { - // ignore invalid date from server - } - - // Determine icon based on type and MIME type - let icon = 'file' - if (isFolder) { - icon = 'folder' - } else if (item.mime?.startsWith('video/')) { - icon = 'video' - } - - data.items.push({ - isFolder, - icon, - id: requestPath, - name: item.basename, - modifiedDate, - requestPath, - ...(!isFolder && { - mimeType: item.mime, - size: item.size, - thumbnail: null, - }), - }) - }) - - return data - }) - } - - async download({ id, providerUserSession }) { - return this.withErrorHandling( - 'provider.webdav.download.error', - async () => { - const client = await this.getClient({ providerUserSession }) - /** @type {any} */ - const stat = await client.stat(id) - const stream = client.createReadStream(`/${id}`) - return { stream, size: stat.size } - }, - ) - } - - async thumbnail({ id, providerUserSession }) { - // not implementing this because a public thumbnail from webdav will be used instead - logger.error( - 'call to thumbnail is not implemented', - 'provider.webdav.thumbnail.error', - ) - throw new Error('call to thumbnail is not implemented') - } - - async withErrorHandling(tag, fn) { - try { - return await fn() - } catch (err) { - let err2 = err - if (err.status === 401) err2 = new ProviderAuthError() - if (err.response) { - err2 = new ProviderApiError('WebDAV API error', err.status) - } - logger.error(err2, tag) - throw err2 - } - } -} diff --git a/packages/@uppy/companion/src/server/provider/webdav/index.ts b/packages/@uppy/companion/src/server/provider/webdav/index.ts new file mode 100644 index 000000000..e8ec83416 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/webdav/index.ts @@ -0,0 +1,263 @@ +import type { Readable } from 'node:stream' +import type { WebDAVClientOptions } from 'webdav' +import { AuthType, createClient } from 'webdav' +import { getProtectedHttpAgent, validateURL } from '../../helpers/request.js' +import { isRecord } from '../../helpers/type-guards.js' +import logger from '../../logger.js' +import { + ProviderApiError, + ProviderAuthError, + ProviderUserError, +} from '../error.js' +import Provider, { type Query } from '../Provider.js' + +const defaultDirectory = '/' + +type WebdavUserSession = { webdavUrl?: string } +type WebdavClient = ReturnType + +type WebdavListItem = { + isFolder: boolean + icon: string + id: string + name: string + modifiedDate?: string + requestPath: string + mimeType?: string + size?: number + thumbnail?: null +} + +/** + * Adapter for WebDAV servers that support simple auth (non-OAuth). + */ +export default class WebdavProvider extends Provider { + static override get hasSimpleAuth() { + return true + } + + isAuthenticated({ + providerUserSession, + }: { + providerUserSession: WebdavUserSession + }): boolean { + return providerUserSession.webdavUrl != null + } + + async getClient({ + providerUserSession, + }: { + providerUserSession: WebdavUserSession + }): Promise { + const webdavUrl = providerUserSession?.webdavUrl + const { allowLocalUrls } = this + if ( + webdavUrl == null || + webdavUrl.length === 0 || + !validateURL(webdavUrl, allowLocalUrls) + ) { + throw new Error('invalid public link url') + } + + // Is this an ownCloud or Nextcloud public link URL? e.g. https://example.com/s/kFy9Lek5sm928xP + // they have specific urls that we can identify + // todo not sure if this is the right way to support nextcloud and other webdavs + if (/\/s\/([^/]+)/.test(webdavUrl)) { + const [baseURL, publicLinkToken] = webdavUrl.split('/s/') + if (!baseURL) { + throw new Error('invalid public link url') + } + + return this.getClientHelper({ + url: `${baseURL.replace('/index.php', '')}/public.php/webdav/`, + authType: AuthType.Password, + username: publicLinkToken!, + password: 'null', + }) + } + + // normal public WebDAV urls + return this.getClientHelper({ + url: webdavUrl, + authType: AuthType.None, + }) + } + + override async logout(): Promise<{ revoked: true }> { + return { revoked: true } + } + + override async simpleAuth({ + requestBody, + }: { + requestBody: unknown + }): Promise { + try { + if (!isRecord(requestBody) || !isRecord(requestBody['form'])) { + throw new Error('Invalid request body') + } + const webdavUrl = requestBody['form']['webdavUrl'] + if (typeof webdavUrl !== 'string' || webdavUrl.length === 0) { + throw new Error('Missing webdavUrl') + } + + const providerUserSession: WebdavUserSession = { webdavUrl } + + const client = await this.getClient({ providerUserSession }) + // call the list operation as a way to validate the url + await client.getDirectoryContents(defaultDirectory) + + return providerUserSession + } catch (err) { + const errForLog = err instanceof Error ? err : new Error(String(err)) + logger.error(errForLog, 'provider.webdav.error') + const code = isRecord(err) ? err['code'] : undefined + if ( + typeof code === 'string' && + ['ECONNREFUSED', 'ENOTFOUND'].includes(code) + ) { + throw new ProviderUserError({ message: 'Cannot connect to server' }) + } + throw err + } + } + + async getClientHelper({ + url, + ...options + }: { url: string } & WebDAVClientOptions): Promise { + const { allowLocalUrls } = this + if (!validateURL(url, allowLocalUrls)) { + throw new Error('invalid webdav url') + } + const { protocol } = new URL(url) + const HttpAgentClass = getProtectedHttpAgent({ + protocol, + allowLocalIPs: !allowLocalUrls, + }) + + return createClient(url, { + ...options, + [`${protocol}Agent`]: new HttpAgentClass(), + }) + } + + override async list({ + providerUserSession, + query, + directory, + }: { + providerUserSession: WebdavUserSession + query?: Query | undefined + directory?: string | undefined + }): Promise<{ items: WebdavListItem[] }> { + return this.withErrorHandling('provider.webdav.list.error', async () => { + if (!this.isAuthenticated({ providerUserSession })) { + throw new ProviderAuthError() + } + + const data: { items: WebdavListItem[] } = { items: [] } + const client = await this.getClient({ providerUserSession }) + + const dirResult = await client.getDirectoryContents( + (typeof query?.['directory'] === 'string' + ? query?.['directory'] + : undefined) || '/', + ) + const dir = Array.isArray(dirResult) ? dirResult : dirResult.data + + dir.forEach((item) => { + const isFolder = item.type === 'directory' + const requestPath = encodeURIComponent( + `${directory || ''}/${item.basename}`, + ) + + let modifiedDate: string | undefined + try { + modifiedDate = new Date(item.lastmod).toISOString() + } catch (_e) { + // ignore invalid date from server + } + + // Determine icon based on type and MIME type + let icon = 'file' + if (isFolder) { + icon = 'folder' + } else if (item.mime?.startsWith('video/')) { + icon = 'video' + } + + const listItem: WebdavListItem = { + isFolder, + icon, + id: requestPath, + name: item.basename, + requestPath, + ...(modifiedDate && { modifiedDate }), + ...(!isFolder && { + ...(item.mime != null && { mimeType: item.mime }), + ...(item.size != null && { size: item.size }), + thumbnail: null, + }), + } + data.items.push(listItem) + }) + + return data + }) + } + + override async download({ + id, + providerUserSession, + }: { + id: string + providerUserSession: WebdavUserSession + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.withErrorHandling( + 'provider.webdav.download.error', + async () => { + const client = await this.getClient({ providerUserSession }) + const statResult = await client.stat(id) + const stat = 'data' in statResult ? statResult.data : statResult + const stream = client.createReadStream(`/${id}`) + return { stream, size: stat.size } + }, + ) + } + + override async thumbnail({ + id, + providerUserSession, + }: { + id: string + providerUserSession: WebdavUserSession + }): Promise { + // not implementing this because a public thumbnail from webdav will be used instead + logger.error( + 'call to thumbnail is not implemented', + 'provider.webdav.thumbnail.error', + ) + throw new Error('call to thumbnail is not implemented') + } + + async withErrorHandling(tag: string, fn: () => Promise): Promise { + try { + return await fn() + } catch (err: unknown) { + let err2: unknown = err + const status = isRecord(err) ? err['status'] : undefined + if (status === 401) err2 = new ProviderAuthError() + const response = isRecord(err) ? err['response'] : undefined + if (response != null) { + err2 = new ProviderApiError( + 'WebDAV API error', + typeof status === 'number' ? status : undefined, + ) + } + const errForLog = err2 instanceof Error ? err2 : new Error(String(err2)) + logger.error(errForLog, tag) + throw err2 + } + } +} diff --git a/packages/@uppy/companion/src/server/provider/zoom/adapter.js b/packages/@uppy/companion/src/server/provider/zoom/adapter.js deleted file mode 100644 index bf9671a50..000000000 --- a/packages/@uppy/companion/src/server/provider/zoom/adapter.js +++ /dev/null @@ -1,166 +0,0 @@ -import moment from 'moment-timezone' - -const MIMETYPES = { - MP4: 'video/mp4', - M4A: 'audio/mp4', - CHAT: 'text/plain', - TRANSCRIPT: 'text/vtt', - CC: 'text/vtt', - TIMELINE: 'application/json', -} -const EXT = { - MP4: 'mp4', - M4A: 'm4a', - CHAT: 'txt', - TRANSCRIPT: 'vtt', - CC: 'vtt', - TIMELINE: 'json', -} -const ICONS = { - MP4: 'video', - M4A: 'file', - CHAT: 'file', - TRANSCRIPT: 'file', - CC: 'file', - FOLDER: 'folder', - TIMELINE: 'file', -} - -const getUserEmail = (results) => { - return results.email -} - -// we rely on the file_type attribute to differentiate a recording file from other items -const getIsFolder = (item) => { - return !item.file_type -} - -const getItemName = (item, userResponse) => { - const start = moment - .tz(item.start_time || item.recording_start, userResponse.timezone || 'UTC') - .format('YYYY-MM-DD, HH:mm') - - if (item.file_type) { - const ext = EXT[item.file_type] ? `.${EXT[item.file_type]}` : '' - const itemType = item.recording_type - ? ` - ${item.recording_type.split('_').join(' ')}` - : '' - return `${item.topic}${itemType} (${start})${ext}` - } - - return `${item.topic} (${start})` -} - -const getIcon = (item) => { - if (item.file_type) { - return ICONS[item.file_type] - } - return ICONS.FOLDER -} - -const getMimeType = (item) => { - if (item.file_type) { - return MIMETYPES[item.file_type] - } - return null -} - -const getId = (item) => { - if (item.file_type && item.file_type === 'CC') { - return `${encodeURIComponent(item.meeting_id)}__CC__${encodeURIComponent(item.recording_start)}` - } - if (item.file_type) { - return `${encodeURIComponent(item.meeting_id)}__${encodeURIComponent(item.id)}` - } - return `${encodeURIComponent(item.uuid)}` -} - -const getRequestPath = (item) => { - if (item.file_type && item.file_type === 'CC') { - return `${encodeURIComponent(item.meeting_id)}?recordingId=CC&recordingStart=${encodeURIComponent(item.recording_start)}` - } - if (item.file_type) { - return `${encodeURIComponent(item.meeting_id)}?recordingId=${encodeURIComponent(item.id)}` - } - // Zoom meeting ids are reused so we need to use the UUID. Also, these UUIDs can contain `/` characters which require - // double encoding (see https://devforum.zoom.us/t/double-encode-meeting-uuids/23729). - return `${encodeURIComponent(encodeURIComponent(item.uuid))}` -} - -const getStartDate = (item) => { - if (item.file_type === 'CC') { - return item.recording_start - } - return item.start_time -} - -const getSize = (item) => { - if (item.file_type && item.file_type === 'CC') { - const maxExportFileSize = 1024 * 1024 - return maxExportFileSize - } - if (item.file_type) { - return item.file_size - } - return item.total_size -} - -const getItemTopic = (item) => { - return item.topic -} - -const adaptData = (userResponse, results) => { - if (!results) { - return { items: [] } - } - - const data = { - nextPagePath: null, - items: [], - username: getUserEmail(userResponse), - } - - let itemsToProcess = [] - if (results.meetings) { - itemsToProcess = results.meetings.filter((meeting) => - meeting.recording_files?.some( - (file) => - !file.deleted_time && - file.status === 'completed' && - file.download_url, - ), - ) - } else if (results.recording_files) { - itemsToProcess = results.recording_files - .map((item) => { - return { ...item, topic: results.topic } - }) - .filter( - (file) => - file.file_type !== 'TIMELINE' && - !file.deleted_time && - file.status === 'completed' && - file.download_url, - ) - } - - itemsToProcess.forEach((item) => { - data.items.push({ - isFolder: getIsFolder(item), - icon: getIcon(item), - name: getItemName(item, userResponse), - mimeType: getMimeType(item), - id: getId(item), - thumbnail: null, - requestPath: getRequestPath(item), - modifiedDate: getStartDate(item), - size: getSize(item), - custom: { - topic: getItemTopic(item), - }, - }) - }) - return data -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/zoom/adapter.ts b/packages/@uppy/companion/src/server/provider/zoom/adapter.ts new file mode 100644 index 000000000..b7de21ffc --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/zoom/adapter.ts @@ -0,0 +1,287 @@ +import moment from 'moment-timezone' +import { isRecord } from '../../helpers/type-guards.js' + +const MIMETYPES = { + MP4: 'video/mp4', + M4A: 'audio/mp4', + CHAT: 'text/plain', + TRANSCRIPT: 'text/vtt', + CC: 'text/vtt', + TIMELINE: 'application/json', +} +const EXT = { + MP4: 'mp4', + M4A: 'm4a', + CHAT: 'txt', + TRANSCRIPT: 'vtt', + CC: 'vtt', + TIMELINE: 'json', +} +const ICONS = { + MP4: 'video', + M4A: 'file', + CHAT: 'file', + TRANSCRIPT: 'file', + CC: 'file', + FOLDER: 'folder', + TIMELINE: 'file', +} + +type ZoomFileType = keyof typeof MIMETYPES + +type ZoomUserResponse = { + email?: string + timezone?: string +} + +type ZoomItem = { + topic: string + uuid?: string + meeting_id?: string + start_time?: string + file_type?: ZoomFileType + id?: string + recording_start?: string + recording_type?: string + file_size?: number + total_size?: number + deleted_time?: string + status?: string + download_url?: string +} + +type ZoomRecordingFile = ZoomItem & { + file_type: ZoomFileType + id: string + meeting_id: string + recording_start: string +} + +type ZoomMeeting = ZoomItem & { + uuid: string + meeting_id: string + topic: string + recording_files?: ZoomRecordingFile[] +} + +type ZoomAdaptedItem = { + isFolder: boolean + icon: string + name: string + mimeType: string | null + id: string + thumbnail: null + requestPath: string + modifiedDate: string | undefined + size: number | undefined + custom: { topic: string } +} + +const getUserEmail = (results: ZoomUserResponse): string | undefined => { + return results.email +} + +// we rely on the file_type attribute to differentiate a recording file from other items +const getIsFolder = (item: ZoomItem): boolean => { + return !item.file_type +} + +const getItemName = ( + item: ZoomItem, + userResponse: ZoomUserResponse, +): string => { + const timestamp = item.start_time || item.recording_start + const start = moment + .tz(timestamp, userResponse.timezone || 'UTC') + .format('YYYY-MM-DD, HH:mm') + + if (item.file_type) { + const ext = Object.hasOwn(EXT, item.file_type) + ? `.${EXT[item.file_type]}` + : '' + const itemType = + 'recording_type' in item && item.recording_type + ? ` - ${item.recording_type.split('_').join(' ')}` + : '' + return `${item.topic}${itemType} (${start})${ext}` + } + + return `${item.topic} (${start})` +} + +const getIcon = (item: ZoomItem) => { + if (item.file_type) { + return ICONS[item.file_type] + } + return ICONS.FOLDER +} + +const getMimeType = (item: ZoomItem) => { + if (item.file_type) { + return MIMETYPES[item.file_type] + } + return null +} + +const getId = (item: ZoomItem): string => { + if (item.file_type && item.file_type === 'CC') { + return `${encodeURIComponent(String(item.meeting_id))}__CC__${encodeURIComponent(String(item.recording_start))}` + } + if (item.file_type) { + return `${encodeURIComponent(String(item.meeting_id))}__${encodeURIComponent(String(item.id))}` + } + return `${encodeURIComponent(String(item.uuid))}` +} + +const getRequestPath = (item: ZoomItem): string => { + if (item.file_type && item.file_type === 'CC') { + return `${encodeURIComponent(String(item.meeting_id))}?recordingId=CC&recordingStart=${encodeURIComponent(String(item.recording_start))}` + } + if (item.file_type) { + return `${encodeURIComponent(String(item.meeting_id))}?recordingId=${encodeURIComponent(String(item.id))}` + } + // Zoom meeting ids are reused so we need to use the UUID. Also, these UUIDs can contain `/` characters which require + // double encoding (see https://devforum.zoom.us/t/double-encode-meeting-uuids/23729). + return `${encodeURIComponent(encodeURIComponent(String(item.uuid)))}` +} + +const getStartDate = (item: ZoomItem): string | undefined => { + if (item.file_type === 'CC') { + return item.recording_start + } + return item.start_time +} + +const getSize = (item: ZoomItem): number | undefined => { + if (item.file_type && item.file_type === 'CC') { + const maxExportFileSize = 1024 * 1024 + return maxExportFileSize + } + if (item.file_type) { + return item.file_size + } + return item.total_size +} + +const getItemTopic = (item: ZoomItem): string => { + return item.topic +} + +function isZoomRecordingFile(value: unknown): value is ZoomRecordingFile { + if (!isRecord(value)) return false + const fileType = value['file_type'] + if (typeof fileType !== 'string') return false + if (!Object.hasOwn(MIMETYPES, fileType)) return false + return ( + typeof value['id'] === 'string' && + typeof value['meeting_id'] === 'string' && + typeof value['recording_start'] === 'string' + ) +} + +function toZoomMeeting(value: unknown): ZoomMeeting | null { + if (!isRecord(value)) return null + const uuid = value['uuid'] + const meetingId = value['meeting_id'] + const topic = value['topic'] + if (typeof uuid !== 'string') return null + if (typeof meetingId !== 'string') return null + if (typeof topic !== 'string') return null + + const startTime = value['start_time'] + const totalSize = value['total_size'] + const recordingFilesValue = value['recording_files'] + const recordingFiles: ZoomRecordingFile[] = Array.isArray(recordingFilesValue) + ? recordingFilesValue.filter(isZoomRecordingFile) + : [] + + const out: ZoomMeeting = { + uuid, + meeting_id: meetingId, + topic, + recording_files: recordingFiles, + } + if (typeof startTime === 'string') out.start_time = startTime + if (typeof totalSize === 'number') out.total_size = totalSize + return out +} + +const adaptData = ( + userResponse: ZoomUserResponse, + results: unknown, +): + | { + nextPagePath: null + items: ZoomAdaptedItem[] + username: string | undefined + } + | { items: [] } => { + if (!results || !isRecord(results)) { + return { items: [] } + } + + const data: { + nextPagePath: null + items: ZoomAdaptedItem[] + username: string | undefined + } = { + nextPagePath: null, + items: [], + username: getUserEmail(userResponse), + } + + let itemsToProcess: ZoomItem[] = [] + const meetingsValue = results['meetings'] + const recordingFilesValue = results['recording_files'] + + if (Array.isArray(meetingsValue)) { + itemsToProcess = meetingsValue + .map(toZoomMeeting) + .filter((meeting): meeting is ZoomMeeting => meeting != null) + .filter((meeting) => + meeting.recording_files?.some( + (file) => + !file.deleted_time && + file.status === 'completed' && + typeof file.download_url === 'string' && + file.download_url.length > 0, + ), + ) + } else if ( + Array.isArray(recordingFilesValue) && + typeof results['topic'] === 'string' + ) { + const topic = results['topic'] + itemsToProcess = recordingFilesValue + .filter(isZoomRecordingFile) + .map((item) => ({ ...item, topic })) + .filter( + (file) => + file.file_type !== 'TIMELINE' && + !file.deleted_time && + file.status === 'completed' && + file.download_url != null && + file.download_url.length > 0, + ) + } + + itemsToProcess.forEach((item) => { + data.items.push({ + isFolder: getIsFolder(item), + icon: getIcon(item), + name: getItemName(item, userResponse), + mimeType: getMimeType(item), + id: getId(item), + thumbnail: null, + requestPath: getRequestPath(item), + modifiedDate: getStartDate(item), + size: getSize(item), + custom: { + topic: getItemTopic(item), + }, + }) + }) + return data +} + +export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/zoom/index.js b/packages/@uppy/companion/src/server/provider/zoom/index.js deleted file mode 100644 index a72f6b253..000000000 --- a/packages/@uppy/companion/src/server/provider/zoom/index.js +++ /dev/null @@ -1,251 +0,0 @@ -import got from 'got' -import moment from 'moment-timezone' -import pMap from 'p-map' -import { getBasicAuthHeader, prepareStream } from '../../helpers/utils.js' -import Provider from '../Provider.js' -import { withProviderErrorHandling } from '../providerErrors.js' -import adaptData from './adapter.js' - -const BASE_URL = 'https://zoom.us/v2' -const PAGE_SIZE = 300 -const DEAUTH_EVENT_NAME = 'app_deauthorized' - -const getClient = ({ token }) => - got.extend({ - prefixUrl: BASE_URL, - headers: { - authorization: `Bearer ${token}`, - }, - }) - -async function findFile({ client, meetingId, fileId, recordingStart }) { - const { recording_files: files } = await client - .get(`meetings/${encodeURIComponent(meetingId)}/recordings`, { - responseType: 'json', - }) - .json() - - return files.find( - (file) => - fileId === file.id || - (file.file_type === fileId && file.recording_start === recordingStart), - ) -} - -/** - * Adapter for API https://marketplace.zoom.us/docs/api-reference/zoom-api - */ -export default class Zoom extends Provider { - static get oauthProvider() { - return 'zoom' - } - - async list(options) { - return this.#withErrorHandling('provider.zoom.list.error', async () => { - const { - providerUserSession: { accessToken: token }, - } = options - const query = options.query || {} - const meetingId = options.directory || '' - const requestedYear = query.year ? parseInt(query.year, 10) : null - - const client = getClient({ token }) - const user = await client.get('users/me', { responseType: 'json' }).json() - const { timezone } = user - const userTz = timezone || 'UTC' - - if (meetingId) { - const recordingInfo = await client - .get(`meetings/${encodeURIComponent(meetingId)}/recordings`, { - responseType: 'json', - }) - .json() - return adaptData(user, recordingInfo) - } - - if (requestedYear) { - const now = moment.tz(userTz) - const numMonths = - now.get('year') === requestedYear ? now.get('month') + 1 : 12 - const monthsToCheck = Array.from({ length: numMonths }, (_, i) => i) // in moment, months are 0-indexed - - // Run each month in parallel: - const allMeetingsInYear = ( - await pMap( - monthsToCheck, - async (month) => { - const startDate = moment - .tz({ year: requestedYear, month, day: 1 }, userTz) - .startOf('month') - const endDate = startDate.clone().endOf('month') - - const searchParams = { - page_size: PAGE_SIZE, - from: startDate.clone().tz('UTC').format('YYYY-MM-DD'), - to: endDate.clone().tz('UTC').format('YYYY-MM-DD'), - } - - const paginatedMeetings = [] - do { - const currentChunkMeetingsInfo = await client - .get('users/me/recordings', { - searchParams, - responseType: 'json', - }) - .json() - paginatedMeetings.push( - ...(currentChunkMeetingsInfo.meetings ?? []), - ) - searchParams.next_page_token = - currentChunkMeetingsInfo.next_page_token - } while (searchParams.next_page_token) - - return paginatedMeetings - }, - { concurrency: 3 }, - ) - ).flat() // this is effectively a flatMap - // concurrency 3 seems like a sensible number... - - const finalResult = { meetings: allMeetingsInYear } - return adaptData(user, finalResult) - } - - const accountCreationDate = moment.utc(user.created_at) - const startYear = accountCreationDate.year() - const currentYear = moment.tz(userTz).year() - const years = [] - - for (let year = currentYear; year >= startYear; year--) { - years.push({ - isFolder: true, - icon: 'folder', - name: `${year}`, - mimeType: null, - id: `${year}`, - thumbnail: null, - requestPath: `?year=${year}`, - modifiedDate: `${year}-12-31`, // Representative date - size: null, - }) - } - - return { - username: user.email, - items: years, - nextPagePath: null, - } - }) - } - - async download({ - id: meetingId, - providerUserSession: { accessToken: token }, - query, - }) { - return this.#withErrorHandling('provider.zoom.download.error', async () => { - // meeting id + file id required - // cc files don't have an ID or size - const { recordingStart, recordingId: fileId } = query - - const client = getClient({ token }) - - const foundFile = await findFile({ - client, - meetingId, - fileId, - recordingStart, - }) - const url = foundFile?.download_url - if (!url) throw new Error('Download URL not found') - - const stream = client.stream.get(`${url}?access_token=${token}`, { - prefixUrl: '', - responseType: 'json', - }) - const { size } = await prepareStream(stream) - return { stream, size } - }) - } - - async size({ - id: meetingId, - providerUserSession: { accessToken: token }, - query, - }) { - return this.#withErrorHandling('provider.zoom.size.error', async () => { - const client = getClient({ token }) - const { recordingStart, recordingId: fileId } = query - - const foundFile = await findFile({ - client, - meetingId, - fileId, - recordingStart, - }) - if (!foundFile) throw new Error('File not found') - return foundFile.file_size // Note: May be undefined. - }) - } - - async logout({ companion, providerUserSession: { accessToken: token } }) { - return this.#withErrorHandling('provider.zoom.logout.error', async () => { - const { key, secret } = await companion.getProviderCredentials() - - const { status } = await got - .post('https://zoom.us/oauth/revoke', { - searchParams: { token }, - headers: { Authorization: getBasicAuthHeader(key, secret) }, - responseType: 'json', - }) - .json() - - return { revoked: status === 'success' } - }) - } - - async deauthorizationCallback({ companion, body, headers }) { - return this.#withErrorHandling('provider.zoom.deauth.error', async () => { - if (!body || body.event !== DEAUTH_EVENT_NAME) { - return { data: {}, status: 400 } - } - - const { verificationToken, key, secret } = - await companion.getProviderCredentials() - - const tokenSupplied = headers.authorization - if (!tokenSupplied || verificationToken !== tokenSupplied) { - return { data: {}, status: 400 } - } - - await got.post('https://api.zoom.us/oauth/data/compliance', { - headers: { Authorization: getBasicAuthHeader(key, secret) }, - json: { - client_id: key, - user_id: body.payload.user_id, - account_id: body.payload.account_id, - deauthorization_event_received: body.payload, - compliance_completed: true, - }, - responseType: 'json', - }) - - return {} - }) - } - - async #withErrorHandling(tag, fn) { - const authErrorCodes = [ - 124, // expired token - 401, - ] - - return withProviderErrorHandling({ - fn, - tag, - providerName: Zoom.oauthProvider, - isAuthError: (response) => authErrorCodes.includes(response.statusCode), - getJsonErrorMessage: (body) => body?.message, - }) - } -} diff --git a/packages/@uppy/companion/src/server/provider/zoom/index.ts b/packages/@uppy/companion/src/server/provider/zoom/index.ts new file mode 100644 index 000000000..13e34b398 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/zoom/index.ts @@ -0,0 +1,418 @@ +import type { Readable } from 'node:stream' +import got from 'got' +import moment from 'moment-timezone' +import pMap from 'p-map' +import { isRecord } from '../../helpers/type-guards.js' +import { getBasicAuthHeader, prepareStream } from '../../helpers/utils.js' +import Provider, { + type CompanionLike, + type ProviderListResponse, + type Query, +} from '../Provider.js' +import { withProviderErrorHandling } from '../providerErrors.js' +import adaptData from './adapter.js' + +const BASE_URL = 'https://zoom.us/v2' +const PAGE_SIZE = 300 +const DEAUTH_EVENT_NAME = 'app_deauthorized' + +type ZoomClient = ReturnType + +const getClient = ({ token }: { token: string }): ZoomClient => + got.extend({ + prefixUrl: BASE_URL, + headers: { + authorization: `Bearer ${token}`, + }, + }) + +type ZoomFoundFile = { + download_url?: string + file_size?: number + id?: string + file_type?: string + recording_start?: string +} + +async function findFile({ + client, + meetingId, + fileId, + recordingStart, +}: { + client: ZoomClient + meetingId: string + fileId: string + recordingStart?: string +}): Promise { + const body: unknown = await client + .get(`meetings/${encodeURIComponent(meetingId)}/recordings`, { + responseType: 'json', + }) + .json() + + const filesValue = isRecord(body) ? body['recording_files'] : undefined + const files = Array.isArray(filesValue) ? filesValue : [] + + for (const file of files) { + if (!isRecord(file)) continue + const id = typeof file['id'] === 'string' ? file['id'] : undefined + const fileType = + typeof file['file_type'] === 'string' ? file['file_type'] : undefined + const fileRecStart = + typeof file['recording_start'] === 'string' + ? file['recording_start'] + : undefined + + const matches = + (id != null && fileId === id) || + (fileType != null && + file['file_type'] === fileId && + fileRecStart != null && + fileRecStart === recordingStart) + + if (!matches) continue + + const found: ZoomFoundFile = {} + const downloadUrl = + typeof file['download_url'] === 'string' + ? file['download_url'] + : undefined + const fileSize = + typeof file['file_size'] === 'number' ? file['file_size'] : undefined + if (downloadUrl) found.download_url = downloadUrl + if (typeof fileSize === 'number') found.file_size = fileSize + if (id) found.id = id + if (fileType) found.file_type = fileType + if (fileRecStart) found.recording_start = fileRecStart + return found + } + + return undefined +} + +interface ZoomUserSession { + accessToken: string +} + +/** + * Adapter for API https://marketplace.zoom.us/docs/api-reference/zoom-api + */ +export default class Zoom extends Provider { + static override get oauthProvider() { + return 'zoom' + } + + override async list(options: { + providerUserSession: ZoomUserSession + query?: { cursor?: string | null } & Record + directory?: string | undefined + }): Promise { + return this.#withErrorHandling('provider.zoom.list.error', async () => { + const { + providerUserSession: { accessToken: token }, + } = options + const query = options.query ?? {} + const meetingId = options.directory ?? '' + const requestedYear = + typeof query['year'] === 'string' ? parseInt(query['year'], 10) : null + + const client = getClient({ token }) + const userRaw = await client + .get('users/me', { responseType: 'json' }) + .json() + const userObj: Record = isRecord(userRaw) ? userRaw : {} + const email = + typeof userObj['email'] === 'string' ? userObj['email'] : undefined + const timezoneValue = + typeof userObj['timezone'] === 'string' + ? userObj['timezone'] + : undefined + const user: Parameters[0] = { + ...(email ? { email } : {}), + ...(timezoneValue ? { timezone: timezoneValue } : {}), + } + const timezone = user.timezone ?? null + const userTz = timezone || 'UTC' + + if (meetingId) { + const recordingInfo = await client + .get(`meetings/${encodeURIComponent(meetingId)}/recordings`, { + responseType: 'json', + }) + .json() + return adaptData(user, recordingInfo) + } + + if (requestedYear) { + const now = moment.tz(userTz) + const numMonths = + now.get('year') === requestedYear ? now.get('month') + 1 : 12 + const monthsToCheck = Array.from({ length: numMonths }, (_, i) => i) // in moment, months are 0-indexed + + // Run each month in parallel: + const allMeetingsInYear = ( + await pMap( + monthsToCheck, + async (month) => { + const startDate = moment + .tz({ year: requestedYear, month, day: 1 }, userTz) + .startOf('month') + const endDate = startDate.clone().endOf('month') + + const searchParams = new URLSearchParams({ + page_size: String(PAGE_SIZE), + from: startDate.clone().tz('UTC').format('YYYY-MM-DD'), + to: endDate.clone().tz('UTC').format('YYYY-MM-DD'), + }) + + const paginatedMeetings: unknown[] = [] + let nextPageToken: string | null = null + do { + const currentChunkMeetingsInfo = await client + .get('users/me/recordings', { + searchParams, + responseType: 'json', + }) + .json() + paginatedMeetings.push( + ...(isRecord(currentChunkMeetingsInfo) && + Array.isArray(currentChunkMeetingsInfo['meetings']) + ? currentChunkMeetingsInfo['meetings'] + : []), + ) + const tokenValue = isRecord(currentChunkMeetingsInfo) + ? currentChunkMeetingsInfo['next_page_token'] + : undefined + nextPageToken = + typeof tokenValue === 'string' ? tokenValue : null + if (nextPageToken) { + searchParams.set('next_page_token', nextPageToken) + } else { + searchParams.delete('next_page_token') + } + } while (nextPageToken) + + return paginatedMeetings + }, + { concurrency: 3 }, + ) + ).flat() // this is effectively a flatMap + // concurrency 3 seems like a sensible number... + + const finalResult = { meetings: allMeetingsInYear } + return adaptData(user, finalResult) + } + + const accountCreationDate = moment.utc( + typeof userObj['created_at'] === 'string' + ? userObj['created_at'] + : undefined, + ) + const startYear = accountCreationDate.year() + const currentYear = moment.tz(userTz).year() + const years: Array<{ + isFolder: true + icon: 'folder' + name: string + mimeType: null + id: string + thumbnail: null + requestPath: string + modifiedDate: string + size: null + }> = [] + + for (let year = currentYear; year >= startYear; year--) { + years.push({ + isFolder: true, + icon: 'folder', + name: `${year}`, + mimeType: null, + id: `${year}`, + thumbnail: null, + requestPath: `?year=${year}`, + modifiedDate: `${year}-12-31`, // Representative date + size: null, + }) + } + + const response: { + username: string | null + items: typeof years + nextPagePath: null + } = { + username: user.email ?? null, + items: years, + nextPagePath: null, + } + + return response + }) + } + + override async download({ + id: meetingId, + providerUserSession: { accessToken: token }, + query, + }: { + id: string + providerUserSession: ZoomUserSession + query: Query + }): Promise<{ stream: Readable; size: number | undefined }> { + return this.#withErrorHandling('provider.zoom.download.error', async () => { + // meeting id + file id required + // cc files don't have an ID or size + const recordingStart = + typeof query['recordingStart'] === 'string' + ? query['recordingStart'] + : undefined + const fileId = + typeof query['recordingId'] === 'string' + ? query['recordingId'] + : undefined + if (!fileId) throw new Error('Missing recordingId') + + const client = getClient({ token }) + + const findFileArgs = { + client, + meetingId, + fileId, + ...(recordingStart && { recordingStart }), + } + const foundFile = await findFile(findFileArgs) + const url = foundFile?.download_url + if (!url) throw new Error('Download URL not found') + + const stream = client.stream.get(`${url}?access_token=${token}`, { + prefixUrl: '', + responseType: 'json', + }) + const { size } = await prepareStream(stream) + return { stream, size } + }) + } + + override async size({ + id: meetingId, + providerUserSession: { accessToken: token }, + query, + }: { + id: string + providerUserSession: ZoomUserSession + query: Query + }): Promise { + return this.#withErrorHandling('provider.zoom.size.error', async () => { + const client = getClient({ token }) + const recordingStart = + typeof query['recordingStart'] === 'string' + ? query['recordingStart'] + : undefined + const fileId = + typeof query['recordingId'] === 'string' + ? query['recordingId'] + : undefined + if (fileId == null) throw new Error('Missing recordingId') + + const findFileArgs = { + client, + meetingId, + fileId, + ...(recordingStart ? { recordingStart } : {}), + } + const foundFile = await findFile(findFileArgs) + if (!foundFile) throw new Error('File not found') + return foundFile.file_size // Note: May be undefined. + }) + } + + override async logout({ + companion, + providerUserSession: { accessToken: token }, + }: { + companion: CompanionLike + providerUserSession: ZoomUserSession + }): Promise<{ revoked: boolean }> { + return this.#withErrorHandling('provider.zoom.logout.error', async () => { + const { key, secret } = (await companion.getProviderCredentials?.())! + + const { status } = await got + .post('https://zoom.us/oauth/revoke', { + searchParams: { token }, + headers: { Authorization: getBasicAuthHeader(key, secret) }, + responseType: 'json', + }) + .json<{ status: unknown }>() + + return { revoked: status === 'success' } + }) + } + + override async deauthorizationCallback({ + companion, + body, + headers, + }: { + companion: CompanionLike + body: unknown + headers: Record + }): Promise<{ data?: unknown; status?: number }> { + return this.#withErrorHandling('provider.zoom.deauth.error', async () => { + if (!isRecord(body) || body['event'] !== DEAUTH_EVENT_NAME) { + return { data: {}, status: 400 } + } + + const { key, secret, verificationToken } = + (await companion.getProviderCredentials?.())! + + const tokenSupplied = headers['authorization'] + if ( + !tokenSupplied || + !verificationToken || + verificationToken !== tokenSupplied + ) { + return { data: {}, status: 400 } + } + + const payload = body['payload'] + if (!isRecord(payload)) return { data: {}, status: 400 } + const userId = payload['user_id'] + const accountId = payload['account_id'] + + await got.post('https://api.zoom.us/oauth/data/compliance', { + headers: { Authorization: getBasicAuthHeader(key, secret) }, + json: { + client_id: key, + user_id: userId, + account_id: accountId, + deauthorization_event_received: payload, + compliance_completed: true, + }, + responseType: 'json', + }) + + return {} + }) + } + + async #withErrorHandling(tag: string, fn: () => Promise): Promise { + const authErrorCodes = [ + 124, // expired token + 401, + ] + + return withProviderErrorHandling({ + fn, + tag, + providerName: Zoom.oauthProvider, + isAuthError: (response) => + typeof response.statusCode === 'number' && + authErrorCodes.includes(response.statusCode), + getJsonErrorMessage: (body) => + isRecord(body) && typeof body['message'] === 'string' + ? body['message'] + : undefined, + }) + } +} diff --git a/packages/@uppy/companion/src/server/redis.js b/packages/@uppy/companion/src/server/redis.js deleted file mode 100644 index 33a6ae27c..000000000 --- a/packages/@uppy/companion/src/server/redis.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Redis } from 'ioredis' -import * as logger from './logger.js' - -/** @type {import('ioredis').Redis} */ -let redisClient - -/** - * A Singleton module that provides a single redis client through out - * the lifetime of the server - * - * @param {string} [redisUrl] ioredis url - * @param {Record} [redisOptions] ioredis client options - */ -function createClient(redisUrl, redisOptions) { - if (!redisClient) { - if (redisUrl) { - redisClient = new Redis(redisUrl, redisOptions) - } else { - redisClient = new Redis(redisOptions) - } - redisClient.on('error', (err) => - logger.error('redis error', err.toString()), - ) - } - - return redisClient -} - -export function client( - { redisUrl, redisOptions } = { redisUrl: undefined, redisOptions: undefined }, -) { - if (!redisUrl && !redisOptions) { - return redisClient - } - - return createClient(redisUrl, redisOptions) -} diff --git a/packages/@uppy/companion/src/server/redis.ts b/packages/@uppy/companion/src/server/redis.ts new file mode 100644 index 000000000..3ed6a0df9 --- /dev/null +++ b/packages/@uppy/companion/src/server/redis.ts @@ -0,0 +1,40 @@ +import type { RedisOptions } from 'ioredis' +import { Redis } from 'ioredis' +import * as logger from './logger.js' + +let redisClient: Redis | undefined + +/** + * A singleton module that provides a single Redis client throughout the + * lifetime of the server. + */ +function createClient( + redisUrl: string | undefined, + redisOptions: RedisOptions | undefined, +): Redis { + if (redisClient) return redisClient + + if (redisUrl) { + redisClient = redisOptions + ? new Redis(redisUrl, redisOptions) + : new Redis(redisUrl) + } else if (redisOptions) { + redisClient = new Redis(redisOptions) + } else { + redisClient = new Redis() + } + redisClient.on('error', (err) => logger.error('redis error', err.toString())) + + return redisClient +} + +export function client( + options: { + redisUrl?: string | undefined + redisOptions?: RedisOptions | undefined + } = {}, +): Redis | undefined { + const { redisUrl, redisOptions } = options + if (!redisUrl && !redisOptions) return redisClient + return createClient(redisUrl, redisOptions) +} diff --git a/packages/@uppy/companion/src/server/s3-client.js b/packages/@uppy/companion/src/server/s3-client.ts similarity index 54% rename from packages/@uppy/companion/src/server/s3-client.js rename to packages/@uppy/companion/src/server/s3-client.ts index 59766623c..34656e1e9 100644 --- a/packages/@uppy/companion/src/server/s3-client.js +++ b/packages/@uppy/companion/src/server/s3-client.ts @@ -1,53 +1,61 @@ +import type { S3ClientConfig } from '@aws-sdk/client-s3' import { S3Client } from '@aws-sdk/client-s3' +import type { CompanionRuntimeOptions } from '../types/companion-options.js' /** * instantiates the aws-sdk s3 client that will be used for s3 uploads. * - * @param {object} companionOptions the companion options object - * @param {boolean} createPresignedPostMode whether this s3 client is for createPresignedPost + * @param companionOptions the companion options object + * @param createPresignedPostMode whether this s3 client is for createPresignedPost */ export default function s3Client( - companionOptions, + companionOptions: Pick, createPresignedPostMode = false, -) { - let s3Client = null - if (companionOptions.s3) { - const { s3 } = companionOptions - - if (s3.accessKeyId || s3.secretAccessKey) { +): S3Client | null { + let s3Client: S3Client | null = null + const s3 = companionOptions.s3 + if (s3) { + if (s3['accessKeyId'] || s3['secretAccessKey']) { throw new Error( 'Found `providerOptions.s3.accessKeyId` or `providerOptions.s3.secretAccessKey` configuration, but Companion requires `key` and `secret` option names instead. Please use the `key` property instead of `accessKeyId` and the `secret` property instead of `secretAccessKey`.', ) } - const rawClientOptions = s3.awsClientOptions if ( - rawClientOptions && - (rawClientOptions.accessKeyId || rawClientOptions.secretAccessKey) + s3['awsClientOptions']?.['accessKeyId'] || + s3['awsClientOptions']?.['secretAccessKey'] ) { throw new Error( 'Found unsupported `providerOptions.s3.awsClientOptions.accessKeyId` or `providerOptions.s3.awsClientOptions.secretAccessKey` configuration. Please use the `providerOptions.s3.key` and `providerOptions.s3.secret` options instead.', ) } - let { endpoint } = s3 - if (typeof endpoint === 'string') { + let { + endpoint, + region, + forcePathStyle, + bucket, + key, + secret, + sessionToken, + useAccelerateEndpoint, + awsClientOptions, + } = s3 + + if (endpoint && region) { // TODO: deprecate those replacements in favor of what AWS SDK supports out of the box. - endpoint = endpoint - .replace(/{service}/, 's3') - .replace(/{region}/, s3.region) + endpoint = endpoint.replace(/{service}/, 's3').replace(/{region}/, region) } - /** @type {import('@aws-sdk/client-s3').S3ClientConfig} */ - let s3ClientOptions = { - region: s3.region, - forcePathStyle: s3.forcePathStyle, + let s3ClientOptions: S3ClientConfig = { + ...(region != null && { region }), + ...(forcePathStyle != null && { forcePathStyle }), } - if (s3.useAccelerateEndpoint) { + if (useAccelerateEndpoint) { // https://github.com/transloadit/uppy/issues/4809#issuecomment-1847320742 if (createPresignedPostMode) { - if (s3.bucket != null) { + if (bucket != null) { s3ClientOptions = { ...s3ClientOptions, useAccelerateEndpoint: true, @@ -65,28 +73,40 @@ export default function s3Client( } } else { // no accelearate, we allow custom s3 endpoint - s3ClientOptions = { - ...s3ClientOptions, - endpoint, + if (endpoint != null) { + s3ClientOptions = { + ...s3ClientOptions, + endpoint, + } } } - s3ClientOptions = { - ...s3ClientOptions, - ...rawClientOptions, + if (awsClientOptions) { + s3ClientOptions = { + ...s3ClientOptions, + ...awsClientOptions, + } } // Use credentials to allow assumed roles to pass STS sessions in. // If the user doesn't specify key and secret, the default credentials (process-env) // will be used by S3 in calls below. - if (s3.key && s3.secret && !s3ClientOptions.credentials) { + if (key && secret && !s3ClientOptions.credentials) { s3ClientOptions.credentials = { - accessKeyId: s3.key, - secretAccessKey: s3.secret, - sessionToken: s3.sessionToken, + accessKeyId: key, + secretAccessKey: secret, + ...(sessionToken ? { sessionToken } : {}), } } - s3Client = new S3Client(s3ClientOptions) + try { + s3Client = new S3Client(s3ClientOptions) + } catch (err) { + // Keep S3 optional when no region can be resolved at all. + if (err instanceof Error && err.message === 'Region is missing') { + return null + } + throw err + } } return s3Client diff --git a/packages/@uppy/companion/src/server/socket.js b/packages/@uppy/companion/src/server/socket.ts similarity index 53% rename from packages/@uppy/companion/src/server/socket.js rename to packages/@uppy/companion/src/server/socket.ts index 7602bd2af..71dc7581a 100644 --- a/packages/@uppy/companion/src/server/socket.js +++ b/packages/@uppy/companion/src/server/socket.ts @@ -1,16 +1,28 @@ +import assert from 'node:assert' +import type { Server as HttpServer } from 'node:http' +import type { Server as HttpsServer } from 'node:https' import { WebSocketServer } from 'ws' import emitter from './emitter/index.js' +import { isRecord } from './helpers/type-guards.js' import { jsonStringify } from './helpers/utils.js' import * as logger from './logger.js' import * as redis from './redis.js' import Uploader from './Uploader.js' +type SocketMessage = { action: string; payload: Record } + +function isSocketMessage(value: unknown): value is SocketMessage { + return ( + isRecord(value) && + typeof value['action'] === 'string' && + isRecord(value['payload']) + ) +} + /** - * the socket is used to send progress events during an upload - * - * @param {import('http').Server | import('https').Server} server + * The socket is used to send progress events during an upload. */ -export default function setupSocket(server) { +export default function setupSocket(server: HttpServer | HttpsServer): void { const wss = new WebSocketServer({ server }) const redisClient = redis.client() @@ -19,31 +31,31 @@ export default function setupSocket(server) { // client attempts to reconnect. wss.on('connection', (ws, req) => { const fullPath = req.url + assert(fullPath != null, 'WebSocket connection URL is missing') // the token identifies which ongoing upload's progress, the socket // connection wishes to listen to. const token = fullPath.replace(/^.*\/api\//, '') logger.info(`connection received from ${token}`, 'socket.connect') - /** - * - * @param {{action: string, payload: object}} data - */ - function send(data) { + function send(data: SocketMessage): void { ws.send(jsonStringify(data), (err) => { - if (err) + if (err) { logger.error(err, 'socket.redis.error', Uploader.shortenToken(token)) + } }) } // if the redisClient is available, then we attempt to check the storage - // if we have any already stored state on the upload. + // if we have any already stored state on the upload, and send it to the client immediately after connection, + // so that the client can update the UI accordingly without the user having to wait for another event if (redisClient) { redisClient .get(`${Uploader.STORAGE_PREFIX}:${token}`) .then((data) => { - if (data) { - const dataObj = JSON.parse(data.toString()) - if (dataObj.action) send(dataObj) + if (!data) return + const dataObj: unknown = JSON.parse(data) + if (isSocketMessage(dataObj)) { + send(dataObj) } }) .catch((err) => @@ -52,13 +64,18 @@ export default function setupSocket(server) { } emitter().emit(`connection:${token}`) - emitter().on(token, send) + const onTokenMessage = (...args: unknown[]) => { + const data = args[0] + if (!isSocketMessage(data)) return + send(data) + } + emitter().on(token, onTokenMessage) ws.on('error', (err) => { // https://github.com/websockets/ws/issues/1543 // https://github.com/websockets/ws/blob/b73b11828d166e9692a9bffe9c01a7e93bab04a8/test/receiver.test.js#L936 if ( - err?.name === 'RangeError' && + err.name === 'RangeError' && 'code' in err && err.code === 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH' ) { @@ -74,18 +91,23 @@ export default function setupSocket(server) { ws.on('message', (jsonData) => { try { - const data = JSON.parse(jsonData.toString()) + const data: unknown = JSON.parse(jsonData.toString()) // whitelist triggered actions - if (['pause', 'resume', 'cancel'].includes(data.action)) { - emitter().emit(`${data.action}:${token}`) + const action = isRecord(data) ? data['action'] : undefined + if (action === 'pause' || action === 'resume' || action === 'cancel') { + emitter().emit(`${action}:${token}`) } } catch (err) { - logger.error(err, 'websocket.error', Uploader.shortenToken(token)) + logger.error( + err instanceof Error ? err : String(err), + 'websocket.error', + Uploader.shortenToken(token), + ) } }) ws.on('close', () => { - emitter().removeListener(token, send) + emitter().removeListener(token, onTokenMessage) }) }) } diff --git a/packages/@uppy/companion/src/standalone/helper.js b/packages/@uppy/companion/src/standalone/helper.js deleted file mode 100644 index 80299e92b..000000000 --- a/packages/@uppy/companion/src/standalone/helper.js +++ /dev/null @@ -1,294 +0,0 @@ -import crypto from 'node:crypto' -import fs from 'node:fs' -import { stripIndent } from 'common-tags' -import merge from 'lodash/merge.js' -import packageJson from '../../package.json' with { type: 'json' } -import * as utils from '../server/helpers/utils.js' -import logger from '../server/logger.js' - -/** - * Tries to read the secret from a file if the according environment variable is set. - * Otherwise it falls back to the standard secret environment variable. - * - * @param {string} baseEnvVar - * - * @returns {string} - */ -const getSecret = (baseEnvVar) => { - const secretFile = process.env[`${baseEnvVar}_FILE`] - return secretFile - ? fs.readFileSync(secretFile).toString() - : process.env[baseEnvVar] -} - -/** - * Auto-generates server secret - * - * @returns {string} - */ -export const generateSecret = (secretName) => { - logger.warn( - `auto-generating server ${secretName} because none was specified`, - 'startup.secret', - ) - return crypto.randomBytes(64).toString('hex') -} - -/** - * - * @param {string} url - */ -const hasProtocol = (url) => { - return url.startsWith('https://') || url.startsWith('http://') -} - -const companionProtocol = process.env.COMPANION_PROTOCOL || 'http' - -function getCorsOrigins() { - if (process.env.COMPANION_CLIENT_ORIGINS) { - switch (process.env.COMPANION_CLIENT_ORIGINS) { - case 'true': - return true - case 'false': - return false - case '*': - return '*' - - default: - return process.env.COMPANION_CLIENT_ORIGINS.split(',').map((url) => - hasProtocol(url) ? url : `${companionProtocol}://${url}`, - ) - } - } - if (process.env.COMPANION_CLIENT_ORIGINS_REGEX) { - return new RegExp(process.env.COMPANION_CLIENT_ORIGINS_REGEX) - } - return undefined -} - -const s3Prefix = process.env.COMPANION_AWS_PREFIX || '' - -/** - * Default getKey for Companion standalone variant - * - * @returns {string} - */ -const defaultStandaloneGetKey = (...args) => - `${s3Prefix}${utils.defaultGetKey(...args)}` - -/** - * Loads the config from environment variables - * - * @returns {object} - */ -const getConfigFromEnv = () => { - const uploadUrls = process.env.COMPANION_UPLOAD_URLS - const domains = - process.env.COMPANION_DOMAINS || process.env.COMPANION_DOMAIN || null - const validHosts = domains ? domains.split(',') : [] - - return { - providerOptions: { - drive: { - key: process.env.COMPANION_GOOGLE_KEY, - secret: getSecret('COMPANION_GOOGLE_SECRET'), - credentialsURL: process.env.COMPANION_GOOGLE_KEYS_ENDPOINT, - }, - dropbox: { - key: process.env.COMPANION_DROPBOX_KEY, - secret: getSecret('COMPANION_DROPBOX_SECRET'), - credentialsURL: process.env.COMPANION_DROPBOX_KEYS_ENDPOINT, - }, - box: { - key: process.env.COMPANION_BOX_KEY, - secret: getSecret('COMPANION_BOX_SECRET'), - credentialsURL: process.env.COMPANION_BOX_KEYS_ENDPOINT, - }, - instagram: { - key: process.env.COMPANION_INSTAGRAM_KEY, - secret: getSecret('COMPANION_INSTAGRAM_SECRET'), - credentialsURL: process.env.COMPANION_INSTAGRAM_KEYS_ENDPOINT, - }, - facebook: { - key: process.env.COMPANION_FACEBOOK_KEY, - secret: getSecret('COMPANION_FACEBOOK_SECRET'), - credentialsURL: process.env.COMPANION_FACEBOOK_KEYS_ENDPOINT, - }, - onedrive: { - key: process.env.COMPANION_ONEDRIVE_KEY, - secret: getSecret('COMPANION_ONEDRIVE_SECRET'), - credentialsURL: process.env.COMPANION_ONEDRIVE_KEYS_ENDPOINT, - }, - zoom: { - key: process.env.COMPANION_ZOOM_KEY, - secret: getSecret('COMPANION_ZOOM_SECRET'), - verificationToken: getSecret('COMPANION_ZOOM_VERIFICATION_TOKEN'), - credentialsURL: process.env.COMPANION_ZOOM_KEYS_ENDPOINT, - }, - unsplash: { - key: process.env.COMPANION_UNSPLASH_KEY, - secret: process.env.COMPANION_UNSPLASH_SECRET, - }, - }, - s3: { - key: process.env.COMPANION_AWS_KEY, - getKey: defaultStandaloneGetKey, - secret: getSecret('COMPANION_AWS_SECRET'), - bucket: process.env.COMPANION_AWS_BUCKET, - endpoint: process.env.COMPANION_AWS_ENDPOINT, - region: process.env.COMPANION_AWS_REGION, - useAccelerateEndpoint: - process.env.COMPANION_AWS_USE_ACCELERATE_ENDPOINT === 'true', - expires: parseInt(process.env.COMPANION_AWS_EXPIRES || '800', 10), - acl: process.env.COMPANION_AWS_ACL, - forcePathStyle: process.env.COMPANION_AWS_FORCE_PATH_STYLE === 'true', - }, - server: { - host: process.env.COMPANION_DOMAIN, - protocol: companionProtocol, - path: process.env.COMPANION_PATH, - implicitPath: process.env.COMPANION_IMPLICIT_PATH, - oauthDomain: process.env.COMPANION_OAUTH_DOMAIN, - validHosts, - }, - enableUrlEndpoint: process.env.COMPANION_ENABLE_URL_ENDPOINT === 'true', - enableGooglePickerEndpoint: - process.env.COMPANION_ENABLE_GOOGLE_PICKER_ENDPOINT === 'true', - periodicPingUrls: process.env.COMPANION_PERIODIC_PING_URLS - ? process.env.COMPANION_PERIODIC_PING_URLS.split(',') - : [], - periodicPingInterval: process.env.COMPANION_PERIODIC_PING_INTERVAL - ? parseInt(process.env.COMPANION_PERIODIC_PING_INTERVAL, 10) - : undefined, - periodicPingStaticPayload: process.env - .COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD - ? JSON.parse(process.env.COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD) - : undefined, - periodicPingCount: process.env.COMPANION_PERIODIC_PING_COUNT - ? parseInt(process.env.COMPANION_PERIODIC_PING_COUNT, 10) - : undefined, - filePath: process.env.COMPANION_DATADIR, - redisPubSubScope: process.env.COMPANION_REDIS_PUBSUB_SCOPE, - redisUrl: process.env.COMPANION_REDIS_URL, - // redisOptions refers to https://redis.github.io/ioredis/index.html#RedisOptions - redisOptions: (() => { - try { - if (!process.env.COMPANION_REDIS_OPTIONS) { - return undefined - } - return JSON.parse(process.env.COMPANION_REDIS_OPTIONS) - } catch (e) { - logger.warn('COMPANION_REDIS_OPTIONS parse error', e) - } - return undefined - })(), - sendSelfEndpoint: process.env.COMPANION_SELF_ENDPOINT, - uploadUrls: uploadUrls ? uploadUrls.split(',') : null, - secret: getSecret('COMPANION_SECRET'), - preAuthSecret: getSecret('COMPANION_PREAUTH_SECRET'), - allowLocalUrls: process.env.COMPANION_ALLOW_LOCAL_URLS === 'true', - // cookieDomain is kind of a hack to support distributed systems. This should be improved but we never got so far. - cookieDomain: process.env.COMPANION_COOKIE_DOMAIN, - streamingUpload: process.env.COMPANION_STREAMING_UPLOAD - ? process.env.COMPANION_STREAMING_UPLOAD === 'true' - : undefined, - tusDeferredUploadLength: process.env.COMPANION_TUS_DEFERRED_UPLOAD_LENGTH - ? process.env.COMPANION_TUS_DEFERRED_UPLOAD_LENGTH === 'true' - : true, - maxFileSize: process.env.COMPANION_MAX_FILE_SIZE - ? parseInt(process.env.COMPANION_MAX_FILE_SIZE, 10) - : undefined, - maxFilenameLength: process.env.COMPANION_MAX_FILENAME_LENGTH - ? parseInt(process.env.COMPANION_MAX_FILENAME_LENGTH, 10) - : 500, - chunkSize: process.env.COMPANION_CHUNK_SIZE - ? parseInt(process.env.COMPANION_CHUNK_SIZE, 10) - : undefined, - clientSocketConnectTimeout: process.env - .COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT - ? parseInt(process.env.COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT, 10) - : undefined, - metrics: process.env.COMPANION_HIDE_METRICS !== 'true', - loggerProcessName: process.env.COMPANION_LOGGER_PROCESS_NAME, - corsOrigins: getCorsOrigins(), - testDynamicOauthCredentials: - process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS === 'true', - testDynamicOauthCredentialsSecret: - process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET, - uploadHeaders: process.env.COMPANION_UPLOAD_HEADERS - ? JSON.parse(process.env.COMPANION_UPLOAD_HEADERS) - : undefined, - } -} - -/** - * Returns the config path specified via cli arguments - * - * @returns {string} - */ -const getConfigPath = () => { - let configPath - - for (let i = process.argv.length - 1; i >= 0; i--) { - const isConfigFlag = - process.argv[i] === '-c' || process.argv[i] === '--config' - const flagHasValue = i + 1 <= process.argv.length - if (isConfigFlag && flagHasValue) { - configPath = process.argv[i + 1] - break - } - } - - return configPath -} - -/** - * Loads the config from a file and returns it as an object - * - * @returns {object} - */ -const getConfigFromFile = () => { - const path = getConfigPath() - if (!path) return {} - - const rawdata = fs.readFileSync(getConfigPath()) - // @ts-ignore - return JSON.parse(rawdata) -} - -/** - * Reads all companion configuration set via environment variables - * and via the config file path - * - * @returns {object} - */ -export const getCompanionOptions = (options = {}) => { - return merge({}, getConfigFromEnv(), getConfigFromFile(), options) -} - -export const buildHelpfulStartupMessage = (companionOptions) => { - const buildURL = utils.getURLBuilder(companionOptions) - const callbackURLs = [] - Object.keys(companionOptions.providerOptions).forEach((providerName) => { - callbackURLs.push(buildURL(`/${providerName}/redirect`, true)) - }) - - return stripIndent` - Welcome to Companion v${packageJson.version} - =================================== - - Congratulations on setting up Companion! Thanks for joining our cause, you have taken - the first step towards the future of file uploading! We - hope you are as excited about this as we are! - - While you did an awesome job on getting Companion running, this is just the welcome - message, so let's talk about the places that really matter: - - - Be sure to add the following URLs as your Oauth redirect uris on their corresponding developer interfaces: - ${callbackURLs.join(', ')} - - The URL ${buildURL('/metrics', true)} is available for statistics to keep Companion running smoothly - - https://github.com/transloadit/uppy/issues - report your bugs here - - So quit lollygagging, start uploading and experience the future! - ` -} diff --git a/packages/@uppy/companion/src/standalone/helper.ts b/packages/@uppy/companion/src/standalone/helper.ts new file mode 100644 index 000000000..c55ab8350 --- /dev/null +++ b/packages/@uppy/companion/src/standalone/helper.ts @@ -0,0 +1,330 @@ +import crypto from 'node:crypto' +import fs from 'node:fs' +import { stripIndent } from 'common-tags' +import merge from 'lodash/merge.js' +import z from 'zod' +import packageJson from '../../package.json' with { type: 'json' } +import type { CompanionInitOptions } from '../schemas/index.js' +import * as utils from '../server/helpers/utils.js' +import logger from '../server/logger.js' + +/** + * Tries to read the secret from a file if the according environment variable is set. + * Otherwise it falls back to the standard secret environment variable. + */ +const getSecret = (baseEnvVar: string): string | undefined => { + const secretFile = process.env[`${baseEnvVar}_FILE`] + return secretFile + ? fs.readFileSync(secretFile).toString() + : process.env[baseEnvVar] +} + +/** + * Auto-generates server secret. + */ +export const generateSecret = (secretName: string): string => { + logger.warn( + `auto-generating server ${secretName} because none was specified`, + 'startup.secret', + ) + return crypto.randomBytes(64).toString('hex') +} + +const hasProtocol = (url: string): boolean => { + return url.startsWith('https://') || url.startsWith('http://') +} + +const companionProtocol = process.env['COMPANION_PROTOCOL'] || 'http' + +function getCorsOrigins() { + if (process.env['COMPANION_CLIENT_ORIGINS']) { + switch (process.env['COMPANION_CLIENT_ORIGINS']) { + case 'true': + return true + case 'false': + return false + case '*': + return '*' + + default: + return process.env['COMPANION_CLIENT_ORIGINS'] + .split(',') + .map((url) => + hasProtocol(url) ? url : `${companionProtocol}://${url}`, + ) + } + } + if (process.env['COMPANION_CLIENT_ORIGINS_REGEX']) { + return new RegExp(process.env['COMPANION_CLIENT_ORIGINS_REGEX']) + } + return undefined +} + +const s3Prefix = process.env['COMPANION_AWS_PREFIX'] || '' + +/** + * Default `getKey` for Companion standalone variant. + */ +const defaultStandaloneGetKey = ( + ...args: Parameters +): string => `${s3Prefix}${utils.defaultGetKey(...args)}` + +const aclSchema = z + .enum([ + 'authenticated-read', + 'aws-exec-read', + 'bucket-owner-full-control', + 'bucket-owner-read', + 'private', + 'public-read', + 'public-read-write', + ]) + .optional() + +type StandaloneCompanionOptions = Pick< + CompanionInitOptions, + | 'providerOptions' + | 'preAuthSecret' + | 'redisUrl' + | 'redisOptions' + | 'redisPubSubScope' + | 'metrics' + | 'loggerProcessName' + | 'uploadUrls' + | 's3' + | 'enableUrlEndpoint' + | 'enableGooglePickerEndpoint' + | 'periodicPingUrls' + | 'periodicPingInterval' + | 'periodicPingStaticPayload' + | 'periodicPingCount' + | 'sendSelfEndpoint' + | 'allowLocalUrls' + | 'cookieDomain' + | 'streamingUpload' + | 'tusDeferredUploadLength' + | 'maxFileSize' + | 'maxFilenameLength' + | 'chunkSize' + | 'clientSocketConnectTimeout' + | 'corsOrigins' + | 'testDynamicOauthCredentials' + | 'testDynamicOauthCredentialsSecret' + | 'uploadHeaders' +> & { + server: Omit & { + host: CompanionInitOptions['server']['host'] | undefined + } + secret: CompanionInitOptions['secret'] | undefined + filePath: CompanionInitOptions['filePath'] | undefined +} + +/** + * Loads the config from environment variables. + */ +const getConfigFromEnv = (): StandaloneCompanionOptions => { + const uploadUrls = process.env['COMPANION_UPLOAD_URLS'] + const domains = + process.env['COMPANION_DOMAINS'] || process.env['COMPANION_DOMAIN'] || null + const validHosts = domains ? domains.split(',') : [] + + return { + providerOptions: { + drive: { + key: process.env['COMPANION_GOOGLE_KEY'], + secret: getSecret('COMPANION_GOOGLE_SECRET'), + credentialsURL: process.env['COMPANION_GOOGLE_KEYS_ENDPOINT'], + }, + dropbox: { + key: process.env['COMPANION_DROPBOX_KEY'], + secret: getSecret('COMPANION_DROPBOX_SECRET'), + credentialsURL: process.env['COMPANION_DROPBOX_KEYS_ENDPOINT'], + }, + box: { + key: process.env['COMPANION_BOX_KEY'], + secret: getSecret('COMPANION_BOX_SECRET'), + credentialsURL: process.env['COMPANION_BOX_KEYS_ENDPOINT'], + }, + instagram: { + key: process.env['COMPANION_INSTAGRAM_KEY'], + secret: getSecret('COMPANION_INSTAGRAM_SECRET'), + credentialsURL: process.env['COMPANION_INSTAGRAM_KEYS_ENDPOINT'], + }, + facebook: { + key: process.env['COMPANION_FACEBOOK_KEY'], + secret: getSecret('COMPANION_FACEBOOK_SECRET'), + credentialsURL: process.env['COMPANION_FACEBOOK_KEYS_ENDPOINT'], + }, + onedrive: { + key: process.env['COMPANION_ONEDRIVE_KEY'], + secret: getSecret('COMPANION_ONEDRIVE_SECRET'), + credentialsURL: process.env['COMPANION_ONEDRIVE_KEYS_ENDPOINT'], + }, + zoom: { + key: process.env['COMPANION_ZOOM_KEY'], + secret: getSecret('COMPANION_ZOOM_SECRET'), + verificationToken: getSecret('COMPANION_ZOOM_VERIFICATION_TOKEN'), + credentialsURL: process.env['COMPANION_ZOOM_KEYS_ENDPOINT'], + }, + unsplash: { + key: process.env['COMPANION_UNSPLASH_KEY'], + secret: process.env['COMPANION_UNSPLASH_SECRET'], + }, + }, + s3: { + key: process.env['COMPANION_AWS_KEY'], + getKey: defaultStandaloneGetKey, + secret: getSecret('COMPANION_AWS_SECRET'), + bucket: process.env['COMPANION_AWS_BUCKET'], + endpoint: process.env['COMPANION_AWS_ENDPOINT'], + region: process.env['COMPANION_AWS_REGION'], + useAccelerateEndpoint: + process.env['COMPANION_AWS_USE_ACCELERATE_ENDPOINT'] === 'true', + expires: parseInt(process.env['COMPANION_AWS_EXPIRES'] || '800', 10), + acl: aclSchema.parse(process.env['COMPANION_AWS_ACL']), + forcePathStyle: process.env['COMPANION_AWS_FORCE_PATH_STYLE'] === 'true', + }, + server: { + host: process.env['COMPANION_DOMAIN'], + protocol: companionProtocol, + path: process.env['COMPANION_PATH'], + implicitPath: process.env['COMPANION_IMPLICIT_PATH'], + oauthDomain: process.env['COMPANION_OAUTH_DOMAIN'], + validHosts, + }, + enableUrlEndpoint: process.env['COMPANION_ENABLE_URL_ENDPOINT'] === 'true', + enableGooglePickerEndpoint: + process.env['COMPANION_ENABLE_GOOGLE_PICKER_ENDPOINT'] === 'true', + periodicPingUrls: process.env['COMPANION_PERIODIC_PING_URLS'] + ? process.env['COMPANION_PERIODIC_PING_URLS'].split(',') + : [], + periodicPingInterval: process.env['COMPANION_PERIODIC_PING_INTERVAL'] + ? parseInt(process.env['COMPANION_PERIODIC_PING_INTERVAL'], 10) + : undefined, + periodicPingStaticPayload: process.env[ + 'COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD' + ] + ? JSON.parse(process.env['COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD']) + : undefined, + periodicPingCount: process.env['COMPANION_PERIODIC_PING_COUNT'] + ? parseInt(process.env['COMPANION_PERIODIC_PING_COUNT'], 10) + : undefined, + filePath: process.env['COMPANION_DATADIR'], + redisPubSubScope: process.env['COMPANION_REDIS_PUBSUB_SCOPE'], + redisUrl: process.env['COMPANION_REDIS_URL'], + // redisOptions refers to https://redis.github.io/ioredis/index.html#RedisOptions + redisOptions: (() => { + try { + if (!process.env['COMPANION_REDIS_OPTIONS']) { + return undefined + } + return JSON.parse(process.env['COMPANION_REDIS_OPTIONS']) + } catch (e) { + logger.warn(e, 'COMPANION_REDIS_OPTIONS parse error') + } + return undefined + })(), + sendSelfEndpoint: process.env['COMPANION_SELF_ENDPOINT'], + uploadUrls: uploadUrls ? uploadUrls.split(',') : null, + secret: getSecret('COMPANION_SECRET'), + preAuthSecret: getSecret('COMPANION_PREAUTH_SECRET'), + allowLocalUrls: process.env['COMPANION_ALLOW_LOCAL_URLS'] === 'true', + // cookieDomain is kind of a hack to support distributed systems. This should be improved but we never got so far. + cookieDomain: process.env['COMPANION_COOKIE_DOMAIN'], + streamingUpload: process.env['COMPANION_STREAMING_UPLOAD'] + ? process.env['COMPANION_STREAMING_UPLOAD'] === 'true' + : undefined, + tusDeferredUploadLength: process.env['COMPANION_TUS_DEFERRED_UPLOAD_LENGTH'] + ? process.env['COMPANION_TUS_DEFERRED_UPLOAD_LENGTH'] === 'true' + : true, + maxFileSize: process.env['COMPANION_MAX_FILE_SIZE'] + ? parseInt(process.env['COMPANION_MAX_FILE_SIZE'], 10) + : undefined, + maxFilenameLength: process.env['COMPANION_MAX_FILENAME_LENGTH'] + ? parseInt(process.env['COMPANION_MAX_FILENAME_LENGTH'], 10) + : 500, + chunkSize: process.env['COMPANION_CHUNK_SIZE'] + ? parseInt(process.env['COMPANION_CHUNK_SIZE'], 10) + : undefined, + clientSocketConnectTimeout: process.env[ + 'COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT' + ] + ? parseInt(process.env['COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT'], 10) + : undefined, + metrics: process.env['COMPANION_HIDE_METRICS'] !== 'true', + loggerProcessName: process.env['COMPANION_LOGGER_PROCESS_NAME'], + corsOrigins: getCorsOrigins(), + testDynamicOauthCredentials: + process.env['COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS'] === 'true', + testDynamicOauthCredentialsSecret: + process.env['COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET'], + uploadHeaders: process.env['COMPANION_UPLOAD_HEADERS'] + ? JSON.parse(process.env['COMPANION_UPLOAD_HEADERS']) + : undefined, + } +} + +const getConfigPath = (): string | undefined => { + let configPath: string | undefined + + for (let i = process.argv.length - 1; i >= 0; i--) { + const isConfigFlag = + process.argv[i] === '-c' || process.argv[i] === '--config' + const flagHasValue = i + 1 <= process.argv.length + if (isConfigFlag && flagHasValue) { + configPath = process.argv[i + 1] + break + } + } + + return configPath +} + +// todo use zod schema +const getConfigFromFile = () => { + const path = getConfigPath() + if (!path) return {} + + const rawdata = fs.readFileSync(path) + return JSON.parse(rawdata.toString('utf8')) +} + +export const getCompanionOptions = ( + options?: CompanionInitOptions | undefined, +): CompanionInitOptions => { + return merge({}, getConfigFromEnv(), getConfigFromFile(), options) + // This schema is intentionally tolerant and should not change runtime behavior. +} + +export const buildHelpfulStartupMessage = ( + companionOptions: StandaloneCompanionOptions, +): string => { + const buildURL = utils.getURLBuilder({ + server: companionOptions.server ?? {}, + }) + const callbackURLs: string[] = [] + Object.keys(companionOptions.providerOptions ?? {}).forEach( + (providerName) => { + callbackURLs.push(buildURL(`/${providerName}/redirect`, true)) + }, + ) + + return stripIndent` + Welcome to Companion v${packageJson.version} + =================================== + + Congratulations on setting up Companion! Thanks for joining our cause, you have taken + the first step towards the future of file uploading! We + hope you are as excited about this as we are! + + While you did an awesome job on getting Companion running, this is just the welcome + message, so let's talk about the places that really matter: + + - Be sure to add the following URLs as your Oauth redirect uris on their corresponding developer interfaces: + ${callbackURLs.join(', ')} + - The URL ${buildURL('/metrics', true)} is available for statistics to keep Companion running smoothly + - https://github.com/transloadit/uppy/issues - report your bugs here + + So quit lollygagging, start uploading and experience the future! + ` +} diff --git a/packages/@uppy/companion/src/standalone/index.js b/packages/@uppy/companion/src/standalone/index.ts similarity index 74% rename from packages/@uppy/companion/src/standalone/index.js rename to packages/@uppy/companion/src/standalone/index.ts index e17344b19..221573841 100644 --- a/packages/@uppy/companion/src/standalone/index.js +++ b/packages/@uppy/companion/src/standalone/index.ts @@ -2,11 +2,15 @@ import { randomUUID } from 'node:crypto' import qs from 'node:querystring' import { URL } from 'node:url' import RedisStore from 'connect-redis' +import type { NextFunction, Request, Response } from 'express' import express from 'express' +import type { SessionOptions } from 'express-session' import session from 'express-session' import helmet from 'helmet' import morgan from 'morgan' import * as companion from '../companion.js' +import type { CompanionInitOptions } from '../schemas/index.js' +import { isRecord, toError } from '../server/helpers/type-guards.js' import logger from '../server/logger.js' import * as redis from '../server/redis.js' import { @@ -15,12 +19,7 @@ import { getCompanionOptions, } from './helper.js' -/** - * Configures an Express app for running Companion standalone - * - * @returns {object} - */ -export default function server(inputCompanionOptions) { +export default function server(inputCompanionOptions?: CompanionInitOptions) { const companionOptions = getCompanionOptions(inputCompanionOptions) companion.setLoggerProcessName(companionOptions) @@ -34,8 +33,9 @@ export default function server(inputCompanionOptions) { const router = express.Router() - if (companionOptions.server.path) { - app.use(companionOptions.server.path, router) + const serverPath = companionOptions.server.path + if (serverPath != null) { + app.use(serverPath, router) } else { app.use(router) } @@ -51,18 +51,17 @@ export default function server(inputCompanionOptions) { * The input type is more broad that it needs to be, this way typescript can help us guarantee that we're dealing with all * possible inputs :) * - * @param {Record} rawQuery - * @returns {{ - * query: Record, - * censored: boolean - * }} + * @param rawQuery */ - function censorQuery(rawQuery) { - /** @type {Record} */ - const query = {} + function censorQuery(rawQuery: Record): { + query: Record + censored: boolean + } { + const query: Record = {} let censored = false Object.keys(rawQuery).forEach((key) => { - if (typeof rawQuery[key] !== 'string') { + const value = rawQuery[key] + if (typeof value !== 'string') { return } if (sensitiveKeys.has(key)) { @@ -70,7 +69,7 @@ export default function server(inputCompanionOptions) { query[key] = '********' censored = true } else { - query[key] = rawQuery[key] + query[key] = value } }) return { query, censored } @@ -89,16 +88,16 @@ export default function server(inputCompanionOptions) { const { query, censored } = censorQuery(req.query) return censored ? `${req.path}?${qs.stringify(query)}` - : req.originalUrl || req.url + : req.originalUrl || req.url || '-' }) morgan.token('referrer', (req) => { - const ref = req.headers.referer || req.headers.referrer + const ref = req.headers['referer'] || req.headers['referrer'] if (typeof ref === 'string') { - let parsed + let parsed: URL try { parsed = new URL(ref) - } catch (_) { + } catch { return ref } const rawQuery = qs.parse(parsed.search.replace('?', '')) @@ -107,7 +106,7 @@ export default function server(inputCompanionOptions) { ? `${parsed.href.split('?')[0]}?${qs.stringify(query)}` : parsed.href } - return undefined + return '-' }) // Use helmet to secure Express headers @@ -118,25 +117,28 @@ export default function server(inputCompanionOptions) { app.disable('x-powered-by') - const sessionOptions = { + const sessionOptions: SessionOptions = { secret: companionOptions.secret, resave: true, saveUninitialized: true, } - const redisClient = redis.client(companionOptions) + const redisClient = redis.client({ + redisUrl: companionOptions.redisUrl, + redisOptions: companionOptions.redisOptions, + }) if (redisClient) { sessionOptions.store = new RedisStore({ client: redisClient, prefix: - process.env.COMPANION_REDIS_EXPRESS_SESSION_PREFIX || + process.env['COMPANION_REDIS_EXPRESS_SESSION_PREFIX'] || 'companion-session:', }) } - if (process.env.COMPANION_COOKIE_DOMAIN) { + if (process.env['COMPANION_COOKIE_DOMAIN']) { sessionOptions.cookie = { - domain: process.env.COMPANION_COOKIE_DOMAIN, + domain: process.env['COMPANION_COOKIE_DOMAIN'], maxAge: 24 * 60 * 60 * 1000, // 1 day } } @@ -148,7 +150,7 @@ export default function server(inputCompanionOptions) { router.use(session(sessionOptions)) // Routes - if (process.env.COMPANION_HIDE_WELCOME !== 'true') { + if (process.env['COMPANION_HIDE_WELCOME'] !== 'true') { router.get('/', (req, res) => { res.setHeader('Content-Type', 'text/plain') res.send(buildHelpfulStartupMessage(companionOptions)) @@ -167,15 +169,15 @@ export default function server(inputCompanionOptions) { // that you might have mixed the values for COMPANION_ONEDRIVE_KEY and COMPANION_ONEDRIVE_SECRET, // please DO NOT set any value for COMPANION_ONEDRIVE_DOMAIN_VALIDATION if ( - process.env.COMPANION_ONEDRIVE_DOMAIN_VALIDATION === 'true' && - process.env.COMPANION_ONEDRIVE_KEY + process.env['COMPANION_ONEDRIVE_DOMAIN_VALIDATION'] === 'true' && + process.env['COMPANION_ONEDRIVE_KEY'] ) { router.get( '/.well-known/microsoft-identity-association.json', (req, res) => { const content = JSON.stringify({ associatedApplications: [ - { applicationId: process.env.COMPANION_ONEDRIVE_KEY }, + { applicationId: process.env['COMPANION_ONEDRIVE_KEY'] }, ], }) res.header('Content-Length', `${Buffer.byteLength(content, 'utf8')}`) @@ -192,12 +194,14 @@ export default function server(inputCompanionOptions) { return res.status(404).json({ message: 'Not Found' }) }) - app.use((err, req, res, next) => { + app.use((err: unknown, req: Request, res: Response, _next: NextFunction) => { + const error = toError(err) + const status = isRecord(err) ? err['status'] : undefined if (app.get('env') === 'production') { // if the error is a URIError from the requested URL we only log the error message // to avoid uneccessary error alerts - if (err.status === 400 && err.name === 'URIError') { - logger.error(err.message, 'root.error', req.id) + if (status === 400 && error.name === 'URIError') { + logger.error(error.message, 'root.error', req.id) } else { logger.error(err, 'root.error', req.id) } @@ -208,7 +212,7 @@ export default function server(inputCompanionOptions) { logger.error(err, 'root.error', req.id) res .status(500) - .json({ message: err.message, error: err, requestId: req.id }) + .json({ message: error.message, error: err, requestId: req.id }) } }) diff --git a/packages/@uppy/companion/src/standalone/start-server.js b/packages/@uppy/companion/src/standalone/start-server.ts old mode 100755 new mode 100644 similarity index 80% rename from packages/@uppy/companion/src/standalone/start-server.js rename to packages/@uppy/companion/src/standalone/start-server.ts index 127ab19c0..d585ba4c3 --- a/packages/@uppy/companion/src/standalone/start-server.js +++ b/packages/@uppy/companion/src/standalone/start-server.ts @@ -4,7 +4,8 @@ import * as companion from '../companion.js' import logger from '../server/logger.js' import standalone from './index.js' -const port = process.env.COMPANION_PORT || process.env.PORT || 3020 +const port: string | number = + process.env['COMPANION_PORT'] || process.env['PORT'] || 3020 const { app } = standalone() diff --git a/packages/@uppy/companion/src/types/companion-options.ts b/packages/@uppy/companion/src/types/companion-options.ts new file mode 100644 index 000000000..14a67fcd2 --- /dev/null +++ b/packages/@uppy/companion/src/types/companion-options.ts @@ -0,0 +1,8 @@ +import type { defaultOptions } from '../config/companion.js' +import type { CompanionInitOptions } from '../schemas/companion.js' + +type DefaultOptions = typeof defaultOptions + +// Runtime Companion options are the merged default options + init options. + +export type CompanionRuntimeOptions = DefaultOptions & CompanionInitOptions diff --git a/packages/@uppy/companion/src/types/express.d.ts b/packages/@uppy/companion/src/types/express.d.ts new file mode 100644 index 000000000..0180663e8 --- /dev/null +++ b/packages/@uppy/companion/src/types/express.d.ts @@ -0,0 +1,73 @@ +import type { S3Client } from '@aws-sdk/client-s3' +import type { CompanionRuntimeOptions } from './companion-options.js' +import type Provider from '../server/provider/Provider.js' +import { CredentialsFetchResponse } from '../schemas/companion.js' + +export type BuildUrl = ( + subPath: string, + isExternal: boolean, + excludeHost?: boolean, +) => string + +export interface ProviderGrantConfig { + dynamic?: string[] + redirect_uri?: string | undefined +} + +export interface ProviderUserSession { + accessToken?: string + refreshToken?: string | undefined + [key: string]: unknown +} + +export type CompanionContext = { + options: CompanionRuntimeOptions + provider?: Provider + providerName?: string + providerClass?: typeof Provider + providerGrantConfig?: ProviderGrantConfig + providerUserSession?: ProviderUserSession | undefined + authToken?: string | undefined + buildURL?: BuildUrl + s3Client?: S3Client + s3ClientCreatePresignedPost?: S3Client + getProviderCredentials?: () => Promise +} + +export interface GrantDynamic { + state?: string +} + +export interface CompanionSession { + grant?: { + state?: string | null + dynamic?: GrantDynamic | null + response?: { + access_token?: string + refresh_token?: string + } + } +} + +export interface CompanionExpressLocals { + grant?: { + dynamic?: { + key?: string + secret?: string + origins?: string[] + redirect_uri?: string + } | null + } +} + +declare global { + namespace Express { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface Request { + companion: CompanionContext + id?: string + cookies?: Record + session?: CompanionSession + } + } +} diff --git a/packages/@uppy/companion/src/types/shims.d.ts b/packages/@uppy/companion/src/types/shims.d.ts new file mode 100644 index 000000000..5c8a3cbbf --- /dev/null +++ b/packages/@uppy/companion/src/types/shims.d.ts @@ -0,0 +1,28 @@ +declare module 'express-interceptor' { + import type { Request, Response, RequestHandler } from 'express' + + type InterceptorConfig = { + isInterceptable: () => boolean + intercept: (body: unknown, send: (body: unknown) => void) => void + } + + export default function interceptor( + fn: (req: Request, res: Response) => InterceptorConfig, + ): RequestHandler +} + +declare module 'supports-color' { + type ColorSupport = { + level: number + hasBasic: boolean + has256: boolean + has16m: boolean + } + + const supportsColor: { + stdout: ColorSupport | false + stderr: ColorSupport | false + } + + export default supportsColor +} diff --git a/packages/@uppy/companion/start-dev b/packages/@uppy/companion/start-dev index fc3728f9e..f47531bee 100755 --- a/packages/@uppy/companion/start-dev +++ b/packages/@uppy/companion/start-dev @@ -1,8 +1,12 @@ #!/usr/bin/env bash +./node_modules/.bin/tsc --build tsconfig.build.json --watch --preserveWatchOutput & +TSC_WATCH_PID=$! +trap 'kill $TSC_WATCH_PID 2>/dev/null || true' EXIT + # Load local env vars. In CI, these are injected. if [ -f ../../../.env ]; then - DOTENV_CONFIG_PATH=../../../.env node --watch -r dotenv/config src/standalone/start-server.js + DOTENV_CONFIG_PATH=../../../.env node --watch -r dotenv/config dist/standalone/start-server.js else env \ COMPANION_DATADIR="./output" \ @@ -13,5 +17,5 @@ else COMPANION_SECRET="development" \ COMPANION_PREAUTH_SECRET="development2" \ COMPANION_ALLOW_LOCAL_URLS="true" \ - node --watch src/standalone/start-server.js -fi \ No newline at end of file + node --watch dist/standalone/start-server.js +fi diff --git a/packages/@uppy/companion/test/auth-buffer-secrets.test.ts b/packages/@uppy/companion/test/auth-buffer-secrets.test.ts new file mode 100644 index 000000000..90a2096a1 --- /dev/null +++ b/packages/@uppy/companion/test/auth-buffer-secrets.test.ts @@ -0,0 +1,185 @@ +import { createServer } from 'node:http' +import express from 'express' +import request from 'supertest' +import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest' +import { defaultOptions } from '../src/config/companion.js' +import * as tokenService from '../src/server/helpers/jwt.js' +import * as oAuthState from '../src/server/helpers/oauth-state.js' +import { gentleVerifyToken, verifyToken } from '../src/server/middlewares.js' +import { getCredentialsOverrideMiddleware } from '../src/server/provider/credentials.js' +import Provider from '../src/server/provider/Provider.js' + +vi.mock('express-prom-bundle') + +class DriveProvider extends Provider { + static override get oauthProvider(): string { + return 'drive' + } +} + +const secret = Buffer.from([ + 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, +]) +const preAuthSecret = Buffer.from([ + 0xab, 0xcd, 0xef, 0x42, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, + 0xa0, 0xb0, 0xc0, +]) + +type OAuthReqOptions = { + secret: Buffer +} + +function createOAuthApp(options: OAuthReqOptions) { + const app = express() + const companionOptions = { + ...defaultOptions, + secret: '', + filePath: '', + server: { ...defaultOptions.server, host: '' }, + } + Reflect.set(companionOptions, 'secret', options.secret) + app.use((req, _res, next) => { + req.companion = { + options: companionOptions, + providerClass: DriveProvider, + authToken: req.get('uppy-auth-token') ?? undefined, + } + next() + }) + return app +} + +describe('buffer secret compatibility', () => { + test('verifyToken accepts auth tokens signed with Buffer secrets', async () => { + const app = createOAuthApp({ secret }) + app.get('/verify/:providerName', verifyToken, (req, res) => { + res.json({ session: req.companion.providerUserSession }) + }) + + const token = tokenService.generateEncryptedAuthToken( + { drive: { accessToken: 'buffer-token' } }, + secret, + ) + + const res = await request(app) + .get('/verify/drive') + .set('uppy-auth-token', token) + .expect(200) + + expect(res.body).toEqual({ + session: { accessToken: 'buffer-token' }, + }) + }) + + test('gentleVerifyToken decodes auth tokens with Buffer secrets', async () => { + const app = createOAuthApp({ secret }) + app.get('/gentle/:providerName', gentleVerifyToken, (req, res) => { + res.json({ session: req.companion.providerUserSession ?? null }) + }) + + const token = tokenService.generateEncryptedAuthToken( + { drive: { accessToken: 'buffer-token' } }, + secret, + ) + + const res = await request(app) + .get('/gentle/drive') + .set('uppy-auth-token', token) + .expect(200) + + expect(res.body).toEqual({ + session: { accessToken: 'buffer-token' }, + }) + }) + + describe('credentials override middleware', () => { + const providers = { + drive: DriveProvider, + } + + let credentialsURL = '' + let credentialsServer: ReturnType | undefined + + beforeAll(async () => { + credentialsServer = createServer((req, res) => { + if (req.url !== '/keys' || req.method !== 'POST') { + res.statusCode = 404 + res.end() + return + } + res.setHeader('content-type', 'application/json') + res.end( + JSON.stringify({ + credentials: { + key: 'dynamic-key', + secret: 'dynamic-secret', + }, + }), + ) + }) + + await new Promise((resolve) => { + credentialsServer?.listen(0, '127.0.0.1', () => resolve()) + }) + + const address = credentialsServer.address() + if (!address || typeof address === 'string') { + throw new Error('Expected credentials server to listen on a TCP port') + } + credentialsURL = `http://127.0.0.1:${address.port}/keys` + }) + + afterAll(async () => { + await new Promise((resolve) => { + credentialsServer?.close(() => resolve()) + }) + }) + + test('supports Buffer secret/preAuthSecret for dynamic credentials', async () => { + const app = express() + const companionOptions = { + ...defaultOptions, + secret: '', + filePath: '', + server: { ...defaultOptions.server, host: '' }, + providerOptions: { + drive: { + credentialsURL, + }, + }, + } + Reflect.set(companionOptions, 'secret', secret) + Reflect.set(companionOptions, 'preAuthSecret', preAuthSecret) + + app.get( + '/:oauthProvider/connect', + getCredentialsOverrideMiddleware(providers, companionOptions), + (_req, res) => { + res.json(res.locals['grant'] ?? null) + }, + ) + + const preAuthToken = tokenService.generateEncryptedToken( + 'dynamic-credentials-request', + preAuthSecret, + ) + const state = oAuthState.encodeState( + { id: 'test-state', preAuthToken }, + secret, + ) + + const res = await request(app) + .get('/drive/connect') + .query({ state }) + .expect(200) + + expect(res.body).toEqual({ + dynamic: { + key: 'dynamic-key', + secret: 'dynamic-secret', + }, + }) + }) + }) +}) diff --git a/packages/@uppy/companion/test/callback.test.js b/packages/@uppy/companion/test/callback.test.ts similarity index 84% rename from packages/@uppy/companion/test/callback.test.js rename to packages/@uppy/companion/test/callback.test.ts index 4ad00b6c7..72750ced2 100644 --- a/packages/@uppy/companion/test/callback.test.js +++ b/packages/@uppy/companion/test/callback.test.ts @@ -15,7 +15,7 @@ describe('test authentication callback', () => { .get('/drive/callback') .expect(302) .expect((res) => { - expect(res.header.location).toContain( + expect(res.header['location']).toContain( 'http://localhost:3020/drive/send-token?uppyAuthToken=', ) }) @@ -26,13 +26,15 @@ describe('test authentication callback', () => { .get('/dropbox/callback') .expect(302) .expect((res) => { - expect(res.header.location).toContain( + expect(res.header['location']).toContain( 'http://localhost:3020/dropbox/send-token?uppyAuthToken=', ) + const setCookie = res.header['set-cookie'] + if (!Array.isArray(setCookie) || !setCookie[0]) { + throw new Error('Missing set-cookie header') + } const authToken = decodeURIComponent( - res.header['set-cookie'][0] - .split(';')[0] - .split('uppyAuthToken--dropbox=')[1], + setCookie[0].split(';')[0].split('uppyAuthToken--dropbox=')[1], ) const payload = tokenService.verifyEncryptedAuthToken( authToken, diff --git a/packages/@uppy/companion/test/companion.test.js b/packages/@uppy/companion/test/companion.test.ts similarity index 95% rename from packages/@uppy/companion/test/companion.test.js rename to packages/@uppy/companion/test/companion.test.ts index c034760fa..be3f458a6 100644 --- a/packages/@uppy/companion/test/companion.test.js +++ b/packages/@uppy/companion/test/companion.test.ts @@ -3,6 +3,7 @@ import request from 'supertest' import { afterAll, afterEach, describe, expect, it, test, vi } from 'vitest' import packageJson from '../package.json' with { type: 'json' } import * as tokenService from '../src/server/helpers/jwt.js' +import { isRecord } from '../src/server/helpers/type-guards.js' import * as defaults from './fixtures/constants.js' import { nockGoogleDownloadFile } from './fixtures/drive.js' import mockOauthState from './mockoauthstate.js' @@ -16,7 +17,11 @@ const fakeLocalhost = 'localhost.com' vi.mock('node:dns', () => ({ default: { - lookup: (hostname, options, callback) => { + lookup: ( + hostname: string, + _options: unknown, + callback: (err: Error | null, address?: string, family?: number) => void, + ) => { if (fakeLocalhost === hostname || hostname === 'localhost') { return callback(null, '127.0.0.1', 4) } @@ -46,7 +51,7 @@ afterAll(() => { describe('validate upload data', () => { test('access token expired or invalid when starting provider download', async () => { - const meta = { + const meta: { size: null; mimeType: string; id: string } = { size: null, mimeType: 'video/mp4', id: defaults.ITEM_ID, @@ -250,27 +255,28 @@ it('periodically pings', async () => { COMPANION_PERIODIC_PING_INTERVAL: '10', COMPANION_PERIODIC_PING_COUNT: '1', }), - new Promise((resolve) => { + new Promise((resolve) => { nock('http://localhost') .post( '/ping', - (body) => - body.some === 'value' && - body.version === packageJson.version && - typeof body.processId === 'string', + (body: unknown) => + isRecord(body) && + body['some'] === 'value' && + body['version'] === packageJson.version && + typeof body['processId'] === 'string', ) .reply(200, () => resolve()) }), ]) }, 3000) -async function runUrlMetaTest(url) { +async function runUrlMetaTest(url: string) { const server = await getServer() return request(server).post('/url/meta').send({ url }) } -async function runUrlGetTest(url) { +async function runUrlGetTest(url: string) { const server = await getServer() return request(server).post('/url/get').send({ diff --git a/packages/@uppy/companion/test/cors.test.js b/packages/@uppy/companion/test/cors.test.js deleted file mode 100644 index bfb631a0f..000000000 --- a/packages/@uppy/companion/test/cors.test.js +++ /dev/null @@ -1,120 +0,0 @@ -import { describe, expect, test, vi } from 'vitest' - -import { cors } from '../src/server/middlewares.js' - -function testWithMock({ - // @ts-ignore - corsOptions, - get = () => {}, - origin = 'https://localhost:1234', -} = {}) { - const res = { - get, - getHeader: get, - setHeader: vi.fn(), - end: vi.fn(), - } - const req = { - method: 'OPTIONS', - headers: { - origin, - }, - } - const next = vi.fn() - cors(corsOptions)(req, res, next) - return { res } -} - -describe('cors', () => { - test('should properly merge with existing headers', () => { - const get = (header) => { - if (header.toLowerCase() === 'access-control-allow-methods') - return 'PATCH,OPTIONS, post' - if (header.toLowerCase() === 'access-control-allow-headers') - return 'test-allow-header' - if (header.toLowerCase() === 'access-control-expose-headers') - return 'test' - return undefined - } - - const { res } = testWithMock({ - // @ts-ignore - corsOptions: { - sendSelfEndpoint: true, - corsOrigins: /^https:\/\/localhost:.*$/, - }, - get, - }) - expect(res.setHeader.mock.calls).toEqual([ - ['Access-Control-Allow-Origin', 'https://localhost:1234'], - ['Vary', 'Origin'], - ['Access-Control-Allow-Credentials', 'true'], - ['Access-Control-Allow-Methods', 'PATCH,OPTIONS,POST,GET,DELETE'], - [ - 'Access-Control-Allow-Headers', - 'test-allow-header,uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', - ], - ['Access-Control-Expose-Headers', 'test,i-am'], - ['Content-Length', '0'], - ]) - // expect(next).toHaveBeenCalled() - }) - - test('should also work when nothing added', () => { - const { res } = testWithMock() - expect(res.setHeader.mock.calls).toEqual([ - ['Access-Control-Allow-Origin', 'https://localhost:1234'], - ['Vary', 'Origin'], - ['Access-Control-Allow-Credentials', 'true'], - ['Access-Control-Allow-Methods', 'GET,POST,OPTIONS,DELETE'], - [ - 'Access-Control-Allow-Headers', - 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', - ], - ['Content-Length', '0'], - ]) - }) - - test('should support disabling cors', () => { - // @ts-ignore - const { res } = testWithMock({ corsOptions: { corsOrigins: false } }) - expect(res.setHeader.mock.calls).toEqual([]) - }) - - test('should support incorrect url', () => { - const { res } = testWithMock({ - // @ts-ignore - corsOptions: { corsOrigins: /^incorrect$/ }, - }) - expect(res.setHeader.mock.calls).toEqual([ - ['Vary', 'Origin'], - ['Access-Control-Allow-Credentials', 'true'], - ['Access-Control-Allow-Methods', 'GET,POST,OPTIONS,DELETE'], - [ - 'Access-Control-Allow-Headers', - 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', - ], - ['Content-Length', '0'], - ]) - }) - - test('should support array origin', () => { - const { res } = testWithMock({ - // @ts-ignore - corsOptions: { - corsOrigins: ['http://google.com', 'https://localhost:1234'], - }, - }) - expect(res.setHeader.mock.calls).toEqual([ - ['Access-Control-Allow-Origin', 'https://localhost:1234'], - ['Vary', 'Origin'], - ['Access-Control-Allow-Credentials', 'true'], - ['Access-Control-Allow-Methods', 'GET,POST,OPTIONS,DELETE'], - [ - 'Access-Control-Allow-Headers', - 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', - ], - ['Content-Length', '0'], - ]) - }) -}) diff --git a/packages/@uppy/companion/test/cors.test.ts b/packages/@uppy/companion/test/cors.test.ts new file mode 100644 index 000000000..6e3bc58f6 --- /dev/null +++ b/packages/@uppy/companion/test/cors.test.ts @@ -0,0 +1,119 @@ +import express from 'express' +import request from 'supertest' +import { describe, expect, test } from 'vitest' + +import { cors } from '../src/server/middlewares.js' + +async function run({ + corsOptions = {}, + origin = 'https://localhost:1234', + existingHeaders = {}, +}: { + corsOptions?: Parameters[0] + origin?: string + existingHeaders?: Record +}): Promise> { + const app = express() + app.use((_req, res, next) => { + for (const [k, v] of Object.entries(existingHeaders)) res.setHeader(k, v) + next() + }) + app.use(cors(corsOptions)) + app.options('*', (_req, res) => { + res.status(204).end() + }) + + const res = await request(app).options('/').set('Origin', origin) + return res.headers +} + +describe('cors', () => { + test('should properly merge with existing headers', () => { + return run({ + corsOptions: { + sendSelfEndpoint: 'localhost:3020', + corsOrigins: /^https:\/\/localhost:.*$/, + }, + existingHeaders: { + 'Access-Control-Allow-Methods': 'PATCH,OPTIONS, post', + 'Access-Control-Allow-Headers': 'test-allow-header', + 'Access-Control-Expose-Headers': 'test', + }, + }).then((headers) => { + expect(headers['access-control-allow-origin']).toBe( + 'https://localhost:1234', + ) + expect(headers['vary']).toBe('Origin') + expect(headers['access-control-allow-credentials']).toBe('true') + expect(headers['access-control-allow-methods']).toBe( + 'PATCH,OPTIONS,POST,GET,DELETE', + ) + expect(headers['access-control-allow-headers']).toBe( + 'test-allow-header,uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', + ) + expect(headers['access-control-expose-headers']).toBe('test,i-am') + expect(headers['content-length']).toBe('0') + }) + }) + + test('should also work when nothing added', () => { + return run({}).then((headers) => { + expect(headers['access-control-allow-origin']).toBe( + 'https://localhost:1234', + ) + expect(headers['vary']).toBe('Origin') + expect(headers['access-control-allow-credentials']).toBe('true') + expect(headers['access-control-allow-methods']).toBe( + 'GET,POST,OPTIONS,DELETE', + ) + expect(headers['access-control-allow-headers']).toBe( + 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', + ) + expect(headers['content-length']).toBe('0') + }) + }) + + test('should support disabling cors', () => { + return run({ corsOptions: { corsOrigins: false } }).then((headers) => { + expect(headers['access-control-allow-origin']).toBeUndefined() + }) + }) + + test('should support incorrect url', () => { + return run({ corsOptions: { corsOrigins: /^incorrect$/ } }).then( + (headers) => { + expect(headers['access-control-allow-origin']).toBeUndefined() + expect(headers['vary']).toBe('Origin') + expect(headers['access-control-allow-credentials']).toBe('true') + expect(headers['access-control-allow-methods']).toBe( + 'GET,POST,OPTIONS,DELETE', + ) + expect(headers['access-control-allow-headers']).toBe( + 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', + ) + expect(headers['content-length']).toBe('0') + }, + ) + }) + + test('should support array origin', () => { + return run({ + corsOptions: { + corsOrigins: ['http://google.com', 'https://localhost:1234'], + }, + }).then((headers) => { + expect(headers['access-control-allow-origin']).toBe( + 'https://localhost:1234', + ) + expect(headers['vary']).toBe('Origin') + expect(headers['access-control-allow-credentials']).toBe('true') + expect(headers['access-control-allow-methods']).toBe( + 'GET,POST,OPTIONS,DELETE', + ) + expect(headers['access-control-allow-headers']).toBe( + 'uppy-auth-token,uppy-credentials-params,authorization,origin,content-type,accept', + ) + expect(headers['content-length']).toBe('0') + }) + }) +}) diff --git a/packages/@uppy/companion/test/credentials.test.js b/packages/@uppy/companion/test/credentials.test.ts similarity index 100% rename from packages/@uppy/companion/test/credentials.test.js rename to packages/@uppy/companion/test/credentials.test.ts diff --git a/packages/@uppy/companion/test/deauthorization.test.js b/packages/@uppy/companion/test/deauthorization.test.ts similarity index 100% rename from packages/@uppy/companion/test/deauthorization.test.js rename to packages/@uppy/companion/test/deauthorization.test.ts diff --git a/packages/@uppy/companion/test/fixtures/box.js b/packages/@uppy/companion/test/fixtures/box.ts similarity index 80% rename from packages/@uppy/companion/test/fixtures/box.js rename to packages/@uppy/companion/test/fixtures/box.ts index f65526cec..41ff74f72 100644 --- a/packages/@uppy/companion/test/fixtures/box.js +++ b/packages/@uppy/companion/test/fixtures/box.ts @@ -1,3 +1,3 @@ export const expects = { itemIcon: 'file', -} +} as const diff --git a/packages/@uppy/companion/test/fixtures/constants.js b/packages/@uppy/companion/test/fixtures/constants.ts similarity index 100% rename from packages/@uppy/companion/test/fixtures/constants.js rename to packages/@uppy/companion/test/fixtures/constants.ts diff --git a/packages/@uppy/companion/test/fixtures/drive.js b/packages/@uppy/companion/test/fixtures/drive.ts similarity index 100% rename from packages/@uppy/companion/test/fixtures/drive.js rename to packages/@uppy/companion/test/fixtures/drive.ts diff --git a/packages/@uppy/companion/test/fixtures/dropbox.js b/packages/@uppy/companion/test/fixtures/dropbox.ts similarity index 100% rename from packages/@uppy/companion/test/fixtures/dropbox.js rename to packages/@uppy/companion/test/fixtures/dropbox.ts diff --git a/packages/@uppy/companion/test/fixtures/facebook.js b/packages/@uppy/companion/test/fixtures/facebook.ts similarity index 62% rename from packages/@uppy/companion/test/fixtures/facebook.js rename to packages/@uppy/companion/test/fixtures/facebook.ts index 64763d332..edf7b4928 100644 --- a/packages/@uppy/companion/test/fixtures/facebook.js +++ b/packages/@uppy/companion/test/fixtures/facebook.ts @@ -1,6 +1,11 @@ import * as defaults from './constants.js' -export const expects = { +export const expects: { + listPath: string + itemName: string + itemMimeType: string + itemSize: null +} = { listPath: 'ALBUM-ID', itemName: `${defaults.ITEM_ID} 2015-07-17T17:26:50+0000`, itemMimeType: 'image/jpeg', diff --git a/packages/@uppy/companion/test/fixtures/index.js b/packages/@uppy/companion/test/fixtures/index.ts similarity index 97% rename from packages/@uppy/companion/test/fixtures/index.js rename to packages/@uppy/companion/test/fixtures/index.ts index 752794077..70593d650 100644 --- a/packages/@uppy/companion/test/fixtures/index.js +++ b/packages/@uppy/companion/test/fixtures/index.ts @@ -15,6 +15,6 @@ export const providers = { onedrive, facebook, zoom, -} +} as const export const defaults = constants diff --git a/packages/@uppy/companion/test/fixtures/instagram.js b/packages/@uppy/companion/test/fixtures/instagram.ts similarity index 54% rename from packages/@uppy/companion/test/fixtures/instagram.js rename to packages/@uppy/companion/test/fixtures/instagram.ts index bc4fd12af..f1193ec00 100644 --- a/packages/@uppy/companion/test/fixtures/instagram.js +++ b/packages/@uppy/companion/test/fixtures/instagram.ts @@ -1,4 +1,8 @@ -export const expects = { +export const expects: { + itemName: string + itemMimeType: string + itemSize: null +} = { itemName: 'Instagram 2017-08-31T18:10:00+00000.jpeg', itemMimeType: 'image/jpeg', itemSize: null, diff --git a/packages/@uppy/companion/test/fixtures/onedrive.js b/packages/@uppy/companion/test/fixtures/onedrive.ts similarity index 92% rename from packages/@uppy/companion/test/fixtures/onedrive.js rename to packages/@uppy/companion/test/fixtures/onedrive.ts index 86a3ff16b..ea54ce270 100644 --- a/packages/@uppy/companion/test/fixtures/onedrive.js +++ b/packages/@uppy/companion/test/fixtures/onedrive.ts @@ -2,4 +2,4 @@ import * as defaults from './constants.js' export const expects = { itemRequestPath: `${defaults.ITEM_ID}?driveId=DUMMY-DRIVE-ID`, -} +} as const diff --git a/packages/@uppy/companion/test/fixtures/zoom.js b/packages/@uppy/companion/test/fixtures/zoom.ts similarity index 88% rename from packages/@uppy/companion/test/fixtures/zoom.js rename to packages/@uppy/companion/test/fixtures/zoom.ts index 8efb743e6..3800e7a4b 100644 --- a/packages/@uppy/companion/test/fixtures/zoom.js +++ b/packages/@uppy/companion/test/fixtures/zoom.ts @@ -14,9 +14,9 @@ export const expects = { remoteZoomKey: 'REMOTE-ZOOM-KEY', remoteZoomSecret: 'REMOTE-ZOOM-SECRET', remoteZoomVerificationToken: 'REMOTE-ZOOM-VERIFICATION-TOKEN', -} +} as const -export const nockZoomRecordings = ({ times = 1 } = {}) => { +export const nockZoomRecordings = ({ times = 1 }: { times?: number } = {}) => { nock('https://zoom.us') .get('/v2/meetings/DUMMY-UUID%3D%3D/recordings') .times(times) @@ -50,13 +50,19 @@ export const nockZoomRecordings = ({ times = 1 } = {}) => { }) } -export const nockZoomRevoke = ({ key, secret }) => { +export const nockZoomRevoke = ({ + key, + secret, +}: { + key: string + secret: string +}) => { nock('https://zoom.us') .post('/oauth/revoke?token=token+value') .reply(function () { const { headers } = this.req const expected = getBasicAuthHeader(key, secret) - const success = headers.authorization === expected + const success = headers['authorization'] === expected return success ? [200, { status: 'success' }] : [400] }) } diff --git a/packages/@uppy/companion/test/header-blacklist.test.js b/packages/@uppy/companion/test/header-blacklist.test.ts similarity index 93% rename from packages/@uppy/companion/test/header-blacklist.test.js rename to packages/@uppy/companion/test/header-blacklist.test.ts index 310d3ae3c..e9a73a178 100644 --- a/packages/@uppy/companion/test/header-blacklist.test.js +++ b/packages/@uppy/companion/test/header-blacklist.test.ts @@ -49,9 +49,12 @@ describe('Header black-list testing', () => { test('Return empty object when headers is not an object', () => { expect(headerSanitize({})).toEqual({}) + // @ts-expect-error testing invalid input expect(headerSanitize(null)).toEqual({}) expect(headerSanitize(undefined)).toEqual({}) + // @ts-expect-error testing invalid input expect(headerSanitize('Authorization: Basic 1234')).toEqual({}) + // @ts-expect-error testing invalid input expect(headerSanitize(['Authorization', 'Basic 1234'])).toEqual({}) }) }) diff --git a/packages/@uppy/companion/test/http-agent.test.js b/packages/@uppy/companion/test/http-agent.test.ts similarity index 100% rename from packages/@uppy/companion/test/http-agent.test.js rename to packages/@uppy/companion/test/http-agent.test.ts diff --git a/packages/@uppy/companion/test/logger.test.js b/packages/@uppy/companion/test/logger.test.ts similarity index 91% rename from packages/@uppy/companion/test/logger.test.js rename to packages/@uppy/companion/test/logger.test.ts index 60a5e5442..7ddaed8f5 100644 --- a/packages/@uppy/companion/test/logger.test.js +++ b/packages/@uppy/companion/test/logger.test.ts @@ -1,21 +1,21 @@ import { beforeAll, describe, expect, test } from 'vitest' // We don't care about colors in our tests, so force `supports-color` to disable colors. -process.env.FORCE_COLOR = 'false' +process.env['FORCE_COLOR'] = 'false' import logger from '../src/server/logger.js' const maskables = ['ToBeMasked1', 'toBeMasked2', 'toBeMasked(And)?Escaped'] -function captureConsoleLog(log) { - let loggedMessage = null +function captureConsoleLog(log: () => void): string { + let loggedMessage: string | null = null // override the default console.log to capture the logged message const defaultConsoleLog = console.log try { - console.log = (logPrefix, message) => { - loggedMessage = message + console.log = (logPrefix: unknown, message: unknown) => { + loggedMessage = String(message) defaultConsoleLog(logPrefix, message) } } finally { @@ -23,6 +23,9 @@ function captureConsoleLog(log) { // restore the default console.log before using "expect" to avoid weird log behaviors console.log = defaultConsoleLog } + if (loggedMessage == null) { + throw new Error('Expected logger to write a console message') + } return loggedMessage } @@ -107,7 +110,6 @@ describe('Test Logger secret mask', () => { test('masks inside object', () => { const loggedMessage = captureConsoleLog(() => { - // @ts-ignore logger.warn({ a: 1, deep: { secret: 'there is a ToBeMasked1 hiding here' }, diff --git a/packages/@uppy/companion/test/mockoauthstate.js b/packages/@uppy/companion/test/mockoauthstate.ts similarity index 78% rename from packages/@uppy/companion/test/mockoauthstate.js rename to packages/@uppy/companion/test/mockoauthstate.ts index 69cd4cad7..b648d9d3e 100644 --- a/packages/@uppy/companion/test/mockoauthstate.js +++ b/packages/@uppy/companion/test/mockoauthstate.ts @@ -1,10 +1,10 @@ import { vi } from 'vitest' const mockOauthState = () => { - vi.mock('../src/server/helpers/oauth-state.js', async () => ({ - ...(await vi.importActual('../src/server/helpers/oauth-state.js')), + vi.mock('../src/server/helpers/oauth-state.ts', async () => ({ + ...(await vi.importActual('../src/server/helpers/oauth-state.ts')), generateState: () => ({}), - getFromState: (state) => { + getFromState: (state: string) => { if (state === 'state-with-invalid-instance-url') { return 'http://localhost:3452' } diff --git a/packages/@uppy/companion/test/mockserver.js b/packages/@uppy/companion/test/mockserver.ts similarity index 69% rename from packages/@uppy/companion/test/mockserver.js rename to packages/@uppy/companion/test/mockserver.ts index ad3bf1f22..0f2ed32ee 100644 --- a/packages/@uppy/companion/test/mockserver.js +++ b/packages/@uppy/companion/test/mockserver.ts @@ -25,18 +25,22 @@ const defaultEnv = { COMPANION_DROPBOX_KEY: 'dropbox_key', COMPANION_DROPBOX_SECRET: 'dropbox_secret', COMPANION_DROPBOX_KEYS_ENDPOINT: undefined, + COMPANION_DROPBOX_SECRET_FILE: undefined, COMPANION_BOX_KEY: 'box_key', COMPANION_BOX_SECRET: 'box_secret', COMPANION_BOX_KEYS_ENDPOINT: undefined, + COMPANION_BOX_SECRET_FILE: undefined, COMPANION_GOOGLE_KEY: 'google_key', COMPANION_GOOGLE_SECRET: 'google_secret', COMPANION_GOOGLE_KEYS_ENDPOINT: undefined, + COMPANION_GOOGLE_SECRET_FILE: undefined, COMPANION_INSTAGRAM_KEY: 'instagram_key', COMPANION_INSTAGRAM_SECRET: 'instagram_secret', COMPANION_INSTAGRAM_KEYS_ENDPOINT: undefined, + COMPANION_INSTAGRAM_SECRET_FILE: undefined, COMPANION_FACEBOOK_KEY: 'facebook_key', COMPANION_FACEBOOK_SECRET: 'facebook_secret', @@ -46,23 +50,35 @@ const defaultEnv = { COMPANION_ZOOM_SECRET: localZoomSecret, COMPANION_ZOOM_VERIFICATION_TOKEN: localZoomVerificationToken, COMPANION_ZOOM_KEYS_ENDPOINT: undefined, + COMPANION_ZOOM_SECRET_FILE: undefined, + COMPANION_ZOOM_VERIFICATION_TOKEN_FILE: undefined, COMPANION_PATH: '', COMPANION_PERIODIC_PING_URLS: '', + COMPANION_PERIODIC_PING_INTERVAL: '', + COMPANION_PERIODIC_PING_COUNT: '', + COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD: '', COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT: '', COMPANION_ENABLE_URL_ENDPOINT: 'true', COMPANION_CLIENT_ORIGINS: 'true', -} -function updateEnv(env) { + COMPANION_OAUTH_DOMAIN: '', + + COMPANION_AWS_KEY: '', + COMPANION_AWS_SECRET: '', + COMPANION_AWS_REGION: '', + COMPANION_AWS_BUCKET: '', +} satisfies Record + +function updateEnv(env: Record): void { Object.keys(env).forEach((key) => { const value = env[key] if (value == null) delete process.env[key] - else process.env[key] = value + else process.env[key] = String(value) }) } @@ -73,7 +89,9 @@ export const grantToken = 'fake token' // companion stores certain global state, so the user needs to reset modules for each test // todo rewrite companion to not use global state // https://github.com/transloadit/uppy/issues/3284 -export const getServer = async (extraEnv) => { +export const getServer = async ( + extraEnv: Record = {}, +): Promise> => { const { default: standalone } = await import('../src/standalone/index.js') const env = { @@ -89,16 +107,20 @@ export const getServer = async (extraEnv) => { session({ secret: 'grant', resave: true, saveUninitialized: true }), ) authServer.all('*/callback', (req, res, next) => { - // @ts-ignore - req.session.grant = { - response: { access_token: grantToken }, + if (req.session) { + req.session['grant'] = { + response: { access_token: grantToken }, + } } next() }) authServer.all(['*/send-token', '*/redirect'], (req, res, next) => { - // @ts-ignore - req.session.grant = { - dynamic: { state: req.query.state || 'non-empty-value' }, + const state = + typeof req.query['state'] === 'string' ? req.query['state'] : null + if (req.session) { + req.session['grant'] = { + dynamic: { state: state ?? 'non-empty-value' }, + } } next() }) diff --git a/packages/@uppy/companion/test/mocksocket.js b/packages/@uppy/companion/test/mocksocket.js deleted file mode 100644 index c528208d6..000000000 --- a/packages/@uppy/companion/test/mocksocket.js +++ /dev/null @@ -1,29 +0,0 @@ -import emitter from '../src/server/emitter/index.js' - -export const connect = (uploadToken) => { - emitter().emit(`connection:${uploadToken}`) -} - -export const onProgress = (uploadToken, cb) => { - emitter().on(uploadToken, (message) => { - if (message.action === 'progress') { - cb(message) - } - }) -} - -export const onUploadSuccess = (uploadToken, cb) => { - emitter().on(uploadToken, (message) => { - if (message.action === 'success') { - cb(message) - } - }) -} - -export const onUploadError = (uploadToken, cb) => { - emitter().on(uploadToken, (message) => { - if (message.action === 'error') { - cb(message) - } - }) -} diff --git a/packages/@uppy/companion/test/mocksocket.ts b/packages/@uppy/companion/test/mocksocket.ts new file mode 100644 index 000000000..4567482e1 --- /dev/null +++ b/packages/@uppy/companion/test/mocksocket.ts @@ -0,0 +1,45 @@ +import emitter from '../src/server/emitter/index.js' +import { isRecord } from '../src/server/helpers/type-guards.js' + +type UploadMessage = Record & { action: string } + +function isUploadMessage(value: unknown): value is UploadMessage { + return isRecord(value) && typeof value['action'] === 'string' +} + +export const connect = (uploadToken: string): void => { + emitter().emit(`connection:${uploadToken}`) +} + +export const onProgress = ( + uploadToken: string, + cb: (message: UploadMessage) => void, +): void => { + emitter().on(uploadToken, (message: unknown) => { + if (isUploadMessage(message) && message['action'] === 'progress') { + cb(message) + } + }) +} + +export const onUploadSuccess = ( + uploadToken: string, + cb: (message: UploadMessage) => void, +): void => { + emitter().on(uploadToken, (message: unknown) => { + if (isUploadMessage(message) && message['action'] === 'success') { + cb(message) + } + }) +} + +export const onUploadError = ( + uploadToken: string, + cb: (message: UploadMessage) => void, +): void => { + emitter().on(uploadToken, (message: unknown) => { + if (isUploadMessage(message) && message['action'] === 'error') { + cb(message) + } + }) +} diff --git a/packages/@uppy/companion/test/preauth.test.js b/packages/@uppy/companion/test/preauth.test.ts similarity index 100% rename from packages/@uppy/companion/test/preauth.test.js rename to packages/@uppy/companion/test/preauth.test.ts diff --git a/packages/@uppy/companion/test/provider-manager.test.js b/packages/@uppy/companion/test/provider-manager.test.js deleted file mode 100644 index d1d21a1aa..000000000 --- a/packages/@uppy/companion/test/provider-manager.test.js +++ /dev/null @@ -1,215 +0,0 @@ -import { beforeEach, describe, expect, test } from 'vitest' -import GrantConfig from '../src/config/grant.js' -import * as providerManager from '../src/server/provider/index.js' -import { getCompanionOptions } from '../src/standalone/helper.js' -import { setDefaultEnv } from './mockserver.js' - -let grantConfig -let companionOptions - -const getOauthProvider = (providerName) => - providerManager.getDefaultProviders()[providerName]?.oauthProvider - -describe('Test Provider options', () => { - beforeEach(() => { - setDefaultEnv() - grantConfig = GrantConfig() - companionOptions = getCompanionOptions() - }) - - test('adds provider options', () => { - providerManager.addProviderOptions( - companionOptions, - grantConfig, - getOauthProvider, - ) - expect(grantConfig.dropbox.key).toBe('dropbox_key') - expect(grantConfig.dropbox.secret).toBe('dropbox_secret') - - expect(grantConfig.box.key).toBe('box_key') - expect(grantConfig.box.secret).toBe('box_secret') - - expect(grantConfig.googledrive.key).toBe('google_key') - expect(grantConfig.googledrive.secret).toBe('google_secret') - - expect(grantConfig.googledrive.secret).toBe('google_secret') - - expect(grantConfig.instagram.key).toBe('instagram_key') - expect(grantConfig.instagram.secret).toBe('instagram_secret') - - expect(grantConfig.zoom.key).toBe('zoom_key') - expect(grantConfig.zoom.secret).toBe('zoom_secret') - }) - - test('adds extra provider config', () => { - process.env.COMPANION_INSTAGRAM_KEY = '123456' - providerManager.addProviderOptions( - getCompanionOptions(), - grantConfig, - getOauthProvider, - ) - expect(grantConfig.instagram).toEqual({ - transport: 'session', - state: true, - callback: '/instagram/callback', - redirect_uri: 'http://localhost:3020/instagram/redirect', - key: '123456', - secret: 'instagram_secret', - protocol: 'https', - scope: ['user_profile', 'user_media'], - }) - - expect(grantConfig.dropbox).toEqual({ - key: 'dropbox_key', - secret: 'dropbox_secret', - transport: 'session', - state: true, - redirect_uri: 'http://localhost:3020/dropbox/redirect', - authorize_url: 'https://www.dropbox.com/oauth2/authorize', - access_url: 'https://api.dropbox.com/oauth2/token', - callback: '/dropbox/callback', - custom_params: { - token_access_type: 'offline', - }, - }) - - expect(grantConfig.box).toEqual({ - key: 'box_key', - secret: 'box_secret', - transport: 'session', - state: true, - redirect_uri: 'http://localhost:3020/box/redirect', - authorize_url: 'https://account.box.com/api/oauth2/authorize', - access_url: 'https://api.box.com/oauth2/token', - callback: '/box/callback', - }) - - expect(grantConfig.googledrive).toEqual({ - access_url: 'https://oauth2.googleapis.com/token', - authorize_url: 'https://accounts.google.com/o/oauth2/v2/auth', - oauth: 2, - scope_delimiter: ' ', - - key: 'google_key', - secret: 'google_secret', - transport: 'session', - state: true, - redirect_uri: 'http://localhost:3020/drive/redirect', - scope: ['https://www.googleapis.com/auth/drive.readonly'], - callback: '/drive/callback', - custom_params: { - access_type: 'offline', - prompt: 'consent', - }, - }) - - expect(grantConfig.zoom).toEqual({ - key: 'zoom_key', - secret: 'zoom_secret', - transport: 'session', - state: true, - authorize_url: 'https://zoom.us/oauth/authorize', - redirect_uri: 'http://localhost:3020/zoom/redirect', - access_url: 'https://zoom.us/oauth/token', - callback: '/zoom/callback', - }) - }) - - test('adds provider options for secret files', () => { - process.env.COMPANION_DROPBOX_SECRET_FILE = `${process.env.PWD}/test/resources/dropbox_secret_file` - process.env.COMPANION_BOX_SECRET_FILE = `${process.env.PWD}/test/resources/box_secret_file` - process.env.COMPANION_GOOGLE_SECRET_FILE = `${process.env.PWD}/test/resources/google_secret_file` - process.env.COMPANION_INSTAGRAM_SECRET_FILE = `${process.env.PWD}/test/resources/instagram_secret_file` - process.env.COMPANION_ZOOM_SECRET_FILE = `${process.env.PWD}/test/resources/zoom_secret_file` - process.env.COMPANION_ZOOM_VERIFICATION_TOKEN_FILE = `${process.env.PWD}/test/resources/zoom_verification_token_file` - - companionOptions = getCompanionOptions() - - providerManager.addProviderOptions( - companionOptions, - grantConfig, - getOauthProvider, - ) - - expect(grantConfig.dropbox.secret).toBe('xobpord') - expect(grantConfig.box.secret).toBe('xwbepqd') - expect(grantConfig.googledrive.secret).toBe('elgoog') - expect(grantConfig.instagram.secret).toBe('margatsni') - expect(grantConfig.zoom.secret).toBe('u8Z5ceq') - expect(companionOptions.providerOptions.zoom.verificationToken).toBe( - 'o0u8Z5c', - ) - }) - - test('does not add provider options if protocol and host are not set', () => { - delete companionOptions.server.host - delete companionOptions.server.protocol - - providerManager.addProviderOptions( - companionOptions, - grantConfig, - getOauthProvider, - ) - expect(grantConfig.dropbox.key).toBeUndefined() - expect(grantConfig.dropbox.secret).toBeUndefined() - - expect(grantConfig.box.key).toBeUndefined() - expect(grantConfig.box.secret).toBeUndefined() - - expect(grantConfig.googledrive.key).toBeUndefined() - expect(grantConfig.googledrive.secret).toBeUndefined() - - expect(grantConfig.instagram.key).toBeUndefined() - expect(grantConfig.instagram.secret).toBeUndefined() - - expect(grantConfig.zoom.key).toBeUndefined() - expect(grantConfig.zoom.secret).toBeUndefined() - }) - - test('sets a main redirect uri, if oauthDomain is set', () => { - companionOptions.server.oauthDomain = 'domain.com' - providerManager.addProviderOptions( - companionOptions, - grantConfig, - getOauthProvider, - ) - - expect(grantConfig.dropbox.redirect_uri).toBe( - 'http://domain.com/dropbox/redirect', - ) - expect(grantConfig.box.redirect_uri).toBe('http://domain.com/box/redirect') - expect(grantConfig.googledrive.redirect_uri).toBe( - 'http://domain.com/drive/redirect', - ) - expect(grantConfig.instagram.redirect_uri).toBe( - 'http://domain.com/instagram/redirect', - ) - expect(grantConfig.zoom.redirect_uri).toBe( - 'http://domain.com/zoom/redirect', - ) - }) -}) - -describe('Test Custom Provider options', () => { - test('adds custom provider options', () => { - const providers = providerManager.getDefaultProviders() - providerManager.addCustomProviders( - { - foo: { - config: { - key: 'foo_key', - secret: 'foo_secret', - }, - // @ts-ignore - module: { oauthProvider: 'some_provider' }, - }, - }, - providers, - grantConfig, - ) - - expect(grantConfig.some_provider.key).toBe('foo_key') - expect(grantConfig.some_provider.secret).toBe('foo_secret') - expect(providers.foo).toBeTruthy() - }) -}) diff --git a/packages/@uppy/companion/test/provider-manager.test.ts b/packages/@uppy/companion/test/provider-manager.test.ts new file mode 100644 index 000000000..ce386fc6b --- /dev/null +++ b/packages/@uppy/companion/test/provider-manager.test.ts @@ -0,0 +1,306 @@ +import { beforeEach, describe, expect, test } from 'vitest' +import createGrantConfig from '../src/config/grant.js' +import * as providerManager from '../src/server/provider/index.js' +import Provider, { type ProviderCtor } from '../src/server/provider/Provider.js' +import { getCompanionOptions } from '../src/standalone/helper.js' +import { setDefaultEnv } from './mockserver.js' + +type GrantConfigType = providerManager.GrantConfig + +let grantConfig: GrantConfigType +let companionOptions: ReturnType + +const getOauthProvider = (providerName: string) => + providerManager.getDefaultProviders()[ + providerName as keyof ReturnType< + (typeof providerManager)['getDefaultProviders'] + > + ]?.oauthProvider + +function getAddProviderOptionsArgs( + options: ReturnType, +): Parameters[0] { + const { server, providerOptions } = options + return { + ...(server === undefined ? {} : { server }), + ...(providerOptions === undefined ? {} : { providerOptions }), + } +} + +function requireGrantProviderConfig( + config: GrantConfigType, + providerName: string, +) { + const providerConfig = config[providerName] + if (!providerConfig) { + throw new Error(`Expected grantConfig['${providerName}'] to be an object`) + } + return providerConfig +} + +function getGrantProviderField( + config: GrantConfigType, + providerName: string, + fieldName: keyof providerManager.GrantProviderConfig, +): unknown { + const providerConfig = config[providerName] + return providerConfig?.[fieldName] +} + +describe('Test Provider options', () => { + beforeEach(() => { + setDefaultEnv() + grantConfig = createGrantConfig() + companionOptions = getCompanionOptions() + }) + + test('adds provider options', () => { + providerManager.addProviderOptions( + getAddProviderOptionsArgs(companionOptions), + grantConfig, + getOauthProvider, + ) + const dropbox = requireGrantProviderConfig(grantConfig, 'dropbox') + expect(dropbox['key']).toBe('dropbox_key') + expect(dropbox['secret']).toBe('dropbox_secret') + + const box = requireGrantProviderConfig(grantConfig, 'box') + expect(box['key']).toBe('box_key') + expect(box['secret']).toBe('box_secret') + + const googledrive = requireGrantProviderConfig(grantConfig, 'googledrive') + expect(googledrive['key']).toBe('google_key') + expect(googledrive['secret']).toBe('google_secret') + + expect(googledrive['secret']).toBe('google_secret') + + const instagram = requireGrantProviderConfig(grantConfig, 'instagram') + expect(instagram['key']).toBe('instagram_key') + expect(instagram['secret']).toBe('instagram_secret') + + const zoom = requireGrantProviderConfig(grantConfig, 'zoom') + expect(zoom['key']).toBe('zoom_key') + expect(zoom['secret']).toBe('zoom_secret') + }) + + test('adds extra provider config', () => { + process.env['COMPANION_INSTAGRAM_KEY'] = '123456' + providerManager.addProviderOptions( + getAddProviderOptionsArgs(getCompanionOptions()), + grantConfig, + getOauthProvider, + ) + expect(requireGrantProviderConfig(grantConfig, 'instagram')).toEqual({ + transport: 'session', + state: true, + callback: '/instagram/callback', + redirect_uri: 'http://localhost:3020/instagram/redirect', + key: '123456', + secret: 'instagram_secret', + protocol: 'https', + scope: ['user_profile', 'user_media'], + }) + + expect(requireGrantProviderConfig(grantConfig, 'dropbox')).toEqual({ + key: 'dropbox_key', + secret: 'dropbox_secret', + transport: 'session', + state: true, + redirect_uri: 'http://localhost:3020/dropbox/redirect', + authorize_url: 'https://www.dropbox.com/oauth2/authorize', + access_url: 'https://api.dropbox.com/oauth2/token', + callback: '/dropbox/callback', + custom_params: { + token_access_type: 'offline', + }, + }) + + expect(requireGrantProviderConfig(grantConfig, 'box')).toEqual({ + key: 'box_key', + secret: 'box_secret', + transport: 'session', + state: true, + redirect_uri: 'http://localhost:3020/box/redirect', + authorize_url: 'https://account.box.com/api/oauth2/authorize', + access_url: 'https://api.box.com/oauth2/token', + callback: '/box/callback', + }) + + expect(requireGrantProviderConfig(grantConfig, 'googledrive')).toEqual({ + access_url: 'https://oauth2.googleapis.com/token', + authorize_url: 'https://accounts.google.com/o/oauth2/v2/auth', + oauth: 2, + scope_delimiter: ' ', + + key: 'google_key', + secret: 'google_secret', + transport: 'session', + state: true, + redirect_uri: 'http://localhost:3020/drive/redirect', + scope: ['https://www.googleapis.com/auth/drive.readonly'], + callback: '/drive/callback', + custom_params: { + access_type: 'offline', + prompt: 'consent', + }, + }) + + expect(requireGrantProviderConfig(grantConfig, 'zoom')).toEqual({ + key: 'zoom_key', + secret: 'zoom_secret', + transport: 'session', + state: true, + authorize_url: 'https://zoom.us/oauth/authorize', + redirect_uri: 'http://localhost:3020/zoom/redirect', + access_url: 'https://zoom.us/oauth/token', + callback: '/zoom/callback', + }) + }) + + test('adds provider options for secret files', () => { + process.env['COMPANION_DROPBOX_SECRET_FILE'] = + `${process.env['PWD']}/test/resources/dropbox_secret_file` + process.env['COMPANION_BOX_SECRET_FILE'] = + `${process.env['PWD']}/test/resources/box_secret_file` + process.env['COMPANION_GOOGLE_SECRET_FILE'] = + `${process.env['PWD']}/test/resources/google_secret_file` + process.env['COMPANION_INSTAGRAM_SECRET_FILE'] = + `${process.env['PWD']}/test/resources/instagram_secret_file` + process.env['COMPANION_ZOOM_SECRET_FILE'] = + `${process.env['PWD']}/test/resources/zoom_secret_file` + process.env['COMPANION_ZOOM_VERIFICATION_TOKEN_FILE'] = + `${process.env['PWD']}/test/resources/zoom_verification_token_file` + + companionOptions = getCompanionOptions() + + providerManager.addProviderOptions( + getAddProviderOptionsArgs(companionOptions), + grantConfig, + getOauthProvider, + ) + + expect(requireGrantProviderConfig(grantConfig, 'dropbox')['secret']).toBe( + 'xobpord', + ) + expect(requireGrantProviderConfig(grantConfig, 'box')['secret']).toBe( + 'xwbepqd', + ) + expect( + requireGrantProviderConfig(grantConfig, 'googledrive')['secret'], + ).toBe('elgoog') + expect(requireGrantProviderConfig(grantConfig, 'instagram')['secret']).toBe( + 'margatsni', + ) + expect(requireGrantProviderConfig(grantConfig, 'zoom')['secret']).toBe( + 'u8Z5ceq', + ) + + const providerOptions = companionOptions.providerOptions + const zoomProviderOptions = providerOptions?.['zoom'] + if (zoomProviderOptions == null) { + throw new Error( + 'Expected companionOptions.providerOptions["zoom"] to exist', + ) + } + expect(zoomProviderOptions['verificationToken']).toBe('o0u8Z5c') + }) + + test('does not add provider options if protocol and host are not set', () => { + const server = companionOptions.server + + // @ts-expect-error we are intentionally deleting these fields to test the behavior when they are missing + delete server['host'] + delete server['protocol'] + + providerManager.addProviderOptions( + getAddProviderOptionsArgs(companionOptions), + grantConfig, + getOauthProvider, + ) + expect(getGrantProviderField(grantConfig, 'dropbox', 'key')).toBeUndefined() + expect( + getGrantProviderField(grantConfig, 'dropbox', 'secret'), + ).toBeUndefined() + + expect(getGrantProviderField(grantConfig, 'box', 'key')).toBeUndefined() + expect(getGrantProviderField(grantConfig, 'box', 'secret')).toBeUndefined() + + expect( + getGrantProviderField(grantConfig, 'googledrive', 'key'), + ).toBeUndefined() + expect( + getGrantProviderField(grantConfig, 'googledrive', 'secret'), + ).toBeUndefined() + + expect( + getGrantProviderField(grantConfig, 'instagram', 'key'), + ).toBeUndefined() + expect( + getGrantProviderField(grantConfig, 'instagram', 'secret'), + ).toBeUndefined() + + expect(getGrantProviderField(grantConfig, 'zoom', 'key')).toBeUndefined() + expect(getGrantProviderField(grantConfig, 'zoom', 'secret')).toBeUndefined() + }) + + test('sets a main redirect uri, if oauthDomain is set', () => { + const server = companionOptions.server + if (server == null) throw new Error('Expected companionOptions.server') + server['oauthDomain'] = 'domain.com' + providerManager.addProviderOptions( + getAddProviderOptionsArgs(companionOptions), + grantConfig, + getOauthProvider, + ) + + expect( + requireGrantProviderConfig(grantConfig, 'dropbox')['redirect_uri'], + ).toBe('http://domain.com/dropbox/redirect') + expect(requireGrantProviderConfig(grantConfig, 'box')['redirect_uri']).toBe( + 'http://domain.com/box/redirect', + ) + expect( + requireGrantProviderConfig(grantConfig, 'googledrive')['redirect_uri'], + ).toBe('http://domain.com/drive/redirect') + expect( + requireGrantProviderConfig(grantConfig, 'instagram')['redirect_uri'], + ).toBe('http://domain.com/instagram/redirect') + expect( + requireGrantProviderConfig(grantConfig, 'zoom')['redirect_uri'], + ).toBe('http://domain.com/zoom/redirect') + }) +}) + +describe('Test Custom Provider options', () => { + test('adds custom provider options', () => { + const providers = providerManager.getDefaultProviders() + + class SomeProvider extends Provider { + static override get oauthProvider(): string { + return 'some_provider' + } + } + + providerManager.addCustomProviders( + { + foo: { + config: { + key: 'foo_key', + secret: 'foo_secret', + }, + module: SomeProvider, + }, + }, + providers as Record, + grantConfig, + ) + + const someProvider = requireGrantProviderConfig( + grantConfig, + 'some_provider', + ) + expect(someProvider['key']).toBe('foo_key') + expect(someProvider['secret']).toBe('foo_secret') + expect(providers['foo' as keyof typeof providers]).toBeTruthy() + }) +}) diff --git a/packages/@uppy/companion/test/providers.test.js b/packages/@uppy/companion/test/providers.test.ts similarity index 86% rename from packages/@uppy/companion/test/providers.test.js rename to packages/@uppy/companion/test/providers.test.ts index ec5f77578..f7d45a215 100644 --- a/packages/@uppy/companion/test/providers.test.js +++ b/packages/@uppy/companion/test/providers.test.ts @@ -10,6 +10,7 @@ import { vi, } from 'vitest' import * as tokenService from '../src/server/helpers/jwt.js' +import { isRecord } from '../src/server/helpers/type-guards.js' import * as providerModule from '../src/server/provider/index.js' import * as defaults from './fixtures/constants.js' import { nockGoogleDownloadFile } from './fixtures/drive.js' @@ -42,20 +43,21 @@ const OAUTH_STATE = 'some-cool-nice-encrytpion' const secret = 'secret' const providers = providerModule.getDefaultProviders() +const fixtureProviders = fixtures.providers const providerNames = Object.keys(providers) -const oauthProviders = Object.fromEntries( +const oauthProviders: Record = Object.fromEntries( Object.entries(providers).flatMap(([name, provider]) => provider.oauthProvider != null ? [[name, provider.oauthProvider]] : [], ), ) -const authData = {} +const authData: Record = {} providerNames.forEach((provider) => { authData[provider] = { accessToken: 'token value' } }) const token = tokenService.generateEncryptedAuthToken(authData, secret) -const thisOrThat = (value1, value2) => { +const thisOrThat = (value1: T | undefined, value2: T): T => { if (value1 !== undefined) { return value1 } @@ -99,10 +101,12 @@ afterAll(() => { }) describe('list provider files', () => { - async function runTest(providerName) { - const providerFixture = fixtures.providers[providerName]?.expects ?? {} + async function runTest(providerName: keyof typeof fixtureProviders) { + const providerFixture = fixtureProviders[providerName]?.expects ?? {} + const listPath = + 'listPath' in providerFixture ? providerFixture.listPath : '' return request(await getServerWithEnv()) - .get(`/${providerName}/list/${providerFixture.listPath || ''}`) + .get(`/${providerName}/list/${listPath}`) .set('uppy-auth-token', token) .expect(200) .then((res) => { @@ -110,29 +114,52 @@ describe('list provider files', () => { return { username: res.body.username, - items: res.body.items, + items: Array.isArray(res.body.items) + ? res.body.items.filter(isRecord) + : [], providerFixture, } }) } - function expect1({ username, items, providerFixture }) { + function expect1({ + username, + items, + providerFixture, + }: { + username: unknown + items: Array> + providerFixture: (typeof fixtureProviders)[keyof typeof fixtureProviders]['expects'] + }) { expect(username).toBe(defaults.USERNAME) const item = items[0] - expect(item.isFolder).toBe(false) - expect(item.name).toBe(providerFixture.itemName || defaults.ITEM_NAME) - expect(item.mimeType).toBe( - providerFixture.itemMimeType || defaults.MIME_TYPE, - ) - expect(item.id).toBe(providerFixture.itemId || defaults.ITEM_ID) - expect(item.size).toBe( - thisOrThat(providerFixture.itemSize, defaults.FILE_SIZE), - ) - expect(item.requestPath).toBe( - providerFixture.itemRequestPath || defaults.ITEM_ID, - ) - expect(item.icon).toBe(providerFixture.itemIcon || defaults.THUMBNAIL_URL) + if (!item) throw new Error('Expected at least one item') + + const fixtureItemName = + 'itemName' in providerFixture ? providerFixture.itemName : undefined + const fixtureItemMimeType = + 'itemMimeType' in providerFixture + ? providerFixture['itemMimeType'] + : undefined + const fixtureItemId = + 'itemId' in providerFixture ? providerFixture['itemId'] : undefined + const fixtureItemSize = + 'itemSize' in providerFixture ? providerFixture.itemSize : undefined + const fixtureItemRequestPath = + 'itemRequestPath' in providerFixture + ? providerFixture['itemRequestPath'] + : undefined + const fixtureItemIcon = + 'itemIcon' in providerFixture ? providerFixture['itemIcon'] : undefined + + expect(item['isFolder']).toBe(false) + expect(item['name']).toBe(fixtureItemName ?? defaults.ITEM_NAME) + expect(item['mimeType']).toBe(fixtureItemMimeType ?? defaults.MIME_TYPE) + expect(item['id']).toBe(fixtureItemId ?? defaults.ITEM_ID) + expect(item['size']).toBe(thisOrThat(fixtureItemSize, defaults.FILE_SIZE)) + expect(item['requestPath']).toBe(fixtureItemRequestPath ?? defaults.ITEM_ID) + expect(item['icon']).toBe(fixtureItemIcon ?? defaults.THUMBNAIL_URL) } test('dropbox', async () => { @@ -387,12 +414,14 @@ describe('list provider files', () => { }) describe('provider file gets downloaded from', () => { - async function runTest(providerName) { - const providerFixture = fixtures.providers[providerName]?.expects ?? {} + async function runTest(providerName: keyof typeof fixtureProviders) { + const providerFixture = fixtureProviders[providerName]?.expects ?? {} + const requestPath = + 'itemRequestPath' in providerFixture + ? providerFixture.itemRequestPath + : defaults.ITEM_ID const res = await request(await getServerWithEnv()) - .post( - `/${providerName}/get/${providerFixture.itemRequestPath || defaults.ITEM_ID}`, - ) + .post(`/${providerName}/get/${requestPath}`) .set('uppy-auth-token', token) .set('Content-Type', 'application/json') .send({ @@ -500,7 +529,7 @@ describe('provider file gets downloaded from', () => { describe('connect to provider', () => { test.each(providerNames)( 'connect to %s via grant.js endpoint', - async (providerName) => { + async (providerName: string) => { const oauthProvider = oauthProviders[providerName] if (oauthProvider == null) return @@ -518,7 +547,7 @@ describe('connect to provider', () => { }) describe('logout of provider', () => { - async function runTest(providerName) { + async function runTest(providerName: string) { const res = await request(await getServerWithEnv()) .get(`/${providerName}/logout/`) .set('uppy-auth-token', token) diff --git a/packages/@uppy/companion/test/s3-client.test.ts b/packages/@uppy/companion/test/s3-client.test.ts new file mode 100644 index 000000000..3f297286c --- /dev/null +++ b/packages/@uppy/companion/test/s3-client.test.ts @@ -0,0 +1,50 @@ +import { afterEach, describe, expect, test } from 'vitest' +import { defaultOptions } from '../src/config/companion.js' +import s3Client from '../src/server/s3-client.js' + +const originalAwsRegion = process.env['AWS_REGION'] + +afterEach(() => { + if (originalAwsRegion === undefined) { + delete process.env['AWS_REGION'] + } else { + process.env['AWS_REGION'] = originalAwsRegion + } +}) + +describe('s3-client', () => { + test('creates an S3 client when region comes from AWS SDK environment resolution', () => { + process.env['AWS_REGION'] = 'us-east-1' + + const options = { + ...defaultOptions, + s3: { + ...defaultOptions.s3, + endpoint: 'https://s3.amazonaws.com', + bucket: 'test-bucket', + key: 'test-key', + secret: 'test-secret', + }, + } + + expect(s3Client(options)).not.toBeNull() + }) + + test('creates an S3 client when region is provided as awsClientOptions provider', () => { + const options = { + ...defaultOptions, + s3: { + ...defaultOptions.s3, + endpoint: 'https://s3.amazonaws.com', + bucket: 'test-bucket', + key: 'test-key', + secret: 'test-secret', + awsClientOptions: { + region: async () => 'us-east-1', + }, + }, + } + + expect(s3Client(options)).not.toBeNull() + }) +}) diff --git a/packages/@uppy/companion/test/subpath.test.js b/packages/@uppy/companion/test/subpath.test.ts similarity index 100% rename from packages/@uppy/companion/test/subpath.test.js rename to packages/@uppy/companion/test/subpath.test.ts diff --git a/packages/@uppy/companion/test/uploader.test.js b/packages/@uppy/companion/test/uploader.test.ts similarity index 57% rename from packages/@uppy/companion/test/uploader.test.js rename to packages/@uppy/companion/test/uploader.test.ts index fa5e11be8..0c783b1dc 100644 --- a/packages/@uppy/companion/test/uploader.test.js +++ b/packages/@uppy/companion/test/uploader.test.ts @@ -1,8 +1,22 @@ import fs from 'node:fs' import { Readable } from 'node:stream' +import type { Request } from 'express' +import express from 'express' import nock from 'nock' -import { afterAll, afterEach, describe, expect, test, vi } from 'vitest' +import request from 'supertest' +import * as tusClient from 'tus-js-client' +import { + afterAll, + afterEach, + beforeAll, + describe, + expect, + test, + vi, +} from 'vitest' +import { defaultOptions } from '../src/config/companion.js' import Emitter from '../src/server/emitter/index.js' +import { isRecord } from '../src/server/helpers/type-guards.js' import Uploader, { ValidationError } from '../src/server/Uploader.js' import standalone from '../src/standalone/index.js' import * as socketClient from './mocksocket.js' @@ -10,31 +24,77 @@ import * as socketClient from './mocksocket.js' vi.mock('tus-js-client') vi.mock('express-prom-bundle') +function getTusMockLastUploadFile(): unknown { + const getter = Reflect.get(tusClient, '__getLastUploadFile') + if (typeof getter !== 'function') { + throw new Error('Expected tus mock to expose __getLastUploadFile()') + } + return getter() +} + +function resetTusMockState(): void { + const reset = Reflect.get(tusClient, '__resetTusMockState') + if (typeof reset !== 'function') { + throw new Error('Expected tus mock to expose __resetTusMockState()') + } + reset() +} + afterEach(() => { nock.cleanAll() + resetTusMockState() }) afterAll(() => { nock.restore() }) -process.env.COMPANION_DATADIR = './test/output' -process.env.COMPANION_DOMAIN = 'localhost:3020' -process.env.COMPANION_CLIENT_ORIGINS = 'true' +process.env['COMPANION_DATADIR'] = './test/output' +process.env['COMPANION_DOMAIN'] = 'localhost:3020' +process.env['COMPANION_CLIENT_ORIGINS'] = 'true' const { companionOptions } = standalone() +const runtimeOptions = { + ...defaultOptions, + secret: '', + filePath: '', + server: { ...defaultOptions.server, host: '' }, +} +const pathPrefix = + companionOptions.filePath != null + ? companionOptions.filePath + : './test/output' -const mockReq = {} +let mockReq: Request | undefined + +function requireMockReq(): Request { + if (!mockReq) throw new Error('mockReq was not initialized') + return mockReq +} + +beforeAll(async () => { + const app = express() + app.get('/', (req, res) => { + res.status(200).end() + mockReq = req + }) + await request(app).get('/') + if (!mockReq) throw new Error('Expected an Express request instance') + mockReq.companion = { options: runtimeOptions } +}) describe('uploader', () => { test('uploader respects uploadUrls', async () => { const opts = { - endpoint: 'http://localhost/files', companionOptions: { ...companionOptions, uploadUrls: [/^http:\/\/url.myendpoint.com\//], }, - } + endpoint: 'http://localhost/files', + protocol: 'multipart', + size: 1, + pathPrefix, + metadata: { name: 'file.txt', type: 'text/plain' }, + } satisfies ConstructorParameters[0] - // @ts-ignore expect(() => new Uploader(opts)).toThrow( new ValidationError( 'upload destination does not match any allowed destinations', @@ -44,47 +104,53 @@ describe('uploader', () => { test('uploader respects uploadUrls, valid', async () => { const opts = { - endpoint: 'http://url.myendpoint.com/files', companionOptions: { ...companionOptions, uploadUrls: [/^http:\/\/url.myendpoint.com\//], }, - } + endpoint: 'http://url.myendpoint.com/files', + protocol: 'multipart', + size: 1, + pathPrefix, + metadata: { name: 'file.txt', type: 'text/plain' }, + } satisfies ConstructorParameters[0] - // @ts-ignore new Uploader(opts) // no validation error }) test('uploader respects uploadUrls, localhost', async () => { const opts = { - endpoint: 'http://localhost:1337/', companionOptions: { ...companionOptions, uploadUrls: [/^http:\/\/localhost:1337\//], }, - } + endpoint: 'http://localhost:1337/', + protocol: 'multipart', + size: 1, + pathPrefix, + metadata: { name: 'file.txt', type: 'text/plain' }, + } satisfies ConstructorParameters[0] - // @ts-ignore new Uploader(opts) // no validation error }) test('upload functions with tus protocol', async () => { const fileContent = Buffer.from('Some file content') const stream = Readable.from([fileContent]) - const opts = { - companionOptions, + const opts: ConstructorParameters[0] = { + companionOptions: { ...companionOptions, streamingUpload: false }, endpoint: 'http://url.myendpoint.com/files', protocol: 'tus', size: fileContent.length, - pathPrefix: companionOptions.filePath, + pathPrefix, + metadata: { name: 'file.txt', type: 'text/plain' }, } - // @ts-ignore const uploader = new Uploader(opts) const uploadToken = uploader.token expect(uploadToken).toBeTruthy() - let firstReceivedProgress + let firstReceivedProgress: number | undefined const onProgress = vi.fn() const onUploadSuccess = vi.fn() @@ -100,15 +166,25 @@ describe('uploader', () => { // emulate socket connection socketClient.connect(uploadToken) socketClient.onProgress(uploadToken, (message) => { - if (firstReceivedProgress == null) - firstReceivedProgress = message.payload.bytesUploaded + const payload = isRecord(message['payload']) ? message['payload'] : {} + const bytesUploaded = + typeof payload['bytesUploaded'] === 'number' + ? payload['bytesUploaded'] + : null + if ( + firstReceivedProgress == null && + bytesUploaded != null && + bytesUploaded > 0 + ) { + firstReceivedProgress = bytesUploaded + } onProgress(message) }) socketClient.onUploadError(uploadToken, onUploadError) socketClient.onUploadSuccess(uploadToken, onUploadSuccess) await promise - // @ts-ignore - await uploader.tryUploadStream(stream, mockReq) + await uploader.tryUploadStream(stream, requireMockReq()) + expect(getTusMockLastUploadFile()).toBeInstanceOf(Readable) expect(onUploadError).not.toHaveBeenCalled() @@ -122,7 +198,7 @@ describe('uploader', () => { }), ) const expectedPayload = expect.objectContaining({ - // see __mocks__/tus-js-client.js + // see __mocks__/tus-js-client.ts url: 'https://tus.endpoint/files/foo-bar', }) expect(onUploadSuccess).toHaveBeenCalledWith( @@ -141,37 +217,42 @@ describe('uploader', () => { test('upload functions with tus protocol without size', async () => { const fileContent = Buffer.alloc(1e6) const stream = Readable.from([fileContent]) - const opts = { - companionOptions, + const opts: ConstructorParameters[0] = { + companionOptions: { ...companionOptions, streamingUpload: false }, endpoint: 'http://url.myendpoint.com/files', protocol: 'tus', - size: null, - pathPrefix: companionOptions.filePath, + pathPrefix, + metadata: { name: 'file.bin' }, } - // @ts-ignore const uploader = new Uploader(opts) const originalTryDeleteTmpPath = uploader.tryDeleteTmpPath.bind(uploader) uploader.tryDeleteTmpPath = async () => { // validate that the tmp file has been downloaded and saved into the file path // must do it before it gets deleted - const fileInfo = fs.statSync(uploader.tmpPath) + const tmpPath = uploader.tmpPath + if (tmpPath == null) { + throw new Error('Expected uploader.tmpPath to be a string') + } + const fileInfo = fs.statSync(tmpPath) expect(fileInfo.isFile()).toBe(true) expect(fileInfo.size).toBe(fileContent.length) - return originalTryDeleteTmpPath() + await originalTryDeleteTmpPath() } const uploadToken = uploader.token expect(uploadToken).toBeTruthy() - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { // validate that the test is resolved on socket connection uploader.awaitReady(60000).then(() => { - // @ts-ignore - uploader.tryUploadStream(stream, mockReq).then(() => { + uploader.tryUploadStream(stream, requireMockReq()).then(() => { try { - // @ts-ignore - expect(fs.existsSync(uploader.path)).toBe(false) + const tmpPath = uploader.tmpPath + if (tmpPath == null) { + throw new Error('Expected uploader.tmpPath to be a string') + } + expect(fs.existsSync(tmpPath)).toBe(false) resolve() } catch (err) { reject(err) @@ -179,20 +260,31 @@ describe('uploader', () => { }) }) - let firstReceivedProgress + let firstReceivedProgress: number | undefined // emulate socket connection socketClient.connect(uploadToken) socketClient.onProgress(uploadToken, (message) => { - if (firstReceivedProgress == null) - firstReceivedProgress = message.payload + const payload = isRecord(message['payload']) ? message['payload'] : {} + const bytesUploaded = + typeof payload['bytesUploaded'] === 'number' + ? payload['bytesUploaded'] + : null + if ( + firstReceivedProgress == null && + bytesUploaded != null && + bytesUploaded > 0 + ) { + firstReceivedProgress = bytesUploaded + } }) socketClient.onUploadSuccess(uploadToken, (message) => { try { - expect(firstReceivedProgress.bytesUploaded).toBe(500_000) + expect(firstReceivedProgress).toBe(500_000) - // see __mocks__/tus-js-client.js - expect(message.payload.url).toBe('https://tus.endpoint/files/foo-bar') + // see __mocks__/tus-js-client.ts + const payload = isRecord(message['payload']) ? message['payload'] : {} + expect(payload['url']).toBe('https://tus.endpoint/files/foo-bar') } catch (err) { reject(err) } @@ -201,31 +293,39 @@ describe('uploader', () => { }) async function runMultipartTest({ - // @ts-ignore metadata, - // @ts-ignore useFormData, includeSize = true, address = 'localhost', - // @ts-ignore extraCompanionOpts, + }: { + metadata?: Record + useFormData?: boolean + includeSize?: boolean + address?: string + extraCompanionOpts?: Record } = {}) { const fileContent = Buffer.from('Some file content') const stream = Readable.from([fileContent]) - const opts = { - companionOptions: { ...companionOptions, ...extraCompanionOpts }, + const opts: ConstructorParameters[0] = { + companionOptions: { + ...companionOptions, + streamingUpload: true, + ...extraCompanionOpts, + }, endpoint: `http://${address}`, protocol: 'multipart', - size: includeSize ? fileContent.length : undefined, - metadata, - pathPrefix: companionOptions.filePath, - useFormData, + ...(includeSize && { size: fileContent.length }), + metadata: metadata ?? {}, + pathPrefix, + ...(useFormData != null && { useFormData }), } + stream.pause() + const uploader = new Uploader(opts) - // @ts-ignore - return uploader.uploadStream(stream) + return uploader.uploadStream(stream, requireMockReq()) } test('upload functions with xhr protocol', async () => { @@ -245,7 +345,6 @@ describe('uploader', () => { .reply(200, () => '') const ret = await runMultipartTest({ - // @ts-ignore extraCompanionOpts: { uploadHeaders: { 'header-a': '1', 'header-b': '2' }, }, @@ -255,16 +354,20 @@ describe('uploader', () => { extraData: { response: expect.anything(), bytesUploaded: 17 }, }) - expect(ret.extraData.response?.headers?.['header-a']).toBeUndefined() // headers sent to destination, not received back + const responseHeaders = + ret?.extraData && + isRecord(ret.extraData['response']) && + isRecord(ret.extraData['response']['headers']) + ? ret.extraData['response']['headers'] + : null + expect(responseHeaders?.['header-a']).toBeUndefined() // headers sent to destination, not received back }) const formDataNoMetaMatch = /^--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="files\[\]"; filename="uppy-file-[^"]+"\r\nContent-Type: application\/octet-stream\r\n\r\nSome file content\r\n--form-data-boundary-[a-z0-9]+--\r\n\r\n$/ - test('upload functions with xhr formdata', async () => { nock('http://localhost').post('/', formDataNoMetaMatch).reply(200) - // @ts-ignore const ret = await runMultipartTest({ useFormData: true }) expect(ret).toMatchObject({ url: null, @@ -276,7 +379,6 @@ describe('uploader', () => { nock('http://localhost').post('/', formDataNoMetaMatch).reply(200) const ret = await runMultipartTest({ - // @ts-ignore useFormData: true, includeSize: false, }) @@ -291,19 +393,19 @@ describe('uploader', () => { nock('http://localhost') .post( '/', - /^--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key1"\r\n\r\nnull\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key2"\r\n\r\ntrue\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key3"\r\n\r\n\d+\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key4"\r\n\r\n\[object Object\]\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key5"\r\n\r\n\(\) => \{\}\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="files\[\]"; filename="uppy-file-[^"]+"\r\nContent-Type: application\/octet-stream\r\n\r\nSome file content\r\n--form-data-boundary-[a-z0-9]+--\r\n\r\n$/, + /^--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key1"\r\n\r\nnull\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key2"\r\n\r\ntrue\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key3"\r\n\r\n\d+\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key4"\r\n\r\n\[object Object\]\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="key5"\r\n\r\n\(\) => \{\s*\}\r\n--form-data-boundary-[a-z0-9]+\r\nContent-Disposition: form-data; name="files\[\]"; filename="uppy-file-[^"]+"\r\nContent-Type: application\/octet-stream\r\n\r\nSome file content\r\n--form-data-boundary-[a-z0-9]+--\r\n\r\n$/, ) .times(10) .reply(200) + const key1: null = null const metadata = { - key1: null, + key1, key2: true, key3: 1234, key4: {}, key5: () => {}, } - // @ts-ignore const ret = await runMultipartTest({ useFormData: true, metadata }) expect(ret).toMatchObject({ url: null, @@ -312,16 +414,19 @@ describe('uploader', () => { }) test('uploader checks metadata', () => { - const opts = { + const baseOpts = { companionOptions, endpoint: 'http://localhost', - } + protocol: 'multipart', + size: 1, + pathPrefix, + metadata: {}, + } satisfies ConstructorParameters[0] - // @ts-ignore - new Uploader({ ...opts, metadata: { key: 'string value' } }) + new Uploader({ ...baseOpts, metadata: { key: 'string value' } }) - // @ts-ignore - expect(() => new Uploader({ ...opts, metadata: '' })).toThrow( + // @ts-expect-error - testing runtime validation for invalid metadata type + expect(() => new Uploader({ ...baseOpts, metadata: '' })).toThrow( new ValidationError('metadata must be an object'), ) }) @@ -331,9 +436,11 @@ describe('uploader', () => { endpoint: 'http://url.myendpoint.com/files', companionOptions: { ...companionOptions, maxFileSize: 100 }, size: 101, - } + protocol: 'tus', + pathPrefix, + metadata: {}, + } satisfies ConstructorParameters[0] - // @ts-ignore expect(() => new Uploader(opts)).toThrow( new ValidationError('maxFileSize exceeded'), ) @@ -344,35 +451,42 @@ describe('uploader', () => { endpoint: 'http://url.myendpoint.com/files', companionOptions: { ...companionOptions, maxFileSize: 100 }, size: 99, - } + protocol: 'tus', + pathPrefix, + metadata: {}, + } satisfies ConstructorParameters[0] - // @ts-ignore new Uploader(opts) // no validation error }) test('uploader respects maxFileSize with unknown size', async () => { const fileContent = Buffer.alloc(10000) const stream = Readable.from([fileContent]) + const opts = { - companionOptions: { ...companionOptions, maxFileSize: 1000 }, + companionOptions: { + ...companionOptions, + maxFileSize: 1000, + // Make sure the uploader downloads the full stream so the maxFileSize + // check can run even when size is unknown. + streamingUpload: false, + }, endpoint: 'http://url.myendpoint.com/files', protocol: 'tus', - size: null, - pathPrefix: companionOptions.filePath, - } + pathPrefix, + metadata: {}, + } satisfies ConstructorParameters[0] - // @ts-ignore const uploader = new Uploader(opts) const uploadToken = uploader.token // validate that the test is resolved on socket connection uploader .awaitReady(60000) - // @ts-ignore - .then(() => uploader.tryUploadStream(stream, mockReq)) + .then(() => uploader.tryUploadStream(stream, requireMockReq())) socketClient.connect(uploadToken) - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { socketClient.onUploadError(uploadToken, (message) => { try { expect(message).toMatchObject({ diff --git a/packages/@uppy/companion/test/url.test.js b/packages/@uppy/companion/test/url.test.ts similarity index 100% rename from packages/@uppy/companion/test/url.test.js rename to packages/@uppy/companion/test/url.test.ts diff --git a/packages/@uppy/companion/tsconfig.build.json b/packages/@uppy/companion/tsconfig.build.json index 30076d281..64fc49d4a 100644 --- a/packages/@uppy/companion/tsconfig.build.json +++ b/packages/@uppy/companion/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.shared", "compilerOptions": { - "outDir": "./lib", + "outDir": "./dist", "rootDir": "./src", "noEmitOnError": true }, diff --git a/packages/@uppy/companion/tsconfig.json b/packages/@uppy/companion/tsconfig.json index c8b971e84..016b37aab 100644 --- a/packages/@uppy/companion/tsconfig.json +++ b/packages/@uppy/companion/tsconfig.json @@ -3,5 +3,10 @@ "compilerOptions": { "noEmit": true }, - "include": ["src/**/*", "test/**/*"] + "include": [ + "src/**/*.ts", + "src/types/**/*.d.ts", + "test/**/*.ts", + "__mocks__/**/*.ts" + ] } diff --git a/packages/@uppy/companion/tsconfig.shared.json b/packages/@uppy/companion/tsconfig.shared.json index b923809e5..1707432a8 100644 --- a/packages/@uppy/companion/tsconfig.shared.json +++ b/packages/@uppy/companion/tsconfig.shared.json @@ -3,12 +3,21 @@ "module": "NodeNext", "declaration": true, "target": "es2022", - "noImplicitAny": false, + "noImplicitAny": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "erasableSyntaxOnly": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "useUnknownInCatchVariables": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, "sourceMap": false, - "allowJs": true, - "checkJs": true, + "allowJs": false, + "checkJs": false, "skipLibCheck": true, - "resolveJsonModule": true, - "types": [] + "resolveJsonModule": true } } diff --git a/packages/@uppy/url/package.json b/packages/@uppy/url/package.json index b76225a39..3f3ce8c9c 100644 --- a/packages/@uppy/url/package.json +++ b/packages/@uppy/url/package.json @@ -12,6 +12,7 @@ "build": "tsc --build tsconfig.build.json", "build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css", "typecheck": "tsc --build", + "pretest": "yarn workspace @uppy/companion build", "test": "vitest run --silent='passed-only'", "test:e2e": "vitest run --project browser" }, diff --git a/packages/@uppy/url/vitest.setup.ts b/packages/@uppy/url/vitest.setup.ts index 6203a8d36..a93471d9f 100644 --- a/packages/@uppy/url/vitest.setup.ts +++ b/packages/@uppy/url/vitest.setup.ts @@ -49,7 +49,12 @@ export default async function setup(project: TestProject) { const companionProcess = spawn( 'node', - [join(__dirname, '../../@uppy/companion/test/with-load-balancer.mjs')], + [ + join( + __dirname, + '../../@uppy/companion/dist/scripts/with-load-balancer.js', + ), + ], { stdio: 'inherit', cwd: join(__dirname, '../../../..'), diff --git a/yarn.lock b/yarn.lock index e5ae52e94..9efee9162 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9196,6 +9196,13 @@ __metadata: languageName: node linkType: hard +"@types/common-tags@npm:^1.8.4": + version: 1.8.4 + resolution: "@types/common-tags@npm:1.8.4" + checksum: 10/40c95a2f6388beb1cdeed3c9986ac0d6a3a551fce706e3e364a00ded48ab624b06b1ac8b94679bb2da9653e5eb3e450bad26873f5189993a5d8e8bdace74cbb2 + languageName: node + linkType: hard + "@types/compression@npm:1.7.0": version: 1.7.0 resolution: "@types/compression@npm:1.7.0" @@ -9224,6 +9231,13 @@ __metadata: languageName: node linkType: hard +"@types/content-disposition@npm:^0.5.9": + version: 0.5.9 + resolution: "@types/content-disposition@npm:0.5.9" + checksum: 10/d895703c0027ca6c4c0c1ede363909dbb590deec3b206a84b88a49c8b2840bcbd31b4ddeb2e1e6caa1af00801cc79c5b69a5c75a8152f2959810b10fe75a4e1f + languageName: node + linkType: hard + "@types/cookie-parser@npm:1.4.2": version: 1.4.2 resolution: "@types/cookie-parser@npm:1.4.2" @@ -9247,6 +9261,13 @@ __metadata: languageName: node linkType: hard +"@types/cookiejar@npm:^2.1.5": + version: 2.1.5 + resolution: "@types/cookiejar@npm:2.1.5" + checksum: 10/04d5990e87b6387532d15a87d9ec9b2eb783039291193863751dcfd7fc723a3b3aa30ce4c06b03975cba58632e933772f1ff031af23eaa3ac7f94e71afa6e073 + languageName: node + linkType: hard + "@types/cors@npm:2.8.6": version: 2.8.6 resolution: "@types/cors@npm:2.8.6" @@ -9434,6 +9455,20 @@ __metadata: languageName: node linkType: hard +"@types/methods@npm:^1.1.4": + version: 1.1.4 + resolution: "@types/methods@npm:1.1.4" + checksum: 10/ad2a7178486f2fd167750f3eb920ab032a947ff2e26f55c86670a6038632d790b46f52e5b6ead5823f1e53fc68028f1e9ddd15cfead7903e04517c88debd72b1 + languageName: node + linkType: hard + +"@types/mime-types@npm:^2.1.4": + version: 2.1.4 + resolution: "@types/mime-types@npm:2.1.4" + checksum: 10/f8c521c54ee0c0b9f90a65356a80b1413ed27ccdc94f5c7ebb3de5d63cedb559cd2610ea55b4100805c7349606a920d96e54f2d16b2f0afa6b7cd5253967ccc9 + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.5 resolution: "@types/mime@npm:1.3.5" @@ -9466,6 +9501,15 @@ __metadata: languageName: node linkType: hard +"@types/node-schedule@npm:^2.1.8": + version: 2.1.8 + resolution: "@types/node-schedule@npm:2.1.8" + dependencies: + "@types/node": "npm:*" + checksum: 10/8da986d3b3d529d8d203126e9c89b477d39d8ca6a45d122637fc3b05402da0965bda6410da77af5efa3cbf5ac3f2955d2b9dcf5f90a191271c1096d162c96dd2 + languageName: node + linkType: hard + "@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:^20, @types/node@npm:^20.19.0": version: 20.19.11 resolution: "@types/node@npm:20.19.11" @@ -9569,6 +9613,13 @@ __metadata: languageName: node linkType: hard +"@types/serialize-javascript@npm:^5.0.4": + version: 5.0.4 + resolution: "@types/serialize-javascript@npm:5.0.4" + checksum: 10/c342a4d151736c1ba4913e6d9b00537bcf62401a06e3489dcf96b7d51a4ab147efcf3fe20ca9491b1349ee7e55c6d69606682e1630f2e076e2828eaee3764f94 + languageName: node + linkType: hard + "@types/serve-index@npm:^1.9.4": version: 1.9.4 resolution: "@types/serve-index@npm:1.9.4" @@ -9605,6 +9656,28 @@ __metadata: languageName: node linkType: hard +"@types/superagent@npm:^8.1.0": + version: 8.1.9 + resolution: "@types/superagent@npm:8.1.9" + dependencies: + "@types/cookiejar": "npm:^2.1.5" + "@types/methods": "npm:^1.1.4" + "@types/node": "npm:*" + form-data: "npm:^4.0.0" + checksum: 10/6d9687b0bc3d693b900ef76000b02437a70879c3219b28606879c086d786bb1e48429813e72e32dd0aafc94c053a78a2aa8be67c45bc8e6b968ca62d6d5cc554 + languageName: node + linkType: hard + +"@types/supertest@npm:^6.0.3": + version: 6.0.3 + resolution: "@types/supertest@npm:6.0.3" + dependencies: + "@types/methods": "npm:^1.1.4" + "@types/superagent": "npm:^8.1.0" + checksum: 10/6ec05eb591c97bc856b0e78c12f5bec10545f3a749688f34232d189797a506d971bc95931718eb57b378d8513f6d2d12462383e6d68455fa72df35c19de6e89e + languageName: node + linkType: hard + "@types/tough-cookie@npm:*, @types/tough-cookie@npm:^4.0.5": version: 4.0.5 resolution: "@types/tough-cookie@npm:4.0.5" @@ -9619,6 +9692,13 @@ __metadata: languageName: node linkType: hard +"@types/validator@npm:^13.15.10": + version: 13.15.10 + resolution: "@types/validator@npm:13.15.10" + checksum: 10/63117a776ced4d066d7fb63130d90ba487d38209dd45c25641ca1a6f5040e8394cc9a855750b919b72a923c5ffb51f8474f213b10b5aaa27d9db108bef07ad10 + languageName: node + linkType: hard + "@types/webpack@npm:^5.28.0": version: 5.28.5 resolution: "@types/webpack@npm:5.28.5" @@ -9950,7 +10030,9 @@ __metadata: "@aws-sdk/lib-storage": "npm:3.986.0" "@aws-sdk/s3-presigned-post": "npm:3.986.0" "@aws-sdk/s3-request-presigner": "npm:3.986.0" + "@types/common-tags": "npm:^1.8.4" "@types/compression": "npm:1.7.0" + "@types/content-disposition": "npm:^0.5.9" "@types/cookie-parser": "npm:1.4.2" "@types/cors": "npm:2.8.6" "@types/eslint": "npm:^8.2.0" @@ -9958,10 +10040,15 @@ __metadata: "@types/http-proxy": "npm:^1" "@types/jsonwebtoken": "npm:8.3.7" "@types/lodash": "npm:4.14.191" + "@types/mime-types": "npm:^2.1.4" "@types/morgan": "npm:1.7.37" "@types/ms": "npm:0.7.31" "@types/node": "npm:^20.19.0" + "@types/node-schedule": "npm:^2.1.8" "@types/request": "npm:2.48.8" + "@types/serialize-javascript": "npm:^5.0.4" + "@types/supertest": "npm:^6.0.3" + "@types/validator": "npm:^13.15.10" "@types/webpack": "npm:^5.28.0" "@types/ws": "npm:8.5.3" body-parser: "npm:1.20.4" @@ -10006,8 +10093,9 @@ __metadata: vitest: "npm:^3.2.4" webdav: "npm:^5.8.0" ws: "npm:8.17.1" + zod: "npm:^3.24.0" bin: - companion: ./bin/companion + companion: ./dist/bin/companion.js languageName: unknown linkType: soft @@ -24886,6 +24974,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.24.0": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995 + languageName: node + linkType: hard + "zone.js@npm:~0.15.0": version: 0.15.0 resolution: "zone.js@npm:0.15.0" From f1de25fd6ef1c3420d5ad5a0f6188006f86716fb Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Thu, 7 May 2026 15:36:44 +0200 Subject: [PATCH 10/33] Add Yarn npm package age gate (#6281) ## Summary - add Yarn's native `npmMinimalAgeGate` with a 2 day / 2880 minute cooldown to help protect against supply chain attacks - rely on the existing Yarn 4.12.0 install path instead of a custom package-age script Closes #5974. ## Verification - `corepack yarn config get npmMinimalAgeGate` -> `2880` - `corepack yarn install --immutable` - `corepack yarn check` --- .yarnrc.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index d2890fb76..2057decd7 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -9,5 +9,6 @@ initScope: uppy nodeLinker: node-modules -npmPublishAccess: public +npmMinimalAgeGate: 2880 +npmPublishAccess: public From ad4050b51eb714f753931476df916ef791cb15ef Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Sat, 9 May 2026 15:03:04 +0800 Subject: [PATCH 11/33] Send token using websocket (#6248) instead of window.opener - it is more robust inspired by #4110 closes #6246 closes #4107 Biggest caveat: In cases where window.opener is null (Dropbox), the auth window will not be auto closed (I don't know how to fix that). It will show the user a message "Authentication successful. You may now close this page." https://github.com/transloadit/uppy/pull/6248/changes#diff-ef5b69c4ab5b83168eaba6f57047bb07c53e3a426f375b42fcb32d79c746872cR22 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Prakash --- .changeset/mighty-deers-sin.md | 8 + examples/react/test/index.test.tsx | 1 - examples/sveltekit/test/index.test.ts | 1 - examples/vue/test/index.test.ts | 1 - .../@uppy/companion-client/src/Provider.ts | 137 +++++------ .../src/getAllowedHosts.test.ts | 19 +- .../companion-client/src/getAllowedHosts.ts | 12 - .../src/server/controllers/callback.ts | 43 ++-- .../src/server/controllers/connect.ts | 5 + .../src/server/controllers/send-token.ts | 58 ++--- .../companion/src/server/helpers/html.ts | 92 ++++++++ .../src/server/helpers/oauth-state.ts | 1 + packages/@uppy/companion/src/server/socket.ts | 212 ++++++++++++------ .../@uppy/companion/src/standalone/index.ts | 4 +- .../companion/src/standalone/start-server.ts | 4 +- .../@uppy/companion/test/callback.test.ts | 60 ++++- packages/@uppy/companion/test/mockserver.ts | 15 +- 17 files changed, 440 insertions(+), 233 deletions(-) create mode 100644 .changeset/mighty-deers-sin.md create mode 100644 packages/@uppy/companion/src/server/helpers/html.ts diff --git a/.changeset/mighty-deers-sin.md b/.changeset/mighty-deers-sin.md new file mode 100644 index 000000000..71159166a --- /dev/null +++ b/.changeset/mighty-deers-sin.md @@ -0,0 +1,8 @@ +--- +"@uppy/companion-client": major +"@uppy/companion": major +--- + +Send token using websocket instead of window.opener. +Breaking in `@uppy/companion-client` because it needs newest version of Companion in order to work. +Breaking in `@uppy/companion` because `companion.socket()` now requires `companionOptions` to be passed as the second argument. diff --git a/examples/react/test/index.test.tsx b/examples/react/test/index.test.tsx index 1c69dc57e..886023456 100644 --- a/examples/react/test/index.test.tsx +++ b/examples/react/test/index.test.tsx @@ -129,6 +129,5 @@ describe('RemoteSource Component', () => { await expect.element(loginButton).toBeInTheDocument() await loginButton.click() - await expect.element(loginButton).toBeInTheDocument() }) }) diff --git a/examples/sveltekit/test/index.test.ts b/examples/sveltekit/test/index.test.ts index 2c11f4fb7..a14fb3537 100644 --- a/examples/sveltekit/test/index.test.ts +++ b/examples/sveltekit/test/index.test.ts @@ -132,7 +132,6 @@ describe('RemoteSource Component', () => { await expect.element(loginButton).toBeInTheDocument() await loginButton.click() - await expect.element(loginButton).toBeInTheDocument() }) }) diff --git a/examples/vue/test/index.test.ts b/examples/vue/test/index.test.ts index 8fd0be53b..1aa54275d 100644 --- a/examples/vue/test/index.test.ts +++ b/examples/vue/test/index.test.ts @@ -131,6 +131,5 @@ describe('RemoteSource Component', () => { await expect.element(loginButton).toBeInTheDocument() await loginButton.click() - await expect.element(loginButton).toBeInTheDocument() }) }) diff --git a/packages/@uppy/companion-client/src/Provider.ts b/packages/@uppy/companion-client/src/Provider.ts index 4e0ef1a3b..7a50897e4 100644 --- a/packages/@uppy/companion-client/src/Provider.ts +++ b/packages/@uppy/companion-client/src/Provider.ts @@ -5,8 +5,11 @@ import type { UnknownProviderPlugin, Uppy, } from '@uppy/core' -import type { CompanionClientProvider, RequestOptions } from '@uppy/utils' -import { isOriginAllowed } from './getAllowedHosts.js' +import { + type CompanionClientProvider, + getSocketHost, + type RequestOptions, +} from '@uppy/utils' import type { CompanionPluginOptions } from './index.js' import RequestClient, { authErrorStatusCode } from './RequestClient.js' @@ -135,22 +138,27 @@ export default class Provider authUrl({ authFormData, query, + authCallbackToken, }: { authFormData: unknown query: Record + authCallbackToken?: string | undefined }): string { - const params = new URLSearchParams({ + const searchParams = new URLSearchParams({ ...query, - // This is only used for Companion instances configured to accept multiple origins. + // `origin` is only used for Companion instances configured to accept multiple origins. state: btoa(JSON.stringify({ origin: getOrigin() })), ...this.authQuery({ authFormData }), }) if (this.preAuthToken) { - params.set('uppyPreAuthToken', this.preAuthToken) + searchParams.set('uppyPreAuthToken', this.preAuthToken) + } + if (authCallbackToken) { + searchParams.set('authCallbackToken', authCallbackToken) } - return `${this.hostname}/${this.id}/connect?${params}` + return `${this.hostname}/${this.id}/connect?${searchParams}` } protected async loginSimpleAuth({ @@ -181,67 +189,62 @@ export default class Provider signal: AbortSignal }): Promise { await this.ensurePreAuth() - signal.throwIfAborted() - const link = this.authUrl({ query: { uppyVersions }, authFormData }) + // Important: We need to do this synchronously, or else browsers might block the popup. + // (We cannot wait until the websocket connection is established). + // This opens up a race condtition if the websocket is not connected before the user + // completes(or cancels) authentication, but that’s a small compromose we gotta make. + const authCallbackToken = crypto.randomUUID() + + const link = this.authUrl({ + query: { uppyVersions }, + authFormData, + authCallbackToken, + }) const authWindow = window.open(link, '_blank') let interval: number | undefined - let handleMessage: ((e: MessageEvent) => void) | undefined + let webSocket: WebSocket | undefined try { - return await new Promise((resolve, reject) => { - handleMessage = (e: MessageEvent) => { - if (e.source !== authWindow) { - let jsonData = '' - try { - // TODO improve our uppy logger so that it can take an arbitrary number of arguments, - // each either objects, errors or strings, - // then we don’t have to manually do these things like json stringify when logging. - // the logger should never throw an error. - jsonData = JSON.stringify(e.data) - } catch (_err) { - // in case JSON.stringify fails (ignored) + const host = getSocketHost(this.opts.companionUrl) + + // Note that this promise is not guaranteed to settle in all cases + const token = await new Promise((resolve, reject) => { + webSocket = new WebSocket( + `${host}/api2/auth-callback/token/${authCallbackToken}`, + ) + + webSocket.addEventListener('close', () => { + reject(new Error('Socket closed')) + }) + + webSocket.addEventListener('error', (error) => { + this.uppy.log( + `Companion socket error ${JSON.stringify(error)}, closing socket`, + 'warning', + ) + webSocket?.close() // 'close' event will be emitted + }) + + webSocket.addEventListener('message', (e) => { + try { + const { token, error } = JSON.parse(e.data) + if (error) { + reject(new Error('Authentication reported error')) + } else if (!token) { + reject(new Error('Authentication did not return a token')) + } else { + resolve(token) } - this.uppy.log( - `ignoring event from unknown source ${jsonData}`, - 'warning', - ) - return + } catch (err) { + reject(err) } + }) - const { companionAllowedHosts } = this.#getPlugin().opts - if (!isOriginAllowed(e.origin, companionAllowedHosts)) { - this.uppy.log( - `ignoring event from ${e.origin} vs allowed pattern ${companionAllowedHosts}`, - 'warning', - ) - // We cannot reject here because the page might send events from other origins - // before sending the "real" auth completed event. - // for example Box has a "Pendo" tool that sends events to the opener - // https://github.com/transloadit/uppy/pull/5719 - return - } - - // Check if it's a string before doing the JSON.parse to maintain support - // for older Companion versions that used object references - const data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data - - if (data.error) { - const { uppy } = this - const message = uppy.i18n('authAborted') - uppy.info({ message }, 'warning', 5000) - reject(new Error('auth aborted')) - return - } - - if (!data.token) { - reject(new Error('did not receive token from auth window')) - return - } - - resolve(this.setAuthToken(data.token)) - } + signal.addEventListener('abort', () => + reject(new Error('Authentication was aborted')), + ) // poll for user closure of the window, so we can reject when it happens if (authWindow) { @@ -251,15 +254,21 @@ export default class Provider } }, 500) } - - signal.addEventListener('abort', () => reject(new Error('Aborted'))) - window.addEventListener('message', handleMessage) }) + + this.setAuthToken(token) + } catch (err) { + const message = this.uppy.i18n('authAborted') + this.uppy.info({ message }, 'warning', 5000) + this.uppy.log(`Authentication failed: ${err.message}`, 'warning') + throw err } finally { // cleanup: - authWindow?.close() - window.clearInterval(interval) - if (handleMessage) window.removeEventListener('message', handleMessage) + // if we don't setTimeout, the window doesn't really close (I don't know why). + setTimeout(() => authWindow?.close(), 1) + this.uppy.log(`Closing auth callback socket ${authCallbackToken}`) + webSocket?.close() + clearInterval(interval) } } diff --git a/packages/@uppy/companion-client/src/getAllowedHosts.test.ts b/packages/@uppy/companion-client/src/getAllowedHosts.test.ts index d82c31583..45eef785e 100644 --- a/packages/@uppy/companion-client/src/getAllowedHosts.test.ts +++ b/packages/@uppy/companion-client/src/getAllowedHosts.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import getAllowedHosts, { isOriginAllowed } from './getAllowedHosts.js' +import getAllowedHosts from './getAllowedHosts.js' describe('getAllowedHosts', () => { it('can convert companionAllowedHosts', () => { @@ -30,20 +30,3 @@ describe('getAllowedHosts', () => { ) }) }) - -describe('isOriginAllowed', () => { - it('should check origin', () => { - expect(isOriginAllowed('a', [/^.+$/])).toBeTruthy() - expect(isOriginAllowed('a', ['^.+$'])).toBeTruthy() - expect( - isOriginAllowed('www.transloadit.com', ['^www\\.transloadit\\.com$']), - ).toBeTruthy() - expect( - isOriginAllowed('www.transloadit.com', ['^transloadit\\.com$']), - ).toBeFalsy() - expect(isOriginAllowed('match', ['fail', 'match'])).toBeTruthy() - expect( - isOriginAllowed('www.transloadit.com', ['\\.transloadit\\.com$']), - ).toBeTruthy() - }) -}) diff --git a/packages/@uppy/companion-client/src/getAllowedHosts.ts b/packages/@uppy/companion-client/src/getAllowedHosts.ts index 5487dca03..ff58300d8 100644 --- a/packages/@uppy/companion-client/src/getAllowedHosts.ts +++ b/packages/@uppy/companion-client/src/getAllowedHosts.ts @@ -47,15 +47,3 @@ export default function getAllowedHosts( ret = escapeRegex(ret) return ret } - -export function isOriginAllowed( - origin: string, - allowedOrigin: string | RegExp | Array | undefined, -): boolean { - const patterns = Array.isArray(allowedOrigin) - ? allowedOrigin.map(wrapInRegex) - : [wrapInRegex(allowedOrigin)] - return patterns.some( - (pattern) => pattern?.test(origin) || pattern?.test(`${origin}/`), - ) // allowing for trailing '/' -} diff --git a/packages/@uppy/companion/src/server/controllers/callback.ts b/packages/@uppy/companion/src/server/controllers/callback.ts index 93f864d8f..7e1ab3a69 100644 --- a/packages/@uppy/companion/src/server/controllers/callback.ts +++ b/packages/@uppy/companion/src/server/controllers/callback.ts @@ -3,32 +3,23 @@ */ import type { NextFunction, Request, Response } from 'express' -import serialize from 'serialize-javascript' +import emitter from '../emitter/index.js' +import { + authCallbackErrorHtml, + legacyAuthCallbackHtml, +} from '../helpers/html.js' import * as tokenService from '../helpers/jwt.js' import * as oAuthState from '../helpers/oauth-state.js' import logger from '../logger.js' -const closePageHtml = (origin: string | undefined) => ` - - - - - - - Authentication failed. - ` - export default function callback( req: Request, res: Response, next: NextFunction, ): void { const providerName = req.params['providerName'] + const { companion } = req + if (providerName == null || providerName.length === 0) { res.sendStatus(400) return @@ -51,7 +42,25 @@ export default function callback( req.id, ) logger.debug(req.session?.grant?.response, 'callback.oauth.resp', req.id) - res.status(400).send(closePageHtml(originString)) + const authCallbackToken = + grantDynamic.state && + oAuthState.getFromState( + grantDynamic.state, + 'authCallbackToken', + companion.options.secret, + ) + // only new Uppy clients will set an authCallbackToken in the state + // in that case, we send the token through the emitter. + if (authCallbackToken) { + emitter().emit(authCallbackToken, { error: true }) + res.status(400).send(authCallbackErrorHtml()) + } else { + // This is backwards compatible with old Uppy clients: + res + .status(400) + .send(legacyAuthCallbackHtml({ error: true }, originString)) + } + return } diff --git a/packages/@uppy/companion/src/server/controllers/connect.ts b/packages/@uppy/companion/src/server/controllers/connect.ts index 2d62c4d95..a30e607da 100644 --- a/packages/@uppy/companion/src/server/controllers/connect.ts +++ b/packages/@uppy/companion/src/server/controllers/connect.ts @@ -123,6 +123,11 @@ export default function connect( stateObj.preAuthToken = preAuthTokenValue } + const authCallbackToken = req.query['authCallbackToken'] + if (typeof authCallbackToken === 'string') { + stateObj.authCallbackToken = authCallbackToken + } + // Get the computed header generated by `cors` in a previous middleware. stateObj.origin = res.getHeader('Access-Control-Allow-Origin') let clientOrigin: string | undefined diff --git a/packages/@uppy/companion/src/server/controllers/send-token.ts b/packages/@uppy/companion/src/server/controllers/send-token.ts index b0396fa28..44efb0679 100644 --- a/packages/@uppy/companion/src/server/controllers/send-token.ts +++ b/packages/@uppy/companion/src/server/controllers/send-token.ts @@ -1,45 +1,12 @@ import type { NextFunction, Request, Response } from 'express' -import serialize from 'serialize-javascript' +import emitter from '../emitter/index.js' +import { + authCallbackSuccessHtml, + legacyAuthCallbackHtml, +} from '../helpers/html.js' import * as oAuthState from '../helpers/oauth-state.js' import { isOriginAllowed } from './connect.js' -const htmlContent = (token: string, origin: string): string => { - return ` - - - - - - - - - - ` -} - export default function sendToken( req: Request, res: Response, @@ -74,5 +41,18 @@ export default function sendToken( return } - res.send(htmlContent(`${uppyAuthToken}`, clientOrigin)) + const authCallbackToken = oAuthState.getFromState( + state, + 'authCallbackToken', + companion.options.secret, + ) + // only new Uppy clients will set an authCallbackToken in the state + // in that case, we send the token through the emitter. + if (authCallbackToken) { + emitter().emit(authCallbackToken, { token: uppyAuthToken }) + res.send(authCallbackSuccessHtml()) + } else { + // This is backwards compatible with old Uppy clients: + res.send(legacyAuthCallbackHtml({ token: uppyAuthToken }, clientOrigin)) + } } diff --git a/packages/@uppy/companion/src/server/helpers/html.ts b/packages/@uppy/companion/src/server/helpers/html.ts new file mode 100644 index 000000000..a7e723db5 --- /dev/null +++ b/packages/@uppy/companion/src/server/helpers/html.ts @@ -0,0 +1,92 @@ +import serialize from 'serialize-javascript' + +export const authCallbackSuccessHtml = () => { + return ` + + + + + + + +
Authentication successful. You may now close this page.
+ + ` +} + +export const authCallbackErrorHtml = () => { + return ` + + + + + + + +
Authentication failed. You may now close this page.
+ + ` +} + +/** + * Generate an HTML page that will post a message to the opener window and then close itself. + * This is only used by old Uppy clients + * + * @param {unknown} data data payload + * @param {string} origin url string + */ +export const legacyAuthCallbackHtml = ( + data: unknown, + origin: string | undefined, +) => { + return ` + + + + + + + + + + ` +} diff --git a/packages/@uppy/companion/src/server/helpers/oauth-state.ts b/packages/@uppy/companion/src/server/helpers/oauth-state.ts index a1080ce79..2348e3ef8 100644 --- a/packages/@uppy/companion/src/server/helpers/oauth-state.ts +++ b/packages/@uppy/companion/src/server/helpers/oauth-state.ts @@ -9,6 +9,7 @@ export type OAuthState = { preAuthToken?: string companionInstance?: string customerDefinedAllowedOrigins?: string[] + authCallbackToken?: string } export const encodeState = ( diff --git a/packages/@uppy/companion/src/server/socket.ts b/packages/@uppy/companion/src/server/socket.ts index 71dc7581a..54d39ec53 100644 --- a/packages/@uppy/companion/src/server/socket.ts +++ b/packages/@uppy/companion/src/server/socket.ts @@ -1,10 +1,10 @@ -import assert from 'node:assert' import type { Server as HttpServer } from 'node:http' import type { Server as HttpsServer } from 'node:https' -import { WebSocketServer } from 'ws' +import { type WebSocket, WebSocketServer } from 'ws' +import type { CompanionInitOptions } from '../schemas/companion.js' import emitter from './emitter/index.js' import { isRecord } from './helpers/type-guards.js' -import { jsonStringify } from './helpers/utils.js' +import { getURLBuilder, jsonStringify } from './helpers/utils.js' import * as logger from './logger.js' import * as redis from './redis.js' import Uploader from './Uploader.js' @@ -19,57 +19,134 @@ function isSocketMessage(value: unknown): value is SocketMessage { ) } -/** - * The socket is used to send progress events during an upload. - */ -export default function setupSocket(server: HttpServer | HttpsServer): void { - const wss = new WebSocketServer({ server }) - const redisClient = redis.client() - +function handleUploadSocketConnection({ + token, + ws, +}: { + token: string + ws: WebSocket +}) { // A new connection is usually created when an upload begins, // or when connection fails while an upload is on-going and, // client attempts to reconnect. - wss.on('connection', (ws, req) => { - const fullPath = req.url - assert(fullPath != null, 'WebSocket connection URL is missing') - // the token identifies which ongoing upload's progress, the socket - // connection wishes to listen to. - const token = fullPath.replace(/^.*\/api\//, '') - logger.info(`connection received from ${token}`, 'socket.connect') - function send(data: SocketMessage): void { - ws.send(jsonStringify(data), (err) => { - if (err) { - logger.error(err, 'socket.redis.error', Uploader.shortenToken(token)) + // the token identifies which ongoing upload's progress, the socket + // connection wishes to listen to. + const redisClient = redis.client() + + function send(data: { action: string; payload: object }) { + ws.send(jsonStringify(data), (err) => { + if (err) + logger.error( + err, + 'socket.upload.redis.error', + Uploader.shortenToken(token), + ) + }) + } + + // if the redisClient is available, then we attempt to check the storage + // if we have any already stored state on the upload. + if (redisClient) { + redisClient + .get(`${Uploader.STORAGE_PREFIX}:${token}`) + .then((data) => { + if (data) { + const dataObj = JSON.parse(data.toString()) + if (isSocketMessage(dataObj)) send(dataObj) } }) - } + .catch((err) => + logger.error( + err, + 'socket.upload.redis.error', + Uploader.shortenToken(token), + ), + ) + } - // if the redisClient is available, then we attempt to check the storage - // if we have any already stored state on the upload, and send it to the client immediately after connection, - // so that the client can update the UI accordingly without the user having to wait for another event - if (redisClient) { - redisClient - .get(`${Uploader.STORAGE_PREFIX}:${token}`) - .then((data) => { - if (!data) return - const dataObj: unknown = JSON.parse(data) - if (isSocketMessage(dataObj)) { - send(dataObj) - } - }) - .catch((err) => - logger.error(err, 'socket.redis.error', Uploader.shortenToken(token)), + emitter().emit(`connection:${token}`) + const onRedisMessage = (...args: unknown[]) => { + const data = args[0] + if (!isSocketMessage(data)) return + send(data) + } + emitter().on(token, onRedisMessage) + + ws.on('message', (jsonData) => { + try { + const data: unknown = JSON.parse(jsonData.toString()) + // whitelist triggered actions + const action = isRecord(data) ? data['action'] : undefined + if (action === 'pause' || action === 'resume' || action === 'cancel') { + emitter().emit(`${action}:${token}`) + } + } catch (err) { + logger.error(err, 'websocket.error', Uploader.shortenToken(token)) + } + }) + + ws.on('close', () => { + emitter().removeListener(token, onRedisMessage) + }) +} + +function handleAuthCallbackSocketConnection({ + token, + ws, +}: { + token: string + ws: WebSocket +}) { + function send(data: unknown) { + ws.send(jsonStringify(data), (err) => { + if (err) + logger.error( + err, + 'socket.auth.redis.error', + Uploader.shortenToken(token), ) + }) + } + + // todo we should use a unique prefix for these and upload tokens, so that we can easily distinguish them in the emitter and avoid any potential conflicts. + // but it's a breaking change so let's not do it now + // it's unlikely there will be any collision + emitter().on(token, send) + + ws.on('close', () => { + emitter().removeListener(token, send) + }) +} + +export default function setupSockets( + server: HttpServer | HttpsServer, + companionOptions: CompanionInitOptions, +) { + const wss = new WebSocketServer({ server }) + + const urlBuilder = getURLBuilder(companionOptions) + + const externalBasePath = urlBuilder('', true, true) + + wss.on('connection', (ws, req) => { + // basic router: + let path = req.url + + // strip off base path if any + if (path != null && externalBasePath && path.startsWith(externalBasePath)) { + path = path.slice(externalBasePath.length) } - emitter().emit(`connection:${token}`) - const onTokenMessage = (...args: unknown[]) => { - const data = args[0] - if (!isSocketMessage(data)) return - send(data) - } - emitter().on(token, onTokenMessage) + // authentication callback token? + const authCallbackTokenMatch = path?.match( + /^\/api2\/auth-callback\/token\/([^/]+)/, + ) + const authCallbackToken = authCallbackTokenMatch?.[1] + + // or token that identifies which ongoing upload's progress, the socket connection wishes to listen to. + const uploadTokenMatch = path?.match(/^\/api\/([^/]+)/) + const uploadToken = uploadTokenMatch?.[1] ws.on('error', (err) => { // https://github.com/websockets/ws/issues/1543 @@ -81,33 +158,38 @@ export default function setupSocket(server: HttpServer | HttpsServer): void { ) { logger.error( 'WebSocket message too large', - 'websocket.error', - Uploader.shortenToken(token), + 'socket.upload.error', + uploadToken && Uploader.shortenToken(uploadToken), ) } else { - logger.error(err, 'websocket.error', Uploader.shortenToken(token)) - } - }) - - ws.on('message', (jsonData) => { - try { - const data: unknown = JSON.parse(jsonData.toString()) - // whitelist triggered actions - const action = isRecord(data) ? data['action'] : undefined - if (action === 'pause' || action === 'resume' || action === 'cancel') { - emitter().emit(`${action}:${token}`) - } - } catch (err) { logger.error( - err instanceof Error ? err : String(err), - 'websocket.error', - Uploader.shortenToken(token), + err, + 'socket.error', + uploadToken && Uploader.shortenToken(uploadToken), ) } }) - ws.on('close', () => { - emitter().removeListener(token, onTokenMessage) - }) + if (uploadToken) { + logger.info( + `Upload token connection received from ${uploadToken}`, + 'socket.upload.connect', + ) + + handleUploadSocketConnection({ token: uploadToken, ws }) + return + } + + if (authCallbackToken) { + logger.info( + `Auth callback token connection received from ${authCallbackToken}`, + 'socket.auth.callback.connect', + ) + + handleAuthCallbackSocketConnection({ token: authCallbackToken, ws }) + return + } + + ws.close() }) } diff --git a/packages/@uppy/companion/src/standalone/index.ts b/packages/@uppy/companion/src/standalone/index.ts index 221573841..488fb90a8 100644 --- a/packages/@uppy/companion/src/standalone/index.ts +++ b/packages/@uppy/companion/src/standalone/index.ts @@ -158,7 +158,7 @@ export default function server(inputCompanionOptions?: CompanionInitOptions) { } // initialize companion - const { app: companionApp } = companion.app(companionOptions) + const { app: companionApp, emitter } = companion.app(companionOptions) // add companion to server middleware router.use(companionApp) @@ -216,5 +216,5 @@ export default function server(inputCompanionOptions?: CompanionInitOptions) { } }) - return { app, companionOptions } + return { app, companionOptions, emitter } } diff --git a/packages/@uppy/companion/src/standalone/start-server.ts b/packages/@uppy/companion/src/standalone/start-server.ts index d585ba4c3..ec4dc713b 100644 --- a/packages/@uppy/companion/src/standalone/start-server.ts +++ b/packages/@uppy/companion/src/standalone/start-server.ts @@ -7,9 +7,9 @@ import standalone from './index.js' const port: string | number = process.env['COMPANION_PORT'] || process.env['PORT'] || 3020 -const { app } = standalone() +const { app, companionOptions } = standalone() -companion.socket(app.listen(port)) +companion.socket(app.listen(port), companionOptions) logger.info(`Welcome to Companion! v${packageJson.version}`) logger.info(`Listening on http://localhost:${port}`) diff --git a/packages/@uppy/companion/test/callback.test.ts b/packages/@uppy/companion/test/callback.test.ts index 72750ced2..3a19e0093 100644 --- a/packages/@uppy/companion/test/callback.test.ts +++ b/packages/@uppy/companion/test/callback.test.ts @@ -1,16 +1,19 @@ import request from 'supertest' -import { describe, expect, test, vi } from 'vitest' +import { beforeEach, describe, expect, test, vi } from 'vitest' import * as tokenService from '../src/server/helpers/jwt.js' -import mockOauthState from './mockoauthstate.js' -import { getServer, grantToken } from './mockserver.js' - -vi.mock('express-prom-bundle') -mockOauthState() const secret = 'secret' +beforeEach(() => { + vi.mock('express-prom-bundle') + + vi.resetModules() + vi.clearAllMocks() +}) + describe('test authentication callback', () => { test('authentication callback redirects to send-token url', async () => { + const { getServer } = await import('./mockserver.js') return request(await getServer()) .get('/drive/callback') .expect(302) @@ -22,6 +25,7 @@ describe('test authentication callback', () => { }) test('authentication callback sets cookie', async () => { + const { getServer, grantToken } = await import('./mockserver.js') return request(await getServer()) .get('/dropbox/callback') .expect(302) @@ -45,13 +49,55 @@ describe('test authentication callback', () => { }) }) - test('the token gets sent via html', async () => { + test('the token gets sent via websocket', async () => { + const callbackToken = 'auth-callback-token' + + const oauthState = await import('../src/server/helpers/oauth-state.js') + vi.spyOn(oauthState, 'getFromState').mockImplementation((state, key) => { + if (key === 'authCallbackToken') return callbackToken + + return 'http://localhost:3020' + }) + const authData = { dropbox: { accessToken: 'token value' }, drive: { accessToken: 'token value' }, } const token = tokenService.generateEncryptedAuthToken(authData, secret) + const onEmitted = vi.fn() + + const { getServerWithEmitter } = await import('./mockserver.js') + const { server, emitter } = await getServerWithEmitter() + emitter.on(callbackToken, onEmitted) + + await request(server) + .get(`/dropbox/send-token?uppyAuthToken=${encodeURIComponent(token)}`) + .expect(200) + .expect((res) => { + expect(res.text).toMatch('Authentication successful') + }) + + expect(onEmitted).toHaveBeenLastCalledWith({ + token, + }) + }) + + test('the token gets sent via legacy html mechanism', async () => { + const oauthState = await import('../src/server/helpers/oauth-state.js') + vi.spyOn(oauthState, 'getFromState').mockImplementation((state, key) => { + if (key === 'authCallbackToken') return undefined + + return 'http://localhost:3020' + }) + + const authData = { + dropbox: { accessToken: 'token value' }, + drive: { accessToken: 'token value' }, + } + const token = tokenService.generateEncryptedAuthToken(authData, secret) + + const { getServer } = await import('./mockserver.js') // see mock ../../src/server/helpers/oauth-state above for state values return request(await getServer()) .get(`/dropbox/send-token?uppyAuthToken=${encodeURIComponent(token)}`) diff --git a/packages/@uppy/companion/test/mockserver.ts b/packages/@uppy/companion/test/mockserver.ts index 0f2ed32ee..5fb178467 100644 --- a/packages/@uppy/companion/test/mockserver.ts +++ b/packages/@uppy/companion/test/mockserver.ts @@ -89,9 +89,9 @@ export const grantToken = 'fake token' // companion stores certain global state, so the user needs to reset modules for each test // todo rewrite companion to not use global state // https://github.com/transloadit/uppy/issues/3284 -export const getServer = async ( +export const getServerWithEmitter = async ( extraEnv: Record = {}, -): Promise> => { +) => { const { default: standalone } = await import('../src/standalone/index.js') const env = { @@ -125,7 +125,14 @@ export const getServer = async ( next() }) - const { app } = standalone() + const { app, emitter } = standalone() authServer.use(app) - return authServer + return { server: authServer, emitter } +} + +export const getServer = async ( + extraEnv?: Record | undefined, +) => { + const { server } = await getServerWithEmitter(extraEnv) + return server } From b32781e2807f82af262493e298d504f8bb387bed Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 13:00:03 +0800 Subject: [PATCH 12/33] ci: remove qemu from companion edge deploy workflow (#6282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - replace QEMU-based multi-platform build in `.github/workflows/companion-deploy.yml` with native runner matrix builds - build amd64 on `ubuntu-24.04` and arm64 on `ubuntu-24.04-arm` - push architecture-specific tags (`edge-amd64`, `edge-arm64`) and publish `transloadit/companion:edge` as a manifest that references both - add explicit workflow permissions (`contents: read`) and keep workflow expression formatting consistent - remove conflicting `DOCKER_BUILDKIT`/`COMPOSE_DOCKER_CLI_BUILD` env overrides from the docker job ## Validation - `corepack yarn check:ci` ✅ - baseline full run before edits: `corepack yarn check:ci && corepack yarn build && corepack yarn test` (test step had pre-existing failures in `@uppy/utils` due `Promise.withResolvers` in this environment) - parallel validation (Code Review + CodeQL) ✅ ## TODO - [ ] do the same for release? https://github.com/transloadit/uppy/blob/main/.github/workflows/release.yml --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mifi <402547+mifi@users.noreply.github.com> Co-authored-by: Mikael Finstad --- .github/workflows/companion-deploy.yml | 52 ++++++++++++++++---------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/.github/workflows/companion-deploy.yml b/.github/workflows/companion-deploy.yml index b7696d1b1..53e87b9f0 100644 --- a/.github/workflows/companion-deploy.yml +++ b/.github/workflows/companion-deploy.yml @@ -38,35 +38,49 @@ jobs: path: /tmp/companion-${{ github.sha }}.tar.gz docker: - name: DockerHub - runs-on: ubuntu-latest - env: - DOCKER_BUILDKIT: 0 - COMPOSE_DOCKER_CLI_BUILD: 0 + name: DockerHub (${{ matrix.platform }}) + strategy: + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + platform_tag: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + platform_tag: arm64 + runs-on: ${{ matrix.runner }} steps: - name: Checkout sources uses: actions/checkout@v6 - - name: Docker meta - id: docker_meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 - with: - images: transloadit/companion - tags: | - type=edge - type=raw,value=latest,enable=false - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - uses: docker/setup-buildx-action@v3 - name: Log in to DockerHub uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - username: ${{secrets.DOCKER_USERNAME}} - password: ${{secrets.DOCKER_PASSWORD}} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 with: push: true context: . - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} file: Dockerfile - tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} \ No newline at end of file + tags: transloadit/companion:edge-${{ matrix.platform_tag }} + + docker-manifest: + name: DockerHub manifest + needs: docker + runs-on: ubuntu-latest + steps: + - uses: docker/setup-buildx-action@v3 + - name: Log in to DockerHub + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Publish edge manifest + run: | + docker buildx imagetools create \ + --tag transloadit/companion:edge \ + transloadit/companion:edge-amd64 \ + transloadit/companion:edge-arm64 From 0e09bd209691f9675c03acd89a760417653425e4 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 12 May 2026 14:14:10 +0200 Subject: [PATCH 13/33] Harden dependency installs (#6291) ## Why Recent npm supply-chain compromises showed that dependency installs and shared CI caches can execute or preserve newly published malicious packages before advisories catch up. This PR reduces that exposure for this repo. ## What changed - Made eligible Yarn installs immutable and removed shared dependency caching from the manual CDN upload path; existing minimal age gate remains unchanged. ## Validation - Ran `git diff --check` across the prepared worktree. - Audited this PR set for `pull_request_target` and release/deploy/CDN cache reuse; patched actionable hits. - Did not run the full test suite; this is a workflow/config-only change. --- .github/workflows/bundlers.yml | 2 +- .github/workflows/ci.yml | 4 ++-- .github/workflows/manual-cdn.yml | 12 ------------ 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/.github/workflows/bundlers.yml b/.github/workflows/bundlers.yml index 0f2035da8..a0dcf03ee 100644 --- a/.github/workflows/bundlers.yml +++ b/.github/workflows/bundlers.yml @@ -42,7 +42,7 @@ jobs: node-version: lts/* - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable env: # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation CYPRESS_INSTALL_BINARY: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d657c7ef..8846111ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: node-version: ${{matrix.node-version}} - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable - name: Install Playwright Browsers run: corepack yarn workspace @uppy/dashboard playwright install --with-deps - name: Build @@ -84,7 +84,7 @@ jobs: node-version: lts/* - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable - run: corepack yarn run typecheck lint_js: diff --git a/.github/workflows/manual-cdn.yml b/.github/workflows/manual-cdn.yml index 2d511a965..0efbe6fa7 100644 --- a/.github/workflows/manual-cdn.yml +++ b/.github/workflows/manual-cdn.yml @@ -30,18 +30,6 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v6 - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: - echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v5 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - name: Install Node.js uses: actions/setup-node@v6 with: From 57f8daf55de6d61a430f3b591f33b4be34c1ae3e Mon Sep 17 00:00:00 2001 From: Prakash Date: Wed, 13 May 2026 02:52:53 +0530 Subject: [PATCH 14/33] @uppy/transloadit: add AssemblyStatus to plugin state (#6267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fixes content repo testing area bug https://github.com/transloadit/content/issues/4943 (tested locally in content repo) - Simplifies the testing area code — no need to manually construct the assembly object and listen for multiple events; just subscribe to state using `useUppyState` and that's it (tested locally in content repo) - Addresses https://transloadit.slack.com/archives/C0AFZGN6W2F/p1775580430051829?thread_ts=1775555821.837409&cid=C0AFZGN6W2F (one of our customers wanted to create a custom UI around assembly execution); this would become much easier now (need to verify) - Addresses https://github.com/transloadit/content/blob/9474e8d8e72c73d27288507c874f550c2df6cee4/_console/js/features/templates/components/TestingArea/uppy.tsx#L131-L147 - Partially addresses #6264 --- .changeset/legal-drinks-marry.md | 5 +++ packages/@uppy/transloadit/src/Assembly.ts | 7 +++++ packages/@uppy/transloadit/src/index.test.js | 19 +++++++++++ packages/@uppy/transloadit/src/index.ts | 33 ++++++++++++++++++-- 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 .changeset/legal-drinks-marry.md diff --git a/.changeset/legal-drinks-marry.md b/.changeset/legal-drinks-marry.md new file mode 100644 index 000000000..e859660be --- /dev/null +++ b/.changeset/legal-drinks-marry.md @@ -0,0 +1,5 @@ +--- +"@uppy/transloadit": minor +--- + +Add assemblyStatus and lastAssemblyStatus to transloadit's plugin state diff --git a/packages/@uppy/transloadit/src/Assembly.ts b/packages/@uppy/transloadit/src/Assembly.ts index ea2f676cf..d98900ac1 100644 --- a/packages/@uppy/transloadit/src/Assembly.ts +++ b/packages/@uppy/transloadit/src/Assembly.ts @@ -140,6 +140,13 @@ class TransloaditAssembly extends Emitter { this.#sse.addEventListener('assembly_execution_progress', (e) => { const details = JSON.parse(e.data) + // setting combined execution progress of the assembly + if (typeof details.progress_combined === 'number') { + this.status = { + ...this.status, + progress_combined: details.progress_combined, + } + } this.emit('execution-progress', details) }) diff --git a/packages/@uppy/transloadit/src/index.test.js b/packages/@uppy/transloadit/src/index.test.js index 8f3cf6e7d..0bd6f1854 100644 --- a/packages/@uppy/transloadit/src/index.test.js +++ b/packages/@uppy/transloadit/src/index.test.js @@ -189,6 +189,15 @@ describe('Transloadit', () => { }, }) + // Plugin state should start empty; track every distinct `ok` that lands in + // it so we can verify the assembly lifecycle is reflected. + expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined() + const okHistory = [] + const unsubscribe = uppy.store.subscribe((_prev, next) => { + const ok = next.plugins.Transloadit.assemblyStatus?.ok + if (ok && ok !== okHistory.at(-1)) okHistory.push(ok) + }) + uppy.addFile({ source: 'test', name: 'cat.jpg', @@ -228,12 +237,22 @@ describe('Transloadit', () => { uppy.resumeAll() await uploadPromise + unsubscribe() expect(successSpy).toHaveBeenCalled() // Should be reset to true after upload completes expect(uppy.getState().allowNewUpload).toBe(true) + // The createAssembly mock returned ASSEMBLY_EXECUTING and the assembly + // setter forwarded that status into plugin state during the upload. + expect(okHistory).toContain('ASSEMBLY_EXECUTING') + // `assemblyStatus` is the live slot — it clears when `this.assembly` + // becomes undefined at the end of `#afterUpload`. `lastAssembly` is + // intentionally not populated here because no terminal event fires in + // this mocked flow (the server keeps returning ASSEMBLY_EXECUTING). + expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined() + server.close() }) diff --git a/packages/@uppy/transloadit/src/index.ts b/packages/@uppy/transloadit/src/index.ts index 60ce29fa1..5d226595f 100644 --- a/packages/@uppy/transloadit/src/index.ts +++ b/packages/@uppy/transloadit/src/index.ts @@ -26,7 +26,9 @@ import AssemblyWatcher from './AssemblyWatcher.js' import Client, { type AssemblyError } from './Client.js' import locale from './locale.js' -export type AssemblyResponse = AssemblyStatus +export type AssemblyResponse = AssemblyStatus & { + progress_combined?: number +} export type AssemblyFile = AssemblyStatusUpload export type AssemblyResult = AssemblyStatusResult & { localId: string | null } export type AssemblyParameters = AssemblyInstructionsInput @@ -79,6 +81,19 @@ type TransloaditState = { string, { assembly: string; id: string; uploadedFile: AssemblyFile } > + /** + * Live status of the currently-active assembly. Tracks every status + * transition (UPLOADING → EXECUTING → ...). Cleared automatically when + * `this.assembly = undefined` (no live assembly). + */ + assemblyStatus: AssemblyResponse | undefined + /** + * Snapshot of the most recent non-null status seen. Persists across the + * gap between uploads so the UI can keep showing "your last upload's + * result" after `assemblyStatus` clears. Overwritten by the next + * status update routed through `#handleAssemblyStatusUpdate`. + */ + lastAssemblyStatus: AssemblyResponse | undefined results: Array<{ result: AssemblyResult stepName: string @@ -499,11 +514,20 @@ export default class Transloadit< } /** - * Allows Golden Retriever plugin to serialize the Assembly status so we can restore it later + * Mirrors the live Assembly status into plugin state and lets Golden + * Retriever serialize it for restore. `assemblyStatus` is written + * unconditionally — when `this.assembly = undefined`, `assemblyResponse` + * is undefined and `assemblyStatus` clears too. `lastAssemblyStatus` + * captures the most recent non-null status so the UI can keep displaying + * the previous run's result after `assemblyStatus` clears. */ #handleAssemblyStatusUpdate = ( assemblyResponse: AssemblyResponse | undefined, ) => { + if (assemblyResponse != null) { + this.setPluginState({ lastAssemblyStatus: assemblyResponse }) + } + this.setPluginState({ assemblyStatus: assemblyResponse }) this.uppy.emit('restore:plugin-data-changed', { [this.id]: assemblyResponse ? { assemblyResponse } : undefined, }) @@ -650,6 +674,9 @@ export default class Transloadit< this.uppy.log(err) } } + // `assemblyStatus` is cleared automatically when `this.assembly = undefined` + // (via `#cancelAssembly` above, or by `#afterUpload`'s finally block). + // Reset allowNewUpload when upload is cancelled this.uppy.setState({ allowNewUpload: true }) } @@ -1006,6 +1033,8 @@ export default class Transloadit< this.uppy.on('restored', this.#onRestored) this.setPluginState({ + assemblyStatus: undefined, + lastAssemblyStatus: undefined, // Contains file data from Transloadit, indexed by their Transloadit-assigned ID. files: {}, // Contains result data from Transloadit. From 12de077e6d7019c5d907d36868a6809d139057ca Mon Sep 17 00:00:00 2001 From: Prakash Date: Wed, 13 May 2026 14:42:10 +0530 Subject: [PATCH 15/33] remove @uppy/instagram (#6257) closes #5455 , this PR removes all Instagram support from both the client and Companion server. Removed: - Instagram from @uppy/remote-sources (src, package.json, keywords) - Instagram export from uppy bundle (bundle.ts, index.ts, package.json) - Companion Instagram OAuth provider (provider/index.js, grant.js) - Companion standalone helper Instagram env vars (helper.js, env_example) - All Companion Instagram tests (providers.test.js, provider-manager.test.js, fixtures/index.js, mockserver.js) --- .changeset/gold-rice-jog.md | 9 + .env.example | 3 - .github/CONTRIBUTING.md | 4 +- BUNDLE-README.md | 2 +- CLAUDE.md | 2 +- README.md | 14 +- examples/companion/client/index.html | 5 - examples/companion/server/index.js | 4 - package.json | 2 +- packages/@uppy/companion/KUBERNETES.md | 2 - packages/@uppy/companion/README.md | 2 +- packages/@uppy/companion/env_example | 4 - packages/@uppy/companion/src/config/grant.ts | 4 - .../@uppy/companion/src/server/Uploader.ts | 2 +- .../companion/src/server/provider/index.ts | 2 - .../provider/instagram/graph/adapter.ts | 103 ---------- .../server/provider/instagram/graph/index.ts | 161 --------------- .../@uppy/companion/src/standalone/helper.ts | 5 - .../@uppy/companion/test/fixtures/index.ts | 2 - .../companion/test/fixtures/instagram.ts | 9 - packages/@uppy/companion/test/mockserver.ts | 5 - .../companion/test/provider-manager.test.ts | 30 --- .../@uppy/companion/test/providers.test.ts | 42 ---- .../test/resources/instagram_secret_file | 1 - .../@uppy/components/src/ProviderIcon.tsx | 31 --- .../components/src/hooks/remote-source.ts | 1 - packages/@uppy/core/README.md | 4 +- packages/@uppy/core/package.json | 2 +- packages/@uppy/core/src/Uppy.test.ts | 6 +- packages/@uppy/dashboard/README.md | 4 +- .../@uppy/dashboard/src/utils/trapFocus.ts | 4 +- packages/@uppy/instagram/.npmignore | 1 - packages/@uppy/instagram/CHANGELOG.md | 183 ------------------ packages/@uppy/instagram/LICENSE | 21 -- packages/@uppy/instagram/README.md | 48 ----- packages/@uppy/instagram/package.json | 52 ----- packages/@uppy/instagram/src/Instagram.tsx | 133 ------------- packages/@uppy/instagram/src/index.ts | 2 - packages/@uppy/instagram/src/locale.ts | 5 - packages/@uppy/instagram/tsconfig.build.json | 23 --- packages/@uppy/instagram/tsconfig.json | 22 --- packages/@uppy/instagram/turbo.json | 8 - packages/@uppy/locales/src/ca_ES.ts | 1 - packages/@uppy/locales/src/de_DE.ts | 1 - packages/@uppy/locales/src/en_US.ts | 1 - packages/@uppy/locales/src/es_ES.ts | 1 - packages/@uppy/locales/src/fa_IR.ts | 1 - packages/@uppy/locales/src/ms_MY.ts | 1 - packages/@uppy/locales/src/nl_NL.ts | 1 - packages/@uppy/locales/src/pl_PL.ts | 1 - packages/@uppy/locales/src/pt_BR.ts | 1 - packages/@uppy/locales/src/sv_SE.ts | 1 - packages/@uppy/locales/src/uk_UA.ts | 1 - packages/@uppy/locales/src/uz_UZ.ts | 1 - packages/@uppy/locales/src/vi_VN.ts | 1 - packages/@uppy/locales/turbo.json | 3 +- .../SearchProviderView/SearchProviderView.tsx | 2 +- packages/@uppy/remote-sources/package.json | 4 +- .../@uppy/remote-sources/src/index.test.ts | 2 +- packages/@uppy/remote-sources/src/index.ts | 3 - .../@uppy/remote-sources/tsconfig.build.json | 3 - packages/@uppy/remote-sources/tsconfig.json | 3 - packages/@uppy/transloadit/src/index.ts | 1 - packages/uppy/package.json | 3 +- packages/uppy/src/bundle.ts | 1 - packages/uppy/src/index.ts | 1 - packages/uppy/tsconfig.build.json | 3 - packages/uppy/tsconfig.json | 3 - private/dev/Dashboard.js | 2 - yarn.lock | 17 -- 70 files changed, 36 insertions(+), 997 deletions(-) create mode 100644 .changeset/gold-rice-jog.md delete mode 100644 packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts delete mode 100644 packages/@uppy/companion/src/server/provider/instagram/graph/index.ts delete mode 100644 packages/@uppy/companion/test/fixtures/instagram.ts delete mode 100644 packages/@uppy/companion/test/resources/instagram_secret_file delete mode 100644 packages/@uppy/instagram/.npmignore delete mode 100644 packages/@uppy/instagram/CHANGELOG.md delete mode 100644 packages/@uppy/instagram/LICENSE delete mode 100644 packages/@uppy/instagram/README.md delete mode 100644 packages/@uppy/instagram/package.json delete mode 100644 packages/@uppy/instagram/src/Instagram.tsx delete mode 100644 packages/@uppy/instagram/src/index.ts delete mode 100644 packages/@uppy/instagram/src/locale.ts delete mode 100644 packages/@uppy/instagram/tsconfig.build.json delete mode 100644 packages/@uppy/instagram/tsconfig.json delete mode 100644 packages/@uppy/instagram/turbo.json diff --git a/.changeset/gold-rice-jog.md b/.changeset/gold-rice-jog.md new file mode 100644 index 000000000..71b7a8fc0 --- /dev/null +++ b/.changeset/gold-rice-jog.md @@ -0,0 +1,9 @@ +--- +"@uppy/components": major +"@uppy/companion": major +"uppy": major +"@uppy/transloadit": minor +"@uppy/locales": minor +--- + +Remove @uppy/instagram references from all the packages diff --git a/.env.example b/.env.example index a3bbe74b7..f8ccdd5f4 100644 --- a/.env.example +++ b/.env.example @@ -44,9 +44,6 @@ COMPANION_DROPBOX_SECRET=*** COMPANION_GOOGLE_KEY=*** COMPANION_GOOGLE_SECRET=*** -COMPANION_INSTAGRAM_KEY=*** -COMPANION_INSTAGRAM_SECRET=*** - COMPANION_FACEBOOK_KEY=*** COMPANION_FACEBOOK_SECRET=*** diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 22ea1f915..b154e0281 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -57,7 +57,7 @@ This is not needed for changing existing components. ## Companion If you’d like to work on features that the basic development version of Uppy -doesn’t support, such as Uppy integrations with Instagram/Google Drive/Facebook +doesn’t support, such as Uppy integrations with Google Drive/Facebook etc., you need to set up your `.env` file (copy the contents of `.env.example` and adjust them based on what you need to work on), and run: @@ -78,7 +78,7 @@ when files are changed. ### How the Authentication and Token mechanism works This section describes how Authentication works between Companion and Providers. -While this behaviour is the same for all Providers (Dropbox, Instagram, Google +While this behaviour is the same for all Providers (Dropbox, Google Drive, etc.), we are going to be referring to Dropbox in place of any Provider throughout this section. diff --git a/BUNDLE-README.md b/BUNDLE-README.md index ffc6fc6c0..5e6396bd5 100644 --- a/BUNDLE-README.md +++ b/BUNDLE-README.md @@ -83,7 +83,7 @@ inline into the page. This, and many more configuration options can be found here: . Uppy has many more Plugins besides Xhr and the Dashboard. For example, you can -enable Webcam, Instagram, or video encoding support. Note that for some Plugins, +enable Webcam or video encoding support. Note that for some Plugins, you will need to run a server side component called: Companion. Those plugins are marked with a (c) symbol. Alternatively, you can sign up for a free Transloadit account. Transloadit runs Companion for you, tusd servers to handle diff --git a/CLAUDE.md b/CLAUDE.md index eb73dda14..4091038aa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,7 +46,7 @@ yarn workspace @uppy/[package-name] build - **Uppy Core** (`@uppy/core`) - Main class that manages plugins, state, and events - **Plugins** - Modular components for different functionalities: - **UI Plugins**: Dashboard, Drag & Drop, File Input, Webcam, etc. - - **Provider Plugins**: Google Drive, Dropbox, Instagram, etc. (require Companion) + - **Provider Plugins**: Google Drive, Dropbox, etc. (require Companion) - **Uploader Plugins**: Tus (resumable), XHR Upload, AWS S3, etc. - **Utility Plugins**: Golden Retriever (recovery), Thumbnail Generator, etc. diff --git a/README.md b/README.md index 261e5ab0b..2b63aff7f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ with any application. It’s fast, has a comprehensible API and lets you worry about more important problems than building a file uploader. - **Fetch** files from local disk, remote URLs, Google Drive, Dropbox, Box, - Instagram or snap and record selfies with a camera + or snap and record selfies with a camera - **Preview** and edit metadata with a nice interface - **Upload** to the final destination, optionally process/encode @@ -82,7 +82,7 @@ For the supported frameworks (except Angular) Uppy offers three ways to build us - Lightweight, modular plugin-based architecture, light on dependencies :zap: - Resumable file uploads via the open [tus](https://tus.io/) standard, so large uploads survive network hiccups -- Supports picking files from: Webcam, Dropbox, Box, Google Drive, Instagram, +- Supports picking files from: Webcam, Dropbox, Box, Google Drive, bypassing the user’s device where possible, syncing between servers directly via [@uppy/companion](https://uppy.io/docs/companion) - Works great with file encoding and processing backends, such as @@ -140,7 +140,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. - [Uppy](https://uppy.io/docs/uppy/) — full list of options, methods and events - [Companion](https://uppy.io/docs/companion/) — setting up and running a - Companion instance, which adds support for Instagram, Dropbox, Box, Google + Companion instance, which adds support for Dropbox, Box, Google Drive and remote URLs - [React](https://uppy.io/docs/react/) — components to integrate Uppy UI plugins with React apps @@ -153,7 +153,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. - [`Dashboard`](https://uppy.io/docs/dashboard/) — universal UI with previews, progress bars, metadata editor and all the cool stuff. Required for most UI - plugins like Webcam and Instagram + plugins like Webcam - Headless components ([react](https://uppy.io/docs/react/), [svelte](https://uppy.io/docs/svelte/), [vue](https://uppy.io/docs/vue/)) ### Sources @@ -166,8 +166,6 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. Google Drive - ⓒ [`Dropbox`](https://uppy.io/docs/dropbox/) — import files from Dropbox - ⓒ [`Box`](https://uppy.io/docs/box/) — import files from Box -- ⓒ [`Instagram`](https://uppy.io/docs/instagram/) — import images and videos - from Instagram - ⓒ [`Facebook`](https://uppy.io/docs/facebook/) — import images and videos from Facebook - ⓒ [`OneDrive`](https://uppy.io/docs/onedrive/) — import files from Microsoft @@ -222,7 +220,7 @@ cases, the file input leaves some to be desired: - Uppy supports editing meta information before uploading. - Uppy allows cropping images before uploading. - There’s the situation where people are using their mobile devices and want to - upload on the go, but they have their picture on Instagram, files in Dropbox + upload on the go, but they have files in Dropbox or a plain file URL from anywhere on the open web. Uppy allows to pick files from those and push it to the destination without downloading it to your mobile device first. @@ -272,7 +270,7 @@ If you want resumability with the Tus plugin, use [one of the tus server implementations](https://tus.io/implementations.html) 👌🏼 And you’ll need [`@uppy/companion`](https://uppy.io/docs/companion) if you’d -like your users to be able to pick files from Instagram, Google Drive, Dropbox +like your users to be able to pick files from Google Drive, Dropbox or via direct URLs (with more services coming). ## Contributions are welcome diff --git a/examples/companion/client/index.html b/examples/companion/client/index.html index 26489beb8..64d93e91c 100644 --- a/examples/companion/client/index.html +++ b/examples/companion/client/index.html @@ -16,17 +16,12 @@ import { Uppy, Dashboard, - Instagram, GoogleDrive, Tus, } from 'https://releases.transloadit.com/uppy/v4.18.0/uppy.min.mjs' const uppy = new Uppy({ debug: true, autoProceed: false }) .use(Dashboard, { trigger: '#uppyModalOpener' }) - .use(Instagram, { - target: Dashboard, - companionUrl: 'http://localhost:3020', - }) .use(GoogleDrive, { target: Dashboard, companionUrl: 'http://localhost:3020', diff --git a/examples/companion/server/index.js b/examples/companion/server/index.js index 076e187cd..ab7c5f6ee 100644 --- a/examples/companion/server/index.js +++ b/examples/companion/server/index.js @@ -32,10 +32,6 @@ const companionOptions = { key: 'your google key', secret: 'your google secret', }, - instagram: { - key: 'your instagram key', - secret: 'your instagram secret', - }, dropbox: { key: 'your dropbox key', secret: 'your dropbox secret', diff --git a/package.json b/package.json index fbc1d08dc..19499e50c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@uppy-dev/build", "version": "0.0.0", "private": true, - "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:", + "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox, Google Drive, S3 and more :dog:", "license": "MIT", "workspaces": [ "examples/*", diff --git a/packages/@uppy/companion/KUBERNETES.md b/packages/@uppy/companion/KUBERNETES.md index 5b148a478..e72b2c131 100644 --- a/packages/@uppy/companion/KUBERNETES.md +++ b/packages/@uppy/companion/KUBERNETES.md @@ -38,8 +38,6 @@ data: COMPANION_BOX_SECRET: 'YOUR BOX SECRET' COMPANION_GOOGLE_KEY: 'YOUR GOOGLE KEY' COMPANION_GOOGLE_SECRET: 'YOUR GOOGLE SECRET' - COMPANION_INSTAGRAM_KEY: 'YOUR INSTAGRAM KEY' - COMPANION_INSTAGRAM_SECRET: 'YOUR INSTAGRAM SECRET' COMPANION_AWS_KEY: 'YOUR AWS KEY' COMPANION_AWS_SECRET: 'YOUR AWS SECRET' COMPANION_AWS_BUCKET: 'YOUR AWS S3 BUCKET' diff --git a/packages/@uppy/companion/README.md b/packages/@uppy/companion/README.md index bed8ac782..30e37e963 100644 --- a/packages/@uppy/companion/README.md +++ b/packages/@uppy/companion/README.md @@ -8,7 +8,7 @@ Companion is a server integration for [Uppy](https://github.com/transloadit/uppy) file uploader. It handles the server-to-server communication between your server and file -storage providers such as Google Drive, Dropbox, Instagram, etc. **Companion is +storage providers such as Google Drive, Dropbox, etc. **Companion is not a target to upload files to**. For this, use a server (if you want resumable) or your existing Apache/Nginx server (if you don’t). [See here for full documentation](https://uppy.io/docs/companion/) diff --git a/packages/@uppy/companion/env_example b/packages/@uppy/companion/env_example index cd5726e69..162232a21 100644 --- a/packages/@uppy/companion/env_example +++ b/packages/@uppy/companion/env_example @@ -26,10 +26,6 @@ COMPANION_GOOGLE_KEY= COMPANION_GOOGLE_SECRET= COMPANION_GOOGLE_SECRET_FILE= -COMPANION_INSTAGRAM_KEY= -COMPANION_INSTAGRAM_SECRET= -COMPANION_INSTAGRAM_SECRET_FILE= - COMPANION_FACEBOOK_KEY= COMPANION_FACEBOOK_SECRET= COMPANION_FACEBOOK_SECRET_FILE= diff --git a/packages/@uppy/companion/src/config/grant.ts b/packages/@uppy/companion/src/config/grant.ts index c923b02c7..c8ad6af17 100644 --- a/packages/@uppy/companion/src/config/grant.ts +++ b/packages/@uppy/companion/src/config/grant.ts @@ -56,10 +56,6 @@ export default function grantConfig(): GrantStaticConfig { access_url: 'https://api.box.com/oauth2/token', callback: '/box/callback', }, - instagram: { - ...defaults, - callback: '/instagram/callback', - }, facebook: { ...defaults, scope: ['email', 'user_photos'], diff --git a/packages/@uppy/companion/src/server/Uploader.ts b/packages/@uppy/companion/src/server/Uploader.ts index 2352e34d5..b564cdafa 100644 --- a/packages/@uppy/companion/src/server/Uploader.ts +++ b/packages/@uppy/companion/src/server/Uploader.ts @@ -222,7 +222,7 @@ export default class Uploader { /** * Uploads file to destination based on the supplied protocol (tus, s3-multipart, multipart) * For tus uploads, the deferredLength option is enabled, because file size value can be unreliable - * for some providers (Instagram particularly) + * for some providers. * * @param optionsIn */ diff --git a/packages/@uppy/companion/src/server/provider/index.ts b/packages/@uppy/companion/src/server/provider/index.ts index 31b28fe1a..3329d027b 100644 --- a/packages/@uppy/companion/src/server/provider/index.ts +++ b/packages/@uppy/companion/src/server/provider/index.ts @@ -7,7 +7,6 @@ import { getCredentialsResolver } from './credentials.js' import dropbox from './dropbox/index.js' import facebook from './facebook/index.js' import { Drive } from './google/drive/index.js' -import instagram from './instagram/graph/index.js' import onedrive from './onedrive/index.js' import { isOAuthProvider, type ProviderCtor } from './Provider.js' import unsplash from './unsplash/index.js' @@ -113,7 +112,6 @@ export function getDefaultProviders() { facebook, onedrive, zoom, - instagram, unsplash, webdav, } diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts b/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts deleted file mode 100644 index 8779361d5..000000000 --- a/packages/@uppy/companion/src/server/provider/instagram/graph/adapter.ts +++ /dev/null @@ -1,103 +0,0 @@ -import querystring from 'node:querystring' - -const MEDIA_TYPES = Object.freeze({ - video: 'VIDEO', - carousel: 'CAROUSEL_ALBUM', - image: 'IMAGE', -}) - -type InstagramMedia = { - id: string - media_type: string - media_url?: string - thumbnail_url?: string - timestamp: string - children?: { data: InstagramMedia[] } -} - -type InstagramListResponse = { - data: InstagramMedia[] - paging?: { cursors?: { after?: string } } -} - -const isVideo = (item: InstagramMedia): boolean => - item.media_type === MEDIA_TYPES.video - -const isFolder = (_item: InstagramMedia): boolean => { - return false -} - -const getItemIcon = (item: InstagramMedia): string | undefined => { - return isVideo(item) ? item.thumbnail_url : item.media_url -} - -const getItemSubList = (item: InstagramListResponse): InstagramMedia[] => { - const newItems: InstagramMedia[] = [] - item.data.forEach((subItem) => { - if (subItem.media_type === MEDIA_TYPES.carousel) { - subItem.children?.data.forEach((i) => newItems.push(i)) - } else { - newItems.push(subItem) - } - }) - return newItems -} - -const getItemName = (item: InstagramMedia, index: number): string => { - const ext = isVideo(item) ? 'mp4' : 'jpeg' - // adding index, so the name is unique - return `Instagram ${item.timestamp}${index}.${ext}` -} - -const getMimeType = (item: InstagramMedia): string => { - return isVideo(item) ? 'video/mp4' : 'image/jpeg' -} - -const getItemId = (item: InstagramMedia): string => item.id - -const getItemRequestPath = (item: InstagramMedia): string => item.id - -const getItemModifiedDate = (item: InstagramMedia): string => item.timestamp - -const getItemThumbnailUrl = (item: InstagramMedia): string | undefined => - getItemIcon(item) - -const getNextPagePath = ( - data: InstagramListResponse, - currentQuery: Record, - currentPath: string | undefined, -): string | null => { - if (!data.paging || !data.paging.cursors) { - return null - } - - const after = data.paging.cursors.after - if (after == null || after.length === 0) return null - - const query = { ...currentQuery, cursor: after } - return `${currentPath || ''}?${querystring.stringify(query)}` -} - -const adaptData = ( - res: InstagramListResponse, - username: string | null, - directory: string | undefined, - currentQuery: Record, -) => { - const items = getItemSubList(res).map((item, i) => ({ - isFolder: isFolder(item), - icon: getItemIcon(item), - name: getItemName(item, i), - mimeType: getMimeType(item), - id: getItemId(item), - size: null, - thumbnail: getItemThumbnailUrl(item), - requestPath: getItemRequestPath(item), - modifiedDate: getItemModifiedDate(item), - })) - - const nextPagePath = getNextPagePath(res, currentQuery, directory) - return { username, items, nextPagePath } -} - -export default adaptData diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts b/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts deleted file mode 100644 index 791bd5008..000000000 --- a/packages/@uppy/companion/src/server/provider/instagram/graph/index.ts +++ /dev/null @@ -1,161 +0,0 @@ -import type { Readable } from 'node:stream' -import got from 'got' -import { isRecord } from '../../../helpers/type-guards.js' -import { prepareStream } from '../../../helpers/utils.js' -import logger from '../../../logger.js' -import Provider, { - type ProviderListResponse, - type Query, -} from '../../Provider.js' -import { withProviderErrorHandling } from '../../providerErrors.js' -import adaptData from './adapter.js' - -type InstagramClient = ReturnType - -interface InstagramUserSession { - accessToken: string -} - -const getClient = ({ token }: { token: string }): InstagramClient => - got.extend({ - prefixUrl: 'https://graph.instagram.com', - headers: { - authorization: `Bearer ${token}`, - }, - }) - -async function getMediaUrl({ - token, - id, -}: { - token: string - id: string -}): Promise { - const body = await getClient({ token }) - .get(String(id), { - searchParams: { fields: 'media_url' }, - responseType: 'json', - }) - .json<{ media_url: string }>() - - return body.media_url -} - -/** - * Adapter for API https://developers.facebook.com/docs/instagram-api/overview - */ -export default class Instagram extends Provider { - // for "grant" - static override getExtraGrantConfig() { - return { - protocol: 'https', - scope: ['user_profile', 'user_media'], - } - } - - static override get oauthProvider() { - return 'instagram' - } - - override async list({ - directory, - providerUserSession: { accessToken: token }, - query, - }: { - directory?: string | undefined - providerUserSession: InstagramUserSession - query?: Query | undefined - }): Promise { - return this.#withErrorHandling( - 'provider.instagram.list.error', - async () => { - const qs: Record = { - fields: - 'id,media_type,thumbnail_url,media_url,timestamp,children{media_type,media_url,thumbnail_url,timestamp}', - } - - if (typeof query?.['cursor'] === 'string') { - qs['after'] = query['cursor'] - } - - const client = getClient({ token }) - - const [me, list] = await Promise.all([ - client - .get('me', { - searchParams: { fields: 'username' }, - responseType: 'json', - }) - .json<{ username?: string }>(), - client - .get('me/media', { searchParams: qs, responseType: 'json' }) - .json[0]>(), - ]) - - const username = me.username != null ? me.username : null - const currentQuery: Record = {} - if (typeof query?.['cursor'] === 'string') - currentQuery['cursor'] = query['cursor'] - return adaptData(list, username, directory, currentQuery) - }, - ) - } - - override async download({ - id, - providerUserSession: { accessToken: token }, - }: { - id: string - providerUserSession: InstagramUserSession - }): Promise<{ stream: Readable; size: number | undefined }> { - return this.#withErrorHandling( - 'provider.instagram.download.error', - async () => { - const url = await getMediaUrl({ token, id }) - const stream = got.stream.get(url, { responseType: 'json' }) - const { size } = await prepareStream(stream) - return { stream, size } - }, - ) - } - - override async thumbnail(): Promise<{ - stream: Readable - contentType: string - }> { - // not implementing this because a public thumbnail from instagram will be used instead - logger.error( - 'call to thumbnail is not implemented', - 'provider.instagram.thumbnail.error', - ) - throw new Error('call to thumbnail is not implemented') - } - - override async logout() { - // access revoke is not supported by Instagram's API - return { - revoked: false, - manual_revoke_url: 'https://www.instagram.com/accounts/manage_access/', - } - } - - async #withErrorHandling(tag: string, fn: () => Promise): Promise { - return withProviderErrorHandling({ - fn, - tag, - providerName: Instagram.oauthProvider, - isAuthError: (response) => { - const body = response.body - if (!isRecord(body)) return false - const err = body['error'] - return isRecord(err) && err['code'] === 190 - }, // Invalid OAuth 2.0 Access Token - getJsonErrorMessage: (body) => { - if (!isRecord(body)) return undefined - const err = body['error'] - if (!isRecord(err)) return undefined - return typeof err['message'] === 'string' ? err['message'] : undefined - }, - }) - } -} diff --git a/packages/@uppy/companion/src/standalone/helper.ts b/packages/@uppy/companion/src/standalone/helper.ts index c55ab8350..d14cf8eb3 100644 --- a/packages/@uppy/companion/src/standalone/helper.ts +++ b/packages/@uppy/companion/src/standalone/helper.ts @@ -145,11 +145,6 @@ const getConfigFromEnv = (): StandaloneCompanionOptions => { secret: getSecret('COMPANION_BOX_SECRET'), credentialsURL: process.env['COMPANION_BOX_KEYS_ENDPOINT'], }, - instagram: { - key: process.env['COMPANION_INSTAGRAM_KEY'], - secret: getSecret('COMPANION_INSTAGRAM_SECRET'), - credentialsURL: process.env['COMPANION_INSTAGRAM_KEYS_ENDPOINT'], - }, facebook: { key: process.env['COMPANION_FACEBOOK_KEY'], secret: getSecret('COMPANION_FACEBOOK_SECRET'), diff --git a/packages/@uppy/companion/test/fixtures/index.ts b/packages/@uppy/companion/test/fixtures/index.ts index 70593d650..2a9f61332 100644 --- a/packages/@uppy/companion/test/fixtures/index.ts +++ b/packages/@uppy/companion/test/fixtures/index.ts @@ -3,7 +3,6 @@ import * as constants from './constants.js' import * as drive from './drive.js' import * as dropbox from './dropbox.js' import * as facebook from './facebook.js' -import * as instagram from './instagram.js' import * as onedrive from './onedrive.js' import * as zoom from './zoom.js' @@ -11,7 +10,6 @@ export const providers = { box, drive, dropbox, - instagram, onedrive, facebook, zoom, diff --git a/packages/@uppy/companion/test/fixtures/instagram.ts b/packages/@uppy/companion/test/fixtures/instagram.ts deleted file mode 100644 index f1193ec00..000000000 --- a/packages/@uppy/companion/test/fixtures/instagram.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const expects: { - itemName: string - itemMimeType: string - itemSize: null -} = { - itemName: 'Instagram 2017-08-31T18:10:00+00000.jpeg', - itemMimeType: 'image/jpeg', - itemSize: null, -} diff --git a/packages/@uppy/companion/test/mockserver.ts b/packages/@uppy/companion/test/mockserver.ts index 5fb178467..1a66514ca 100644 --- a/packages/@uppy/companion/test/mockserver.ts +++ b/packages/@uppy/companion/test/mockserver.ts @@ -37,11 +37,6 @@ const defaultEnv = { COMPANION_GOOGLE_KEYS_ENDPOINT: undefined, COMPANION_GOOGLE_SECRET_FILE: undefined, - COMPANION_INSTAGRAM_KEY: 'instagram_key', - COMPANION_INSTAGRAM_SECRET: 'instagram_secret', - COMPANION_INSTAGRAM_KEYS_ENDPOINT: undefined, - COMPANION_INSTAGRAM_SECRET_FILE: undefined, - COMPANION_FACEBOOK_KEY: 'facebook_key', COMPANION_FACEBOOK_SECRET: 'facebook_secret', COMPANION_FACEBOOK_KEYS_ENDPOINT: undefined, diff --git a/packages/@uppy/companion/test/provider-manager.test.ts b/packages/@uppy/companion/test/provider-manager.test.ts index ce386fc6b..79031e568 100644 --- a/packages/@uppy/companion/test/provider-manager.test.ts +++ b/packages/@uppy/companion/test/provider-manager.test.ts @@ -74,32 +74,17 @@ describe('Test Provider options', () => { expect(googledrive['secret']).toBe('google_secret') - const instagram = requireGrantProviderConfig(grantConfig, 'instagram') - expect(instagram['key']).toBe('instagram_key') - expect(instagram['secret']).toBe('instagram_secret') - const zoom = requireGrantProviderConfig(grantConfig, 'zoom') expect(zoom['key']).toBe('zoom_key') expect(zoom['secret']).toBe('zoom_secret') }) test('adds extra provider config', () => { - process.env['COMPANION_INSTAGRAM_KEY'] = '123456' providerManager.addProviderOptions( getAddProviderOptionsArgs(getCompanionOptions()), grantConfig, getOauthProvider, ) - expect(requireGrantProviderConfig(grantConfig, 'instagram')).toEqual({ - transport: 'session', - state: true, - callback: '/instagram/callback', - redirect_uri: 'http://localhost:3020/instagram/redirect', - key: '123456', - secret: 'instagram_secret', - protocol: 'https', - scope: ['user_profile', 'user_media'], - }) expect(requireGrantProviderConfig(grantConfig, 'dropbox')).toEqual({ key: 'dropbox_key', @@ -164,8 +149,6 @@ describe('Test Provider options', () => { `${process.env['PWD']}/test/resources/box_secret_file` process.env['COMPANION_GOOGLE_SECRET_FILE'] = `${process.env['PWD']}/test/resources/google_secret_file` - process.env['COMPANION_INSTAGRAM_SECRET_FILE'] = - `${process.env['PWD']}/test/resources/instagram_secret_file` process.env['COMPANION_ZOOM_SECRET_FILE'] = `${process.env['PWD']}/test/resources/zoom_secret_file` process.env['COMPANION_ZOOM_VERIFICATION_TOKEN_FILE'] = @@ -188,9 +171,6 @@ describe('Test Provider options', () => { expect( requireGrantProviderConfig(grantConfig, 'googledrive')['secret'], ).toBe('elgoog') - expect(requireGrantProviderConfig(grantConfig, 'instagram')['secret']).toBe( - 'margatsni', - ) expect(requireGrantProviderConfig(grantConfig, 'zoom')['secret']).toBe( 'u8Z5ceq', ) @@ -232,13 +212,6 @@ describe('Test Provider options', () => { getGrantProviderField(grantConfig, 'googledrive', 'secret'), ).toBeUndefined() - expect( - getGrantProviderField(grantConfig, 'instagram', 'key'), - ).toBeUndefined() - expect( - getGrantProviderField(grantConfig, 'instagram', 'secret'), - ).toBeUndefined() - expect(getGrantProviderField(grantConfig, 'zoom', 'key')).toBeUndefined() expect(getGrantProviderField(grantConfig, 'zoom', 'secret')).toBeUndefined() }) @@ -262,9 +235,6 @@ describe('Test Provider options', () => { expect( requireGrantProviderConfig(grantConfig, 'googledrive')['redirect_uri'], ).toBe('http://domain.com/drive/redirect') - expect( - requireGrantProviderConfig(grantConfig, 'instagram')['redirect_uri'], - ).toBe('http://domain.com/instagram/redirect') expect( requireGrantProviderConfig(grantConfig, 'zoom')['redirect_uri'], ).toBe('http://domain.com/zoom/redirect') diff --git a/packages/@uppy/companion/test/providers.test.ts b/packages/@uppy/companion/test/providers.test.ts index f7d45a215..b9d8f9288 100644 --- a/packages/@uppy/companion/test/providers.test.ts +++ b/packages/@uppy/companion/test/providers.test.ts @@ -316,30 +316,6 @@ describe('list provider files', () => { expect1({ username, items, providerFixture }) }) - test('instagram', async () => { - nock('https://graph.instagram.com').get('/me?fields=username').reply(200, { - id: '17841405793187218', - username: defaults.USERNAME, - }) - nock('https://graph.instagram.com') - .get( - '/me/media?fields=id%2Cmedia_type%2Cthumbnail_url%2Cmedia_url%2Ctimestamp%2Cchildren%7Bmedia_type%2Cmedia_url%2Cthumbnail_url%2Ctimestamp%7D', - ) - .reply(200, { - data: [ - { - id: defaults.ITEM_ID, - media_type: 'IMAGE', - timestamp: '2017-08-31T18:10:00+0000', - media_url: defaults.THUMBNAIL_URL, - }, - ], - }) - - const { username, items, providerFixture } = await runTest('instagram') - expect1({ username, items, providerFixture }) - }) - test('onedrive', async () => { nock('https://graph.microsoft.com').get('/v1.0/me').reply(200, { userPrincipalName: defaults.USERNAME, @@ -490,20 +466,6 @@ describe('provider file gets downloaded from', () => { await runTest('facebook') }) - test('instagram', async () => { - // times(2) because of size request - nock('https://graph.instagram.com') - .get(`/${defaults.ITEM_ID}?fields=media_url`) - .times(2) - .reply(200, { - id: defaults.ITEM_ID, - media_type: 'IMAGE', - media_url: defaults.THUMBNAIL_URL, - timestamp: '2017-08-31T18:10:00+0000', - }) - await runTest('instagram') - }) - test('onedrive', async () => { nock('https://graph.microsoft.com') .get(`/v1.0/drives/DUMMY-DRIVE-ID/items/${defaults.ITEM_ID}`) @@ -609,10 +571,6 @@ describe('logout of provider', () => { await runTest('facebook') }) - test('instagram', async () => { - await runTest('instagram') - }) - test('onedrive', async () => { await runTest('onedrive') }) diff --git a/packages/@uppy/companion/test/resources/instagram_secret_file b/packages/@uppy/companion/test/resources/instagram_secret_file deleted file mode 100644 index b57fd4dde..000000000 --- a/packages/@uppy/companion/test/resources/instagram_secret_file +++ /dev/null @@ -1 +0,0 @@ -margatsni \ No newline at end of file diff --git a/packages/@uppy/components/src/ProviderIcon.tsx b/packages/@uppy/components/src/ProviderIcon.tsx index 3dc00007e..730855f6a 100644 --- a/packages/@uppy/components/src/ProviderIcon.tsx +++ b/packages/@uppy/components/src/ProviderIcon.tsx @@ -8,7 +8,6 @@ export type ProviderIconProps = { | 'audio' | 'dropbox' | 'facebook' - | 'instagram' | 'onedrive' | 'googlephotos' | 'googledrive' @@ -94,36 +93,6 @@ export default function ProviderIcon(props: ProviderIconProps) { ) - case 'instagram': - return ( - - ) case 'onedrive': return ( { }) core.addFile({ - source: 'instagram', + source: 'dropbox', name: 'foo.jpg', type: 'image/jpeg', // @ts-ignore @@ -2028,7 +2028,7 @@ describe('src/Core', () => { }) }) core.addFile({ - source: 'instagram', + source: 'dropbox', name: 'foo.jpg', type: 'image/jpeg', // @ts-ignore @@ -2045,7 +2045,7 @@ describe('src/Core', () => { }) }) core.addFile({ - source: 'instagram', + source: 'dropbox', name: 'bar.jpg', type: 'image/jpeg', // @ts-ignore diff --git a/packages/@uppy/dashboard/README.md b/packages/@uppy/dashboard/README.md index 0ee113f7b..57544da7a 100644 --- a/packages/@uppy/dashboard/README.md +++ b/packages/@uppy/dashboard/README.md @@ -10,8 +10,8 @@ Dashboard is a universal UI plugin for Uppy: - Drag and Drop, paste, select from local disk / my device -- UI for Webcam and remote sources: Google Drive, Dropbox, Instagram (all - optional, added via plugins) +- UI for Webcam and remote sources: Google Drive, Dropbox (all optional, added + via plugins) - File previews and info - Metadata editor - Progress: total and for individual files diff --git a/packages/@uppy/dashboard/src/utils/trapFocus.ts b/packages/@uppy/dashboard/src/utils/trapFocus.ts index ad2ceafff..c902f4fbd 100644 --- a/packages/@uppy/dashboard/src/utils/trapFocus.ts +++ b/packages/@uppy/dashboard/src/utils/trapFocus.ts @@ -24,8 +24,6 @@ function focusOnLastNode(event: $TSFixMe, nodes: $TSFixMe) { // Firefox thinks
    is focusable, but we don't have
      s in our FOCUSABLE_ELEMENTS. Which means that if we tab into // the
        , code will think that we are not in the active overlay, and we should focusOnFirstNode() of the currently // active overlay! -// [Practical check] if we use (focusedItemIndex === -1), instagram provider in firefox will never get focus on its pics -// in the
          . function isFocusInOverlay(activeOverlayEl: $TSFixMe) { return activeOverlayEl.contains(document.activeElement) } @@ -60,7 +58,7 @@ function trapFocus( } } -// Traps focus inside of the currently open overlay (e.g. Dashboard, or e.g. Instagram), +// Traps focus inside of the currently open overlay (e.g. Dashboard), // never lets focus disappear from the modal. export { trapFocus as forModal } diff --git a/packages/@uppy/instagram/.npmignore b/packages/@uppy/instagram/.npmignore deleted file mode 100644 index 6c816673f..000000000 --- a/packages/@uppy/instagram/.npmignore +++ /dev/null @@ -1 +0,0 @@ -tsconfig.* diff --git a/packages/@uppy/instagram/CHANGELOG.md b/packages/@uppy/instagram/CHANGELOG.md deleted file mode 100644 index 56a1b50ca..000000000 --- a/packages/@uppy/instagram/CHANGELOG.md +++ /dev/null @@ -1,183 +0,0 @@ -# @uppy/instagram - -## 5.1.0 - -### Minor Changes - -- 79e6460: - Add PluginTypeRegistry and typed getPlugin overload in @uppy/core - - Register plugin ids across packages so uppy.getPlugin('Dashboard' | 'Webcam') returns the concrete plugin type and removes the need to pass generics in getPlugin() - -### Patch Changes - -- Updated dependencies [e661348] -- Updated dependencies [79e6460] -- Updated dependencies [ac12f35] -- Updated dependencies [4817585] - - @uppy/provider-views@5.2.0 - - @uppy/core@5.2.0 - - @uppy/utils@7.1.4 - -## 5.0.1 - -### Patch Changes - -- 975317d: Removed "main" from package.json, since export maps serve as the contract for the public API. -- Updated dependencies [4b6a76c] -- Updated dependencies [975317d] -- Updated dependencies [9bac4c8] - - @uppy/core@5.0.2 - - @uppy/companion-client@5.0.1 - - @uppy/provider-views@5.0.2 - - @uppy/utils@7.0.2 - -## 5.0.0 - -### Major Changes - -- c5b51f6: ### Export maps for all packages - - All packages now have export maps. This is a breaking change in two cases: - - 1. The css imports have changed from `@uppy[package]/dist/styles.min.css` to `@uppy[package]/css/styles.min.css` - 2. You were importing something that wasn't exported from the root, for instance `@uppy/core/lib/foo.js`. You can now only import things we explicitly exported. - - #### Changed imports for `@uppy/react`, `@uppy/vue`, and `@uppy/svelte` - - Some components, like Dashboard, require a peer dependency to work but since all components were exported from a single file you were forced to install all peer dependencies. Even if you never imported, for instance, the status bar component. - - Every component that requires a peer dependency has now been moved to a subpath, such as `@uppy/react/dashboard`, so you only need to install the peer dependencies you need. - - **Example for `@uppy/react`:** - - **Before:** - - ```javascript - import { Dashboard, StatusBar } from "@uppy/react"; - ``` - - **Now:** - - ```javascript - import Dashboard from "@uppy/react/dashboard"; - import StatusBar from "@uppy/react/status-bar"; - ``` - -### Patch Changes - -- Updated dependencies [d301c01] -- Updated dependencies [c5b51f6] - - @uppy/utils@7.0.0 - - @uppy/companion-client@5.0.0 - - @uppy/provider-views@5.0.0 - - @uppy/core@5.0.0 - -## 4.3.2 - -### Patch Changes - -- 1b1a9e3: Define "files" in package.json -- Updated dependencies [1b1a9e3] -- Updated dependencies [c66fd85] - - @uppy/companion-client@4.5.2 - - @uppy/provider-views@4.5.2 - - @uppy/utils@6.2.2 - - @uppy/core@4.5.2 - -## 4.3.0 - -### Minor Changes - -- 0c24c5a: Use TypeScript compiler instead of Babel - -### Patch Changes - -- Updated dependencies [0c24c5a] -- Updated dependencies [0c24c5a] - - @uppy/core@4.5.0 - - @uppy/companion-client@4.5.0 - - @uppy/provider-views@4.5.0 - - @uppy/utils@6.2.0 - -## 4.2.3 - -Released: 2025-05-18 -Included in: Uppy v4.16.0 - -- @uppy/audio,@uppy/box,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/google-drive-picker,@uppy/google-drive,@uppy/google-photos-picker,@uppy/image-editor,@uppy/instagram,@uppy/onedrive,@uppy/remote-sources,@uppy/screen-capture,@uppy/unsplash,@uppy/url,@uppy/utils,@uppy/webcam,@uppy/webdav,@uppy/zoom: ts: make locale strings optional (Merlijn Vos / #5728) - -## 4.2.0 - -Released: 2025-01-06 -Included in: Uppy v4.11.0 - -- @uppy/angular,@uppy/audio,@uppy/aws-s3,@uppy/box,@uppy/companion-client,@uppy/compressor,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/drop-target,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/form,@uppy/golden-retriever,@uppy/google-drive-picker,@uppy/google-drive,@uppy/google-photos-picker,@uppy/google-photos,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/locales,@uppy/onedrive,@uppy/progress-bar,@uppy/provider-views,@uppy/react,@uppy/remote-sources,@uppy/screen-capture,@uppy/status-bar,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/vue,@uppy/webcam,@uppy/webdav,@uppy/xhr-upload,@uppy/zoom: Remove "paths" from all tsconfig's (Merlijn Vos / #5572) - -## 4.1.2 - -Released: 2024-12-05 -Included in: Uppy v4.8.0 - -- @uppy/audio,@uppy/aws-s3,@uppy/box,@uppy/companion-client,@uppy/compressor,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/drop-target,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/form,@uppy/golden-retriever,@uppy/google-drive,@uppy/google-photos,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/locales,@uppy/onedrive,@uppy/progress-bar,@uppy/provider-views,@uppy/react,@uppy/remote-sources,@uppy/screen-capture,@uppy/status-bar,@uppy/store-default,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/utils,@uppy/vue,@uppy/webcam,@uppy/xhr-upload,@uppy/zoom: cleanup tsconfig (Mikael Finstad / #5520) - -## 4.1.1 - -Released: 2024-10-31 -Included in: Uppy v4.6.0 - -- @uppy/aws-s3,@uppy/box,@uppy/companion-client,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/form,@uppy/golden-retriever,@uppy/google-drive,@uppy/google-photos,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/locales,@uppy/onedrive,@uppy/progress-bar,@uppy/provider-views,@uppy/react-native,@uppy/react,@uppy/redux-dev-tools,@uppy/screen-capture,@uppy/status-bar,@uppy/store-default,@uppy/store-redux,@uppy/svelte,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/utils,@uppy/vue,@uppy/webcam,@uppy/xhr-upload,@uppy/zoom: Fix links (Anthony Veaudry / #5492) - -## 4.1.0 - -Released: 2024-08-29 -Included in: Uppy v4.3.0 - -- @uppy/aws-s3,@uppy/box,@uppy/compressor,@uppy/dropbox,@uppy/facebook,@uppy/google-drive,@uppy/google-photos,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/onedrive,@uppy/screen-capture,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/xhr-upload,@uppy/zoom: export plugin options (Antoine du Hamel / #5433) - -## 4.0.0-beta.1 - -Released: 2024-03-28 -Included in: Uppy v4.0.0-beta.1 - -- @uppy/instagram: refactor to TypeScript (Murderlon / #4979) - -## 3.3.0 - -Released: 2024-03-27 -Included in: Uppy v3.24.0 - -- @uppy/instagram: refactor to TypeScript (Murderlon / #4979) - -## 3.0.1 - -Released: 2022-09-25 -Included in: Uppy v3.1.0 - -- @uppy/audio,@uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/box,@uppy/companion-client,@uppy/companion,@uppy/compressor,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/drop-target,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/form,@uppy/golden-retriever,@uppy/google-drive,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/locales,@uppy/onedrive,@uppy/progress-bar,@uppy/provider-views,@uppy/react,@uppy/redux-dev-tools,@uppy/remote-sources,@uppy/screen-capture,@uppy/status-bar,@uppy/store-default,@uppy/store-redux,@uppy/svelte,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/utils,@uppy/vue,@uppy/webcam,@uppy/xhr-upload,@uppy/zoom: add missing entries to changelog for individual packages (Antoine du Hamel / #4092) - -## 3.0.0 - -Released: 2022-08-22 -Included in: Uppy v3.0.0 - -- Switch to ESM - -## 2.1.1 - -Released: 2022-05-30 -Included in: Uppy v2.11.0 - -- @uppy/angular,@uppy/audio,@uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/box,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/form,@uppy/golden-retriever,@uppy/google-drive,@uppy/image-editor,@uppy/informer,@uppy/instagram,@uppy/onedrive,@uppy/progress-bar,@uppy/react,@uppy/redux-dev-tools,@uppy/robodog,@uppy/screen-capture,@uppy/status-bar,@uppy/store-default,@uppy/store-redux,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/tus,@uppy/unsplash,@uppy/url,@uppy/vue,@uppy/webcam,@uppy/xhr-upload,@uppy/zoom: doc: update bundler recommendation (Antoine du Hamel / #3763) - -## 2.1.0 - -Released: 2022-05-14 -Included in: Uppy v2.10.0 - -- @uppy/instagram: refactor to ESM (Antoine du Hamel / #3696) - -## 2.0.5 - -Released: 2021-12-07 -Included in: Uppy v2.3.0 - -- @uppy/aws-s3,@uppy/box,@uppy/core,@uppy/dashboard,@uppy/drag-drop,@uppy/dropbox,@uppy/facebook,@uppy/file-input,@uppy/google-drive,@uppy/image-editor,@uppy/instagram,@uppy/locales,@uppy/onedrive,@uppy/screen-capture,@uppy/status-bar,@uppy/thumbnail-generator,@uppy/transloadit,@uppy/url,@uppy/webcam,@uppy/xhr-upload,@uppy/zoom: Refactor locale scripts & generate types and docs (Merlijn Vos / #3276) diff --git a/packages/@uppy/instagram/LICENSE b/packages/@uppy/instagram/LICENSE deleted file mode 100644 index c23747330..000000000 --- a/packages/@uppy/instagram/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 Transloadit - -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/@uppy/instagram/README.md b/packages/@uppy/instagram/README.md deleted file mode 100644 index acb3c588b..000000000 --- a/packages/@uppy/instagram/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# @uppy/instagram - -Uppy logo: a smiling puppy above a pink upwards arrow - -[![npm version](https://img.shields.io/npm/v/@uppy/instagram.svg?style=flat-square)](https://www.npmjs.com/package/@uppy/instagram) -![CI status for Uppy tests](https://github.com/transloadit/uppy/workflows/CI/badge.svg) -![CI status for Companion tests](https://github.com/transloadit/uppy/workflows/Companion/badge.svg) -![CI status for browser tests](https://github.com/transloadit/uppy/workflows/End-to-end%20tests/badge.svg) - -The Instagram plugin lets users import photos from their Instagram account. - -A [Companion](https://uppy.io/docs/companion) instance is required for the -Instagram plugin to work. Companion handles authentication with Instagram, -downloads the pictures and videos, and uploads them to the destination. This -saves the user bandwidth, especially helpful if they are on a mobile connection. - -Uppy is being developed by the folks at [Transloadit](https://transloadit.com), -a versatile file encoding service. - -## Example - -```js -import Uppy from '@uppy/core' -import Instagram from '@uppy/instagram' - -const uppy = new Uppy() -uppy.use(Instagram, {}) -``` - -## Installation - -```bash -$ npm install @uppy/instagram -``` - -Alternatively, you can also use this plugin in a pre-built bundle from -Transloadit’s CDN: Smart CDN. In that case `Uppy` will attach itself to the -global `window.Uppy` object. See the -[main Uppy documentation](https://uppy.io/docs/#Installation) for instructions. - -## Documentation - -Documentation for this plugin can be found on the -[Uppy website](https://uppy.io/docs/instagram). - -## License - -[The MIT License](./LICENSE). diff --git a/packages/@uppy/instagram/package.json b/packages/@uppy/instagram/package.json deleted file mode 100644 index 2bf6927a0..000000000 --- a/packages/@uppy/instagram/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@uppy/instagram", - "description": "Import photos and videos from Instagram, into Uppy.", - "version": "5.1.0", - "license": "MIT", - "type": "module", - "sideEffects": false, - "scripts": { - "build": "tsc --build tsconfig.build.json", - "typecheck": "tsc --build" - }, - "keywords": [ - "file uploader", - "uppy", - "uppy-plugin", - "instagram", - "provider", - "photos", - "videos" - ], - "homepage": "https://uppy.io", - "bugs": { - "url": "https://github.com/transloadit/uppy/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/transloadit/uppy.git" - }, - "files": [ - "src", - "lib", - "dist", - "CHANGELOG.md" - ], - "exports": { - ".": "./lib/index.js", - "./package.json": "./package.json" - }, - "dependencies": { - "@uppy/companion-client": "workspace:^", - "@uppy/provider-views": "workspace:^", - "@uppy/utils": "workspace:^", - "preact": "^10.26.10" - }, - "peerDependencies": { - "@uppy/core": "workspace:^" - }, - "devDependencies": { - "@uppy/core": "workspace:^", - "typescript": "^5.8.3" - } -} diff --git a/packages/@uppy/instagram/src/Instagram.tsx b/packages/@uppy/instagram/src/Instagram.tsx deleted file mode 100644 index 9f56b0379..000000000 --- a/packages/@uppy/instagram/src/Instagram.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import { - type CompanionPluginOptions, - getAllowedHosts, - Provider, - tokenStorage, -} from '@uppy/companion-client' -import type { - AsyncStore, - Body, - Meta, - UnknownProviderPlugin, - UnknownProviderPluginState, - UppyFile, -} from '@uppy/core' -import { UIPlugin, type Uppy } from '@uppy/core' -import { ProviderViews } from '@uppy/provider-views' - -import type { LocaleStrings } from '@uppy/utils' -// biome-ignore lint/style/useImportType: h is not a type -import { type ComponentChild, h } from 'preact' -import packageJson from '../package.json' with { type: 'json' } -import locale from './locale.js' - -declare module '@uppy/core' { - export interface PluginTypeRegistry { - Instagram: Instagram - } -} - -export type InstagramOptions = CompanionPluginOptions & { - locale?: LocaleStrings -} - -export default class Instagram - extends UIPlugin - implements UnknownProviderPlugin -{ - static VERSION = packageJson.version - - icon: () => h.JSX.Element - - provider: Provider - - view!: ProviderViews - - storage: AsyncStore - - files: UppyFile[] - - rootFolderId: string | null = 'recent' - - constructor(uppy: Uppy, opts: InstagramOptions) { - super(uppy, opts) - this.type = 'acquirer' - this.files = [] - this.storage = this.opts.storage || tokenStorage - this.id = this.opts.id || 'Instagram' - this.icon = () => ( - - ) - - this.defaultLocale = locale - - this.i18nInit() - this.title = this.i18n('pluginNameInstagram') - - this.opts.companionAllowedHosts = getAllowedHosts( - this.opts.companionAllowedHosts, - this.opts.companionUrl, - ) - this.provider = new Provider(uppy, { - companionUrl: this.opts.companionUrl, - companionHeaders: this.opts.companionHeaders, - companionKeysParams: this.opts.companionKeysParams, - companionCookiesRule: this.opts.companionCookiesRule, - provider: 'instagram', - pluginId: this.id, - supportsRefreshToken: false, - }) - - this.render = this.render.bind(this) - } - - install(): void { - this.view = new ProviderViews(this, { - provider: this.provider, - viewType: 'grid', - showTitles: false, - showFilter: false, - showBreadcrumbs: false, - }) - - const { target } = this.opts - if (target) { - this.mount(target, this) - } - } - - uninstall(): void { - this.view.tearDown() - this.unmount() - } - - render(state: unknown): ComponentChild { - return this.view.render(state) - } -} diff --git a/packages/@uppy/instagram/src/index.ts b/packages/@uppy/instagram/src/index.ts deleted file mode 100644 index e5948eede..000000000 --- a/packages/@uppy/instagram/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { InstagramOptions } from './Instagram.js' -export { default } from './Instagram.js' diff --git a/packages/@uppy/instagram/src/locale.ts b/packages/@uppy/instagram/src/locale.ts deleted file mode 100644 index edb740b88..000000000 --- a/packages/@uppy/instagram/src/locale.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - strings: { - pluginNameInstagram: 'Instagram', - }, -} diff --git a/packages/@uppy/instagram/tsconfig.build.json b/packages/@uppy/instagram/tsconfig.build.json deleted file mode 100644 index afabb530f..000000000 --- a/packages/@uppy/instagram/tsconfig.build.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "../../../tsconfig.shared", - "compilerOptions": { - "outDir": "./lib", - "rootDir": "./src" - }, - "include": ["./src/**/*.*"], - "exclude": ["./src/**/*.test.ts"], - "references": [ - { - "path": "../companion-client/tsconfig.build.json" - }, - { - "path": "../provider-views/tsconfig.build.json" - }, - { - "path": "../utils/tsconfig.build.json" - }, - { - "path": "../core/tsconfig.build.json" - } - ] -} diff --git a/packages/@uppy/instagram/tsconfig.json b/packages/@uppy/instagram/tsconfig.json deleted file mode 100644 index 847db9a4f..000000000 --- a/packages/@uppy/instagram/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": "../../../tsconfig.shared", - "compilerOptions": { - "emitDeclarationOnly": false, - "noEmit": true - }, - "include": ["./package.json", "./src/**/*.*"], - "references": [ - { - "path": "../companion-client/tsconfig.build.json" - }, - { - "path": "../provider-views/tsconfig.build.json" - }, - { - "path": "../utils/tsconfig.build.json" - }, - { - "path": "../core/tsconfig.build.json" - } - ] -} diff --git a/packages/@uppy/instagram/turbo.json b/packages/@uppy/instagram/turbo.json deleted file mode 100644 index 83c0d57e1..000000000 --- a/packages/@uppy/instagram/turbo.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "dependsOn": ["^build", "@uppy/core#build"] - } - } -} diff --git a/packages/@uppy/locales/src/ca_ES.ts b/packages/@uppy/locales/src/ca_ES.ts index ed30f8517..f05b43102 100644 --- a/packages/@uppy/locales/src/ca_ES.ts +++ b/packages/@uppy/locales/src/ca_ES.ts @@ -134,7 +134,6 @@ ca_ES.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: 'Desenvolupat per %{uppy}', diff --git a/packages/@uppy/locales/src/de_DE.ts b/packages/@uppy/locales/src/de_DE.ts index 77df88e1d..b6bbb4cba 100644 --- a/packages/@uppy/locales/src/de_DE.ts +++ b/packages/@uppy/locales/src/de_DE.ts @@ -124,7 +124,6 @@ de_DE.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: 'Powered by %{uppy}', diff --git a/packages/@uppy/locales/src/en_US.ts b/packages/@uppy/locales/src/en_US.ts index a0634ef26..b8a925181 100644 --- a/packages/@uppy/locales/src/en_US.ts +++ b/packages/@uppy/locales/src/en_US.ts @@ -153,7 +153,6 @@ en_US.strings = { pluginNameGoogleDrive: 'Google Drive', pluginNameGoogleDrivePicker: 'Google Drive', pluginNameGooglePhotosPicker: 'Google Photos', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Screencast', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/es_ES.ts b/packages/@uppy/locales/src/es_ES.ts index 17d491928..7114a7cf2 100644 --- a/packages/@uppy/locales/src/es_ES.ts +++ b/packages/@uppy/locales/src/es_ES.ts @@ -137,7 +137,6 @@ es_ES.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: 'Desarrollado por %{uppy}', diff --git a/packages/@uppy/locales/src/fa_IR.ts b/packages/@uppy/locales/src/fa_IR.ts index 239018953..024e96e59 100644 --- a/packages/@uppy/locales/src/fa_IR.ts +++ b/packages/@uppy/locales/src/fa_IR.ts @@ -128,7 +128,6 @@ fa_IR.strings = { pluginNameDropbox: 'دراپ باکس', pluginNameFacebook: 'فیس بوک', pluginNameGoogleDrive: 'درایو گوگل', - pluginNameInstagram: 'اینستاگرام', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'بزرگ‌نمایی', poweredBy: 'قدرت گرفته از %{uppy}', diff --git a/packages/@uppy/locales/src/ms_MY.ts b/packages/@uppy/locales/src/ms_MY.ts index eec9dcc38..941c65fee 100644 --- a/packages/@uppy/locales/src/ms_MY.ts +++ b/packages/@uppy/locales/src/ms_MY.ts @@ -136,7 +136,6 @@ ms_MY.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Screencast', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/nl_NL.ts b/packages/@uppy/locales/src/nl_NL.ts index dd2632f69..28d2b604a 100644 --- a/packages/@uppy/locales/src/nl_NL.ts +++ b/packages/@uppy/locales/src/nl_NL.ts @@ -147,7 +147,6 @@ nl_NL.strings = { pluginNameGoogleDrive: 'Google Drive', pluginNameGoogleDrivePicker: 'Google Drive', pluginNameGooglePhotosPicker: 'Google Photos', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Screencast', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/pl_PL.ts b/packages/@uppy/locales/src/pl_PL.ts index e69e3a8c6..1ca1d2b15 100644 --- a/packages/@uppy/locales/src/pl_PL.ts +++ b/packages/@uppy/locales/src/pl_PL.ts @@ -144,7 +144,6 @@ pl_PL.strings = { pluginNameGoogleDrive: 'Google Drive', pluginNameGoogleDrivePicker: 'Google Drive', pluginNameGooglePhotosPicker: 'Google Photos', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Zrzut ekranu', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/pt_BR.ts b/packages/@uppy/locales/src/pt_BR.ts index 972673375..24a52c72a 100644 --- a/packages/@uppy/locales/src/pt_BR.ts +++ b/packages/@uppy/locales/src/pt_BR.ts @@ -148,7 +148,6 @@ pt_BR.strings = { pluginNameGoogleDrive: 'Google Drive', pluginNameGoogleDrivePicker: 'Google Drive', pluginNameGooglePhotosPicker: 'Google Photos', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Screencast', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/sv_SE.ts b/packages/@uppy/locales/src/sv_SE.ts index 588c22533..5f0a27b20 100644 --- a/packages/@uppy/locales/src/sv_SE.ts +++ b/packages/@uppy/locales/src/sv_SE.ts @@ -144,7 +144,6 @@ sv_SE.strings = { pluginNameGoogleDrive: 'Google Drive', pluginNameGoogleDrivePicker: 'Google Drive', pluginNameGooglePhotosPicker: 'Google Foton', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameScreenCapture: 'Skärminspelning', pluginNameUnsplash: 'Unsplash', diff --git a/packages/@uppy/locales/src/uk_UA.ts b/packages/@uppy/locales/src/uk_UA.ts index 113a40d76..765503d1c 100644 --- a/packages/@uppy/locales/src/uk_UA.ts +++ b/packages/@uppy/locales/src/uk_UA.ts @@ -138,7 +138,6 @@ uk_UA.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: 'Працює на %{uppy}', diff --git a/packages/@uppy/locales/src/uz_UZ.ts b/packages/@uppy/locales/src/uz_UZ.ts index c31c4d877..dec5b451f 100644 --- a/packages/@uppy/locales/src/uz_UZ.ts +++ b/packages/@uppy/locales/src/uz_UZ.ts @@ -131,7 +131,6 @@ uz_UZ.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: '%{uppy} tomonidan quvvatlanadi', diff --git a/packages/@uppy/locales/src/vi_VN.ts b/packages/@uppy/locales/src/vi_VN.ts index 25dc39a2c..a8f9a371d 100644 --- a/packages/@uppy/locales/src/vi_VN.ts +++ b/packages/@uppy/locales/src/vi_VN.ts @@ -131,7 +131,6 @@ vi_VN.strings = { pluginNameDropbox: 'Dropbox', pluginNameFacebook: 'Facebook', pluginNameGoogleDrive: 'Google Drive', - pluginNameInstagram: 'Instagram', pluginNameOneDrive: 'OneDrive', pluginNameZoom: 'Zoom', poweredBy: 'Được cung cấp bởi %{uppy}', diff --git a/packages/@uppy/locales/turbo.json b/packages/@uppy/locales/turbo.json index 7c1a5e518..cf8c2da6b 100644 --- a/packages/@uppy/locales/turbo.json +++ b/packages/@uppy/locales/turbo.json @@ -24,8 +24,7 @@ "@uppy/dropbox#build", "@uppy/webdav#build", "@uppy/unsplash#build", - "@uppy/webcam#build", - "@uppy/instagram#build" + "@uppy/webcam#build" ], "inputs": [ "script/**/*.{js,ts,jsx,tsx}", diff --git a/packages/@uppy/provider-views/src/SearchProviderView/SearchProviderView.tsx b/packages/@uppy/provider-views/src/SearchProviderView/SearchProviderView.tsx index 2de72ba92..61bfe827f 100644 --- a/packages/@uppy/provider-views/src/SearchProviderView/SearchProviderView.tsx +++ b/packages/@uppy/provider-views/src/SearchProviderView/SearchProviderView.tsx @@ -66,7 +66,7 @@ const defaultOptions = { /** * SearchProviderView, used for Unsplash and future image search providers. - * Extends generic View, shared with regular providers like Google Drive and Instagram. + * Extends generic View, shared with regular providers like Google Drive. */ export default class SearchProviderView { static VERSION = packageJson.version diff --git a/packages/@uppy/remote-sources/package.json b/packages/@uppy/remote-sources/package.json index 833bfb397..0648b4e77 100644 --- a/packages/@uppy/remote-sources/package.json +++ b/packages/@uppy/remote-sources/package.json @@ -1,6 +1,6 @@ { "name": "@uppy/remote-sources", - "description": "Uppy plugin that includes all remote sources that Uppy+Companion offer, like Instagram, Google Drive, Dropox, Box, Unsplash, Url etc", + "description": "Uppy plugin that includes all remote sources that Uppy+Companion offer, like Google Drive, Dropbox, Box, Unsplash, Url etc", "version": "3.1.0", "license": "MIT", "type": "module", @@ -12,7 +12,6 @@ }, "keywords": [ "file uploader", - "instagram", "google-drive", "facebook", "dropbox", @@ -46,7 +45,6 @@ "@uppy/dropbox": "workspace:^", "@uppy/facebook": "workspace:^", "@uppy/google-drive": "workspace:^", - "@uppy/instagram": "workspace:^", "@uppy/onedrive": "workspace:^", "@uppy/unsplash": "workspace:^", "@uppy/url": "workspace:^", diff --git a/packages/@uppy/remote-sources/src/index.test.ts b/packages/@uppy/remote-sources/src/index.test.ts index c7e31cbc6..c7eace47d 100644 --- a/packages/@uppy/remote-sources/src/index.test.ts +++ b/packages/@uppy/remote-sources/src/index.test.ts @@ -46,7 +46,7 @@ describe('RemoteSources', () => { sources: ['Webcam'], }) }).toThrow( - 'Invalid plugin: "Webcam" is not one of: Box, Dropbox, Facebook, GoogleDrive, Instagram, OneDrive, Unsplash, Url, or Zoom.', + 'Invalid plugin: "Webcam" is not one of: Box, Dropbox, Facebook, GoogleDrive, OneDrive, Unsplash, Url, or Zoom.', ) }) diff --git a/packages/@uppy/remote-sources/src/index.ts b/packages/@uppy/remote-sources/src/index.ts index 91d9fbefb..f9ec5f842 100644 --- a/packages/@uppy/remote-sources/src/index.ts +++ b/packages/@uppy/remote-sources/src/index.ts @@ -11,7 +11,6 @@ import { BasePlugin } from '@uppy/core' import Dropbox from '@uppy/dropbox' import Facebook from '@uppy/facebook' import GoogleDrive from '@uppy/google-drive' -import Instagram from '@uppy/instagram' import OneDrive from '@uppy/onedrive' import Unsplash from '@uppy/unsplash' import Url from '@uppy/url' @@ -25,7 +24,6 @@ export const availablePlugins = { Dropbox, Facebook, GoogleDrive, - Instagram, OneDrive, Unsplash, Url, @@ -37,7 +35,6 @@ export type AvailablePluginsKeys = | 'Dropbox' | 'Facebook' | 'GoogleDrive' - | 'Instagram' | 'OneDrive' | 'Unsplash' | 'Url' diff --git a/packages/@uppy/remote-sources/tsconfig.build.json b/packages/@uppy/remote-sources/tsconfig.build.json index 598b35505..49003415b 100644 --- a/packages/@uppy/remote-sources/tsconfig.build.json +++ b/packages/@uppy/remote-sources/tsconfig.build.json @@ -22,9 +22,6 @@ { "path": "../google-drive/tsconfig.build.json" }, - { - "path": "../instagram/tsconfig.build.json" - }, { "path": "../onedrive/tsconfig.build.json" }, diff --git a/packages/@uppy/remote-sources/tsconfig.json b/packages/@uppy/remote-sources/tsconfig.json index 12b17eb48..ed4d1624b 100644 --- a/packages/@uppy/remote-sources/tsconfig.json +++ b/packages/@uppy/remote-sources/tsconfig.json @@ -21,9 +21,6 @@ { "path": "../google-drive/tsconfig.build.json" }, - { - "path": "../instagram/tsconfig.build.json" - }, { "path": "../onedrive/tsconfig.build.json" }, diff --git a/packages/@uppy/transloadit/src/index.ts b/packages/@uppy/transloadit/src/index.ts index 5d226595f..c54150cdd 100644 --- a/packages/@uppy/transloadit/src/index.ts +++ b/packages/@uppy/transloadit/src/index.ts @@ -321,7 +321,6 @@ export default class Transloadit< addPluginVersion('GoogleDrive', 'uppy-google-drive') addPluginVersion('GoogleDrivePicker', 'uppy-google-drive-picker') addPluginVersion('GooglePhotosPicker', 'uppy-google-photos-picker') - addPluginVersion('Instagram', 'uppy-instagram') addPluginVersion('OneDrive', 'uppy-onedrive') addPluginVersion('Zoom', 'uppy-zoom') addPluginVersion('Url', 'uppy-url') diff --git a/packages/uppy/package.json b/packages/uppy/package.json index 88d580041..3f2154a52 100644 --- a/packages/uppy/package.json +++ b/packages/uppy/package.json @@ -1,6 +1,6 @@ { "name": "uppy", - "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:", + "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox, Google Drive, S3 and more :dog:", "version": "5.2.4", "license": "MIT", "main": "lib/index.js", @@ -55,7 +55,6 @@ "@uppy/google-photos-picker": "workspace:*", "@uppy/image-editor": "workspace:*", "@uppy/image-generator": "workspace:*", - "@uppy/instagram": "workspace:*", "@uppy/locales": "workspace:*", "@uppy/onedrive": "workspace:*", "@uppy/provider-views": "workspace:*", diff --git a/packages/uppy/src/bundle.ts b/packages/uppy/src/bundle.ts index 84433c38e..860c41d21 100644 --- a/packages/uppy/src/bundle.ts +++ b/packages/uppy/src/bundle.ts @@ -35,7 +35,6 @@ export { default as GoogleDrive } from '@uppy/google-drive' export { default as GoogleDrivePicker } from '@uppy/google-drive-picker' export { default as GooglePhotosPicker } from '@uppy/google-photos-picker' export { default as ImageEditor } from '@uppy/image-editor' -export { default as Instagram } from '@uppy/instagram' export { default as OneDrive } from '@uppy/onedrive' export { default as RemoteSources } from '@uppy/remote-sources' export { default as ScreenCapture } from '@uppy/screen-capture' diff --git a/packages/uppy/src/index.ts b/packages/uppy/src/index.ts index de33c8399..cf85901dc 100644 --- a/packages/uppy/src/index.ts +++ b/packages/uppy/src/index.ts @@ -17,7 +17,6 @@ export type { FormOptions } from '@uppy/form' export type { GoldenRetrieverOptions } from '@uppy/golden-retriever' export type { GoogleDriveOptions } from '@uppy/google-drive' export type { ImageEditorOptions } from '@uppy/image-editor' -export type { InstagramOptions } from '@uppy/instagram' export type { OneDriveOptions } from '@uppy/onedrive' export type { RemoteSourcesOptions } from '@uppy/remote-sources' export type { ScreenCaptureOptions } from '@uppy/screen-capture' diff --git a/packages/uppy/tsconfig.build.json b/packages/uppy/tsconfig.build.json index ab68b4479..f782a97d5 100644 --- a/packages/uppy/tsconfig.build.json +++ b/packages/uppy/tsconfig.build.json @@ -55,9 +55,6 @@ { "path": "../@uppy/image-editor/tsconfig.build.json" }, - { - "path": "../@uppy/instagram/tsconfig.build.json" - }, { "path": "../@uppy/onedrive/tsconfig.build.json" }, diff --git a/packages/uppy/tsconfig.json b/packages/uppy/tsconfig.json index d748cb51d..1c9df8e7c 100644 --- a/packages/uppy/tsconfig.json +++ b/packages/uppy/tsconfig.json @@ -54,9 +54,6 @@ { "path": "../@uppy/image-editor/tsconfig.build.json" }, - { - "path": "../@uppy/instagram/tsconfig.build.json" - }, { "path": "../@uppy/onedrive/tsconfig.build.json" }, diff --git a/private/dev/Dashboard.js b/private/dev/Dashboard.js index f3b7ffdd5..1a3c2fed2 100644 --- a/private/dev/Dashboard.js +++ b/private/dev/Dashboard.js @@ -122,7 +122,6 @@ export default () => { companionAllowedHosts, ...getCompanionKeysParams('GOOGLE_DRIVE'), }) - // .use(Instagram, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts }) // .use(Dropbox, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts }) // .use(Box, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts }) // .use(Facebook, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts }) @@ -150,7 +149,6 @@ export default () => { 'Box', 'Dropbox', 'Facebook', - 'Instagram', 'OneDrive', 'Unsplash', 'Zoom', diff --git a/yarn.lock b/yarn.lock index 9efee9162..dcf06642e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10373,21 +10373,6 @@ __metadata: languageName: unknown linkType: soft -"@uppy/instagram@workspace:*, @uppy/instagram@workspace:^, @uppy/instagram@workspace:packages/@uppy/instagram": - version: 0.0.0-use.local - resolution: "@uppy/instagram@workspace:packages/@uppy/instagram" - dependencies: - "@uppy/companion-client": "workspace:^" - "@uppy/core": "workspace:^" - "@uppy/provider-views": "workspace:^" - "@uppy/utils": "workspace:^" - preact: "npm:^10.26.10" - typescript: "npm:^5.8.3" - peerDependencies: - "@uppy/core": "workspace:^" - languageName: unknown - linkType: soft - "@uppy/locales@workspace:*, @uppy/locales@workspace:packages/@uppy/locales": version: 0.0.0-use.local resolution: "@uppy/locales@workspace:packages/@uppy/locales" @@ -10488,7 +10473,6 @@ __metadata: "@uppy/dropbox": "workspace:^" "@uppy/facebook": "workspace:^" "@uppy/google-drive": "workspace:^" - "@uppy/instagram": "workspace:^" "@uppy/onedrive": "workspace:^" "@uppy/unsplash": "workspace:^" "@uppy/url": "workspace:^" @@ -23862,7 +23846,6 @@ __metadata: "@uppy/google-photos-picker": "workspace:*" "@uppy/image-editor": "workspace:*" "@uppy/image-generator": "workspace:*" - "@uppy/instagram": "workspace:*" "@uppy/locales": "workspace:*" "@uppy/onedrive": "workspace:*" "@uppy/provider-views": "workspace:*" From 5efc32a2e7bf63651ffdc7d3bc0802ec42374f58 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Mon, 18 May 2026 20:35:10 +0800 Subject: [PATCH 16/33] remove angular eslint (#6164) closes #6161 --------- Co-authored-by: Prakash --- packages/@uppy/angular/.eslintrc.json | 45 -- packages/@uppy/angular/package.json | 7 - .../projects/uppy/angular/.eslintrc.json | 46 -- yarn.lock | 678 +----------------- 4 files changed, 19 insertions(+), 757 deletions(-) delete mode 100644 packages/@uppy/angular/.eslintrc.json delete mode 100644 packages/@uppy/angular/projects/uppy/angular/.eslintrc.json diff --git a/packages/@uppy/angular/.eslintrc.json b/packages/@uppy/angular/.eslintrc.json deleted file mode 100644 index 54e1cd9a1..000000000 --- a/packages/@uppy/angular/.eslintrc.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "ignorePatterns": ["projects/**/*"], - "overrides": [ - { - "files": ["*.ts"], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" - ], - "rules": { - // eslint-disable-line import/newline-after-import - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@typescript-eslint/semi": ["error", "never"], - "import/no-unresolved": "off", - "import/prefer-default-export": "off", - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ], - "semi": ["error", "never"] - } - }, - { - "files": ["*.html"], - "extends": [ - "plugin:@angular-eslint/template/recommended", - "plugin:@angular-eslint/template/accessibility" - ], - "rules": {} - } - ] -} diff --git a/packages/@uppy/angular/package.json b/packages/@uppy/angular/package.json index b6f4ab792..07eb3668e 100644 --- a/packages/@uppy/angular/package.json +++ b/packages/@uppy/angular/package.json @@ -23,16 +23,9 @@ }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", - "@angular-eslint/eslint-plugin": "^18.0.1", - "@angular-eslint/eslint-plugin-template": "^18.0.1", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.2.17", "@types/jasmine": "~5.1.0", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", - "@typescript-eslint/types": "^7.2.0", - "@typescript-eslint/utils": "^7.2.0", - "eslint": "^8.57.0", "jasmine-core": "~5.1.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", diff --git a/packages/@uppy/angular/projects/uppy/angular/.eslintrc.json b/packages/@uppy/angular/projects/uppy/angular/.eslintrc.json deleted file mode 100644 index 67ef3094e..000000000 --- a/packages/@uppy/angular/projects/uppy/angular/.eslintrc.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "extends": "../../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": [ - "packages/@uppy/angular/projects/angular/tsconfig.lib.json", - "packages/@uppy/angular/projects/angular/tsconfig.spec.json" - ], - "createDefaultProgram": true - }, - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "uppy", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "uppy", - "style": "camelCase" - } - ], - "dot-notation": "error", - "indent": "error", - "no-empty-function": "off", - "no-shadow": "error", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "quotes": "error", - "semi": "error" - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/yarn.lock b/yarn.lock index dcf06642e..3f12ff7b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -191,57 +191,6 @@ __metadata: languageName: node linkType: hard -"@angular-eslint/bundled-angular-compiler@npm:18.4.3": - version: 18.4.3 - resolution: "@angular-eslint/bundled-angular-compiler@npm:18.4.3" - checksum: 10/4edd79d9c529154ac0c4406c7868767eb2f8d8d6895b82d6c3abc9c6fcd31e1cf3eee59997e0d502c37156406b382b6045c2ab951dfa5ddbeaf7659c8e3d1425 - languageName: node - linkType: hard - -"@angular-eslint/eslint-plugin-template@npm:^18.0.1": - version: 18.4.3 - resolution: "@angular-eslint/eslint-plugin-template@npm:18.4.3" - dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" - "@angular-eslint/utils": "npm:18.4.3" - aria-query: "npm:5.3.2" - axobject-query: "npm:4.1.0" - peerDependencies: - "@typescript-eslint/types": ^7.11.0 || ^8.0.0 - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: "*" - checksum: 10/5383ac6cd600c8cb97a539a02224a3d5b1783ce76b263c6802ec3137cf20d4fddef1280216953c94a05cfc1b6d4961b2c3458d8fa6fd369a88fd463cd4051366 - languageName: node - linkType: hard - -"@angular-eslint/eslint-plugin@npm:^18.0.1": - version: 18.4.3 - resolution: "@angular-eslint/eslint-plugin@npm:18.4.3" - dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" - "@angular-eslint/utils": "npm:18.4.3" - peerDependencies: - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: "*" - checksum: 10/4047c84caa0a900b3882f98253567cb544bd1391243d8e1cb3014d50de8c76cdac2a3f2289626dbfcaf29e06ab883cf29e5f91e8dda26bdfae8b402c2f218da3 - languageName: node - linkType: hard - -"@angular-eslint/utils@npm:18.4.3": - version: 18.4.3 - resolution: "@angular-eslint/utils@npm:18.4.3" - dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" - peerDependencies: - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: "*" - checksum: 10/588cddc66a211757b0a3995a8c1c5b48c7ac4b3db0bee3a93b3d6c3cd0491443c170c1fa138b21c7697c8038cc42112965cea6b292cbe666a1fa00683c57b419 - languageName: node - linkType: hard - "@angular/animations@npm:^19.2.17": version: 19.2.17 resolution: "@angular/animations@npm:19.2.17" @@ -4589,48 +4538,6 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.7.0 - resolution: "@eslint-community/eslint-utils@npm:4.7.0" - dependencies: - eslint-visitor-keys: "npm:^3.4.3" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10/43ed5d391526d9f5bbe452aef336389a473026fca92057cf97c576db11401ce9bcf8ef0bf72625bbaf6207ed8ba6bf0dcf4d7e809c24f08faa68a28533c491a7 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 10/c08f1dd7dd18fbb60bdd0d85820656d1374dd898af9be7f82cb00451313402a22d5e30569c150315b4385907cdbca78c22389b2a72ab78883b3173be317620cc - languageName: node - linkType: hard - -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 - languageName: node - linkType: hard - -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 10/7562b21be10c2adbfa4aa5bb2eccec2cb9ac649a3569560742202c8d1cb6c931ce634937a2f0f551e078403a1c1285d6c2c0aa345dafc986149665cd69fe8b59 - languageName: node - linkType: hard - "@gar/promisify@npm:^1.1.3": version: 1.1.3 resolution: "@gar/promisify@npm:1.1.3" @@ -4638,31 +4545,6 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" - dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.3" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10/524df31e61a85392a2433bf5d03164e03da26c03d009f27852e7dcfdafbc4a23f17f021dacf88e0a7a9fe04ca032017945d19b57a16e2676d9114c22a53a9d11 - languageName: node - linkType: hard - -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10/e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 - languageName: node - linkType: hard - -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 - languageName: node - linkType: hard - "@img/colour@npm:^1.0.0": version: 1.0.0 resolution: "@img/colour@npm:1.0.0" @@ -5725,7 +5607,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -9728,191 +9610,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.2.0": - version: 7.13.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.13.1" - dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/type-utils": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" - natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^1.3.0" - peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/37fff8c302f93f5f88fc8d6e6c9151a7d1873a3c8af6e15547d737bdc066a6b8887fa54bcd8eb4e4ca6a11494051801c8e957eea8d8b4d4b078a477df6f10692 - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:^7.2.0": - version: 7.13.1 - resolution: "@typescript-eslint/parser@npm:7.13.1" - dependencies: - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/a76cfcf97c289110403b50a377e925f29cda74340de0526f68b0c34199ce643d9c31803e492217e0f3df28361d3019ced4806f974ea70529c559b26b70cec7ef - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/scope-manager@npm:7.13.1" - dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - checksum: 10/fea9ab8f72ace1dd55d835037efe038c70021275581855820cdb7fc4b01e8afb51723856537adff1fdb0ea3899c1f8b593fd75c34b5087ca2ef2f7c72e610050 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/scope-manager@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - checksum: 10/9eb2ae5d69d9f723e706c16b2b97744fc016996a5473bed596035ac4d12429b3d24e7340a8235d704efa57f8f52e1b3b37925ff7c2e3384859d28b23a99b8bcc - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/type-utils@npm:7.13.1" - dependencies: - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.3.0" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/cc03cd44e125933511ea657e386c5cf427eb6a386fdb110cba0858598195fb4f8c71173b00b187f388a6713e16b919a2037a86e0be10f4c40c18bcbdbe06d5de - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/types@npm:7.13.1" - checksum: 10/006a5518608184c1d017b27fb4f66ce28bc75f89e2380ac42969ebdf0dc726af1cfcdf4ba36ce2858e9f6907d6f4295d3453859d7e9a35bc7855d4ebc900955d - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:7.18.0, @typescript-eslint/types@npm:^7.2.0": - version: 7.18.0 - resolution: "@typescript-eslint/types@npm:7.18.0" - checksum: 10/0e30c73a3cc3c67dd06360a5a12fd12cee831e4092750eec3d6c031bdc4feafcb0ab1d882910a73e66b451a4f6e1dd015e9e2c4d45bf6bf716a474e5d123ddf0 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.13.1" - dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/5c68b5faa962e5f984067aa91770486af817858d2fa35b54a44fa4d5c0c612ba23b52b191d8051d9e4439e5425251e32861c81239e9400a29de057f8360537fb - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/b01e66235a91aa4439d02081d4a5f8b4a7cf9cb24f26b334812f657e3c603493e5f41e5c1e89cf4efae7d64509fa1f73affc16afc5e15cb7f83f724577c82036 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/utils@npm:7.13.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" - peerDependencies: - eslint: ^8.56.0 - checksum: 10/e1bc916dcb567c6b35819f635a84561e015f40b28d650b987f74c79b013ec43fb4f5b61199d4039fcdf9480281f945f622650cba2e68739600822da05808a706 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:^7.2.0": - version: 7.18.0 - resolution: "@typescript-eslint/utils@npm:7.18.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - peerDependencies: - eslint: ^8.56.0 - checksum: 10/f43fedb4f4d2e3836bdf137889449063a55c0ece74fdb283929cd376197b992313be8ef4df920c1c801b5c3076b92964c84c6c3b9b749d263b648d0011f5926e - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.13.1" - dependencies: - "@typescript-eslint/types": "npm:7.13.1" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/811e9642851359b5197d45a9878143c4c608aaef887a20c26f57f8b012ce9e316d232b82a311bdd52a2af0c8b8da5d4bd9401ce565fc7bdb43cd44556e76d225 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/b7cfe6fdeae86c507357ac6b2357813c64fb2fbf1aaf844393ba82f73a16e2599b41981b34200d9fc7765d70bc3a8181d76b503051e53f04bcb7c9afef637eab - languageName: node - linkType: hard - -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 - languageName: node - linkType: hard - "@uppy-dev/build@workspace:.": version: 0.0.0-use.local resolution: "@uppy-dev/build@workspace:." @@ -11223,16 +10920,7 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.3.2": - version: 5.3.2 - resolution: "acorn-jsx@npm:5.3.2" - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10/d4371eaef7995530b5b5ca4183ff6f062ca17901a6d3f673c9ac011b01ede37e7a1f7f61f8f5cfe709e88054757bb8f3277dc4061087cdf4f2a1f90ccbcdb977 - languageName: node - linkType: hard - -"acorn@npm:^8.12.1, acorn@npm:^8.14.0, acorn@npm:^8.14.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.12.1, acorn@npm:^8.14.0, acorn@npm:^8.14.1, acorn@npm:^8.8.2": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -11344,25 +11032,11 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" - dependencies: - fast-deep-equal: "npm:^3.1.1" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.4.1" - uri-js: "npm:^4.2.2" - checksum: 10/48d6ad21138d12eb4d16d878d630079a2bda25a04e745c07846a4ad768319533031e28872a9b3c5790fa1ec41aabdf2abed30a56e5a03ebc2cf92184b8ee306c - languageName: node - linkType: hard - "angular@workspace:packages/@uppy/angular": version: 0.0.0-use.local resolution: "angular@workspace:packages/@uppy/angular" dependencies: "@angular-devkit/build-angular": "npm:^19.0.0" - "@angular-eslint/eslint-plugin": "npm:^18.0.1" - "@angular-eslint/eslint-plugin-template": "npm:^18.0.1" "@angular/animations": "npm:^19.2.17" "@angular/cli": "npm:^19.0.0" "@angular/common": "npm:^19.2.17" @@ -11374,11 +11048,6 @@ __metadata: "@angular/platform-browser-dynamic": "npm:^19.2.17" "@angular/router": "npm:^19.2.17" "@types/jasmine": "npm:~5.1.0" - "@typescript-eslint/eslint-plugin": "npm:^7.2.0" - "@typescript-eslint/parser": "npm:^7.2.0" - "@typescript-eslint/types": "npm:^7.2.0" - "@typescript-eslint/utils": "npm:^7.2.0" - eslint: "npm:^8.57.0" jasmine-core: "npm:~5.1.0" karma: "npm:~6.4.0" karma-chrome-launcher: "npm:~3.2.0" @@ -11539,7 +11208,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.3.2, aria-query@npm:^5.0.0, aria-query@npm:^5.3.1": +"aria-query@npm:^5.0.0, aria-query@npm:^5.3.1": version: 5.3.2 resolution: "aria-query@npm:5.3.2" checksum: 10/b2fe9bc98bd401bc322ccb99717c1ae2aaf53ea0d468d6e7aebdc02fac736e4a99b46971ee05b783b08ade23c675b2d8b60e4a1222a95f6e27bc4d2a0bfdcc03 @@ -11646,7 +11315,7 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:4.1.0, axobject-query@npm:^4.1.0": +"axobject-query@npm:^4.1.0": version: 4.1.0 resolution: "axobject-query@npm:4.1.0" checksum: 10/e275dea9b673f71170d914f2d2a18be5d57d8d29717b629e7fedd907dcc2ebdc7a37803ff975874810bd423f222f299c020d28fde40a146f537448bf6bfecb6e @@ -12221,7 +11890,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": +"chalk@npm:^4.1.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -12907,7 +12576,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.5, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.5, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -13188,7 +12857,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -13261,13 +12930,6 @@ __metadata: languageName: node linkType: hard -"deep-is@npm:^0.1.3": - version: 0.1.4 - resolution: "deep-is@npm:0.1.4" - checksum: 10/ec12d074aef5ae5e81fa470b9317c313142c9e8e2afe3f8efa124db309720db96d1d222b82b84c834e5f87e7a614b44a4684b6683583118b87c833b3be40d4d8 - languageName: node - linkType: hard - "deepmerge@npm:^4.3.1": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" @@ -13479,15 +13141,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 - languageName: node - linkType: hard - "dom-accessibility-api@npm:^0.5.9": version: 0.5.16 resolution: "dom-accessibility-api@npm:0.5.16" @@ -14197,7 +13850,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:4.0.0, escape-string-regexp@npm:^4.0.0": +"escape-string-regexp@npm:4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 @@ -14221,71 +13874,6 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b - languageName: node - linkType: hard - -"eslint@npm:^8.57.0": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.1" - "@humanwhocodes/config-array": "npm:^0.13.0" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" - debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" - bin: - eslint: bin/eslint.js - checksum: 10/5504fa24879afdd9f9929b2fbfc2ee9b9441a3d464efd9790fbda5f05738858530182029f13323add68d19fec749d3ab4a70320ded091ca4432b1e9cc4ed104c - languageName: node - linkType: hard - "esm-env@npm:^1.2.1, esm-env@npm:^1.2.2": version: 1.2.2 resolution: "esm-env@npm:1.2.2" @@ -14293,17 +13881,6 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" - dependencies: - acorn: "npm:^8.9.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 - languageName: node - linkType: hard - "esprima@npm:^4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -14314,15 +13891,6 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": - version: 1.6.0 - resolution: "esquery@npm:1.6.0" - dependencies: - estraverse: "npm:^5.1.0" - checksum: 10/c587fb8ec9ed83f2b1bc97cf2f6854cc30bf784a79d62ba08c6e358bf22280d69aee12827521cf38e69ae9761d23fb7fde593ce315610f85655c139d99b05e5a - languageName: node - linkType: hard - "esrap@npm:^1.4.6": version: 1.4.6 resolution: "esrap@npm:1.4.6" @@ -14348,7 +13916,7 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": +"estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e @@ -14935,7 +14503,7 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": +"fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" checksum: 10/e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d @@ -14955,20 +14523,6 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0": - version: 2.1.0 - resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e - languageName: node - linkType: hard - -"fast-levenshtein@npm:^2.0.6": - version: 2.0.6 - resolution: "fast-levenshtein@npm:2.0.6" - checksum: 10/eb7e220ecf2bab5159d157350b81d01f75726a4382f5a9266f42b9150c4523b9795f7f5d9fbbbeaeac09a441b2369f05ee02db48ea938584205530fe5693cfe1 - languageName: node - linkType: hard - "fast-safe-stringify@npm:^2.1.1": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" @@ -15076,15 +14630,6 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" - dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b - languageName: node - linkType: hard - "fill-range@npm:^7.1.1": version: 7.1.1 resolution: "fill-range@npm:7.1.1" @@ -15170,16 +14715,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" - dependencies: - locate-path: "npm:^6.0.0" - path-exists: "npm:^4.0.0" - checksum: 10/07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 - languageName: node - linkType: hard - "find-up@npm:^6.3.0": version: 6.3.0 resolution: "find-up@npm:6.3.0" @@ -15190,17 +14725,6 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" - dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 - languageName: node - linkType: hard - "flat@npm:^5.0.2": version: 5.0.2 resolution: "flat@npm:5.0.2" @@ -15210,7 +14734,7 @@ __metadata: languageName: node linkType: hard -"flatted@npm:^3.2.7, flatted@npm:^3.2.9": +"flatted@npm:^3.2.7": version: 3.3.3 resolution: "flatted@npm:3.3.3" checksum: 10/8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe @@ -15596,7 +15120,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.1, glob-parent@npm:^6.0.2": +"glob-parent@npm:^6.0.1": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" dependencies: @@ -15676,15 +15200,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e - languageName: node - linkType: hard - "globalthis@npm:^1.0.3": version: 1.0.4 resolution: "globalthis@npm:1.0.4" @@ -15695,7 +15210,7 @@ __metadata: languageName: node linkType: hard -"globby@npm:^11.0.0, globby@npm:^11.1.0": +"globby@npm:^11.0.0": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: @@ -15791,13 +15306,6 @@ __metadata: languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10/6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 - languageName: node - linkType: hard - "graphql@npm:^16.8.1": version: 16.11.0 resolution: "graphql@npm:16.11.0" @@ -16254,7 +15762,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"ignore@npm:^5.2.0": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 10/0a884c2fbc8c316f0b9f92beaf84464253b73230a4d4d286697be45fca081199191ca33e1c2e82d9e5f851f5e9a48a78e25a35c951e7eb41e59f150db3530065 @@ -16284,7 +15792,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": +"import-fresh@npm:^3.3.0": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" dependencies: @@ -16553,7 +16061,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": +"is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -16631,13 +16139,6 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.3": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: 10/abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 - languageName: node - linkType: hard - "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -17114,13 +16615,6 @@ __metadata: languageName: node linkType: hard -"json-schema-traverse@npm:^0.4.1": - version: 0.4.1 - resolution: "json-schema-traverse@npm:0.4.1" - checksum: 10/7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b - languageName: node - linkType: hard - "json-schema-traverse@npm:^1.0.0": version: 1.0.0 resolution: "json-schema-traverse@npm:1.0.0" @@ -17128,13 +16622,6 @@ __metadata: languageName: node linkType: hard -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10/12786c2e2f22c27439e6db0532ba321f1d0617c27ad8cb1c352a0e9249a50182fd1ba8b52a18899291604b0c32eafa8afd09e51203f19109a0537f68db2b652d - languageName: node - linkType: hard - "json-stringify-safe@npm:^5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" @@ -17440,16 +16927,6 @@ __metadata: languageName: node linkType: hard -"levn@npm:^0.4.1": - version: 0.4.1 - resolution: "levn@npm:0.4.1" - dependencies: - prelude-ls: "npm:^1.2.1" - type-check: "npm:~0.4.0" - checksum: 10/2e4720ff79f21ae08d42374b0a5c2f664c5be8b6c8f565bb4e1315c96ed3a8acaa9de788ffed82d7f2378cf36958573de07ef92336cb5255ed74d08b8318c9ee - languageName: node - linkType: hard - "license-webpack-plugin@npm:4.0.2": version: 4.0.2 resolution: "license-webpack-plugin@npm:4.0.2" @@ -17824,15 +17301,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^6.0.0": - version: 6.0.0 - resolution: "locate-path@npm:6.0.0" - dependencies: - p-locate: "npm:^5.0.0" - checksum: 10/72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a - languageName: node - linkType: hard - "locate-path@npm:^7.1.0": version: 7.2.0 resolution: "locate-path@npm:7.2.0" @@ -17961,13 +17429,6 @@ __metadata: languageName: node linkType: hard -"lodash.merge@npm:^4.6.2": - version: 4.6.2 - resolution: "lodash.merge@npm:4.6.2" - checksum: 10/d0ea2dd0097e6201be083865d50c3fb54fbfbdb247d9cc5950e086c991f448b7ab0cdab0d57eacccb43473d3f2acd21e134db39f22dac2d6c9ba6bf26978e3d6 - languageName: node - linkType: hard - "lodash.once@npm:^4.0.0": version: 4.1.1 resolution: "lodash.once@npm:4.1.1" @@ -18445,7 +17906,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -18874,13 +18335,6 @@ __metadata: languageName: node linkType: hard -"natural-compare@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare@npm:1.4.0" - checksum: 10/23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d - languageName: node - linkType: hard - "needle@npm:^3.1.0": version: 3.3.1 resolution: "needle@npm:3.3.1" @@ -19625,20 +19079,6 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.3": - version: 0.9.4 - resolution: "optionator@npm:0.9.4" - dependencies: - deep-is: "npm:^0.1.3" - fast-levenshtein: "npm:^2.0.6" - levn: "npm:^0.4.1" - prelude-ls: "npm:^1.2.1" - type-check: "npm:^0.4.0" - word-wrap: "npm:^1.2.5" - checksum: 10/a8398559c60aef88d7f353a4f98dcdff6090a4e70f874c827302bf1213d9106a1c4d5fcb68dacb1feb3c30a04c4102f41047aa55d4c576b863d6fc876e001af6 - languageName: node - linkType: hard - "ora@npm:5.4.1, ora@npm:^5.1.0": version: 5.4.1 resolution: "ora@npm:5.4.1" @@ -19709,15 +19149,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2": - version: 3.1.0 - resolution: "p-limit@npm:3.1.0" - dependencies: - yocto-queue: "npm:^0.1.0" - checksum: 10/7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 - languageName: node - linkType: hard - "p-limit@npm:^4.0.0": version: 4.0.0 resolution: "p-limit@npm:4.0.0" @@ -19736,15 +19167,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^5.0.0": - version: 5.0.0 - resolution: "p-locate@npm:5.0.0" - dependencies: - p-limit: "npm:^3.0.2" - checksum: 10/1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 - languageName: node - linkType: hard - "p-locate@npm:^6.0.0": version: 6.0.0 resolution: "p-locate@npm:6.0.0" @@ -20744,13 +20166,6 @@ __metadata: languageName: node linkType: hard -"prelude-ls@npm:^1.2.1": - version: 1.2.1 - resolution: "prelude-ls@npm:1.2.1" - checksum: 10/0b9d2c76801ca652a7f64892dd37b7e3fab149a37d2424920099bf894acccc62abb4424af2155ab36dea8744843060a2d8ddc983518d0b1e22265a22324b72ed - languageName: node - linkType: hard - "prettier@npm:^2.7.1": version: 2.8.8 resolution: "prettier@npm:2.8.8" @@ -20928,7 +20343,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.1": +"punycode@npm:^2.1.1, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 @@ -21894,7 +21309,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: @@ -23158,13 +22573,6 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: 10/4383b5baaeffa9bb4cda2ac33a4aa2e6d1f8aaf811848bf73513a9b88fd76372dc461f6fd6d2e9cb5100f48b473be32c6f95bd983509b7d92bb4d92c10747452 - languageName: node - linkType: hard - "thenby@npm:^1.3.4": version: 1.3.4 resolution: "thenby@npm:1.3.4" @@ -23345,15 +22753,6 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" - peerDependencies: - typescript: ">=4.2.0" - checksum: 10/3ee44faa24410cd649b5c864e068d438aa437ef64e9e4a66a41646a6d3024d3097a695eeb3fb26ee364705d3cb9653a65756d009e6a53badb6066a5f447bf7ed - languageName: node - linkType: hard - "tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -23474,22 +22873,6 @@ __metadata: languageName: node linkType: hard -"type-check@npm:^0.4.0, type-check@npm:~0.4.0": - version: 0.4.0 - resolution: "type-check@npm:0.4.0" - dependencies: - prelude-ls: "npm:^1.2.1" - checksum: 10/14687776479d048e3c1dbfe58a2409e00367810d6960c0f619b33793271ff2a27f81b52461f14a162f1f89a9b1d8da1b237fc7c99b0e1fdcec28ec63a86b1fec - languageName: node - linkType: hard - -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 - languageName: node - linkType: hard - "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" @@ -23878,15 +23261,6 @@ __metadata: languageName: unknown linkType: soft -"uri-js@npm:^4.2.2": - version: 4.4.1 - resolution: "uri-js@npm:4.4.1" - dependencies: - punycode: "npm:^2.1.0" - checksum: 10/b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb - languageName: node - linkType: hard - "url-join@npm:^5.0.0": version: 5.0.0 resolution: "url-join@npm:5.0.0" @@ -24717,13 +24091,6 @@ __metadata: languageName: node linkType: hard -"word-wrap@npm:^1.2.5": - version: 1.2.5 - resolution: "word-wrap@npm:1.2.5" - checksum: 10/1ec6f6089f205f83037be10d0c4b34c9183b0b63fca0834a5b3cee55dd321429d73d40bb44c8fc8471b5203d6e8f8275717f49a8ff4b2b0ab41d7e1b563e0854 - languageName: node - linkType: hard - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -24922,13 +24289,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^0.1.0": - version: 0.1.0 - resolution: "yocto-queue@npm:0.1.0" - checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 - languageName: node - linkType: hard - "yocto-queue@npm:^1.0.0": version: 1.0.0 resolution: "yocto-queue@npm:1.0.0" From 622daa498c8646ccad5d1e90be1c2ec30d3df278 Mon Sep 17 00:00:00 2001 From: Prakash Date: Mon, 18 May 2026 21:03:42 +0530 Subject: [PATCH 17/33] @uppy/examples: update examples after recent breaking changes (#6299) --- examples/aws-companion/server.cjs | 2 +- examples/companion/server/index.js | 2 +- packages/@uppy/companion/README.md | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/aws-companion/server.cjs b/examples/aws-companion/server.cjs index a0edb6b16..bcbc1e025 100644 --- a/examples/aws-companion/server.cjs +++ b/examples/aws-companion/server.cjs @@ -66,4 +66,4 @@ const server = app.listen(3020, () => { console.log('listening on port 3020') }) -companion.socket(server) +companion.socket(server, options) diff --git a/examples/companion/server/index.js b/examples/companion/server/index.js index ab7c5f6ee..351737c7d 100644 --- a/examples/companion/server/index.js +++ b/examples/companion/server/index.js @@ -71,7 +71,7 @@ app.use((err, req, res) => { res.status(500).json({ message: err.message, error: err }) }) -companion.socket(app.listen(3020)) +companion.socket(app.listen(3020), companionOptions) console.log('Welcome to Companion!') console.log(`Listening on http://0.0.0.0:${3020}`) diff --git a/packages/@uppy/companion/README.md b/packages/@uppy/companion/README.md index 30e37e963..eebdb77f9 100644 --- a/packages/@uppy/companion/README.md +++ b/packages/@uppy/companion/README.md @@ -68,7 +68,10 @@ on, you call the `socket` method like so. // ... const server = app.listen(PORT) -companion.socket(server) +// Pass the same `options` object you passed to `companion.app(options)` — +// `companion.socket` needs `options.server` to compute the external base path +// for incoming WS URLs (important behind reverse proxies). +companion.socket(server, options) ``` ### Run as standalone server From ca916f6580bbcf672f1249fe05d5a5047bee3451 Mon Sep 17 00:00:00 2001 From: Prakash Date: Wed, 20 May 2026 10:33:47 +0530 Subject: [PATCH 18/33] @uppy/transloadit: fix stale assemblyStatus in 'transloadit:assembly-cancelled' event (#6294) @mifi this is small change which we missed , based on our discussion in uppy call. --------- Co-authored-by: Mikael Finstad --- .changeset/proud-spies-train.md | 5 +++++ packages/@uppy/transloadit/src/index.ts | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/proud-spies-train.md diff --git a/.changeset/proud-spies-train.md b/.changeset/proud-spies-train.md new file mode 100644 index 000000000..10d332013 --- /dev/null +++ b/.changeset/proud-spies-train.md @@ -0,0 +1,5 @@ +--- +"@uppy/transloadit": patch +--- + +emit updated AssemblyState in 'transloadit:assembly-cancelled' event diff --git a/packages/@uppy/transloadit/src/index.ts b/packages/@uppy/transloadit/src/index.ts index c54150cdd..326981b6c 100644 --- a/packages/@uppy/transloadit/src/index.ts +++ b/packages/@uppy/transloadit/src/index.ts @@ -658,7 +658,10 @@ export default class Transloadit< async #cancelAssembly(assembly: AssemblyResponse) { await this.client.cancelAssembly(assembly) // TODO bubble this through AssemblyWatcher so its event handlers can clean up correctly - this.uppy.emit('transloadit:assembly-cancelled', assembly) + + // if assemblyStatus has been updated after the cancellation was triggered, emit the updated assemblyStatus - fallback to the method argument + const updatedAssemblyStatus = this.assembly?.status ?? assembly + this.uppy.emit('transloadit:assembly-cancelled', updatedAssemblyStatus) this.assembly = undefined } From 489d76717cd41b49dfe6db0696c69c2c69c7b9e7 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Wed, 20 May 2026 23:36:46 +0800 Subject: [PATCH 19/33] Upgrade to express 5 (#6175) closes #6157 https://expressjs.com/en/guide/migrating-5.html --------- Co-authored-by: Prakash --- .changeset/happy-timers-kick.md | 5 + .changeset/smooth-chefs-occur.md | 5 + examples/aws-companion/package.json | 2 +- examples/aws-nodejs/package.json | 2 +- .../companion-custom-provider/package.json | 2 +- .../package.json | 2 +- examples/companion/package.json | 2 +- examples/reactrouter/package.json | 4 +- examples/reactrouter/server.ts | 6 +- examples/transloadit/package.json | 2 +- examples/xhr-bundle/package.json | 2 +- packages/@uppy/aws-s3/src/index.ts | 9 +- packages/@uppy/companion/package.json | 4 +- packages/@uppy/companion/src/companion.ts | 11 +- .../src/server/controllers/callback.ts | 2 +- .../companion/src/server/controllers/list.ts | 5 +- .../src/server/controllers/preauth.ts | 2 +- .../src/server/controllers/refresh-token.ts | 2 +- .../companion/src/server/controllers/s3.ts | 24 +- .../src/server/controllers/simple-auth.ts | 2 +- .../src/server/controllers/thumbnail.ts | 2 +- .../@uppy/companion/src/server/middlewares.ts | 8 +- .../companion/src/standalone/start-server.ts | 8 +- .../@uppy/companion/test/companion.test.ts | 22 + packages/@uppy/companion/test/cors.test.ts | 2 +- packages/@uppy/companion/test/mockserver.ts | 23 +- yarn.lock | 2611 +++-------------- 27 files changed, 439 insertions(+), 2332 deletions(-) create mode 100644 .changeset/happy-timers-kick.md create mode 100644 .changeset/smooth-chefs-occur.md diff --git a/.changeset/happy-timers-kick.md b/.changeset/happy-timers-kick.md new file mode 100644 index 000000000..d06fc6eb1 --- /dev/null +++ b/.changeset/happy-timers-kick.md @@ -0,0 +1,5 @@ +--- +"@uppy/aws-s3": patch +--- + +Improve type diff --git a/.changeset/smooth-chefs-occur.md b/.changeset/smooth-chefs-occur.md new file mode 100644 index 000000000..66a598445 --- /dev/null +++ b/.changeset/smooth-chefs-occur.md @@ -0,0 +1,5 @@ +--- +"@uppy/companion": major +--- + +Upgrade to express 5 - Companion no longer works when used as a middleware with Express 4. diff --git a/examples/aws-companion/package.json b/examples/aws-companion/package.json index f061bbcdb..0fe81edb2 100644 --- a/examples/aws-companion/package.json +++ b/examples/aws-companion/package.json @@ -15,7 +15,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.17.3", "npm-run-all": "^4.1.5", "vite": "^7.1.11" diff --git a/examples/aws-nodejs/package.json b/examples/aws-nodejs/package.json index cfcbde2a1..bdc013ed0 100644 --- a/examples/aws-nodejs/package.json +++ b/examples/aws-nodejs/package.json @@ -15,6 +15,6 @@ "@aws-sdk/s3-request-presigner": "^3.338.0", "body-parser": "^1.20.4", "dotenv": "^16.0.0", - "express": "^4.22.0" + "express": "^5.2.1" } } diff --git a/examples/companion-custom-provider/package.json b/examples/companion-custom-provider/package.json index 6d6c08c18..fdf0e4205 100644 --- a/examples/companion-custom-provider/package.json +++ b/examples/companion-custom-provider/package.json @@ -19,7 +19,7 @@ "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.15.6", "npm-run-all": "^4.1.2", "vite": "^7.1.11" diff --git a/examples/companion-digitalocean-spaces/package.json b/examples/companion-digitalocean-spaces/package.json index b308f3455..4a99539a7 100644 --- a/examples/companion-digitalocean-spaces/package.json +++ b/examples/companion-digitalocean-spaces/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "vite": "^7.1.11" }, "private": true, diff --git a/examples/companion/package.json b/examples/companion/package.json index f517ffb97..a85a0b826 100644 --- a/examples/companion/package.json +++ b/examples/companion/package.json @@ -4,7 +4,7 @@ "dependencies": { "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.15.6", "light-server": "^2.4.0" }, diff --git a/examples/reactrouter/package.json b/examples/reactrouter/package.json index c6849a34e..4420f7540 100644 --- a/examples/reactrouter/package.json +++ b/examples/reactrouter/package.json @@ -20,14 +20,14 @@ "@uppy/transloadit": "workspace:*", "@uppy/tus": "workspace:*", "@uppy/xhr-upload": "workspace:*", - "express": "^4.22.0", + "express": "^5.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router": "^7.12.0" }, "devDependencies": { "@react-router/dev": "^7.12.0", - "@types/express": "^4.17.20", + "@types/express": "^5.0.6", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "tsx": "^4.0.0", diff --git a/examples/reactrouter/server.ts b/examples/reactrouter/server.ts index 80ee0542c..8e9c30392 100644 --- a/examples/reactrouter/server.ts +++ b/examples/reactrouter/server.ts @@ -41,7 +41,9 @@ async function startServer() { // TUS upload endpoints (before React Router) app.all('/api/upload/tus', (req, res) => tusServer.handle(req, res)) - app.all('/api/upload/tus/*', (req, res) => tusServer.handle(req, res)) + app.all('/api/upload/tus/{*splat}', (req, res) => + tusServer.handle(req, res), + ) // Handle Chrome DevTools requests silently app.get('/.well-known/appspecific/com.chrome.devtools.json', (req, res) => { @@ -49,7 +51,7 @@ async function startServer() { }) // React Router handles all other routes - app.all('*', reactRouterHandler) + app.all('/{*splat}', reactRouterHandler) const port = process.env.PORT || 3000 const server = app.listen(port, () => { diff --git a/examples/transloadit/package.json b/examples/transloadit/package.json index 6072b43ab..bb08b521e 100644 --- a/examples/transloadit/package.json +++ b/examples/transloadit/package.json @@ -15,7 +15,7 @@ "@uppy/remote-sources": "workspace:*", "@uppy/transloadit": "workspace:*", "@uppy/webcam": "workspace:*", - "express": "^4.22.0", + "express": "^5.2.1", "he": "^1.2.0" }, "private": true, diff --git a/examples/xhr-bundle/package.json b/examples/xhr-bundle/package.json index 249ae1a63..cd36e6bbb 100644 --- a/examples/xhr-bundle/package.json +++ b/examples/xhr-bundle/package.json @@ -6,7 +6,7 @@ "@uppy/dashboard": "workspace:*", "@uppy/xhr-upload": "workspace:*", "cors": "^2.8.5", - "express": "^4.22.0", + "express": "^5.2.1", "multer": "^2.0.2" }, "devDependencies": { diff --git a/packages/@uppy/aws-s3/src/index.ts b/packages/@uppy/aws-s3/src/index.ts index d248f4c5b..e1afe29c1 100644 --- a/packages/@uppy/aws-s3/src/index.ts +++ b/packages/@uppy/aws-s3/src/index.ts @@ -662,10 +662,11 @@ export default class AwsS3Multipart< querify: true, }) - const query = new URLSearchParams({ filename, type, ...metadata } as Record< - string, - string - >) + const query = new URLSearchParams({ + filename, + ...(type != null && { type }), + ...metadata, + }) return this.#client.get(`s3/params?${query}`, options) } diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 42ed317f6..02e389eec 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -47,9 +47,9 @@ "cors": "^2.8.5", "escape-goat": "3.0.0", "escape-string-regexp": "4.0.0", - "express": "4.21.2", + "express": "^5.2.1", "express-interceptor": "1.2.0", - "express-prom-bundle": "7", + "express-prom-bundle": "^8.0.0", "express-session": "1.18.1", "fast-safe-stringify": "^2.1.1", "formdata-node": "^6.0.3", diff --git a/packages/@uppy/companion/src/companion.ts b/packages/@uppy/companion/src/companion.ts index ab32d7d64..290b66561 100644 --- a/packages/@uppy/companion/src/companion.ts +++ b/packages/@uppy/companion/src/companion.ts @@ -125,6 +125,9 @@ export function app(optionsArg: CompanionInitOptions) { const app = express() + // Needed for e.g. s3 `/params` endpoint metadata, like `metadata[key]=value` to be parsed into a metadata object + app.set('query parser', 'extended') + if (options.metrics) { app.use(middlewares.metrics({ path: options.server.path })) } @@ -136,10 +139,10 @@ export function app(optionsArg: CompanionInitOptions) { app.use(interceptGrantErrorResponse) // override provider credentials at request time - // Making `POST` request to the `/connect/:provider/:override?` route requires a form body parser middleware: + // Making `POST` request to the `/connect/:provider{/:override}` route requires a form body parser middleware: // See https://github.com/simov/grant#dynamic-http app.use( - '/connect/:oauthProvider/:override?', + '/connect/:oauthProvider{/:override}', express.urlencoded({ extended: false }), getCredentialsOverrideMiddleware( providers as Record, @@ -159,7 +162,7 @@ export function app(optionsArg: CompanionInitOptions) { app.use(middlewares.cors(options)) // add uppy options to the request object so it can be accessed by subsequent handlers. - app.use('*', middlewares.getCompanionMiddleware(options)) + app.use(middlewares.getCompanionMiddleware(options)) app.use('/s3', s3(options.s3)) if (options.enableUrlEndpoint) app.use('/url', url()) if (options.enableGooglePickerEndpoint) @@ -232,7 +235,7 @@ export function app(optionsArg: CompanionInitOptions) { ) app.get( - '/:providerName/list/:id?', + '/:providerName/list{/:id}', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.list, diff --git a/packages/@uppy/companion/src/server/controllers/callback.ts b/packages/@uppy/companion/src/server/controllers/callback.ts index 7e1ab3a69..83a2b96e6 100644 --- a/packages/@uppy/companion/src/server/controllers/callback.ts +++ b/packages/@uppy/companion/src/server/controllers/callback.ts @@ -20,7 +20,7 @@ export default function callback( const providerName = req.params['providerName'] const { companion } = req - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/list.ts b/packages/@uppy/companion/src/server/controllers/list.ts index f6acfa4d3..8c7f7e244 100644 --- a/packages/@uppy/companion/src/server/controllers/list.ts +++ b/packages/@uppy/companion/src/server/controllers/list.ts @@ -7,8 +7,9 @@ export default async function list( next: NextFunction, ): Promise { const { query, params, companion } = req + const id = params['id'] const { providerUserSession, provider } = companion - if (!provider) { + if (!provider || (typeof id !== 'string' && id != null)) { res.sendStatus(400) return } @@ -17,7 +18,7 @@ export default async function list( const data = await provider.list({ companion, providerUserSession, - directory: params['id'], + directory: id, query, }) res.json(data) diff --git a/packages/@uppy/companion/src/server/controllers/preauth.ts b/packages/@uppy/companion/src/server/controllers/preauth.ts index e3b30a226..210058e2b 100644 --- a/packages/@uppy/companion/src/server/controllers/preauth.ts +++ b/packages/@uppy/companion/src/server/controllers/preauth.ts @@ -14,7 +14,7 @@ export default function preauth(req: Request, res: Response): void { } const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/refresh-token.ts b/packages/@uppy/companion/src/server/controllers/refresh-token.ts index c6d5ab5ac..e8e513dcb 100644 --- a/packages/@uppy/companion/src/server/controllers/refresh-token.ts +++ b/packages/@uppy/companion/src/server/controllers/refresh-token.ts @@ -12,7 +12,7 @@ export default async function refreshToken( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (providerName == null) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/s3.ts b/packages/@uppy/companion/src/server/controllers/s3.ts index dcfd4c4a1..e9bf0e9fc 100644 --- a/packages/@uppy/companion/src/server/controllers/s3.ts +++ b/packages/@uppy/companion/src/server/controllers/s3.ts @@ -1,3 +1,4 @@ +import assert from 'node:assert' import type { Part, S3Client } from '@aws-sdk/client-s3' import { AbortMultipartUploadCommand, @@ -247,6 +248,11 @@ export default function s3( const { uploadId } = req.params const { key } = req.query + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: @@ -260,7 +266,7 @@ export default function s3( const parts: Part[] = [] - function listPartsPage(startAt?: string) { + const listPartsPage = (startAt?: string) => { s3Client .send( new ListPartsCommand({ @@ -303,7 +309,7 @@ export default function s3( const partNumber = req.params['partNumber'] const key = req.query['key'] - if (uploadId == null || uploadId.length === 0) { + if (typeof uploadId !== 'string' || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -314,7 +320,7 @@ export default function s3( }) return } - if (partNumber == null || !parseInt(partNumber, 10)) { + if (typeof partNumber !== 'string' || !parseInt(partNumber, 10)) { res.status(400).json({ error: 's3: the part number must be a number between 1 and 10000.', }) @@ -363,7 +369,7 @@ export default function s3( const key = req.query['key'] const partNumbers = req.query['partNumbers'] - if (uploadId == null || uploadId.length === 0) { + if (typeof uploadId !== 'string' || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -443,6 +449,11 @@ export default function s3( const { uploadId } = req.params const { key } = req.query + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: @@ -488,6 +499,11 @@ export default function s3( const { key } = req.query const { parts }: { parts: unknown } = req.body + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: diff --git a/packages/@uppy/companion/src/server/controllers/simple-auth.ts b/packages/@uppy/companion/src/server/controllers/simple-auth.ts index c1171356c..6ddef8af2 100644 --- a/packages/@uppy/companion/src/server/controllers/simple-auth.ts +++ b/packages/@uppy/companion/src/server/controllers/simple-auth.ts @@ -9,7 +9,7 @@ export default async function simpleAuth( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/thumbnail.ts b/packages/@uppy/companion/src/server/controllers/thumbnail.ts index bae18cafd..03abf9dea 100644 --- a/packages/@uppy/companion/src/server/controllers/thumbnail.ts +++ b/packages/@uppy/companion/src/server/controllers/thumbnail.ts @@ -7,7 +7,7 @@ async function thumbnail( next: NextFunction, ): Promise { const id = req.params['id'] - if (id == null) { + if (typeof id !== 'string' || id.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/middlewares.ts b/packages/@uppy/companion/src/server/middlewares.ts index 4dd3103b6..92def8aee 100644 --- a/packages/@uppy/companion/src/server/middlewares.ts +++ b/packages/@uppy/companion/src/server/middlewares.ts @@ -97,7 +97,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { } const { secret } = req.companion.options const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } @@ -124,7 +124,9 @@ export const verifyToken: RequestHandler = (req, res, next) => { const { providerOptions } = req.companion.options const providerName = req.params['providerName'] const providerOption = - providerName != null ? providerOptions?.[providerName] : undefined + typeof providerName === 'string' + ? providerOptions?.[providerName] + : undefined const key = providerOption?.key if (!key) { logger.info( @@ -146,7 +148,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { // does not fail if token is invalid export const gentleVerifyToken: RequestHandler = (req, res, next) => { const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { next() return } diff --git a/packages/@uppy/companion/src/standalone/start-server.ts b/packages/@uppy/companion/src/standalone/start-server.ts index ec4dc713b..fcc54347a 100644 --- a/packages/@uppy/companion/src/standalone/start-server.ts +++ b/packages/@uppy/companion/src/standalone/start-server.ts @@ -9,7 +9,9 @@ const port: string | number = const { app, companionOptions } = standalone() -companion.socket(app.listen(port), companionOptions) +const server = app.listen(port, () => { + logger.info(`Welcome to Companion! v${packageJson.version}`) + logger.info(`Listening on http://localhost:${port}`) -logger.info(`Welcome to Companion! v${packageJson.version}`) -logger.info(`Listening on http://localhost:${port}`) + companion.socket(server, companionOptions) +}) diff --git a/packages/@uppy/companion/test/companion.test.ts b/packages/@uppy/companion/test/companion.test.ts index be3f458a6..4eef1110b 100644 --- a/packages/@uppy/companion/test/companion.test.ts +++ b/packages/@uppy/companion/test/companion.test.ts @@ -426,4 +426,26 @@ describe('S3 controller', () => { ), ) }) + + test('getUploadParameters supports bracket metadata query format', async () => { + const server = await getServer({ + COMPANION_AWS_KEY: 'test_key', + COMPANION_AWS_SECRET: 'test_secret', + COMPANION_AWS_BUCKET: 'test-bucket', + COMPANION_AWS_REGION: 'us-east-1', + }) + + return request(server) + .get('/s3/params') + .query({ + filename: 'test.txt', + type: 'text/plain', + 'metadata[name]': 'demo-file', + }) + .expect(200) + .then((res) => { + const fields = res.body.fields as Record + expect(fields['x-amz-meta-name']).toBe('demo-file') + }) + }) }) diff --git a/packages/@uppy/companion/test/cors.test.ts b/packages/@uppy/companion/test/cors.test.ts index 6e3bc58f6..3abb2cff9 100644 --- a/packages/@uppy/companion/test/cors.test.ts +++ b/packages/@uppy/companion/test/cors.test.ts @@ -19,7 +19,7 @@ async function run({ next() }) app.use(cors(corsOptions)) - app.options('*', (_req, res) => { + app.options('/{*splat}', (_req, res) => { res.status(204).end() }) diff --git a/packages/@uppy/companion/test/mockserver.ts b/packages/@uppy/companion/test/mockserver.ts index 1a66514ca..4effa2983 100644 --- a/packages/@uppy/companion/test/mockserver.ts +++ b/packages/@uppy/companion/test/mockserver.ts @@ -101,7 +101,7 @@ export const getServerWithEmitter = async ( authServer.use( session({ secret: 'grant', resave: true, saveUninitialized: true }), ) - authServer.all('*/callback', (req, res, next) => { + authServer.all('{*splat}/callback', (req, res, next) => { if (req.session) { req.session['grant'] = { response: { access_token: grantToken }, @@ -109,16 +109,19 @@ export const getServerWithEmitter = async ( } next() }) - authServer.all(['*/send-token', '*/redirect'], (req, res, next) => { - const state = - typeof req.query['state'] === 'string' ? req.query['state'] : null - if (req.session) { - req.session['grant'] = { - dynamic: { state: state ?? 'non-empty-value' }, + authServer.all( + ['{*splat}/send-token', '{*splat}/redirect'], + (req, res, next) => { + const state = + typeof req.query['state'] === 'string' ? req.query['state'] : null + if (req.session) { + req.session['grant'] = { + dynamic: { state: state ?? 'non-empty-value' }, + } } - } - next() - }) + next() + }, + ) const { app, emitter } = standalone() authServer.use(app) diff --git a/yarn.lock b/yarn.lock index 3f12ff7b1..049829d74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -509,7 +509,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:3.986.0": +"@aws-sdk/client-s3@npm:3.986.0, @aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/client-s3@npm:3.986.0" dependencies: @@ -572,211 +572,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": - version: 3.896.0 - resolution: "@aws-sdk/client-s3@npm:3.896.0" - dependencies: - "@aws-crypto/sha1-browser": "npm:5.2.0" - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/credential-provider-node": "npm:3.896.0" - "@aws-sdk/middleware-bucket-endpoint": "npm:3.893.0" - "@aws-sdk/middleware-expect-continue": "npm:3.893.0" - "@aws-sdk/middleware-flexible-checksums": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-location-constraint": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" - "@aws-sdk/middleware-ssec": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@aws-sdk/xml-builder": "npm:3.894.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/eventstream-serde-browser": "npm:^4.1.1" - "@smithy/eventstream-serde-config-resolver": "npm:^4.2.1" - "@smithy/eventstream-serde-node": "npm:^4.1.1" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-blob-browser": "npm:^4.1.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/hash-stream-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/md5-js": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - "@smithy/util-waiter": "npm:^4.1.1" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/4a65786cd019e0fee172f7da37aab882e39669052e239a284bd1409877c394949779ba909ed5596caa4e12586b9d466099a8d596f8a5019f7eb4bc2dfcf89ba8 - languageName: node - linkType: hard - -"@aws-sdk/client-sso-oidc@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.600.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/client-sts": "npm:3.600.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/credential-provider-node": "npm:3.600.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/66343fc13ffd5d412ca2232a91dce14ee287ed611fb27cd1fe887bb36bf380d585c74473251bd9d688fab51b4f9bd4375bf7d8583effb3d07c6ac5f7cb85c597 - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/client-sso@npm:3.598.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/6571a678ae4e0c42c245a2e7b969d5d2e4713dc5fe7604e5edc883a6f729362d1256f1c144094f8146e0fd85da675533c0e460c5217b1d17aecb2042201e169e - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/client-sso@npm:3.896.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/0358688ecd1ac7ce0d451af66ce9c72ca9f7e750f029f5be4450946b8a07d6f52458262e60fdd6c4817ee94e9337a7235ec9bbe58085c6bfef24ed1641772c81 - languageName: node - linkType: hard - "@aws-sdk/client-sso@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/client-sso@npm:3.985.0" @@ -823,55 +618,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.338.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sts@npm:3.600.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/client-sso-oidc": "npm:3.600.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/credential-provider-node": "npm:3.600.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/1b955f0ceacdb7e0a0a15ce588aa7b0a796eae8591c195a9a1db601d6efeec504d7ad07189c4baedba0e8e888e4cbab770d6d9e54de9d07d166247f6f0df7c9a - languageName: node - linkType: hard - -"@aws-sdk/client-sts@npm:3.986.0": +"@aws-sdk/client-sts@npm:3.986.0, @aws-sdk/client-sts@npm:^3.338.0": version: 3.986.0 resolution: "@aws-sdk/client-sts@npm:3.986.0" dependencies: @@ -918,42 +665,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/core@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/core@npm:3.598.0" - dependencies: - "@smithy/core": "npm:^2.2.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/signature-v4": "npm:^3.1.0" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - fast-xml-parser: "npm:4.2.5" - tslib: "npm:^2.6.2" - checksum: 10/6c27302636d6e4c9382590be9d39e1ff2023c92a7aaa78117428d8af9be614ded56c7db2e9a016452144f4f6d81e6b09c81e29ad53df5fa9d506aa0548211f7c - languageName: node - linkType: hard - -"@aws-sdk/core@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/core@npm:3.896.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/xml-builder": "npm:3.894.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/48576dfb4060e802faec525b8553cbaeed5aa735ac3bdc292e14fae92261978b4f022197863e284c3cb49f86e638b967e0b76f346adc04b56a5d3aa7d5d1f370 - languageName: node - linkType: hard - "@aws-sdk/core@npm:^3.973.7": version: 3.973.7 resolution: "@aws-sdk/core@npm:3.973.7" @@ -985,31 +696,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/79c6391aad109d9749b60516dcc425e923a730bf6239d5b41192612fc2658d6fdbcd48b48277076ca7c6db61103164fe305fdc4271994713128d4ec27d32236a - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/82a771fd5b81f67f56816313ae598496676fad60d147c9adebf7557a0e808129c155f3bf6349a10362a16293ea5290d8c96160ba7fe0598c80756b65e2810278 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-env@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-env@npm:3.972.5" @@ -1023,41 +709,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-stream": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/e8411e33faec1798a2e50166cd1777b4becd2ff07ec97d044424faf1db3a2e97d8b4ee8c43d0b4e763d94dfb8971f0542b160e69a94ca38b175c8227e4f71904 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-stream": "npm:^4.3.2" - tslib: "npm:^2.6.2" - checksum: 10/c2dfd4ff720d8b6dd1e3f05899c73056a0babe8f7d4b6c45aa6a6bf1afe19d1609db0bfa1e47266e69024f46941b0f35175c76bd3bdbbbd1b3723039a96e20d5 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-http@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/credential-provider-http@npm:3.972.7" @@ -1076,48 +727,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.598.0" - "@aws-sdk/credential-provider-http": "npm:3.598.0" - "@aws-sdk/credential-provider-process": "npm:3.598.0" - "@aws-sdk/credential-provider-sso": "npm:3.598.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/credential-provider-imds": "npm:^3.1.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: 10/2f3aa54850dc1da4732d1dbc5a8e6ec095107ff08c46af4bffec41e1535a9c9a320586386f67358dd0acec83069dbb2b420bbd09412aa56993d088eb08ffef2b - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/credential-provider-env": "npm:3.896.0" - "@aws-sdk/credential-provider-http": "npm:3.896.0" - "@aws-sdk/credential-provider-process": "npm:3.896.0" - "@aws-sdk/credential-provider-sso": "npm:3.896.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b727580a5ad0d8062ad6d374983d49999d68ef19bcd4cb28df66bfb8dba101e4be94f9c7c9f73fabe79519e0d09b4352a19530a9c29165e8357301296f6c435d - languageName: node - linkType: hard - "@aws-sdk/credential-provider-ini@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-ini@npm:3.972.5" @@ -1156,46 +765,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.598.0" - "@aws-sdk/credential-provider-http": "npm:3.598.0" - "@aws-sdk/credential-provider-ini": "npm:3.598.0" - "@aws-sdk/credential-provider-process": "npm:3.598.0" - "@aws-sdk/credential-provider-sso": "npm:3.598.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/credential-provider-imds": "npm:^3.1.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/b5ab56a5c8acd566f41ba834214718a0ab8825090fe71b0ecc4ebec5e76de3afa47387ab99d061f3ac6ecd5ead9af621d7311ffa0a6b16df312f3c9de311747d - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.896.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.896.0" - "@aws-sdk/credential-provider-http": "npm:3.896.0" - "@aws-sdk/credential-provider-ini": "npm:3.896.0" - "@aws-sdk/credential-provider-process": "npm:3.896.0" - "@aws-sdk/credential-provider-sso": "npm:3.896.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/161f6bab93a3980deed49e328bdfd9a98ef0c998f0258caa4b3bfd26c436d9d4db56d9b6ef9bf7aa6012e4f8b1891d7cf5a3c0df8c5ca90d1eddb95fae28697f - languageName: node - linkType: hard - "@aws-sdk/credential-provider-node@npm:^3.972.6": version: 3.972.6 resolution: "@aws-sdk/credential-provider-node@npm:3.972.6" @@ -1216,33 +785,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/c0f9aa2304e273460b93efa7a09664d69e3dcdf6983d789a83bbc77a7975dddc7db915caaccf922f459eaad7b0ed546d1d79bcf0354898bca7c141fc49f5809b - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/1ea8e99cf5fc37c5c11330bf6e1cbb2a879ff61a335bdc6bf0d4dbeb64366e7232b6dd6f4dfe88718790ab07ecb0bb0814c67f59ed4d0a489b7074833e1defa5 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-process@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-process@npm:3.972.5" @@ -1257,37 +799,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" - dependencies: - "@aws-sdk/client-sso": "npm:3.598.0" - "@aws-sdk/token-providers": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/19e6d8390a7824f921ee63105563857171404a09b7e7df1e9ad99a2ef334cc05cd1ae6d95f5a975fb328f5b53713cb1cb228d92b4966a7a8e9afc15637de66de - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.896.0" - dependencies: - "@aws-sdk/client-sso": "npm:3.896.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/token-providers": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f4c0dcc6efa354d3f151bdb73f6b5f6a68a45e90290621b9b70dd9a7d0e59e911b685cad597d6da2ed170d399ec7d469afc7a70f0d00c5ae409153231aee3c60 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-sso@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.5" @@ -1304,35 +815,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: 10/76cf4e389dc565402f1ba0b9c65983590e98435a17ed291d6b15412dac27aea7e35f23036675f76f2a267f8375de616550be759136bf2ff7d63211a22535bbf2 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/460c098de6f26a86b394a4241abf9f93a61d40ac5898f667716c0a3dbb1d6214ba42f3fdefc6a5e40a4d730eb1b0c6ff51d2b3fd10099670734e44bc133d20d6 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-web-identity@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.5" @@ -1365,21 +847,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-arn-parser": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/214fa89d2ed8b699c18d967cc158a77ec24f14b7d70fac80bdaa32940d8d737398a633787fee8efd7456a821f7f3c17f25a4d5db93f274ed071a428c04ad76e9 - languageName: node - linkType: hard - "@aws-sdk/middleware-bucket-endpoint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.3" @@ -1395,18 +862,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/722f38a646b302ae238d254c8a55a5d6fb124ad8b30f29d226c06761cfbc050c798595891c16a2fd78d4ec5e7a0431eef9c8a20c28c73fcb118db66afa9c3491 - languageName: node - linkType: hard - "@aws-sdk/middleware-expect-continue@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.3" @@ -1419,27 +874,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.896.0" - dependencies: - "@aws-crypto/crc32": "npm:5.2.0" - "@aws-crypto/crc32c": "npm:5.2.0" - "@aws-crypto/util": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/is-array-buffer": "npm:^4.1.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/16918d316a8cac38742889065c254c6f5ec33da6dbba6667409ee5fd84b3aeb90161405b4098ec98a9f60f769944e3394eae3bce01e7de51797940b12449889d - languageName: node - linkType: hard - "@aws-sdk/middleware-flexible-checksums@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.972.5" @@ -1462,30 +896,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/53498c94fd769dbee727ba4148d67578d2073fd83217695106e9dd3b572e56aa0362c329da4c13e39a0aaef45597cc7988b8951f2df4d28dc7c29461fa3791cc - languageName: node - linkType: hard - -"@aws-sdk/middleware-host-header@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/600afe3361abab4e6448a6c61ad94623be0c52169cc7e972d7dc8c7c0c6dc68a2f39b41ffafa5dc6b7f847277d4871517cfadbef185c75b63084c6d44b0ab0e2 - languageName: node - linkType: hard - "@aws-sdk/middleware-host-header@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-host-header@npm:3.972.3" @@ -1498,17 +908,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/e97592e4f08c8abdfb63a359a8c89eaffc128e221ed27db309840ecf9b4c1cbe757c394f218db99d200fc0afbc2c215fed47d428735d707144f19ab90476ee4e - languageName: node - linkType: hard - "@aws-sdk/middleware-location-constraint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.3" @@ -1520,28 +919,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-logger@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/e6db8b4e861cc8cc85f4e1b83fd73dc902beece1210fcfa6f2ebd7e78f9ee88f9a1584cdb584358b81c22c5c23b5b3bc58a6a57de2bfc33fb07684d9b9f8dad5 - languageName: node - linkType: hard - -"@aws-sdk/middleware-logger@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-logger@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7deb41cefde575dbc4f0a845fa535b88e52bacde2778b0f4545c3044bf87d70e0981c9dc3e65f5385d1b3d9de1afc06aae763295d2a3b33da02477c527e8bd64 - languageName: node - linkType: hard - "@aws-sdk/middleware-logger@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-logger@npm:3.972.3" @@ -1553,31 +930,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/2bc64666c08ee7f46a2918ac70773d7244f5c7866d0e3521c8734286c0b1bd5e4e64ea2bb4ec656e683dfecb7d44d43cd15283c4ec4cfe16b7aa7f4e19a586b8 - languageName: node - linkType: hard - -"@aws-sdk/middleware-recursion-detection@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws/lambda-invoke-store": "npm:^0.0.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/1d599f38cb269a9a27c2a63c8c6ec0790b38946a27fb06d003aa9b7247466151dab178bb35569740bd6725e25c9d5c733ee272d0de8bd382b1c3f7919bdb4978 - languageName: node - linkType: hard - "@aws-sdk/middleware-recursion-detection@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.3" @@ -1591,28 +943,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-arn-parser": "npm:3.893.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/591d2853276a911acc850742ec60f4d178565067bd3a87525cdb0c6c44487cd0f25ffec2f5afb4e273ab0b7b33bedeaa9f617d483967383f74dac4740807b1d1 - languageName: node - linkType: hard - "@aws-sdk/middleware-sdk-s3@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.7" @@ -1635,17 +965,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f5fe75e0facfbcabbfea296dacc8add47368707e9fa53181f7693f70a8735a22a2926c1c9785c99291ce3e44e173184a977940e7cd8e5e1cea25f16e3e8d17c4 - languageName: node - linkType: hard - "@aws-sdk/middleware-ssec@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-ssec@npm:3.972.3" @@ -1657,34 +976,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/3ed35495781284c3969374c2a53f02863cc433a8d139d5e85d7e1181c138c2ec743ee77a82efe780a0902a24ce524fc8946429939ed1368fec9f4635afb3d7f4 - languageName: node - linkType: hard - -"@aws-sdk/middleware-user-agent@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/9d781950484f900998f9c842ddbeb6820b808470fc01c0b0a3c30083758cc82fe28aa8f844843b9de52f789ba17f109ec8af64c1c499088cfa57566308bbd76e - languageName: node - linkType: hard - "@aws-sdk/middleware-user-agent@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-user-agent@npm:3.972.7" @@ -1700,52 +991,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/nested-clients@npm:3.896.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/7abe22d7ea6878197f9ec90e56778a6871e5b452ac53dc821c4c346a3c970ba183445bd02603352d7cf04eaba713be7d6c6852d4f3b00c5ef41810a7b1cf8a99 - languageName: node - linkType: hard - "@aws-sdk/nested-clients@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/nested-clients@npm:3.985.0" @@ -1792,34 +1037,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-config-provider": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.1" - tslib: "npm:^2.6.2" - checksum: 10/26f7b0225f006e8630db3e86e8cf304ba1a9fae69186f3902ebc3500145cb35af2bde1b83a9abac634e1ca981c4f39258b10be645066f7d3355d53991c3b1b3b - languageName: node - linkType: hard - -"@aws-sdk/region-config-resolver@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/8fe6e40f37c97cafaf2f3f22bdeb1e015da955f75a5e54754301f3a0a98fca126a0f5745cfa07cd25b6e9f574cf4a3e359efc8c71dd12ee7920a0d493b258627 - languageName: node - linkType: hard - "@aws-sdk/region-config-resolver@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/region-config-resolver@npm:3.972.3" @@ -1850,7 +1067,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:3.986.0": +"@aws-sdk/s3-request-presigner@npm:3.986.0, @aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/s3-request-presigner@npm:3.986.0" dependencies: @@ -1866,36 +1083,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": - version: 3.896.0 - resolution: "@aws-sdk/s3-request-presigner@npm:3.896.0" - dependencies: - "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-format-url": "npm:3.893.0" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/a20d4ed2a558b41517cb6342d9f36ac678ab0fabb2c754354d5afd576719754fb5d6e22574b88817f7e61853e1ee9ac1d437513d8933ad773fcc7e90bc3ab298 - languageName: node - linkType: hard - -"@aws-sdk/signature-v4-multi-region@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.896.0" - dependencies: - "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b1b3926c6ec9f54afb2eb43af559cb54dbf7d47012c8e6709c495a9292e9c8f9f61c86300d784fa14743a634210f216bc21ee2da976b5bf82db18d5a3f0abe16 - languageName: node - linkType: hard - "@aws-sdk/signature-v4-multi-region@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/signature-v4-multi-region@npm:3.986.0" @@ -1910,36 +1097,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/token-providers@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sso-oidc": ^3.598.0 - checksum: 10/8542937e6d010ebd6b3dd70390685fa4553b0e01ed4fb8e6dc7bd6395e853162758e8d7a6c251fb56309d36beebc393981788ca112bfb3b1de7e23e599d2476e - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/token-providers@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b50abe20a20aabaac857bb606b694036d693187ab2dd6d6836f1caad008314784f7a2a6c566bf3966f699d59b3a035ed7897c4fff37a828cc47d55c6076dbda4 - languageName: node - linkType: hard - "@aws-sdk/token-providers@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/token-providers@npm:3.985.0" @@ -1955,27 +1112,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/types@npm:3.598.0" - dependencies: - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/29384fbe79ec8693cae00b3082379559e7bbea5fd70de1705e94e93ed1ec57ddb930bb41102f9b229869a9a7ba790deeb1161bc81e2f87a031d37dff2fa73dd0 - languageName: node - linkType: hard - -"@aws-sdk/types@npm:3.893.0, @aws-sdk/types@npm:^3.222.0": - version: 3.893.0 - resolution: "@aws-sdk/types@npm:3.893.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/c7edea067ee8179732b9750b4090d0cc5ca07e954b92cec25c4f55c8e1e9a1ad62df2799e2a82ad24b59ee25a2a4188a5e429db59aa168b10d0ba62347800d5b - languageName: node - linkType: hard - -"@aws-sdk/types@npm:^3.973.1": +"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.973.1": version: 3.973.1 resolution: "@aws-sdk/types@npm:3.973.1" dependencies: @@ -1985,15 +1122,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.893.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/f809777714618c63e92fd5881c9573081bc94df9c5cce53917b8e1db4efa1d44f1132f6c9179f9babc4964c648d42ebee5c1ad75641c6b336007be3df561053f - languageName: node - linkType: hard - "@aws-sdk/util-arn-parser@npm:^3.972.2": version: 3.972.2 resolution: "@aws-sdk/util-arn-parser@npm:3.972.2" @@ -2003,31 +1131,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-endpoints@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-endpoints": "npm:^2.0.2" - tslib: "npm:^2.6.2" - checksum: 10/753c5629e7f9e0abd3b2d8578ffa038089e18e80d8b2a3f49f2321dc565480c2d6dc5ecbfae799f35cb88fbc247018887f2c3b325853af6246547293973c7d45 - languageName: node - linkType: hard - -"@aws-sdk/util-endpoints@npm:3.895.0": - version: 3.895.0 - resolution: "@aws-sdk/util-endpoints@npm:3.895.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-endpoints": "npm:^3.1.2" - tslib: "npm:^2.6.2" - checksum: 10/14f39c2f0f085640cb8f1f178bc710aa237fbd0d856c9081dbf4d5514bfb8aff96c97fdb006450f1cbe839f7604ba19832daa95b1f6dccc65094e52a6e388e6f - languageName: node - linkType: hard - "@aws-sdk/util-endpoints@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/util-endpoints@npm:3.985.0" @@ -2054,18 +1157,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-format-url@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-format-url@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/0cc12a660aaa0fa34294727caa0f52bef97b85f4f7d46aebdc609f176330658275e1177317e06adc559f6ee3f9a7fa5c86be75d18353a7b4311589cfca161a48 - languageName: node - linkType: hard - "@aws-sdk/util-format-url@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-format-url@npm:3.972.3" @@ -2087,30 +1178,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/2c7bb1ec527ae1df15bf8c58320912c2cf41cecbfcf41a84fdb5d2c7b2ed53245d8748607b05445d0aac31ca1fb66280b38199fd457eb1f5650b60668c956f25 - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-browser@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/b268fc03a2afb2741e64175e5bd28b34315314ff55e82fa00e3d98f35a955a681568b1595f7e18b05f0172915244be7fe0cf5e1e90cf6e971bae3a946e3dfa63 - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-browser@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.3" @@ -2123,41 +1190,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/19de8df5e26560f9fc99acd73dd5c5f7890ec62b876568f15132dc1141eab280ec7ad44aeb0b095f765c2329f06fc8babf124e2708d6ccee1c541a9f62b51f5f - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-node@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.896.0" - dependencies: - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/4453a1989deb1a2ad6e087914642760206b4a77a8da4976c74225ed47400812595e6bfa1ad27f42277b561b8d8b8a2dcaf248b3bd8a0c1b0ef2f1e790320d8a9 - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-node@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/util-user-agent-node@npm:3.972.5" @@ -2176,17 +1208,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.894.0": - version: 3.894.0 - resolution: "@aws-sdk/xml-builder@npm:3.894.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - fast-xml-parser: "npm:5.2.5" - tslib: "npm:^2.6.2" - checksum: 10/60a32a4fcc0466fa6eb61e165146bf7c9559252e0adc5f232d7f73237b4dab28ae92dadaf4ee039629b1d8ce47f4731348908e5e7de4e2abcf22f0c19597caf5 - languageName: node - linkType: hard - "@aws-sdk/xml-builder@npm:^3.972.4": version: 3.972.4 resolution: "@aws-sdk/xml-builder@npm:3.972.4" @@ -2198,13 +1219,6 @@ __metadata: languageName: node linkType: hard -"@aws/lambda-invoke-store@npm:^0.0.1": - version: 0.0.1 - resolution: "@aws/lambda-invoke-store@npm:0.0.1" - checksum: 10/e8f54d28aade8828962f2871a22aa4e960ebc40c8fa551414181dd9dd32d6258279013c42f88e57d17aa4252cb5ed00df6a49fc35185f9fa6b6f351ccf821bd6 - languageName: node - linkType: hard - "@aws/lambda-invoke-store@npm:^0.2.2": version: 0.2.3 resolution: "@aws/lambda-invoke-store@npm:0.2.3" @@ -3972,16 +2986,7 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5": - version: 1.5.0 - resolution: "@emnapi/runtime@npm:1.5.0" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10/5311ce854306babc77f4bd94c2f973722714a0fab93c126239104ad52dea16a147bfed4c4cff3ca1eb32709607221c25d2f747ae8524cbeb9088058f02ff962b - languageName: node - linkType: hard - -"@emnapi/runtime@npm:^1.7.0": +"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5, @emnapi/runtime@npm:^1.7.0": version: 1.8.1 resolution: "@emnapi/runtime@npm:1.8.1" dependencies: @@ -6557,26 +5562,6 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/abort-controller@npm:3.1.0" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/1a7459471db6a624bec0a3235251c067b813a47c2bc15145977ebca76894a491974575d9c9c515120259b206cf3d613baa1a61b8da96a7a0233c8c5d7c04e725 - languageName: node - linkType: hard - -"@smithy/abort-controller@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/abort-controller@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/d2a007a4a41afd3ac13c291f2683d1da57709e75db0a09f502225983c097c8169e3b1b78fc01ee691fb12980492fb3ca49628b3f34ece0a66806bd0caf701710 - languageName: node - linkType: hard - "@smithy/abort-controller@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/abort-controller@npm:4.2.8" @@ -6587,16 +5572,6 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/chunked-blob-reader-native@npm:4.1.0" - dependencies: - "@smithy/util-base64": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/5ddca9cb700392ff0e6025726528e2c2e20e189b974af0eb8286b2b7bfa248c10c479c99ff09d0fbf0c3c5feefa98ce5da78f4273bbdae0b85e064d753fdecc9 - languageName: node - linkType: hard - "@smithy/chunked-blob-reader-native@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/chunked-blob-reader-native@npm:4.2.1" @@ -6607,15 +5582,6 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^5.1.0": - version: 5.1.0 - resolution: "@smithy/chunked-blob-reader@npm:5.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/a7d1d7d5b45499dc6e2c6a4bbfd1ac8cfbaf85b5b28db060c8d3cb1f331432cdada0e5586d57d949a3e521d7eb7b88c425d66cd2ee7ab9d1cf4fbff9a1f830e0 - languageName: node - linkType: hard - "@smithy/chunked-blob-reader@npm:^5.2.0": version: 5.2.0 resolution: "@smithy/chunked-blob-reader@npm:5.2.0" @@ -6625,32 +5591,6 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/config-resolver@npm:3.0.3" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-config-provider": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/e1e88d334177f6481ddba3a805e8e2e6513654a581aee500a1a74a0f206379ddbdec9eb48b2f4a1ae1c84b330d122f84cbbba0f0ffbe4c9ebdeeaac872cfee7e - languageName: node - linkType: hard - -"@smithy/config-resolver@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/config-resolver@npm:4.2.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/8b489420646c61c4ac57e2754ad6e4012de27aa6d0bca18d69f1916085908d58d8ba4d8d963e24ba55c9a797996b95cedff18e3fa2674136c6eb14044f942da0 - languageName: node - linkType: hard - "@smithy/config-resolver@npm:^4.4.6": version: 4.4.6 resolution: "@smithy/config-resolver@npm:4.4.6" @@ -6665,40 +5605,6 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^2.2.1": - version: 2.2.3 - resolution: "@smithy/core@npm:2.2.3" - dependencies: - "@smithy/middleware-endpoint": "npm:^3.0.3" - "@smithy/middleware-retry": "npm:^3.0.6" - "@smithy/middleware-serde": "npm:^3.0.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/d1e4885b3800e97bd119a66b2cd75c3bfdcfa5af420db20b4360a6bd9f7a7f31cee0b35edf06ecb61c210fcf042e3f2bf82e6650e571e2a63879082a5805c9cd - languageName: node - linkType: hard - -"@smithy/core@npm:^3.12.0, @smithy/core@npm:^3.13.0": - version: 3.13.0 - resolution: "@smithy/core@npm:3.13.0" - dependencies: - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/75b7045fae55b732e0420b2990255b7f8c962a66a6f9e77bd1509534428434190823bf1e68eabdda927d5abfb5d6d7783f49fa2d08268610ac4cd33c6c3f5594 - languageName: node - linkType: hard - "@smithy/core@npm:^3.22.1, @smithy/core@npm:^3.23.0": version: 3.23.0 resolution: "@smithy/core@npm:3.23.0" @@ -6717,32 +5623,6 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/credential-provider-imds@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/url-parser": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/2d023083f12d1a411251d2402e281dbeb6de83d394d900052aacd02188102b4b24fc9c2791a76b669c7800f8a5fb3baf99ea65fddd1e4cc6a467b1f85575987b - languageName: node - linkType: hard - -"@smithy/credential-provider-imds@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/credential-provider-imds@npm:4.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/c10cbea54ba8475d27cd38e956bda9113efa7e90ad46369aa2b3f8bce511ccc89a45f2198efe8bd00a35de16f5ef411723be01093cc02c10511ea89c5ed0131e - languageName: node - linkType: hard - "@smithy/credential-provider-imds@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/credential-provider-imds@npm:4.2.8" @@ -6756,18 +5636,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-codec@npm:4.1.1" - dependencies: - "@aws-crypto/crc32": "npm:5.2.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/7921997f85957c17fd5493567777dcfa31b90c84a3cb2a27adfc8218846994dd6ddebb4699c0656e02d25709d44b692b58a0c94296e771257097ab61626ebdd3 - languageName: node - linkType: hard - "@smithy/eventstream-codec@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-codec@npm:4.2.8" @@ -6780,17 +5648,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-browser@npm:4.1.1" - dependencies: - "@smithy/eventstream-serde-universal": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/89afea2e1deeb3e771e69e62dbc3d17a4fb366dc0b3edf355069a0d8c429cc09e46c8b78f92456dded8e40e22dd06dade5bc717e17ae197b0fe5997729aac82c - languageName: node - linkType: hard - "@smithy/eventstream-serde-browser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-browser@npm:4.2.8" @@ -6802,16 +5659,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/eventstream-serde-config-resolver@npm:4.2.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/18e1f0e69bb10b427103113ca14542d6e740e9096cd51d706f890cec78d390f5ccc81513ceef0b861ba05ff0004f0244aaac29d4f3eeff2bc062a16a76331944 - languageName: node - linkType: hard - "@smithy/eventstream-serde-config-resolver@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.8" @@ -6822,17 +5669,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-node@npm:4.1.1" - dependencies: - "@smithy/eventstream-serde-universal": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/9ec402098b3d67d051e92d332afb7ea7ab056d178e206d4e35ca47e9b2d12915373358323681c6183f22680e847101277dbf43abb9703bfda2ec23451cc87c51 - languageName: node - linkType: hard - "@smithy/eventstream-serde-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-node@npm:4.2.8" @@ -6844,17 +5680,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-universal@npm:4.1.1" - dependencies: - "@smithy/eventstream-codec": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/bbe77b9f14d718d18972dc4690c53b6518e0088e0c24d7f0a38b3ede3dd0291fd494112bfe7efb93591ba4b923b0ce9b8598ee72eec4e4481812ef3f4bfb5af7 - languageName: node - linkType: hard - "@smithy/eventstream-serde-universal@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-universal@npm:4.2.8" @@ -6866,32 +5691,6 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/fetch-http-handler@npm:3.1.0" - dependencies: - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/querystring-builder": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-base64": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/fcfd98a69798aa5b4c034601c75f125b2c70e24effd5a5137caad4ce24f06d83f8788664cff40b15e205257b055eefba35ec3314f73c0887c1c84fd9c349579f - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/fetch-http-handler@npm:5.2.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/a7038d20ad2ad64bdfda06b61e6a485b20af2086e94b78dc8f955a5baf270efaca6c9a3f7401114b8e856eed3ff8dda9701119a560455e6d72f8ae1957f50d33 - languageName: node - linkType: hard - "@smithy/fetch-http-handler@npm:^5.3.9": version: 5.3.9 resolution: "@smithy/fetch-http-handler@npm:5.3.9" @@ -6905,18 +5704,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-blob-browser@npm:4.1.1" - dependencies: - "@smithy/chunked-blob-reader": "npm:^5.1.0" - "@smithy/chunked-blob-reader-native": "npm:^4.1.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/8e29bf75da5ceebc571bee17c3e6c28162572105dcdc17b249a5edf3691e0987daf579470cb60799e8f200756cb3bd8fa69e0b299a8435edaff490f14101bc13 - languageName: node - linkType: hard - "@smithy/hash-blob-browser@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/hash-blob-browser@npm:4.2.9" @@ -6929,30 +5716,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/hash-node@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/df5c22224f210741b00bde59922b86354d1f21660bea6b0b3f8e9e87236fd80cb90bc81945ceb4914ae99ce7a7570f8cf59d57bffb3f50c75719e3cc3cdacab7 - languageName: node - linkType: hard - -"@smithy/hash-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-node@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/234f3d52975f99583ec8e739f70b3ccb1941f57bb47e1d230af954d5b1b3d7ee6c94907079017ef5fbfec4bcb618c0214b26b2ff7d7a01dc57d1f8f5ff414cba - languageName: node - linkType: hard - "@smithy/hash-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-node@npm:4.2.8" @@ -6965,17 +5728,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-stream-node@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/abdeea567ffb65f41e79c4dec5733c29a419a1de546e968be95113e2d96fc7e870149c1de422ff4fefb4229ee3dd0e29996df14c2c95e42a65027f9cdfa8f03a - languageName: node - linkType: hard - "@smithy/hash-stream-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-stream-node@npm:4.2.8" @@ -6987,26 +5739,6 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/invalid-dependency@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/e4bc6a79d4f514ae81600b3484025dc788013da690de6f3980121374b65d0d92d42bc50760e9c7b44438e7f5794ffd46bef2976a11d2da16fae47fc25b0ac96a - languageName: node - linkType: hard - -"@smithy/invalid-dependency@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/invalid-dependency@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/665e34379c6b3ad3a6bb0cf14ad646ba2bd9785b6e1b571d41192ad2d5617f5f48cd743d2ad75ce5ba6d5a2c2e312f7f86c2be50d2b8b12c9f2c0e5f42c9633e - languageName: node - linkType: hard - "@smithy/invalid-dependency@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/invalid-dependency@npm:4.2.8" @@ -7026,24 +5758,6 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/is-array-buffer@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/cab1fd4033d9863dcd95ff058463eb591574bd47e6b61e36aaaf4c0d0da9ed966a54e1d33ec4db7d67aa85df7d274203e934e04dbb40323d01ef4815f63997fc - languageName: node - linkType: hard - -"@smithy/is-array-buffer@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/is-array-buffer@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/5fba7ea13175100d39bc88b480dc70dc04bb62c62dc470e61e09b287f3b4c851c56473bda2ec077eca31675cde184dadc4d50ef11f065fb566e0b88f92d9465a - languageName: node - linkType: hard - "@smithy/is-array-buffer@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/is-array-buffer@npm:4.2.0" @@ -7053,17 +5767,6 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/md5-js@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/383d9acb06adad67c1089283988195d478475a53fa6e9954f5b237989b5ae15a8f2ec70f8f64557c65ce2984e8503bdc55ea4ff487def8c04822af1132f6746b - languageName: node - linkType: hard - "@smithy/md5-js@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/md5-js@npm:4.2.8" @@ -7075,28 +5778,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/middleware-content-length@npm:3.0.2" - dependencies: - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/520c28af22819724fefb8f487d6080b497f64ddf34fb75fd6829df0c1b075e23d0cdcfbbbd265b6556843735ae9721b8b349e2b6c194e3e71a94916c9a929cf6 - languageName: node - linkType: hard - -"@smithy/middleware-content-length@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-content-length@npm:4.1.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/eb2a99c11d01484ff0b17ba9c5d02878b92c61153568080eab011699de4460ff4534a302d9131583deb83963be83494a43e1973235c1e7edbaaaa2ace5e2b202 - languageName: node - linkType: hard - "@smithy/middleware-content-length@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-content-length@npm:4.2.8" @@ -7108,37 +5789,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/middleware-endpoint@npm:3.0.3" - dependencies: - "@smithy/middleware-serde": "npm:^3.0.2" - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/shared-ini-file-loader": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/url-parser": "npm:^3.0.2" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/fd3628405b4970f90448d5c52e7c3b808bbe149d72cbb21001a9a707b5b43a7e4e2275751b9486886bac2e740eaafc9c880800e6c69e02436731629b277bc55b - languageName: node - linkType: hard - -"@smithy/middleware-endpoint@npm:^4.2.4, @smithy/middleware-endpoint@npm:^4.2.5": - version: 4.2.5 - resolution: "@smithy/middleware-endpoint@npm:4.2.5" - dependencies: - "@smithy/core": "npm:^3.13.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/b9a8a0791cfe79d9507620f66fe4592e6d4586739d295a2cc4dd3b329c05bcc68af7806523ba05647c0bc32a466481ff9f11b9808756e70c41394ed3a0174bc3 - languageName: node - linkType: hard - "@smithy/middleware-endpoint@npm:^4.4.13, @smithy/middleware-endpoint@npm:^4.4.14": version: 4.4.14 resolution: "@smithy/middleware-endpoint@npm:4.4.14" @@ -7155,40 +5805,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": - version: 3.0.6 - resolution: "@smithy/middleware-retry@npm:3.0.6" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/service-error-classification": "npm:^3.0.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-middleware": "npm:^3.0.2" - "@smithy/util-retry": "npm:^3.0.2" - tslib: "npm:^2.6.2" - uuid: "npm:^9.0.1" - checksum: 10/8c0d696a840b6d307718e4cfaeb2eae41840be639c91c0653329beb1e4faf2b8f6a31225651c80da3f0b6a130d009fcc4f4f7c6549f9d8e298074b132731c953 - languageName: node - linkType: hard - -"@smithy/middleware-retry@npm:^4.3.0": - version: 4.3.1 - resolution: "@smithy/middleware-retry@npm:4.3.1" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/service-error-classification": "npm:^4.1.2" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/85b92dbd6c2b72d4fe38d56de69160bd44a3d99b51eb1a66456f75b1a4a3931999d986b58e4426608ca1d2089187a1ab43f6904b24803b0750fbd17226c8900d - languageName: node - linkType: hard - "@smithy/middleware-retry@npm:^4.4.30": version: 4.4.31 resolution: "@smithy/middleware-retry@npm:4.4.31" @@ -7206,27 +5822,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-serde@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/ef05cbd0b7a8b5187094ce134620e57dcb50a5c77b7f555f44f050e69a3677aff7f0c05ff02771b2bc92f515df527eef4d10ac5ff515648b8ec6cb92783cd072 - languageName: node - linkType: hard - -"@smithy/middleware-serde@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-serde@npm:4.1.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/01d907751748a4b2806aba43ec4a668d313c89c04ecd6ba3b15663e39b9b447842387e4300e47d8ce7066c415fb70b05b53c11967f98c4d8ea5488891070cad6 - languageName: node - linkType: hard - "@smithy/middleware-serde@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/middleware-serde@npm:4.2.9" @@ -7238,26 +5833,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-stack@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/21b7d7d6e73c1628b5ed384f23ac850df3bbca5054ea1e6ba03c3bf1d389fe5a440a4fbdb8aaa210c4b2ba864ac082264bb3c6ec7a2e03f0e6b790c6b23178a6 - languageName: node - linkType: hard - -"@smithy/middleware-stack@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-stack@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7c07663cb381f785d2bf39ff7fa5ee14e233168021274ede6b86335fff60a23260f42535f5ef32c8fe581c780a80acd06df39fcbcd3634e61c1eae685372a65c - languageName: node - linkType: hard - "@smithy/middleware-stack@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-stack@npm:4.2.8" @@ -7268,30 +5843,6 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/node-config-provider@npm:3.1.2" - dependencies: - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/shared-ini-file-loader": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/b0b9d665efc075803dcf9a26014def9b650270593667d5f01511758d4909387ab820c1fdcaf1a82e1f4fbd6c26a67ecab88ac26cc5450bf815788e4090d4e476 - languageName: node - linkType: hard - -"@smithy/node-config-provider@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/node-config-provider@npm:4.2.2" - dependencies: - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/18f290c8be9c5de33b64e7cae847bfbf1b926e7fbb1df31e853a7d04ef3275adb690f5cf3450ffef23ab68fc8f37f45d42bee9c05bf791b8b66c447c97ba2e25 - languageName: node - linkType: hard - "@smithy/node-config-provider@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/node-config-provider@npm:4.3.8" @@ -7304,32 +5855,6 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/node-http-handler@npm:3.1.0" - dependencies: - "@smithy/abort-controller": "npm:^3.1.0" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/querystring-builder": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/05ff2d9db1f67e08efd8b486c00506163dce70644add50ab3ca4995424bd73f168ee0f1f3b2f9aac77fa46c7775c7d28db558450a36fa641a862f80f957c1aad - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/node-http-handler@npm:4.2.1" - dependencies: - "@smithy/abort-controller": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/71f6551dbd06e2a9eb2b536bf13f11ec32c93da324376bf82ff3614e24241970e9ba4106cbbc8a0ac2867595fad3b12c6b2807366f921561ec41086a90af2ece - languageName: node - linkType: hard - "@smithy/node-http-handler@npm:^4.4.10, @smithy/node-http-handler@npm:^4.4.9": version: 4.4.10 resolution: "@smithy/node-http-handler@npm:4.4.10" @@ -7343,26 +5868,6 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/property-provider@npm:3.1.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/7993be1ae7f2f6779599837a246749b98cb0fc60e685ff7d97f1bd7e7ed1ce9e30bd4ce9e46e4a52f4dbf16cf864611bae72230e5fcb91b0c3a3d4de08ce258e - languageName: node - linkType: hard - -"@smithy/property-provider@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/property-provider@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f44da66c108b6bb0d9e59a30d8dbde17fc38656890b3ba688cf22db130e93f84d7436003cde473d2636a16d736eb4a8638e069f9a1cb0228a9bb2a5d90f8e40a - languageName: node - linkType: hard - "@smithy/property-provider@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/property-provider@npm:4.2.8" @@ -7373,26 +5878,6 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": - version: 4.0.2 - resolution: "@smithy/protocol-http@npm:4.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/accd46f06a4ab6549b797d52274d98c4b755a87fe2cd3f6c5edf991b8e44d4233fadbe4628d665f404ccd85ad9caa42127cef3db74a38f3d085f2f81b81d9f42 - languageName: node - linkType: hard - -"@smithy/protocol-http@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/protocol-http@npm:5.2.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7e00b314d6b38d58f4ca692546642b6a641be564d67fc31bae227ec0f0fd8f568522752189727a45828654c6ebcab2784884d4058ce992d2f48fc63ab37f4c2c - languageName: node - linkType: hard - "@smithy/protocol-http@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/protocol-http@npm:5.3.8" @@ -7403,28 +5888,6 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-builder@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-builder@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - "@smithy/util-uri-escape": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/6a455ee7ce135898e9d19cfd8c614f42f131a1439faddf49c2f72612521398de32dd75eebdde2af00754aa97b9418f3e42cf77e41ac264c1a74bd166c6d1dc0e - languageName: node - linkType: hard - -"@smithy/querystring-builder@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-builder@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-uri-escape": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/bbbfd564ccd585273df3829cc5e86572341cf22ed65477fdf31c8b9fc99759e872246ad419863efc259a110fbdab5bac408a5729abc8f883edd8390ae80aaf30 - languageName: node - linkType: hard - "@smithy/querystring-builder@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-builder@npm:4.2.8" @@ -7436,26 +5899,6 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-parser@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/86e5d986df6e0d639d420306a41e444456a8a91457f8e3fc363fb2c9155d3a02f8a651add14f0e341955af5c521a8e6cf1abb920ddf2ce7c89acaafba768299a - languageName: node - linkType: hard - -"@smithy/querystring-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-parser@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/08b81b7e8350d88b5a350cbe55c626c71bb86de06041e8311c44133919accba63b401672f84e65cbdbddce02a08b408da40669161d92af1d4d283dd167863aa5 - languageName: node - linkType: hard - "@smithy/querystring-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-parser@npm:4.2.8" @@ -7466,24 +5909,6 @@ __metadata: languageName: node linkType: hard -"@smithy/service-error-classification@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/service-error-classification@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - checksum: 10/f871ab0a4966a874cae412ff7621a44ab07f31c91070b2fb21f8e5d39f7336e25ad119469ac023861e2d310f0b5739fe308dde89ef5fbc17ec4860e8575f15db - languageName: node - linkType: hard - -"@smithy/service-error-classification@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/service-error-classification@npm:4.1.2" - dependencies: - "@smithy/types": "npm:^4.5.0" - checksum: 10/50e8835e9850167093db1a96e9265ee66991f8e03b44fd2f23c44114de5634d9d65dd80fc6f7f94ebba2f2e892f73a270bbfdca5c07bfc97bb36bbf3b95ad4a3 - languageName: node - linkType: hard - "@smithy/service-error-classification@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/service-error-classification@npm:4.2.8" @@ -7493,26 +5918,6 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/f3d7dde145975c626fb2565af8a24308b00e70b70618d7870dd91c2956918945a8bce557d0809416fa047b3792b5e038521b5aa53ac164c1f345da98c4a663fc - languageName: node - linkType: hard - -"@smithy/shared-ini-file-loader@npm:^4.2.0": - version: 4.2.0 - resolution: "@smithy/shared-ini-file-loader@npm:4.2.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/ee67bbfbbde59407ef15777118cccc2ef39163f70efc0704044144dcd08019316b08ccdec5e8dc94fb17d2be6aeb256a2d7b790a36c9938b6149e2e4c646db89 - languageName: node - linkType: hard - "@smithy/shared-ini-file-loader@npm:^4.4.3": version: 4.4.3 resolution: "@smithy/shared-ini-file-loader@npm:4.4.3" @@ -7523,37 +5928,6 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^3.1.0": - version: 3.1.1 - resolution: "@smithy/signature-v4@npm:3.1.1" - dependencies: - "@smithy/is-array-buffer": "npm:^3.0.0" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-hex-encoding": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.2" - "@smithy/util-uri-escape": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/ad768406d955c038ff0492ecbeec13dd3f5f5ab0c8224a00097a7a8122a17f5cf97fb299cce61d668f27a59003e455dde4b4ab0c1dce27f8946e1af38c0202f7 - languageName: node - linkType: hard - -"@smithy/signature-v4@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/signature-v4@npm:5.2.1" - dependencies: - "@smithy/is-array-buffer": "npm:^4.1.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-uri-escape": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/4f22b6f1a1d15c15627af64ea1490ce797f020fca3177b00ec54d89e72ecdce98ed71ec8a96ece638110ac0b331718065a8393687654776e6989a523f03703b0 - languageName: node - linkType: hard - "@smithy/signature-v4@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/signature-v4@npm:5.3.8" @@ -7570,20 +5944,6 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/smithy-client@npm:3.1.4" - dependencies: - "@smithy/middleware-endpoint": "npm:^3.0.3" - "@smithy/middleware-stack": "npm:^3.0.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-stream": "npm:^3.0.4" - tslib: "npm:^2.6.2" - checksum: 10/9e85bc7c5205d89d012bdd02c74eb3486709fa9f9442574fd84db5b3bccf9ce9a9aef6d7076e156f75cec257b478162242d4b3d5c44f3f32f087dfeb559e6549 - languageName: node - linkType: hard - "@smithy/smithy-client@npm:^4.11.2, @smithy/smithy-client@npm:^4.11.3": version: 4.11.3 resolution: "@smithy/smithy-client@npm:4.11.3" @@ -7599,30 +5959,6 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.6.4, @smithy/smithy-client@npm:^4.6.5": - version: 4.6.5 - resolution: "@smithy/smithy-client@npm:4.6.5" - dependencies: - "@smithy/core": "npm:^3.13.0" - "@smithy/middleware-endpoint": "npm:^4.2.5" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-stream": "npm:^4.3.2" - tslib: "npm:^2.6.2" - checksum: 10/ac8482d2c6cdd2755fd336ebfe4b6ddba5707a4438f199ce771e37bd9ae71be3ae43e32bcf6655345c1276c84416efe00141166708dea47be35bb78c06a4ea85 - languageName: node - linkType: hard - -"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": - version: 3.2.0 - resolution: "@smithy/types@npm:3.2.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/0590537cc2aaa7c2cd3277b6ec94ab1b7a417e7aae8389424e3b161b878dba3b8879c0bdfd0ad85145320006ecda8395f21196d527696e97bcfb98ffe01441b1 - languageName: node - linkType: hard - "@smithy/types@npm:^4.12.0": version: 4.12.0 resolution: "@smithy/types@npm:4.12.0" @@ -7632,37 +5968,6 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^4.5.0": - version: 4.5.0 - resolution: "@smithy/types@npm:4.5.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d25275a0f1cb75dd3534a60a637b0202fbe1343703a448c410aa3e3029d5dc1d128c711c005bbda29a111af5a072aaf01bd8314a05c9806857d18e625f41c075 - languageName: node - linkType: hard - -"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/url-parser@npm:3.0.2" - dependencies: - "@smithy/querystring-parser": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/080214bb1ae59472903d26beb71b7641a6ff49787735a8f56561b16d938cca80b8d560c2f679bf04da173c8c899b50aed881b61aef266bed11b570afbe20bc4f - languageName: node - linkType: hard - -"@smithy/url-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/url-parser@npm:4.1.1" - dependencies: - "@smithy/querystring-parser": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/35904bf3561d433f92c318c2f9d1fb8324e7693ea11af3e7570a334944f701e9c6720d5b426d93830e33cfe105dd026cd5fda842b20d14589ff62b9c67b4118b - languageName: node - linkType: hard - "@smithy/url-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/url-parser@npm:4.2.8" @@ -7674,28 +5979,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-base64@npm:3.0.0" - dependencies: - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/3c883d63a33e1cfeebf7f846f167dfc54c832d1f5514d014fbfff06de3aecd5919f01637fc93668dca8a1029752f3a6fab0a94f455dcb7c88f1d472bde294eef - languageName: node - linkType: hard - -"@smithy/util-base64@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-base64@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/980391b462ab5d8a99ce2ac55441b3bcaef73e197926327f32ef09d708535f6d0449eb05fa166d709e27fdeb212a60f201d6678f2c64122fce072ef3d82c0644 - languageName: node - linkType: hard - "@smithy/util-base64@npm:^4.3.0": version: 4.3.0 resolution: "@smithy/util-base64@npm:4.3.0" @@ -7707,24 +5990,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-body-length-browser@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/a0ab6a6d414a62d18e57f3581769379a54bb1fd93606c69bc8d96a3566fdecb8db7b57da9446568d03eef9f004f2a89d7e94bdda79ef280f28b19a71803c0309 - languageName: node - linkType: hard - -"@smithy/util-body-length-browser@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-browser@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/264b1b0f47127b1d215e95e7c66d3717b3f838d674b195e0150c8405e1875779694b3c75ab1932bf1a51c890ed495f7a9560a25c40e635d2f5585e496d9fbf77 - languageName: node - linkType: hard - "@smithy/util-body-length-browser@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-body-length-browser@npm:4.2.0" @@ -7734,24 +5999,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-body-length-node@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/aabac66d7111612fd375d67150f8787c5cdc828f7e6acb40ef0b18b4c354e64e0ef2e4b8da2d7f01e8abe931ff2ef8109a408164ce7e5662fd41b470c462f1e4 - languageName: node - linkType: hard - -"@smithy/util-body-length-node@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-node@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/5a6d925afdebdcde7a7f1ce55e69d823c0a9b7a5ed8f899417c402952585784b0ac843932691875381ce389f0e5f543d25c9fe4a3d8addeddbd48124a8985b6b - languageName: node - linkType: hard - "@smithy/util-body-length-node@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/util-body-length-node@npm:4.2.1" @@ -7771,26 +6018,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-buffer-from@npm:3.0.0" - dependencies: - "@smithy/is-array-buffer": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/7e6596b38855c07869f7e8f7b0ad9b70c5e658f4a06c7db71c6134a9a785ac1fdaa84f8b3358c4a572767838498df118daad1fa937237d1fb4b9fce735cf8bb0 - languageName: node - linkType: hard - -"@smithy/util-buffer-from@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-buffer-from@npm:4.1.0" - dependencies: - "@smithy/is-array-buffer": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/b1337ac6874adac67bbc91144c6e0e760b194f44af91a9816812c042c19a83d552cd5c8a94b8ed01af6047d2163a854fc32ebcd957a6053b4fd27dedc8793bb5 - languageName: node - linkType: hard - "@smithy/util-buffer-from@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-buffer-from@npm:4.2.0" @@ -7801,24 +6028,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-config-provider@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/614c321c5a5a220d7d72d36359c41b4e390566719f7e01cefebffbe7034aae78b4533b27ab2030f93186c5f22893ddf056a3a2376a077d70ce89275f31e1ac46 - languageName: node - linkType: hard - -"@smithy/util-config-provider@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-config-provider@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/b6daf4d12e721062d7b1888a14a760db23a3df388cced56ba47673cc1a3a24b8933190a7631be1cc548eb62fb5a3b5c34d6de2eb595ffdacdfd7e0dcb7fee5ef - languageName: node - linkType: hard - "@smithy/util-config-provider@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-config-provider@npm:4.2.0" @@ -7828,32 +6037,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" - dependencies: - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/27cfd517c703fad039086c55c10b15b36f424536526dd92a498cbf539e8d82da7b07e5cf3ae0f5ef4cbce70e4acd0af1d8e811f38391882b91191c0711a3e58c - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-browser@npm:^4.1.4": - version: 4.1.5 - resolution: "@smithy/util-defaults-mode-browser@npm:4.1.5" - dependencies: - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/8afc56f0e18da20ea9e283ef07ec669e4593c4b80642548cb07712ce01203d556f056682e4cab702b420cf61ccf31dc07dcfa79800981a920ca19d6bf30a8198 - languageName: node - linkType: hard - "@smithy/util-defaults-mode-browser@npm:^4.3.29": version: 4.3.30 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.30" @@ -7866,36 +6049,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" - dependencies: - "@smithy/config-resolver": "npm:^3.0.3" - "@smithy/credential-provider-imds": "npm:^3.1.2" - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/20476aae3eb5cb4353e63cc5bf4a91c47f40016981631b1a1150fca0d561907df8dc4c7c4c39c5462febc226e8daedbbcd5468df93326d54127fd31932305ae8 - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-node@npm:^4.1.4": - version: 4.1.5 - resolution: "@smithy/util-defaults-mode-node@npm:4.1.5" - dependencies: - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/333739595d1679b54266acbbe558a18754db931e4ec2ecad237a7a0deede6a75b2e11386999b86b39900431d747d7d9188375f9060dc0b613bf68736c2b8fe42 - languageName: node - linkType: hard - "@smithy/util-defaults-mode-node@npm:^4.2.32": version: 4.2.33 resolution: "@smithy/util-defaults-mode-node@npm:4.2.33" @@ -7911,28 +6064,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^2.0.2": - version: 2.0.3 - resolution: "@smithy/util-endpoints@npm:2.0.3" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/145fe25e5ab22ee2214b6ffefc8fa91d77f09e456cf38000565faa96cad4e6da88bbd47e79e6c7c5e8ed1c7e896a3b3c8496706b28c6d2fe748675d467429359 - languageName: node - linkType: hard - -"@smithy/util-endpoints@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/util-endpoints@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/4310b3ae356d69f5bc6a7b3477ac5c16b0d014fe5c36db3445c010bfcea43f8b5de7abcb118f6935ccf9b41b9dcb6f17ca60792a68074c5b3ac70332dbc3c4b2 - languageName: node - linkType: hard - "@smithy/util-endpoints@npm:^3.2.8": version: 3.2.8 resolution: "@smithy/util-endpoints@npm:3.2.8" @@ -7944,24 +6075,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-hex-encoding@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d9f8c4c676410ca51bdbcec5d986883bad0028e26b098fc50e2b57bc81e8a5ce20e160786d08c8552ca0ba662c88ca16f33857ff24a0d183174325b2b40e3c8f - languageName: node - linkType: hard - -"@smithy/util-hex-encoding@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-hex-encoding@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/dc66a330ba5e4a7e034c75ff6bf823e7a3dd9df3283511f0e5e95797063f3a82cd1d68d1bdb2353b33502e7a2ae6806ae195a964c2e3339547e972d917c78ea4 - languageName: node - linkType: hard - "@smithy/util-hex-encoding@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-hex-encoding@npm:4.2.0" @@ -7971,26 +6084,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-middleware@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/1e202038bb332bc8301b5e7b882c917927d9c71aae1aae1d5529c68abbaf8efe4791a29f7d192c24c015b905d7cac3ef5aa867aedf3d9bf9f3557959a6877925 - languageName: node - linkType: hard - -"@smithy/util-middleware@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-middleware@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/bc80179fb554271dd44a9eb8403f09a2ed4f14de5ee1ba44fea17d8ee2d5b2178a433a24c85ee8898d7a69b45a8cf5978b3ef71866b6b461179a7c4ef4e79b58 - languageName: node - linkType: hard - "@smithy/util-middleware@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-middleware@npm:4.2.8" @@ -8001,28 +6094,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-retry@npm:3.0.2" - dependencies: - "@smithy/service-error-classification": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/adda2d16b743dd99c5a3dd93da11a7e5e52eede37c936d966ea74aabd32007e2fc375ec47529ea3ea6052fc5c656a620917f87d66232bb4a23a9b252fa7af2eb - languageName: node - linkType: hard - -"@smithy/util-retry@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/util-retry@npm:4.1.2" - dependencies: - "@smithy/service-error-classification": "npm:^4.1.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/3daf4b560de5dff99c14661b7ae5c4456b7b99642141cd4c7dccb281579435edecd22695a9fe78d47e716c85e25c9bbc555d44598f460f01f2d28d9182834dd4 - languageName: node - linkType: hard - "@smithy/util-retry@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-retry@npm:4.2.8" @@ -8034,38 +6105,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": - version: 3.0.4 - resolution: "@smithy/util-stream@npm:3.0.4" - dependencies: - "@smithy/fetch-http-handler": "npm:^3.1.0" - "@smithy/node-http-handler": "npm:^3.1.0" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-hex-encoding": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/4e53f14fd0b6e32a9b9897193e03f5df969e97f41c28e4f37d3f39082ac0b1b3e8a62117650076e2ea760e14c6b5d2dfd860e69e7c6a7f0145c03b8b6284ce14 - languageName: node - linkType: hard - -"@smithy/util-stream@npm:^4.3.2": - version: 4.3.2 - resolution: "@smithy/util-stream@npm:4.3.2" - dependencies: - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/244739dcb05c1d1cb3e7b2cad313475605846fb1a264220d97777d35ab4c676a9e71a4443fb9f04b5ed0f6cd28c74f692ce75b14840429b0e28abffb6ab10ebb - languageName: node - linkType: hard - "@smithy/util-stream@npm:^4.5.11, @smithy/util-stream@npm:^4.5.12": version: 4.5.12 resolution: "@smithy/util-stream@npm:4.5.12" @@ -8082,24 +6121,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-uri-escape@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d44522339325b0f1fe2c5bf1a3f01d5a699eb8718d800dee24378a1a1b301683756dcfd4be4c32db4d6a00cad85893494778ae39fb246a03aef27d06c9852a67 - languageName: node - linkType: hard - -"@smithy/util-uri-escape@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-uri-escape@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/c576cb2b7d365d02338734efd83d8b9d2e5ab7ea5a91444762ace367b6fe46e060a2a85ba51ba84ca5ac73b3e732436b22fb61359af4b731b41c1f803f3055ff - languageName: node - linkType: hard - "@smithy/util-uri-escape@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-uri-escape@npm:4.2.0" @@ -8119,26 +6140,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-utf8@npm:3.0.0" - dependencies: - "@smithy/util-buffer-from": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/1aead297d835af419f75e0c3113c021aa0da671110d1b498035530d5f35d8030092cad5147edaa7ca458aafe27c9383399ccd8176d342942465a2d8357e5cbf4 - languageName: node - linkType: hard - -"@smithy/util-utf8@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-utf8@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/4565df6e64df958d2e45da4344d3206a81e66b6e6a48734a45b5228fe73c5c5982ec52beedc8065ab73d169a278f9028438a60410a6daa1d40aebd9dd6122a07 - languageName: node - linkType: hard - "@smithy/util-utf8@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-utf8@npm:4.2.0" @@ -8149,17 +6150,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-waiter@npm:4.1.1" - dependencies: - "@smithy/abort-controller": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/019eecded24b9244675da3b956f572261e333d8d2b0d0555f9c85c893f2583f113bf0210521876e825943085d2d89e7e4fdb768cdc802627b9660d809734cce3 - languageName: node - linkType: hard - "@smithy/util-waiter@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-waiter@npm:4.2.8" @@ -8171,15 +6161,6 @@ __metadata: languageName: node linkType: hard -"@smithy/uuid@npm:^1.0.0": - version: 1.0.0 - resolution: "@smithy/uuid@npm:1.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/0c6c1d987bfff8569ac16363f9293b91ebcc62824eaa8ba666a5ca007b0899741b3e472165aa9f2ae1beade9ef7773f24645795a35a3ab09bd58d6e0a32179f2 - languageName: node - linkType: hard - "@smithy/uuid@npm:^1.1.0": version: 1.1.0 resolution: "@smithy/uuid@npm:1.1.0" @@ -9223,7 +7204,19 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": + version: 5.1.1 + resolution: "@types/express-serve-static-core@npm:5.1.1" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 10/7f3d8cf7e68764c9f3e8f6a12825b69ccf5287347fc1c20b29803d4f08a4abc1153ae11d7258852c61aad50f62ef72d4c1b9c97092b0a90462c3dddec2f6026c + languageName: node + linkType: hard + +"@types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": version: 4.19.6 resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: @@ -9244,7 +7237,18 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.20, @types/express@npm:^4.17.21": +"@types/express@npm:*, @types/express@npm:^5.0.0, @types/express@npm:^5.0.6": + version: 5.0.6 + resolution: "@types/express@npm:5.0.6" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/serve-static": "npm:^2" + checksum: 10/da2cc3de1b1a4d7f20ed3fb6f0a8ee08e99feb3c2eb5a8d643db77017d8d0e70fee9e95da38a73f51bcdf5eda3bb6435073c0271dc04fb16fda92e55daf911fa + languageName: node + linkType: hard + +"@types/express@npm:^4.17.21": version: 4.17.23 resolution: "@types/express@npm:4.17.23" dependencies: @@ -9511,7 +7515,17 @@ __metadata: languageName: node linkType: hard -"@types/serve-static@npm:*, @types/serve-static@npm:^1.15.5": +"@types/serve-static@npm:*, @types/serve-static@npm:^2": + version: 2.2.0 + resolution: "@types/serve-static@npm:2.2.0" + dependencies: + "@types/http-errors": "npm:*" + "@types/node": "npm:*" + checksum: 10/f2bad1304c7d0d3b7221faff3e490c40129d3803f4fb1b2fb84f31f561071c5e6a4b876c41bbbe82d5645034eea936e946bcaaf993dac1093ce68b56effad6e0 + languageName: node + linkType: hard + +"@types/serve-static@npm:^1.15.5": version: 1.15.7 resolution: "@types/serve-static@npm:1.15.7" dependencies: @@ -9757,9 +7771,9 @@ __metadata: escape-goat: "npm:3.0.0" escape-string-regexp: "npm:4.0.0" execa: "npm:^9.6.0" - express: "npm:4.21.2" + express: "npm:^5.2.1" express-interceptor: "npm:1.2.0" - express-prom-bundle: "npm:7" + express-prom-bundle: "npm:^8.0.0" express-session: "npm:1.18.1" fast-safe-stringify: "npm:^2.1.1" formdata-node: "npm:^6.0.3" @@ -10910,6 +8924,16 @@ __metadata: languageName: node linkType: hard +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7 + languageName: node + linkType: hard + "accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -11507,26 +9531,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.3": - version: 1.20.3 - resolution: "body-parser@npm:1.20.3" - dependencies: - bytes: "npm:3.1.2" - content-type: "npm:~1.0.5" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - on-finished: "npm:2.4.1" - qs: "npm:6.13.0" - raw-body: "npm:2.5.2" - type-is: "npm:~1.6.18" - unpipe: "npm:1.0.0" - checksum: 10/8723e3d7a672eb50854327453bed85ac48d045f4958e81e7d470c56bf111f835b97e5b73ae9f6393d0011cc9e252771f46fd281bbabc57d33d3986edf1e6aeca - languageName: node - linkType: hard - "body-parser@npm:1.20.4, body-parser@npm:^1.19.0, body-parser@npm:^1.20.4, body-parser@npm:~1.20.3": version: 1.20.4 resolution: "body-parser@npm:1.20.4" @@ -11547,6 +9551,23 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:^2.2.1": + version: 2.2.2 + resolution: "body-parser@npm:2.2.2" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.3" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.7.0" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.1" + raw-body: "npm:^3.0.1" + type-is: "npm:^2.0.1" + checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 + languageName: node + linkType: hard + "bonjour-service@npm:^1.2.1": version: 1.2.1 resolution: "bonjour-service@npm:1.2.1" @@ -11695,7 +9716,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2, bytes@npm:~3.1.2": +"bytes@npm:^3.1.2, bytes@npm:~3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 @@ -12369,7 +10390,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": +"content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -12378,7 +10399,14 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-disposition@npm:^1.0.0": + version: 1.1.0 + resolution: "content-disposition@npm:1.1.0" + checksum: 10/c4f65e3c001a4a8eb87d0d24c0f112abb139836fb13b8ea67276715e7dce09570ef666ba7848ee8b660d467e6588d030c8ed7e8d0128db6ca78a0800dcd8c7a8 + languageName: node + linkType: hard + +"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 @@ -12430,21 +10458,14 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.2": +"cookie-signature@npm:^1.2.1, cookie-signature@npm:^1.2.2": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 languageName: node linkType: hard -"cookie@npm:0.7.1": - version: 0.7.1 - resolution: "cookie@npm:0.7.1" - checksum: 10/aec6a6aa0781761bf55d60447d6be08861d381136a0fe94aa084fddd4f0300faa2b064df490c6798adfa1ebaef9e0af9b08a189c823e0811b8b313b3d9a03380 - languageName: node - linkType: hard - -"cookie@npm:0.7.2, cookie@npm:^0.7.2, cookie@npm:~0.7.1": +"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2, cookie@npm:~0.7.1": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f @@ -12857,7 +10878,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -13020,7 +11041,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0, depd@npm:~2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca @@ -13078,14 +11099,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": - version: 2.0.4 - resolution: "detect-libc@npm:2.0.4" - checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0 - languageName: node - linkType: hard - -"detect-libc@npm:^2.1.2": +"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4, detect-libc@npm:^2.1.2": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10/b736c8d97d5d46164c0d1bed53eb4e6a3b1d8530d460211e2d52f1c552875e706c58a5376854e4e54f8b828c9cada58c855288c968522eb93ac7696d65970766 @@ -13317,6 +11331,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -13324,13 +11345,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -13843,7 +11857,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:~1.0.3": +"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 @@ -13946,7 +11960,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1, etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff @@ -14014,7 +12028,7 @@ __metadata: cookie-parser: "npm:^1.4.7" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.17.3" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14030,7 +12044,7 @@ __metadata: "@aws-sdk/s3-request-presigner": "npm:^3.338.0" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.0" - express: "npm:^4.22.0" + express: "npm:^5.2.1" languageName: unknown linkType: soft @@ -14065,7 +12079,7 @@ __metadata: "@uppy/tus": "workspace:*" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.15.6" npm-run-all: "npm:^4.1.2" preact: "npm:^10.26.10" @@ -14083,7 +12097,7 @@ __metadata: body-parser: "npm:^1.20.4" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" vite: "npm:^7.1.11" languageName: unknown linkType: soft @@ -14094,7 +12108,7 @@ __metadata: dependencies: "@uppy/companion": "workspace:*" body-parser: "npm:^1.20.4" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.15.6" light-server: "npm:^2.4.0" languageName: unknown @@ -14161,7 +12175,7 @@ __metadata: "@react-router/express": "npm:^7.12.0" "@tus/file-store": "npm:latest" "@tus/server": "npm:latest" - "@types/express": "npm:^4.17.20" + "@types/express": "npm:^5.0.6" "@types/react": "npm:^18.2.20" "@types/react-dom": "npm:^18.2.7" "@uppy/core": "workspace:*" @@ -14170,7 +12184,7 @@ __metadata: "@uppy/transloadit": "workspace:*" "@uppy/tus": "workspace:*" "@uppy/xhr-upload": "workspace:*" - express: "npm:^4.22.0" + express: "npm:^5.2.1" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-router: "npm:^7.12.0" @@ -14220,7 +12234,7 @@ __metadata: "@uppy/remote-sources": "workspace:*" "@uppy/transloadit": "workspace:*" "@uppy/webcam": "workspace:*" - express: "npm:^4.22.0" + express: "npm:^5.2.1" he: "npm:^1.2.0" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14259,7 +12273,7 @@ __metadata: "@uppy/dashboard": "workspace:*" "@uppy/xhr-upload": "workspace:*" cors: "npm:^2.8.5" - express: "npm:^4.22.0" + express: "npm:^5.2.1" multer: "npm:^2.0.2" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14363,17 +12377,16 @@ __metadata: languageName: node linkType: hard -"express-prom-bundle@npm:7": - version: 7.0.2 - resolution: "express-prom-bundle@npm:7.0.2" +"express-prom-bundle@npm:^8.0.0": + version: 8.0.0 + resolution: "express-prom-bundle@npm:8.0.0" dependencies: - "@types/express": "npm:^4.17.21" - express: "npm:^4.18.2" + "@types/express": "npm:^5.0.0" on-finished: "npm:^2.3.0" url-value-parser: "npm:^2.0.0" peerDependencies: prom-client: ">=15.0.0" - checksum: 10/19d95252eaaaedae1a05d90bbb96cbcc60e82e7710baa18810bd9c327b864b743f4e16bc2a5b3f7e51dcd505ac86db4fd9391c72c11cf6c0dc2c8df893870e02 + checksum: 10/63bb4769e1ce6258dece3ac1011fccf81e31974bbbdd7e2c7d85679b4cb9bb5b1fc2294ca1648f043bfe42796b9b89f348ad1dfc2680d41c8655394c50606319 languageName: node linkType: hard @@ -14393,46 +12406,7 @@ __metadata: languageName: node linkType: hard -"express@npm:4.21.2": - version: 4.21.2 - resolution: "express@npm:4.21.2" - dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.3" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.7.1" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.3.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.3" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.12" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.13.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.19.0" - serve-static: "npm:1.16.2" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 10/34571c442fc8c9f2c4b442d2faa10ea1175cf8559237fc6a278f5ce6254a8ffdbeb9a15d99f77c1a9f2926ab183e3b7ba560e3261f1ad4149799e3412ab66bd1 - languageName: node - linkType: hard - -"express@npm:^4.18.2, express@npm:^4.21.2, express@npm:^4.22.0": +"express@npm:^4.21.2": version: 4.22.1 resolution: "express@npm:4.22.1" dependencies: @@ -14471,6 +12445,42 @@ __metadata: languageName: node linkType: hard +"express@npm:^5.2.1": + version: 5.2.1 + resolution: "express@npm:5.2.1" + dependencies: + accepts: "npm:^2.0.0" + body-parser: "npm:^2.2.1" + content-disposition: "npm:^1.0.0" + content-type: "npm:^1.0.5" + cookie: "npm:^0.7.1" + cookie-signature: "npm:^1.2.1" + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + finalhandler: "npm:^2.1.0" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + merge-descriptors: "npm:^2.0.0" + mime-types: "npm:^3.0.0" + on-finished: "npm:^2.4.1" + once: "npm:^1.4.0" + parseurl: "npm:^1.3.3" + proxy-addr: "npm:^2.0.7" + qs: "npm:^6.14.0" + range-parser: "npm:^1.2.1" + router: "npm:^2.2.0" + send: "npm:^1.1.0" + serve-static: "npm:^2.2.0" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10/4aa545d89702ac83f645c77abda1b57bcabe288f0b380fb5580fac4e323ea0eb533005c8e666b4e19152fb16d4abf11ba87b22aa9a10857a0485cd86b94639bd + languageName: node + linkType: hard + "exsolve@npm:^1.0.7": version: 1.0.8 resolution: "exsolve@npm:1.0.8" @@ -14537,28 +12547,6 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.2.5": - version: 4.2.5 - resolution: "fast-xml-parser@npm:4.2.5" - dependencies: - strnum: "npm:^1.0.5" - bin: - fxparser: src/cli/cli.js - checksum: 10/4be7ebe24d6a9a60c278e1423cd86a7da9a77ec64c95563e2c552363caf7a777e0c87c9de1255c2f4e8dea9bce8905dc2bdc58a34e9f2b73c4693654456ad284 - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.2.5": - version: 5.2.5 - resolution: "fast-xml-parser@npm:5.2.5" - dependencies: - strnum: "npm:^2.1.0" - bin: - fxparser: src/cli/cli.js - checksum: 10/305017cff6968a34cbac597317be1516e85c44f650f30d982c84f8c30043e81fd38d39a8810d570136c921399dd43b9ac4775bdfbbbcfee96456f3c086b48bdd - languageName: node - linkType: hard - "fast-xml-parser@npm:5.3.4": version: 5.3.4 resolution: "fast-xml-parser@npm:5.3.4" @@ -14654,18 +12642,17 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.3.1": - version: 1.3.1 - resolution: "finalhandler@npm:1.3.1" +"finalhandler@npm:^2.1.0": + version: 2.1.1 + resolution: "finalhandler@npm:2.1.1" dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 10/4babe72969b7373b5842bc9f75c3a641a4d0f8eb53af6b89fa714d4460ce03fb92b28de751d12ba415e96e7e02870c436d67412120555e2b382640535697305b + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + on-finished: "npm:^2.4.1" + parseurl: "npm:^1.3.3" + statuses: "npm:^2.0.1" + checksum: 10/f4ba75c23408d8f9d393c3e875b9452e84d68c925411a6e67b7efa678b0bed5075ef33def4bb65ed8e0dd37c92a3ea354bcbde07303cd4dc2550e12b95885067 languageName: node linkType: hard @@ -14864,6 +12851,13 @@ __metadata: languageName: node linkType: hard +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc + languageName: node + linkType: hard + "fs-extra@npm:^11.0.0": version: 11.3.0 resolution: "fs-extra@npm:11.3.0" @@ -15552,19 +13546,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:~1.6.2": - version: 1.6.3 - resolution: "http-errors@npm:1.6.3" - dependencies: - depd: "npm:~1.1.2" - inherits: "npm:2.0.3" - setprototypeof: "npm:1.1.0" - statuses: "npm:>= 1.4.0 < 2" - checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb - languageName: node - linkType: hard - -"http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": +"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": version: 2.0.1 resolution: "http-errors@npm:2.0.1" dependencies: @@ -15577,6 +13559,18 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:~1.6.2": + version: 1.6.3 + resolution: "http-errors@npm:1.6.3" + dependencies: + depd: "npm:~1.1.2" + inherits: "npm:2.0.3" + setprototypeof: "npm:1.1.0" + statuses: "npm:>= 1.4.0 < 2" + checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb + languageName: node + linkType: hard + "http-parser-js@npm:>=0.5.1": version: 0.5.8 resolution: "http-parser-js@npm:0.5.8" @@ -15710,7 +13704,16 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -15719,12 +13722,12 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" +"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + checksum: 10/24c937b532f868e938386b62410b303b7c767ce3d08dc2829cbe59464d5a26ef86ae5ad1af6b34eec43ddfea39e7d101638644b0178d67262fa87015d59f983a languageName: node linkType: hard @@ -16176,6 +14179,13 @@ __metadata: languageName: node linkType: hard +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a + languageName: node + linkType: hard + "is-reference@npm:^3.0.3": version: 3.0.3 resolution: "is-reference@npm:3.0.3" @@ -17467,14 +15477,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 - languageName: node - linkType: hard - -"lodash@npm:^4.17.23": +"lodash@npm:^4.17.21, lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10/82504c88250f58da7a5a4289f57a4f759c44946c005dd232821c7688b5fcfbf4a6268f6a6cdde4b792c91edd2f3b5398c1d2a0998274432cff76def48735e233 @@ -17736,6 +15739,13 @@ __metadata: languageName: node linkType: hard +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd + languageName: node + linkType: hard + "memfs@npm:^4.6.0": version: 4.9.3 resolution: "memfs@npm:4.9.3" @@ -17762,6 +15772,13 @@ __metadata: languageName: node linkType: hard +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -17793,13 +15810,20 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": +"mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 languageName: node linkType: hard +"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 + languageName: node + linkType: hard + "mime-match@npm:^1.0.2": version: 1.0.2 resolution: "mime-match@npm:1.0.2" @@ -17818,6 +15842,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": + version: 3.0.2 + resolution: "mime-types@npm:3.0.2" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10/9db0ad31f5eff10ee8f848130779b7f2d056ddfdb6bda696cb69be68d486d33a3457b4f3f9bdeb60d0736edb471bd5a7c0a384375c011c51c889fd0d5c3b893e + languageName: node + linkType: hard + "mime@npm:1.6.0, mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -18082,16 +16115,7 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:^3.0.1": - version: 3.0.2 - resolution: "minizlib@npm:3.0.2" - dependencies: - minipass: "npm:^7.1.2" - checksum: 10/c075bed1594f68dcc8c35122333520112daefd4d070e5d0a228bd4cf5580e9eed3981b96c0ae1d62488e204e80fd27b2b9d0068ca9a5ef3993e9565faf63ca41 - languageName: node - linkType: hard - -"minizlib@npm:^3.1.0": +"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" dependencies: @@ -18120,15 +16144,6 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^3.0.1": - version: 3.0.1 - resolution: "mkdirp@npm:3.0.1" - bin: - mkdirp: dist/cjs/src/bin.js - checksum: 10/16fd79c28645759505914561e249b9a1f5fe3362279ad95487a4501e4467abeb714fd35b95307326b8fd03f3c7719065ef11a6f97b7285d7888306d1bd2232ba - languageName: node - linkType: hard - "moment-timezone@npm:^0.5.31": version: 0.5.45 resolution: "moment-timezone@npm:0.5.45" @@ -19465,13 +17480,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.12, path-to-regexp@npm:~0.1.12": - version: 0.1.12 - resolution: "path-to-regexp@npm:0.1.12" - checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e - languageName: node - linkType: hard - "path-to-regexp@npm:^6.3.0": version: 6.3.0 resolution: "path-to-regexp@npm:6.3.0" @@ -19479,6 +17487,20 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^8.0.0": + version: 8.4.2 + resolution: "path-to-regexp@npm:8.4.2" + checksum: 10/70fd2cbce0b962cbcf4d312af07818bfce2bae11c09cf3bd86be99c0e30168238a1a7b02b18b452e73f075897df04597d30d63e56da7be41eecfc37998693389 + languageName: node + linkType: hard + +"path-to-regexp@npm:~0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e + languageName: node + linkType: hard + "path-type@npm:^3.0.0": version: 3.0.0 resolution: "path-type@npm:3.0.0" @@ -20312,7 +18334,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -20364,16 +18386,16 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.13.0": - version: 6.13.0 - resolution: "qs@npm:6.13.0" +"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.6": + version: 6.15.1 + resolution: "qs@npm:6.15.1" dependencies: - side-channel: "npm:^1.0.6" - checksum: 10/f548b376e685553d12e461409f0d6e5c59ec7c7d76f308e2a888fd9db3e0c5e89902bedd0754db3a9038eda5f27da2331a6f019c8517dc5e0a16b3c9a6e9cef8 + side-channel: "npm:^1.1.0" + checksum: 10/ec10b9957446b3f4a38000940f6374720b4e2985209b89df197066038c951472ea24cd98d6bc6df73a0cbec75bc056f638032e3fb447345017ff7e0f0a2693ac languageName: node linkType: hard -"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.9.6, qs@npm:~6.14.0": +"qs@npm:~6.14.0": version: 6.14.0 resolution: "qs@npm:6.14.0" dependencies: @@ -20433,15 +18455,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.2": - version: 2.5.2 - resolution: "raw-body@npm:2.5.2" +"raw-body@npm:^3.0.1": + version: 3.0.2 + resolution: "raw-body@npm:3.0.2" dependencies: - bytes: "npm:3.1.2" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - unpipe: "npm:1.0.0" - checksum: 10/863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95 + bytes: "npm:~3.1.2" + http-errors: "npm:~2.0.1" + iconv-lite: "npm:~0.7.0" + unpipe: "npm:~1.0.0" + checksum: 10/4168c82157bd69175d5bd960e59b74e253e237b358213694946a427a6f750a18b8e150f036fed3421b3e83294b071a4e2bb01037a79ccacdac05360c63d3ebba languageName: node linkType: hard @@ -21076,6 +19098,19 @@ __metadata: languageName: node linkType: hard +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + is-promise: "npm:^4.0.0" + parseurl: "npm:^1.3.3" + path-to-regexp: "npm:^8.0.0" + checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91 + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.8.0": version: 0.8.0 resolution: "rrweb-cssom@npm:0.8.0" @@ -21309,16 +19344,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": - version: 7.7.2 - resolution: "semver@npm:7.7.2" - bin: - semver: bin/semver.js - checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda - languageName: node - linkType: hard - -"semver@npm:^7.7.3": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -21369,6 +19395,25 @@ __metadata: languageName: node linkType: hard +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.1 + resolution: "send@npm:1.2.1" + dependencies: + debug: "npm:^4.4.3" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.1" + mime-types: "npm:^3.0.2" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.2" + checksum: 10/274f842d69ccfa49d4940a85598c6825da58dee6cb8ea33b08d5bd3988e6a82267c4d7c32b23d0e4706aad076ee95b1edfa13f859877db9b589829019397e355 + languageName: node + linkType: hard + "send@npm:~0.19.0": version: 0.19.1 resolution: "send@npm:0.19.1" @@ -21423,15 +19468,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.16.2, serve-static@npm:~1.16.2": - version: 1.16.2 - resolution: "serve-static@npm:1.16.2" +"serve-static@npm:^2.2.0": + version: 2.2.1 + resolution: "serve-static@npm:2.2.1" dependencies: - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.19.0" - checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + parseurl: "npm:^1.3.3" + send: "npm:^1.2.0" + checksum: 10/71500fe80cc7163fec04e4297de7591ad1cb682d137fc030e7a53e57040fda5187e8082a9c1b2ef37f1d3f9c27c9a94d4ba61806ebc28938ba4a7c8947c9f71e languageName: node linkType: hard @@ -21447,6 +19492,18 @@ __metadata: languageName: node linkType: hard +"serve-static@npm:~1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" + dependencies: + encodeurl: "npm:~2.0.0" + escape-html: "npm:~1.0.3" + parseurl: "npm:~1.3.3" + send: "npm:0.19.0" + checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 + languageName: node + linkType: hard + "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -21675,7 +19732,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": +"side-channel@npm:^1.0.4, side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -22054,7 +20111,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:^2.0.1, statuses@npm:~2.0.1, statuses@npm:~2.0.2": +"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.1, statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 @@ -22264,7 +20321,7 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.0.5, strnum@npm:^1.1.1": +"strnum@npm:^1.1.1": version: 1.1.2 resolution: "strnum@npm:1.1.2" checksum: 10/ccd6297a1fdaf0fc8ea0ea904acdae76878d49a4b0d98a70155df4bc081fd88eac5ec99fb150f3d1d1af065c1898d38420705259ba6c39aa850c671bcd54e35d @@ -22494,21 +20551,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.4.3": - version: 7.4.3 - resolution: "tar@npm:7.4.3" - dependencies: - "@isaacs/fs-minipass": "npm:^4.0.0" - chownr: "npm:^3.0.0" - minipass: "npm:^7.1.2" - minizlib: "npm:^3.0.1" - mkdirp: "npm:^3.0.1" - yallist: "npm:^5.0.0" - checksum: 10/12a2a4fc6dee23e07cc47f1aeb3a14a1afd3f16397e1350036a8f4cdfee8dcac7ef5978337a4e7b2ac2c27a9a6d46388fc2088ea7c80cb6878c814b1425f8ecf - languageName: node - linkType: hard - -"tar@npm:^7.5.7": +"tar@npm:^7.4.3, tar@npm:^7.5.7": version: 7.5.12 resolution: "tar@npm:7.5.12" dependencies: @@ -22904,6 +20947,17 @@ __metadata: languageName: node linkType: hard +"type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" + dependencies: + content-type: "npm:^1.0.5" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10/bacdb23c872dacb7bd40fbd9095e6b2fca2895eedbb689160c05534d7d4810a7f4b3fd1ae87e96133c505958f6d602967a68db5ff577b85dd6be76eaa75d58af + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -23185,7 +21239,7 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": +"unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10/4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 @@ -23317,15 +21371,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.1": - version: 9.0.1 - resolution: "uuid@npm:9.0.1" - bin: - uuid: dist/bin/uuid - checksum: 10/9d0b6adb72b736e36f2b1b53da0d559125ba3e39d913b6072f6f033e0c87835b414f0836b45bcfaf2bdf698f92297fea1c3cc19b0b258bc182c9c43cc0fab9f2 - languageName: node - linkType: hard - "valibot@npm:^1.2.0": version: 1.2.0 resolution: "valibot@npm:1.2.0" @@ -23371,7 +21416,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 From d9742ba4e4ac8dfd640b3dcc8a2ca1d647163221 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 21 May 2026 02:36:00 +0530 Subject: [PATCH 20/33] Revert "Upgrade to express 5" (#6303) Reverts transloadit/uppy#6175 --- .changeset/happy-timers-kick.md | 5 - .changeset/smooth-chefs-occur.md | 5 - examples/aws-companion/package.json | 2 +- examples/aws-nodejs/package.json | 2 +- .../companion-custom-provider/package.json | 2 +- .../package.json | 2 +- examples/companion/package.json | 2 +- examples/reactrouter/package.json | 4 +- examples/reactrouter/server.ts | 6 +- examples/transloadit/package.json | 2 +- examples/xhr-bundle/package.json | 2 +- packages/@uppy/aws-s3/src/index.ts | 9 +- packages/@uppy/companion/package.json | 4 +- packages/@uppy/companion/src/companion.ts | 11 +- .../src/server/controllers/callback.ts | 2 +- .../companion/src/server/controllers/list.ts | 5 +- .../src/server/controllers/preauth.ts | 2 +- .../src/server/controllers/refresh-token.ts | 2 +- .../companion/src/server/controllers/s3.ts | 24 +- .../src/server/controllers/simple-auth.ts | 2 +- .../src/server/controllers/thumbnail.ts | 2 +- .../@uppy/companion/src/server/middlewares.ts | 8 +- .../companion/src/standalone/start-server.ts | 8 +- .../@uppy/companion/test/companion.test.ts | 22 - packages/@uppy/companion/test/cors.test.ts | 2 +- packages/@uppy/companion/test/mockserver.ts | 23 +- yarn.lock | 2611 ++++++++++++++--- 27 files changed, 2332 insertions(+), 439 deletions(-) delete mode 100644 .changeset/happy-timers-kick.md delete mode 100644 .changeset/smooth-chefs-occur.md diff --git a/.changeset/happy-timers-kick.md b/.changeset/happy-timers-kick.md deleted file mode 100644 index d06fc6eb1..000000000 --- a/.changeset/happy-timers-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/aws-s3": patch ---- - -Improve type diff --git a/.changeset/smooth-chefs-occur.md b/.changeset/smooth-chefs-occur.md deleted file mode 100644 index 66a598445..000000000 --- a/.changeset/smooth-chefs-occur.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/companion": major ---- - -Upgrade to express 5 - Companion no longer works when used as a middleware with Express 4. diff --git a/examples/aws-companion/package.json b/examples/aws-companion/package.json index 0fe81edb2..f061bbcdb 100644 --- a/examples/aws-companion/package.json +++ b/examples/aws-companion/package.json @@ -15,7 +15,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "dotenv": "^16.0.1", - "express": "^5.2.1", + "express": "^4.22.0", "express-session": "^1.17.3", "npm-run-all": "^4.1.5", "vite": "^7.1.11" diff --git a/examples/aws-nodejs/package.json b/examples/aws-nodejs/package.json index bdc013ed0..cfcbde2a1 100644 --- a/examples/aws-nodejs/package.json +++ b/examples/aws-nodejs/package.json @@ -15,6 +15,6 @@ "@aws-sdk/s3-request-presigner": "^3.338.0", "body-parser": "^1.20.4", "dotenv": "^16.0.0", - "express": "^5.2.1" + "express": "^4.22.0" } } diff --git a/examples/companion-custom-provider/package.json b/examples/companion-custom-provider/package.json index fdf0e4205..6d6c08c18 100644 --- a/examples/companion-custom-provider/package.json +++ b/examples/companion-custom-provider/package.json @@ -19,7 +19,7 @@ "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", "dotenv": "^16.0.1", - "express": "^5.2.1", + "express": "^4.22.0", "express-session": "^1.15.6", "npm-run-all": "^4.1.2", "vite": "^7.1.11" diff --git a/examples/companion-digitalocean-spaces/package.json b/examples/companion-digitalocean-spaces/package.json index 4a99539a7..b308f3455 100644 --- a/examples/companion-digitalocean-spaces/package.json +++ b/examples/companion-digitalocean-spaces/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "dotenv": "^16.0.1", - "express": "^5.2.1", + "express": "^4.22.0", "vite": "^7.1.11" }, "private": true, diff --git a/examples/companion/package.json b/examples/companion/package.json index a85a0b826..f517ffb97 100644 --- a/examples/companion/package.json +++ b/examples/companion/package.json @@ -4,7 +4,7 @@ "dependencies": { "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", - "express": "^5.2.1", + "express": "^4.22.0", "express-session": "^1.15.6", "light-server": "^2.4.0" }, diff --git a/examples/reactrouter/package.json b/examples/reactrouter/package.json index 4420f7540..c6849a34e 100644 --- a/examples/reactrouter/package.json +++ b/examples/reactrouter/package.json @@ -20,14 +20,14 @@ "@uppy/transloadit": "workspace:*", "@uppy/tus": "workspace:*", "@uppy/xhr-upload": "workspace:*", - "express": "^5.2.1", + "express": "^4.22.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router": "^7.12.0" }, "devDependencies": { "@react-router/dev": "^7.12.0", - "@types/express": "^5.0.6", + "@types/express": "^4.17.20", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "tsx": "^4.0.0", diff --git a/examples/reactrouter/server.ts b/examples/reactrouter/server.ts index 8e9c30392..80ee0542c 100644 --- a/examples/reactrouter/server.ts +++ b/examples/reactrouter/server.ts @@ -41,9 +41,7 @@ async function startServer() { // TUS upload endpoints (before React Router) app.all('/api/upload/tus', (req, res) => tusServer.handle(req, res)) - app.all('/api/upload/tus/{*splat}', (req, res) => - tusServer.handle(req, res), - ) + app.all('/api/upload/tus/*', (req, res) => tusServer.handle(req, res)) // Handle Chrome DevTools requests silently app.get('/.well-known/appspecific/com.chrome.devtools.json', (req, res) => { @@ -51,7 +49,7 @@ async function startServer() { }) // React Router handles all other routes - app.all('/{*splat}', reactRouterHandler) + app.all('*', reactRouterHandler) const port = process.env.PORT || 3000 const server = app.listen(port, () => { diff --git a/examples/transloadit/package.json b/examples/transloadit/package.json index bb08b521e..6072b43ab 100644 --- a/examples/transloadit/package.json +++ b/examples/transloadit/package.json @@ -15,7 +15,7 @@ "@uppy/remote-sources": "workspace:*", "@uppy/transloadit": "workspace:*", "@uppy/webcam": "workspace:*", - "express": "^5.2.1", + "express": "^4.22.0", "he": "^1.2.0" }, "private": true, diff --git a/examples/xhr-bundle/package.json b/examples/xhr-bundle/package.json index cd36e6bbb..249ae1a63 100644 --- a/examples/xhr-bundle/package.json +++ b/examples/xhr-bundle/package.json @@ -6,7 +6,7 @@ "@uppy/dashboard": "workspace:*", "@uppy/xhr-upload": "workspace:*", "cors": "^2.8.5", - "express": "^5.2.1", + "express": "^4.22.0", "multer": "^2.0.2" }, "devDependencies": { diff --git a/packages/@uppy/aws-s3/src/index.ts b/packages/@uppy/aws-s3/src/index.ts index e1afe29c1..d248f4c5b 100644 --- a/packages/@uppy/aws-s3/src/index.ts +++ b/packages/@uppy/aws-s3/src/index.ts @@ -662,11 +662,10 @@ export default class AwsS3Multipart< querify: true, }) - const query = new URLSearchParams({ - filename, - ...(type != null && { type }), - ...metadata, - }) + const query = new URLSearchParams({ filename, type, ...metadata } as Record< + string, + string + >) return this.#client.get(`s3/params?${query}`, options) } diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 02e389eec..42ed317f6 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -47,9 +47,9 @@ "cors": "^2.8.5", "escape-goat": "3.0.0", "escape-string-regexp": "4.0.0", - "express": "^5.2.1", + "express": "4.21.2", "express-interceptor": "1.2.0", - "express-prom-bundle": "^8.0.0", + "express-prom-bundle": "7", "express-session": "1.18.1", "fast-safe-stringify": "^2.1.1", "formdata-node": "^6.0.3", diff --git a/packages/@uppy/companion/src/companion.ts b/packages/@uppy/companion/src/companion.ts index 290b66561..ab32d7d64 100644 --- a/packages/@uppy/companion/src/companion.ts +++ b/packages/@uppy/companion/src/companion.ts @@ -125,9 +125,6 @@ export function app(optionsArg: CompanionInitOptions) { const app = express() - // Needed for e.g. s3 `/params` endpoint metadata, like `metadata[key]=value` to be parsed into a metadata object - app.set('query parser', 'extended') - if (options.metrics) { app.use(middlewares.metrics({ path: options.server.path })) } @@ -139,10 +136,10 @@ export function app(optionsArg: CompanionInitOptions) { app.use(interceptGrantErrorResponse) // override provider credentials at request time - // Making `POST` request to the `/connect/:provider{/:override}` route requires a form body parser middleware: + // Making `POST` request to the `/connect/:provider/:override?` route requires a form body parser middleware: // See https://github.com/simov/grant#dynamic-http app.use( - '/connect/:oauthProvider{/:override}', + '/connect/:oauthProvider/:override?', express.urlencoded({ extended: false }), getCredentialsOverrideMiddleware( providers as Record, @@ -162,7 +159,7 @@ export function app(optionsArg: CompanionInitOptions) { app.use(middlewares.cors(options)) // add uppy options to the request object so it can be accessed by subsequent handlers. - app.use(middlewares.getCompanionMiddleware(options)) + app.use('*', middlewares.getCompanionMiddleware(options)) app.use('/s3', s3(options.s3)) if (options.enableUrlEndpoint) app.use('/url', url()) if (options.enableGooglePickerEndpoint) @@ -235,7 +232,7 @@ export function app(optionsArg: CompanionInitOptions) { ) app.get( - '/:providerName/list{/:id}', + '/:providerName/list/:id?', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.list, diff --git a/packages/@uppy/companion/src/server/controllers/callback.ts b/packages/@uppy/companion/src/server/controllers/callback.ts index 83a2b96e6..7e1ab3a69 100644 --- a/packages/@uppy/companion/src/server/controllers/callback.ts +++ b/packages/@uppy/companion/src/server/controllers/callback.ts @@ -20,7 +20,7 @@ export default function callback( const providerName = req.params['providerName'] const { companion } = req - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/list.ts b/packages/@uppy/companion/src/server/controllers/list.ts index 8c7f7e244..f6acfa4d3 100644 --- a/packages/@uppy/companion/src/server/controllers/list.ts +++ b/packages/@uppy/companion/src/server/controllers/list.ts @@ -7,9 +7,8 @@ export default async function list( next: NextFunction, ): Promise { const { query, params, companion } = req - const id = params['id'] const { providerUserSession, provider } = companion - if (!provider || (typeof id !== 'string' && id != null)) { + if (!provider) { res.sendStatus(400) return } @@ -18,7 +17,7 @@ export default async function list( const data = await provider.list({ companion, providerUserSession, - directory: id, + directory: params['id'], query, }) res.json(data) diff --git a/packages/@uppy/companion/src/server/controllers/preauth.ts b/packages/@uppy/companion/src/server/controllers/preauth.ts index 210058e2b..e3b30a226 100644 --- a/packages/@uppy/companion/src/server/controllers/preauth.ts +++ b/packages/@uppy/companion/src/server/controllers/preauth.ts @@ -14,7 +14,7 @@ export default function preauth(req: Request, res: Response): void { } const providerName = req.params['providerName'] - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/refresh-token.ts b/packages/@uppy/companion/src/server/controllers/refresh-token.ts index e8e513dcb..c6d5ab5ac 100644 --- a/packages/@uppy/companion/src/server/controllers/refresh-token.ts +++ b/packages/@uppy/companion/src/server/controllers/refresh-token.ts @@ -12,7 +12,7 @@ export default async function refreshToken( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/s3.ts b/packages/@uppy/companion/src/server/controllers/s3.ts index e9bf0e9fc..dcfd4c4a1 100644 --- a/packages/@uppy/companion/src/server/controllers/s3.ts +++ b/packages/@uppy/companion/src/server/controllers/s3.ts @@ -1,4 +1,3 @@ -import assert from 'node:assert' import type { Part, S3Client } from '@aws-sdk/client-s3' import { AbortMultipartUploadCommand, @@ -248,11 +247,6 @@ export default function s3( const { uploadId } = req.params const { key } = req.query - assert( - typeof uploadId === 'string' && uploadId.length > 0, - 's3: uploadId must be provided.', - ) - if (typeof key !== 'string') { res.status(400).json({ error: @@ -266,7 +260,7 @@ export default function s3( const parts: Part[] = [] - const listPartsPage = (startAt?: string) => { + function listPartsPage(startAt?: string) { s3Client .send( new ListPartsCommand({ @@ -309,7 +303,7 @@ export default function s3( const partNumber = req.params['partNumber'] const key = req.query['key'] - if (typeof uploadId !== 'string' || uploadId.length === 0) { + if (uploadId == null || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -320,7 +314,7 @@ export default function s3( }) return } - if (typeof partNumber !== 'string' || !parseInt(partNumber, 10)) { + if (partNumber == null || !parseInt(partNumber, 10)) { res.status(400).json({ error: 's3: the part number must be a number between 1 and 10000.', }) @@ -369,7 +363,7 @@ export default function s3( const key = req.query['key'] const partNumbers = req.query['partNumbers'] - if (typeof uploadId !== 'string' || uploadId.length === 0) { + if (uploadId == null || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -449,11 +443,6 @@ export default function s3( const { uploadId } = req.params const { key } = req.query - assert( - typeof uploadId === 'string' && uploadId.length > 0, - 's3: uploadId must be provided.', - ) - if (typeof key !== 'string') { res.status(400).json({ error: @@ -499,11 +488,6 @@ export default function s3( const { key } = req.query const { parts }: { parts: unknown } = req.body - assert( - typeof uploadId === 'string' && uploadId.length > 0, - 's3: uploadId must be provided.', - ) - if (typeof key !== 'string') { res.status(400).json({ error: diff --git a/packages/@uppy/companion/src/server/controllers/simple-auth.ts b/packages/@uppy/companion/src/server/controllers/simple-auth.ts index 6ddef8af2..c1171356c 100644 --- a/packages/@uppy/companion/src/server/controllers/simple-auth.ts +++ b/packages/@uppy/companion/src/server/controllers/simple-auth.ts @@ -9,7 +9,7 @@ export default async function simpleAuth( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/thumbnail.ts b/packages/@uppy/companion/src/server/controllers/thumbnail.ts index 03abf9dea..bae18cafd 100644 --- a/packages/@uppy/companion/src/server/controllers/thumbnail.ts +++ b/packages/@uppy/companion/src/server/controllers/thumbnail.ts @@ -7,7 +7,7 @@ async function thumbnail( next: NextFunction, ): Promise { const id = req.params['id'] - if (typeof id !== 'string' || id.length === 0) { + if (id == null) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/middlewares.ts b/packages/@uppy/companion/src/server/middlewares.ts index 92def8aee..4dd3103b6 100644 --- a/packages/@uppy/companion/src/server/middlewares.ts +++ b/packages/@uppy/companion/src/server/middlewares.ts @@ -97,7 +97,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { } const { secret } = req.companion.options const providerName = req.params['providerName'] - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null || providerName.length === 0) { res.sendStatus(400) return } @@ -124,9 +124,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { const { providerOptions } = req.companion.options const providerName = req.params['providerName'] const providerOption = - typeof providerName === 'string' - ? providerOptions?.[providerName] - : undefined + providerName != null ? providerOptions?.[providerName] : undefined const key = providerOption?.key if (!key) { logger.info( @@ -148,7 +146,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { // does not fail if token is invalid export const gentleVerifyToken: RequestHandler = (req, res, next) => { const providerName = req.params['providerName'] - if (typeof providerName !== 'string' || providerName.length === 0) { + if (providerName == null || providerName.length === 0) { next() return } diff --git a/packages/@uppy/companion/src/standalone/start-server.ts b/packages/@uppy/companion/src/standalone/start-server.ts index fcc54347a..ec4dc713b 100644 --- a/packages/@uppy/companion/src/standalone/start-server.ts +++ b/packages/@uppy/companion/src/standalone/start-server.ts @@ -9,9 +9,7 @@ const port: string | number = const { app, companionOptions } = standalone() -const server = app.listen(port, () => { - logger.info(`Welcome to Companion! v${packageJson.version}`) - logger.info(`Listening on http://localhost:${port}`) +companion.socket(app.listen(port), companionOptions) - companion.socket(server, companionOptions) -}) +logger.info(`Welcome to Companion! v${packageJson.version}`) +logger.info(`Listening on http://localhost:${port}`) diff --git a/packages/@uppy/companion/test/companion.test.ts b/packages/@uppy/companion/test/companion.test.ts index 4eef1110b..be3f458a6 100644 --- a/packages/@uppy/companion/test/companion.test.ts +++ b/packages/@uppy/companion/test/companion.test.ts @@ -426,26 +426,4 @@ describe('S3 controller', () => { ), ) }) - - test('getUploadParameters supports bracket metadata query format', async () => { - const server = await getServer({ - COMPANION_AWS_KEY: 'test_key', - COMPANION_AWS_SECRET: 'test_secret', - COMPANION_AWS_BUCKET: 'test-bucket', - COMPANION_AWS_REGION: 'us-east-1', - }) - - return request(server) - .get('/s3/params') - .query({ - filename: 'test.txt', - type: 'text/plain', - 'metadata[name]': 'demo-file', - }) - .expect(200) - .then((res) => { - const fields = res.body.fields as Record - expect(fields['x-amz-meta-name']).toBe('demo-file') - }) - }) }) diff --git a/packages/@uppy/companion/test/cors.test.ts b/packages/@uppy/companion/test/cors.test.ts index 3abb2cff9..6e3bc58f6 100644 --- a/packages/@uppy/companion/test/cors.test.ts +++ b/packages/@uppy/companion/test/cors.test.ts @@ -19,7 +19,7 @@ async function run({ next() }) app.use(cors(corsOptions)) - app.options('/{*splat}', (_req, res) => { + app.options('*', (_req, res) => { res.status(204).end() }) diff --git a/packages/@uppy/companion/test/mockserver.ts b/packages/@uppy/companion/test/mockserver.ts index 4effa2983..1a66514ca 100644 --- a/packages/@uppy/companion/test/mockserver.ts +++ b/packages/@uppy/companion/test/mockserver.ts @@ -101,7 +101,7 @@ export const getServerWithEmitter = async ( authServer.use( session({ secret: 'grant', resave: true, saveUninitialized: true }), ) - authServer.all('{*splat}/callback', (req, res, next) => { + authServer.all('*/callback', (req, res, next) => { if (req.session) { req.session['grant'] = { response: { access_token: grantToken }, @@ -109,19 +109,16 @@ export const getServerWithEmitter = async ( } next() }) - authServer.all( - ['{*splat}/send-token', '{*splat}/redirect'], - (req, res, next) => { - const state = - typeof req.query['state'] === 'string' ? req.query['state'] : null - if (req.session) { - req.session['grant'] = { - dynamic: { state: state ?? 'non-empty-value' }, - } + authServer.all(['*/send-token', '*/redirect'], (req, res, next) => { + const state = + typeof req.query['state'] === 'string' ? req.query['state'] : null + if (req.session) { + req.session['grant'] = { + dynamic: { state: state ?? 'non-empty-value' }, } - next() - }, - ) + } + next() + }) const { app, emitter } = standalone() authServer.use(app) diff --git a/yarn.lock b/yarn.lock index 049829d74..3f12ff7b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -509,7 +509,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:3.986.0, @aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": +"@aws-sdk/client-s3@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/client-s3@npm:3.986.0" dependencies: @@ -572,6 +572,211 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": + version: 3.896.0 + resolution: "@aws-sdk/client-s3@npm:3.896.0" + dependencies: + "@aws-crypto/sha1-browser": "npm:5.2.0" + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/credential-provider-node": "npm:3.896.0" + "@aws-sdk/middleware-bucket-endpoint": "npm:3.893.0" + "@aws-sdk/middleware-expect-continue": "npm:3.893.0" + "@aws-sdk/middleware-flexible-checksums": "npm:3.896.0" + "@aws-sdk/middleware-host-header": "npm:3.893.0" + "@aws-sdk/middleware-location-constraint": "npm:3.893.0" + "@aws-sdk/middleware-logger": "npm:3.893.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" + "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" + "@aws-sdk/middleware-ssec": "npm:3.893.0" + "@aws-sdk/middleware-user-agent": "npm:3.896.0" + "@aws-sdk/region-config-resolver": "npm:3.893.0" + "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-endpoints": "npm:3.895.0" + "@aws-sdk/util-user-agent-browser": "npm:3.893.0" + "@aws-sdk/util-user-agent-node": "npm:3.896.0" + "@aws-sdk/xml-builder": "npm:3.894.0" + "@smithy/config-resolver": "npm:^4.2.2" + "@smithy/core": "npm:^3.12.0" + "@smithy/eventstream-serde-browser": "npm:^4.1.1" + "@smithy/eventstream-serde-config-resolver": "npm:^4.2.1" + "@smithy/eventstream-serde-node": "npm:^4.1.1" + "@smithy/fetch-http-handler": "npm:^5.2.1" + "@smithy/hash-blob-browser": "npm:^4.1.1" + "@smithy/hash-node": "npm:^4.1.1" + "@smithy/hash-stream-node": "npm:^4.1.1" + "@smithy/invalid-dependency": "npm:^4.1.1" + "@smithy/md5-js": "npm:^4.1.1" + "@smithy/middleware-content-length": "npm:^4.1.1" + "@smithy/middleware-endpoint": "npm:^4.2.4" + "@smithy/middleware-retry": "npm:^4.3.0" + "@smithy/middleware-serde": "npm:^4.1.1" + "@smithy/middleware-stack": "npm:^4.1.1" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/node-http-handler": "npm:^4.2.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-body-length-browser": "npm:^4.1.0" + "@smithy/util-body-length-node": "npm:^4.1.0" + "@smithy/util-defaults-mode-browser": "npm:^4.1.4" + "@smithy/util-defaults-mode-node": "npm:^4.1.4" + "@smithy/util-endpoints": "npm:^3.1.2" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-retry": "npm:^4.1.2" + "@smithy/util-stream": "npm:^4.3.2" + "@smithy/util-utf8": "npm:^4.1.0" + "@smithy/util-waiter": "npm:^4.1.1" + "@smithy/uuid": "npm:^1.0.0" + tslib: "npm:^2.6.2" + checksum: 10/4a65786cd019e0fee172f7da37aab882e39669052e239a284bd1409877c394949779ba909ed5596caa4e12586b9d466099a8d596f8a5019f7eb4bc2dfcf89ba8 + languageName: node + linkType: hard + +"@aws-sdk/client-sso-oidc@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.600.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/client-sts": "npm:3.600.0" + "@aws-sdk/core": "npm:3.598.0" + "@aws-sdk/credential-provider-node": "npm:3.600.0" + "@aws-sdk/middleware-host-header": "npm:3.598.0" + "@aws-sdk/middleware-logger": "npm:3.598.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" + "@aws-sdk/middleware-user-agent": "npm:3.598.0" + "@aws-sdk/region-config-resolver": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@aws-sdk/util-endpoints": "npm:3.598.0" + "@aws-sdk/util-user-agent-browser": "npm:3.598.0" + "@aws-sdk/util-user-agent-node": "npm:3.598.0" + "@smithy/config-resolver": "npm:^3.0.2" + "@smithy/core": "npm:^2.2.1" + "@smithy/fetch-http-handler": "npm:^3.0.2" + "@smithy/hash-node": "npm:^3.0.1" + "@smithy/invalid-dependency": "npm:^3.0.1" + "@smithy/middleware-content-length": "npm:^3.0.1" + "@smithy/middleware-endpoint": "npm:^3.0.2" + "@smithy/middleware-retry": "npm:^3.0.4" + "@smithy/middleware-serde": "npm:^3.0.1" + "@smithy/middleware-stack": "npm:^3.0.1" + "@smithy/node-config-provider": "npm:^3.1.1" + "@smithy/node-http-handler": "npm:^3.0.1" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/smithy-client": "npm:^3.1.2" + "@smithy/types": "npm:^3.1.0" + "@smithy/url-parser": "npm:^3.0.1" + "@smithy/util-base64": "npm:^3.0.0" + "@smithy/util-body-length-browser": "npm:^3.0.0" + "@smithy/util-body-length-node": "npm:^3.0.0" + "@smithy/util-defaults-mode-browser": "npm:^3.0.4" + "@smithy/util-defaults-mode-node": "npm:^3.0.4" + "@smithy/util-endpoints": "npm:^2.0.2" + "@smithy/util-middleware": "npm:^3.0.1" + "@smithy/util-retry": "npm:^3.0.1" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/66343fc13ffd5d412ca2232a91dce14ee287ed611fb27cd1fe887bb36bf380d585c74473251bd9d688fab51b4f9bd4375bf7d8583effb3d07c6ac5f7cb85c597 + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/client-sso@npm:3.598.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:3.598.0" + "@aws-sdk/middleware-host-header": "npm:3.598.0" + "@aws-sdk/middleware-logger": "npm:3.598.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" + "@aws-sdk/middleware-user-agent": "npm:3.598.0" + "@aws-sdk/region-config-resolver": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@aws-sdk/util-endpoints": "npm:3.598.0" + "@aws-sdk/util-user-agent-browser": "npm:3.598.0" + "@aws-sdk/util-user-agent-node": "npm:3.598.0" + "@smithy/config-resolver": "npm:^3.0.2" + "@smithy/core": "npm:^2.2.1" + "@smithy/fetch-http-handler": "npm:^3.0.2" + "@smithy/hash-node": "npm:^3.0.1" + "@smithy/invalid-dependency": "npm:^3.0.1" + "@smithy/middleware-content-length": "npm:^3.0.1" + "@smithy/middleware-endpoint": "npm:^3.0.2" + "@smithy/middleware-retry": "npm:^3.0.4" + "@smithy/middleware-serde": "npm:^3.0.1" + "@smithy/middleware-stack": "npm:^3.0.1" + "@smithy/node-config-provider": "npm:^3.1.1" + "@smithy/node-http-handler": "npm:^3.0.1" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/smithy-client": "npm:^3.1.2" + "@smithy/types": "npm:^3.1.0" + "@smithy/url-parser": "npm:^3.0.1" + "@smithy/util-base64": "npm:^3.0.0" + "@smithy/util-body-length-browser": "npm:^3.0.0" + "@smithy/util-body-length-node": "npm:^3.0.0" + "@smithy/util-defaults-mode-browser": "npm:^3.0.4" + "@smithy/util-defaults-mode-node": "npm:^3.0.4" + "@smithy/util-endpoints": "npm:^2.0.2" + "@smithy/util-middleware": "npm:^3.0.1" + "@smithy/util-retry": "npm:^3.0.1" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/6571a678ae4e0c42c245a2e7b969d5d2e4713dc5fe7604e5edc883a6f729362d1256f1c144094f8146e0fd85da675533c0e460c5217b1d17aecb2042201e169e + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/client-sso@npm:3.896.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/middleware-host-header": "npm:3.893.0" + "@aws-sdk/middleware-logger": "npm:3.893.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" + "@aws-sdk/middleware-user-agent": "npm:3.896.0" + "@aws-sdk/region-config-resolver": "npm:3.893.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-endpoints": "npm:3.895.0" + "@aws-sdk/util-user-agent-browser": "npm:3.893.0" + "@aws-sdk/util-user-agent-node": "npm:3.896.0" + "@smithy/config-resolver": "npm:^4.2.2" + "@smithy/core": "npm:^3.12.0" + "@smithy/fetch-http-handler": "npm:^5.2.1" + "@smithy/hash-node": "npm:^4.1.1" + "@smithy/invalid-dependency": "npm:^4.1.1" + "@smithy/middleware-content-length": "npm:^4.1.1" + "@smithy/middleware-endpoint": "npm:^4.2.4" + "@smithy/middleware-retry": "npm:^4.3.0" + "@smithy/middleware-serde": "npm:^4.1.1" + "@smithy/middleware-stack": "npm:^4.1.1" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/node-http-handler": "npm:^4.2.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-body-length-browser": "npm:^4.1.0" + "@smithy/util-body-length-node": "npm:^4.1.0" + "@smithy/util-defaults-mode-browser": "npm:^4.1.4" + "@smithy/util-defaults-mode-node": "npm:^4.1.4" + "@smithy/util-endpoints": "npm:^3.1.2" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-retry": "npm:^4.1.2" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/0358688ecd1ac7ce0d451af66ce9c72ca9f7e750f029f5be4450946b8a07d6f52458262e60fdd6c4817ee94e9337a7235ec9bbe58085c6bfef24ed1641772c81 + languageName: node + linkType: hard + "@aws-sdk/client-sso@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/client-sso@npm:3.985.0" @@ -618,7 +823,55 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.986.0, @aws-sdk/client-sts@npm:^3.338.0": +"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.338.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sts@npm:3.600.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/client-sso-oidc": "npm:3.600.0" + "@aws-sdk/core": "npm:3.598.0" + "@aws-sdk/credential-provider-node": "npm:3.600.0" + "@aws-sdk/middleware-host-header": "npm:3.598.0" + "@aws-sdk/middleware-logger": "npm:3.598.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" + "@aws-sdk/middleware-user-agent": "npm:3.598.0" + "@aws-sdk/region-config-resolver": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@aws-sdk/util-endpoints": "npm:3.598.0" + "@aws-sdk/util-user-agent-browser": "npm:3.598.0" + "@aws-sdk/util-user-agent-node": "npm:3.598.0" + "@smithy/config-resolver": "npm:^3.0.2" + "@smithy/core": "npm:^2.2.1" + "@smithy/fetch-http-handler": "npm:^3.0.2" + "@smithy/hash-node": "npm:^3.0.1" + "@smithy/invalid-dependency": "npm:^3.0.1" + "@smithy/middleware-content-length": "npm:^3.0.1" + "@smithy/middleware-endpoint": "npm:^3.0.2" + "@smithy/middleware-retry": "npm:^3.0.4" + "@smithy/middleware-serde": "npm:^3.0.1" + "@smithy/middleware-stack": "npm:^3.0.1" + "@smithy/node-config-provider": "npm:^3.1.1" + "@smithy/node-http-handler": "npm:^3.0.1" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/smithy-client": "npm:^3.1.2" + "@smithy/types": "npm:^3.1.0" + "@smithy/url-parser": "npm:^3.0.1" + "@smithy/util-base64": "npm:^3.0.0" + "@smithy/util-body-length-browser": "npm:^3.0.0" + "@smithy/util-body-length-node": "npm:^3.0.0" + "@smithy/util-defaults-mode-browser": "npm:^3.0.4" + "@smithy/util-defaults-mode-node": "npm:^3.0.4" + "@smithy/util-endpoints": "npm:^2.0.2" + "@smithy/util-middleware": "npm:^3.0.1" + "@smithy/util-retry": "npm:^3.0.1" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/1b955f0ceacdb7e0a0a15ce588aa7b0a796eae8591c195a9a1db601d6efeec504d7ad07189c4baedba0e8e888e4cbab770d6d9e54de9d07d166247f6f0df7c9a + languageName: node + linkType: hard + +"@aws-sdk/client-sts@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/client-sts@npm:3.986.0" dependencies: @@ -665,6 +918,42 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/core@npm:3.598.0" + dependencies: + "@smithy/core": "npm:^2.2.1" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/signature-v4": "npm:^3.1.0" + "@smithy/smithy-client": "npm:^3.1.2" + "@smithy/types": "npm:^3.1.0" + fast-xml-parser: "npm:4.2.5" + tslib: "npm:^2.6.2" + checksum: 10/6c27302636d6e4c9382590be9d39e1ff2023c92a7aaa78117428d8af9be614ded56c7db2e9a016452144f4f6d81e6b09c81e29ad53df5fa9d506aa0548211f7c + languageName: node + linkType: hard + +"@aws-sdk/core@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/core@npm:3.896.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/xml-builder": "npm:3.894.0" + "@smithy/core": "npm:^3.12.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/signature-v4": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/48576dfb4060e802faec525b8553cbaeed5aa735ac3bdc292e14fae92261978b4f022197863e284c3cb49f86e638b967e0b76f346adc04b56a5d3aa7d5d1f370 + languageName: node + linkType: hard + "@aws-sdk/core@npm:^3.973.7": version: 3.973.7 resolution: "@aws-sdk/core@npm:3.973.7" @@ -696,6 +985,31 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/79c6391aad109d9749b60516dcc425e923a730bf6239d5b41192612fc2658d6fdbcd48b48277076ca7c6db61103164fe305fdc4271994713128d4ec27d32236a + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/82a771fd5b81f67f56816313ae598496676fad60d147c9adebf7557a0e808129c155f3bf6349a10362a16293ea5290d8c96160ba7fe0598c80756b65e2810278 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-env@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-env@npm:3.972.5" @@ -709,6 +1023,41 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/fetch-http-handler": "npm:^3.0.2" + "@smithy/node-http-handler": "npm:^3.0.1" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/smithy-client": "npm:^3.1.2" + "@smithy/types": "npm:^3.1.0" + "@smithy/util-stream": "npm:^3.0.2" + tslib: "npm:^2.6.2" + checksum: 10/e8411e33faec1798a2e50166cd1777b4becd2ff07ec97d044424faf1db3a2e97d8b4ee8c43d0b4e763d94dfb8971f0542b160e69a94ca38b175c8227e4f71904 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/fetch-http-handler": "npm:^5.2.1" + "@smithy/node-http-handler": "npm:^4.2.1" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-stream": "npm:^4.3.2" + tslib: "npm:^2.6.2" + checksum: 10/c2dfd4ff720d8b6dd1e3f05899c73056a0babe8f7d4b6c45aa6a6bf1afe19d1609db0bfa1e47266e69024f46941b0f35175c76bd3bdbbbd1b3723039a96e20d5 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/credential-provider-http@npm:3.972.7" @@ -727,6 +1076,48 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" + dependencies: + "@aws-sdk/credential-provider-env": "npm:3.598.0" + "@aws-sdk/credential-provider-http": "npm:3.598.0" + "@aws-sdk/credential-provider-process": "npm:3.598.0" + "@aws-sdk/credential-provider-sso": "npm:3.598.0" + "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@smithy/credential-provider-imds": "npm:^3.1.1" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/shared-ini-file-loader": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: 10/2f3aa54850dc1da4732d1dbc5a8e6ec095107ff08c46af4bffec41e1535a9c9a320586386f67358dd0acec83069dbb2b420bbd09412aa56993d088eb08ffef2b + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/credential-provider-env": "npm:3.896.0" + "@aws-sdk/credential-provider-http": "npm:3.896.0" + "@aws-sdk/credential-provider-process": "npm:3.896.0" + "@aws-sdk/credential-provider-sso": "npm:3.896.0" + "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" + "@aws-sdk/nested-clients": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/credential-provider-imds": "npm:^4.1.2" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/b727580a5ad0d8062ad6d374983d49999d68ef19bcd4cb28df66bfb8dba101e4be94f9c7c9f73fabe79519e0d09b4352a19530a9c29165e8357301296f6c435d + languageName: node + linkType: hard + "@aws-sdk/credential-provider-ini@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-ini@npm:3.972.5" @@ -765,6 +1156,46 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" + dependencies: + "@aws-sdk/credential-provider-env": "npm:3.598.0" + "@aws-sdk/credential-provider-http": "npm:3.598.0" + "@aws-sdk/credential-provider-ini": "npm:3.598.0" + "@aws-sdk/credential-provider-process": "npm:3.598.0" + "@aws-sdk/credential-provider-sso": "npm:3.598.0" + "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@smithy/credential-provider-imds": "npm:^3.1.1" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/shared-ini-file-loader": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/b5ab56a5c8acd566f41ba834214718a0ab8825090fe71b0ecc4ebec5e76de3afa47387ab99d061f3ac6ecd5ead9af621d7311ffa0a6b16df312f3c9de311747d + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.896.0" + dependencies: + "@aws-sdk/credential-provider-env": "npm:3.896.0" + "@aws-sdk/credential-provider-http": "npm:3.896.0" + "@aws-sdk/credential-provider-ini": "npm:3.896.0" + "@aws-sdk/credential-provider-process": "npm:3.896.0" + "@aws-sdk/credential-provider-sso": "npm:3.896.0" + "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/credential-provider-imds": "npm:^4.1.2" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/161f6bab93a3980deed49e328bdfd9a98ef0c998f0258caa4b3bfd26c436d9d4db56d9b6ef9bf7aa6012e4f8b1891d7cf5a3c0df8c5ca90d1eddb95fae28697f + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:^3.972.6": version: 3.972.6 resolution: "@aws-sdk/credential-provider-node@npm:3.972.6" @@ -785,6 +1216,33 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/shared-ini-file-loader": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/c0f9aa2304e273460b93efa7a09664d69e3dcdf6983d789a83bbc77a7975dddc7db915caaccf922f459eaad7b0ed546d1d79bcf0354898bca7c141fc49f5809b + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/1ea8e99cf5fc37c5c11330bf6e1cbb2a879ff61a335bdc6bf0d4dbeb64366e7232b6dd6f4dfe88718790ab07ecb0bb0814c67f59ed4d0a489b7074833e1defa5 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-process@npm:3.972.5" @@ -799,6 +1257,37 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" + dependencies: + "@aws-sdk/client-sso": "npm:3.598.0" + "@aws-sdk/token-providers": "npm:3.598.0" + "@aws-sdk/types": "npm:3.598.0" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/shared-ini-file-loader": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/19e6d8390a7824f921ee63105563857171404a09b7e7df1e9ad99a2ef334cc05cd1ae6d95f5a975fb328f5b53713cb1cb228d92b4966a7a8e9afc15637de66de + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.896.0" + dependencies: + "@aws-sdk/client-sso": "npm:3.896.0" + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/token-providers": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/f4c0dcc6efa354d3f151bdb73f6b5f6a68a45e90290621b9b70dd9a7d0e59e911b685cad597d6da2ed170d399ec7d469afc7a70f0d00c5ae409153231aee3c60 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.5" @@ -815,6 +1304,35 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: 10/76cf4e389dc565402f1ba0b9c65983590e98435a17ed291d6b15412dac27aea7e35f23036675f76f2a267f8375de616550be759136bf2ff7d63211a22535bbf2 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/nested-clients": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/460c098de6f26a86b394a4241abf9f93a61d40ac5898f667716c0a3dbb1d6214ba42f3fdefc6a5e40a4d730eb1b0c6ff51d2b3fd10099670734e44bc133d20d6 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.5" @@ -847,6 +1365,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-bucket-endpoint@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-arn-parser": "npm:3.893.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-config-provider": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/214fa89d2ed8b699c18d967cc158a77ec24f14b7d70fac80bdaa32940d8d737398a633787fee8efd7456a821f7f3c17f25a4d5db93f274ed071a428c04ad76e9 + languageName: node + linkType: hard + "@aws-sdk/middleware-bucket-endpoint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.3" @@ -862,6 +1395,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-expect-continue@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/722f38a646b302ae238d254c8a55a5d6fb124ad8b30f29d226c06761cfbc050c798595891c16a2fd78d4ec5e7a0431eef9c8a20c28c73fcb118db66afa9c3491 + languageName: node + linkType: hard + "@aws-sdk/middleware-expect-continue@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.3" @@ -874,6 +1419,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-flexible-checksums@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.896.0" + dependencies: + "@aws-crypto/crc32": "npm:5.2.0" + "@aws-crypto/crc32c": "npm:5.2.0" + "@aws-crypto/util": "npm:5.2.0" + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/is-array-buffer": "npm:^4.1.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-stream": "npm:^4.3.2" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/16918d316a8cac38742889065c254c6f5ec33da6dbba6667409ee5fd84b3aeb90161405b4098ec98a9f60f769944e3394eae3bce01e7de51797940b12449889d + languageName: node + linkType: hard + "@aws-sdk/middleware-flexible-checksums@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.972.5" @@ -896,6 +1462,30 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-host-header@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/53498c94fd769dbee727ba4148d67578d2073fd83217695106e9dd3b572e56aa0362c329da4c13e39a0aaef45597cc7988b8951f2df4d28dc7c29461fa3791cc + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/600afe3361abab4e6448a6c61ad94623be0c52169cc7e972d7dc8c7c0c6dc68a2f39b41ffafa5dc6b7f847277d4871517cfadbef185c75b63084c6d44b0ab0e2 + languageName: node + linkType: hard + "@aws-sdk/middleware-host-header@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-host-header@npm:3.972.3" @@ -908,6 +1498,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-location-constraint@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/e97592e4f08c8abdfb63a359a8c89eaffc128e221ed27db309840ecf9b4c1cbe757c394f218db99d200fc0afbc2c215fed47d428735d707144f19ab90476ee4e + languageName: node + linkType: hard + "@aws-sdk/middleware-location-constraint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.3" @@ -919,6 +1520,28 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-logger@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/e6db8b4e861cc8cc85f4e1b83fd73dc902beece1210fcfa6f2ebd7e78f9ee88f9a1584cdb584358b81c22c5c23b5b3bc58a6a57de2bfc33fb07684d9b9f8dad5 + languageName: node + linkType: hard + +"@aws-sdk/middleware-logger@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-logger@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/7deb41cefde575dbc4f0a845fa535b88e52bacde2778b0f4545c3044bf87d70e0981c9dc3e65f5385d1b3d9de1afc06aae763295d2a3b33da02477c527e8bd64 + languageName: node + linkType: hard + "@aws-sdk/middleware-logger@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-logger@npm:3.972.3" @@ -930,6 +1553,31 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/2bc64666c08ee7f46a2918ac70773d7244f5c7866d0e3521c8734286c0b1bd5e4e64ea2bb4ec656e683dfecb7d44d43cd15283c4ec4cfe16b7aa7f4e19a586b8 + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@aws/lambda-invoke-store": "npm:^0.0.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/1d599f38cb269a9a27c2a63c8c6ec0790b38946a27fb06d003aa9b7247466151dab178bb35569740bd6725e25c9d5c733ee272d0de8bd382b1c3f7919bdb4978 + languageName: node + linkType: hard + "@aws-sdk/middleware-recursion-detection@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.3" @@ -943,6 +1591,28 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-sdk-s3@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-arn-parser": "npm:3.893.0" + "@smithy/core": "npm:^3.12.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/signature-v4": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-config-provider": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-stream": "npm:^4.3.2" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/591d2853276a911acc850742ec60f4d178565067bd3a87525cdb0c6c44487cd0f25ffec2f5afb4e273ab0b7b33bedeaa9f617d483967383f74dac4740807b1d1 + languageName: node + linkType: hard + "@aws-sdk/middleware-sdk-s3@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.7" @@ -965,6 +1635,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-ssec@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/f5fe75e0facfbcabbfea296dacc8add47368707e9fa53181f7693f70a8735a22a2926c1c9785c99291ce3e44e173184a977940e7cd8e5e1cea25f16e3e8d17c4 + languageName: node + linkType: hard + "@aws-sdk/middleware-ssec@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-ssec@npm:3.972.3" @@ -976,6 +1657,34 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@aws-sdk/util-endpoints": "npm:3.598.0" + "@smithy/protocol-http": "npm:^4.0.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/3ed35495781284c3969374c2a53f02863cc433a8d139d5e85d7e1181c138c2ec743ee77a82efe780a0902a24ce524fc8946429939ed1368fec9f4635afb3d7f4 + languageName: node + linkType: hard + +"@aws-sdk/middleware-user-agent@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-endpoints": "npm:3.895.0" + "@smithy/core": "npm:^3.12.0" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/9d781950484f900998f9c842ddbeb6820b808470fc01c0b0a3c30083758cc82fe28aa8f844843b9de52f789ba17f109ec8af64c1c499088cfa57566308bbd76e + languageName: node + linkType: hard + "@aws-sdk/middleware-user-agent@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-user-agent@npm:3.972.7" @@ -991,6 +1700,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/nested-clients@npm:3.896.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/middleware-host-header": "npm:3.893.0" + "@aws-sdk/middleware-logger": "npm:3.893.0" + "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" + "@aws-sdk/middleware-user-agent": "npm:3.896.0" + "@aws-sdk/region-config-resolver": "npm:3.893.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-endpoints": "npm:3.895.0" + "@aws-sdk/util-user-agent-browser": "npm:3.893.0" + "@aws-sdk/util-user-agent-node": "npm:3.896.0" + "@smithy/config-resolver": "npm:^4.2.2" + "@smithy/core": "npm:^3.12.0" + "@smithy/fetch-http-handler": "npm:^5.2.1" + "@smithy/hash-node": "npm:^4.1.1" + "@smithy/invalid-dependency": "npm:^4.1.1" + "@smithy/middleware-content-length": "npm:^4.1.1" + "@smithy/middleware-endpoint": "npm:^4.2.4" + "@smithy/middleware-retry": "npm:^4.3.0" + "@smithy/middleware-serde": "npm:^4.1.1" + "@smithy/middleware-stack": "npm:^4.1.1" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/node-http-handler": "npm:^4.2.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-body-length-browser": "npm:^4.1.0" + "@smithy/util-body-length-node": "npm:^4.1.0" + "@smithy/util-defaults-mode-browser": "npm:^4.1.4" + "@smithy/util-defaults-mode-node": "npm:^4.1.4" + "@smithy/util-endpoints": "npm:^3.1.2" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-retry": "npm:^4.1.2" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/7abe22d7ea6878197f9ec90e56778a6871e5b452ac53dc821c4c346a3c970ba183445bd02603352d7cf04eaba713be7d6c6852d4f3b00c5ef41810a7b1cf8a99 + languageName: node + linkType: hard + "@aws-sdk/nested-clients@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/nested-clients@npm:3.985.0" @@ -1037,6 +1792,34 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/region-config-resolver@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/node-config-provider": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + "@smithy/util-config-provider": "npm:^3.0.0" + "@smithy/util-middleware": "npm:^3.0.1" + tslib: "npm:^2.6.2" + checksum: 10/26f7b0225f006e8630db3e86e8cf304ba1a9fae69186f3902ebc3500145cb35af2bde1b83a9abac634e1ca981c4f39258b10be645066f7d3355d53991c3b1b3b + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-config-provider": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + tslib: "npm:^2.6.2" + checksum: 10/8fe6e40f37c97cafaf2f3f22bdeb1e015da955f75a5e54754301f3a0a98fca126a0f5745cfa07cd25b6e9f574cf4a3e359efc8c71dd12ee7920a0d493b258627 + languageName: node + linkType: hard + "@aws-sdk/region-config-resolver@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/region-config-resolver@npm:3.972.3" @@ -1067,7 +1850,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:3.986.0, @aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": +"@aws-sdk/s3-request-presigner@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/s3-request-presigner@npm:3.986.0" dependencies: @@ -1083,6 +1866,36 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": + version: 3.896.0 + resolution: "@aws-sdk/s3-request-presigner@npm:3.896.0" + dependencies: + "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@aws-sdk/util-format-url": "npm:3.893.0" + "@smithy/middleware-endpoint": "npm:^4.2.4" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/smithy-client": "npm:^4.6.4" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/a20d4ed2a558b41517cb6342d9f36ac678ab0fabb2c754354d5afd576719754fb5d6e22574b88817f7e61853e1ee9ac1d437513d8933ad773fcc7e90bc3ab298 + languageName: node + linkType: hard + +"@aws-sdk/signature-v4-multi-region@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.896.0" + dependencies: + "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/signature-v4": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/b1b3926c6ec9f54afb2eb43af559cb54dbf7d47012c8e6709c495a9292e9c8f9f61c86300d784fa14743a634210f216bc21ee2da976b5bf82db18d5a3f0abe16 + languageName: node + linkType: hard + "@aws-sdk/signature-v4-multi-region@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/signature-v4-multi-region@npm:3.986.0" @@ -1097,6 +1910,36 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/token-providers@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/property-provider": "npm:^3.1.1" + "@smithy/shared-ini-file-loader": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + peerDependencies: + "@aws-sdk/client-sso-oidc": ^3.598.0 + checksum: 10/8542937e6d010ebd6b3dd70390685fa4553b0e01ed4fb8e6dc7bd6395e853162758e8d7a6c251fb56309d36beebc393981788ca112bfb3b1de7e23e599d2476e + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/token-providers@npm:3.896.0" + dependencies: + "@aws-sdk/core": "npm:3.896.0" + "@aws-sdk/nested-clients": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/b50abe20a20aabaac857bb606b694036d693187ab2dd6d6836f1caad008314784f7a2a6c566bf3966f699d59b3a035ed7897c4fff37a828cc47d55c6076dbda4 + languageName: node + linkType: hard + "@aws-sdk/token-providers@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/token-providers@npm:3.985.0" @@ -1112,7 +1955,27 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.973.1": +"@aws-sdk/types@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/types@npm:3.598.0" + dependencies: + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + checksum: 10/29384fbe79ec8693cae00b3082379559e7bbea5fd70de1705e94e93ed1ec57ddb930bb41102f9b229869a9a7ba790deeb1161bc81e2f87a031d37dff2fa73dd0 + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.893.0, @aws-sdk/types@npm:^3.222.0": + version: 3.893.0 + resolution: "@aws-sdk/types@npm:3.893.0" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/c7edea067ee8179732b9750b4090d0cc5ca07e954b92cec25c4f55c8e1e9a1ad62df2799e2a82ad24b59ee25a2a4188a5e429db59aa168b10d0ba62347800d5b + languageName: node + linkType: hard + +"@aws-sdk/types@npm:^3.973.1": version: 3.973.1 resolution: "@aws-sdk/types@npm:3.973.1" dependencies: @@ -1122,6 +1985,15 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-arn-parser@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.893.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/f809777714618c63e92fd5881c9573081bc94df9c5cce53917b8e1db4efa1d44f1132f6c9179f9babc4964c648d42ebee5c1ad75641c6b336007be3df561053f + languageName: node + linkType: hard + "@aws-sdk/util-arn-parser@npm:^3.972.2": version: 3.972.2 resolution: "@aws-sdk/util-arn-parser@npm:3.972.2" @@ -1131,6 +2003,31 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-endpoints@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/types": "npm:^3.1.0" + "@smithy/util-endpoints": "npm:^2.0.2" + tslib: "npm:^2.6.2" + checksum: 10/753c5629e7f9e0abd3b2d8578ffa038089e18e80d8b2a3f49f2321dc565480c2d6dc5ecbfae799f35cb88fbc247018887f2c3b325853af6246547293973c7d45 + languageName: node + linkType: hard + +"@aws-sdk/util-endpoints@npm:3.895.0": + version: 3.895.0 + resolution: "@aws-sdk/util-endpoints@npm:3.895.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + "@smithy/util-endpoints": "npm:^3.1.2" + tslib: "npm:^2.6.2" + checksum: 10/14f39c2f0f085640cb8f1f178bc710aa237fbd0d856c9081dbf4d5514bfb8aff96c97fdb006450f1cbe839f7604ba19832daa95b1f6dccc65094e52a6e388e6f + languageName: node + linkType: hard + "@aws-sdk/util-endpoints@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/util-endpoints@npm:3.985.0" @@ -1157,6 +2054,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-format-url@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/util-format-url@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/querystring-builder": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/0cc12a660aaa0fa34294727caa0f52bef97b85f4f7d46aebdc609f176330658275e1177317e06adc559f6ee3f9a7fa5c86be75d18353a7b4311589cfca161a48 + languageName: node + linkType: hard + "@aws-sdk/util-format-url@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-format-url@npm:3.972.3" @@ -1178,6 +2087,30 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/types": "npm:^3.1.0" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/2c7bb1ec527ae1df15bf8c58320912c2cf41cecbfcf41a84fdb5d2c7b2ed53245d8748607b05445d0aac31ca1fb66280b38199fd457eb1f5650b60668c956f25 + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-browser@npm:3.893.0": + version: 3.893.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.893.0" + dependencies: + "@aws-sdk/types": "npm:3.893.0" + "@smithy/types": "npm:^4.5.0" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/b268fc03a2afb2741e64175e5bd28b34315314ff55e82fa00e3d98f35a955a681568b1595f7e18b05f0172915244be7fe0cf5e1e90cf6e971bae3a946e3dfa63 + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-browser@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.3" @@ -1190,6 +2123,41 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" + dependencies: + "@aws-sdk/types": "npm:3.598.0" + "@smithy/node-config-provider": "npm:^3.1.1" + "@smithy/types": "npm:^3.1.0" + tslib: "npm:^2.6.2" + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 10/19de8df5e26560f9fc99acd73dd5c5f7890ec62b876568f15132dc1141eab280ec7ad44aeb0b095f765c2329f06fc8babf124e2708d6ccee1c541a9f62b51f5f + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.896.0": + version: 3.896.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.896.0" + dependencies: + "@aws-sdk/middleware-user-agent": "npm:3.896.0" + "@aws-sdk/types": "npm:3.893.0" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 10/4453a1989deb1a2ad6e087914642760206b4a77a8da4976c74225ed47400812595e6bfa1ad27f42277b561b8d8b8a2dcaf248b3bd8a0c1b0ef2f1e790320d8a9 + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-node@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/util-user-agent-node@npm:3.972.5" @@ -1208,6 +2176,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/xml-builder@npm:3.894.0": + version: 3.894.0 + resolution: "@aws-sdk/xml-builder@npm:3.894.0" + dependencies: + "@smithy/types": "npm:^4.5.0" + fast-xml-parser: "npm:5.2.5" + tslib: "npm:^2.6.2" + checksum: 10/60a32a4fcc0466fa6eb61e165146bf7c9559252e0adc5f232d7f73237b4dab28ae92dadaf4ee039629b1d8ce47f4731348908e5e7de4e2abcf22f0c19597caf5 + languageName: node + linkType: hard + "@aws-sdk/xml-builder@npm:^3.972.4": version: 3.972.4 resolution: "@aws-sdk/xml-builder@npm:3.972.4" @@ -1219,6 +2198,13 @@ __metadata: languageName: node linkType: hard +"@aws/lambda-invoke-store@npm:^0.0.1": + version: 0.0.1 + resolution: "@aws/lambda-invoke-store@npm:0.0.1" + checksum: 10/e8f54d28aade8828962f2871a22aa4e960ebc40c8fa551414181dd9dd32d6258279013c42f88e57d17aa4252cb5ed00df6a49fc35185f9fa6b6f351ccf821bd6 + languageName: node + linkType: hard + "@aws/lambda-invoke-store@npm:^0.2.2": version: 0.2.3 resolution: "@aws/lambda-invoke-store@npm:0.2.3" @@ -2986,7 +3972,16 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5, @emnapi/runtime@npm:^1.7.0": +"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5": + version: 1.5.0 + resolution: "@emnapi/runtime@npm:1.5.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/5311ce854306babc77f4bd94c2f973722714a0fab93c126239104ad52dea16a147bfed4c4cff3ca1eb32709607221c25d2f747ae8524cbeb9088058f02ff962b + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.7.0": version: 1.8.1 resolution: "@emnapi/runtime@npm:1.8.1" dependencies: @@ -5562,6 +6557,26 @@ __metadata: languageName: node linkType: hard +"@smithy/abort-controller@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/abort-controller@npm:3.1.0" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/1a7459471db6a624bec0a3235251c067b813a47c2bc15145977ebca76894a491974575d9c9c515120259b206cf3d613baa1a61b8da96a7a0233c8c5d7c04e725 + languageName: node + linkType: hard + +"@smithy/abort-controller@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/abort-controller@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/d2a007a4a41afd3ac13c291f2683d1da57709e75db0a09f502225983c097c8169e3b1b78fc01ee691fb12980492fb3ca49628b3f34ece0a66806bd0caf701710 + languageName: node + linkType: hard + "@smithy/abort-controller@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/abort-controller@npm:4.2.8" @@ -5572,6 +6587,16 @@ __metadata: languageName: node linkType: hard +"@smithy/chunked-blob-reader-native@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/chunked-blob-reader-native@npm:4.1.0" + dependencies: + "@smithy/util-base64": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/5ddca9cb700392ff0e6025726528e2c2e20e189b974af0eb8286b2b7bfa248c10c479c99ff09d0fbf0c3c5feefa98ce5da78f4273bbdae0b85e064d753fdecc9 + languageName: node + linkType: hard + "@smithy/chunked-blob-reader-native@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/chunked-blob-reader-native@npm:4.2.1" @@ -5582,6 +6607,15 @@ __metadata: languageName: node linkType: hard +"@smithy/chunked-blob-reader@npm:^5.1.0": + version: 5.1.0 + resolution: "@smithy/chunked-blob-reader@npm:5.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/a7d1d7d5b45499dc6e2c6a4bbfd1ac8cfbaf85b5b28db060c8d3cb1f331432cdada0e5586d57d949a3e521d7eb7b88c425d66cd2ee7ab9d1cf4fbff9a1f830e0 + languageName: node + linkType: hard + "@smithy/chunked-blob-reader@npm:^5.2.0": version: 5.2.0 resolution: "@smithy/chunked-blob-reader@npm:5.2.0" @@ -5591,6 +6625,32 @@ __metadata: languageName: node linkType: hard +"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/config-resolver@npm:3.0.3" + dependencies: + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-config-provider": "npm:^3.0.0" + "@smithy/util-middleware": "npm:^3.0.2" + tslib: "npm:^2.6.2" + checksum: 10/e1e88d334177f6481ddba3a805e8e2e6513654a581aee500a1a74a0f206379ddbdec9eb48b2f4a1ae1c84b330d122f84cbbba0f0ffbe4c9ebdeeaac872cfee7e + languageName: node + linkType: hard + +"@smithy/config-resolver@npm:^4.2.2": + version: 4.2.2 + resolution: "@smithy/config-resolver@npm:4.2.2" + dependencies: + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-config-provider": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + tslib: "npm:^2.6.2" + checksum: 10/8b489420646c61c4ac57e2754ad6e4012de27aa6d0bca18d69f1916085908d58d8ba4d8d963e24ba55c9a797996b95cedff18e3fa2674136c6eb14044f942da0 + languageName: node + linkType: hard + "@smithy/config-resolver@npm:^4.4.6": version: 4.4.6 resolution: "@smithy/config-resolver@npm:4.4.6" @@ -5605,6 +6665,40 @@ __metadata: languageName: node linkType: hard +"@smithy/core@npm:^2.2.1": + version: 2.2.3 + resolution: "@smithy/core@npm:2.2.3" + dependencies: + "@smithy/middleware-endpoint": "npm:^3.0.3" + "@smithy/middleware-retry": "npm:^3.0.6" + "@smithy/middleware-serde": "npm:^3.0.2" + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/smithy-client": "npm:^3.1.4" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-middleware": "npm:^3.0.2" + tslib: "npm:^2.6.2" + checksum: 10/d1e4885b3800e97bd119a66b2cd75c3bfdcfa5af420db20b4360a6bd9f7a7f31cee0b35edf06ecb61c210fcf042e3f2bf82e6650e571e2a63879082a5805c9cd + languageName: node + linkType: hard + +"@smithy/core@npm:^3.12.0, @smithy/core@npm:^3.13.0": + version: 3.13.0 + resolution: "@smithy/core@npm:3.13.0" + dependencies: + "@smithy/middleware-serde": "npm:^4.1.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-body-length-browser": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-stream": "npm:^4.3.2" + "@smithy/util-utf8": "npm:^4.1.0" + "@smithy/uuid": "npm:^1.0.0" + tslib: "npm:^2.6.2" + checksum: 10/75b7045fae55b732e0420b2990255b7f8c962a66a6f9e77bd1509534428434190823bf1e68eabdda927d5abfb5d6d7783f49fa2d08268610ac4cd33c6c3f5594 + languageName: node + linkType: hard + "@smithy/core@npm:^3.22.1, @smithy/core@npm:^3.23.0": version: 3.23.0 resolution: "@smithy/core@npm:3.23.0" @@ -5623,6 +6717,32 @@ __metadata: languageName: node linkType: hard +"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/credential-provider-imds@npm:3.1.2" + dependencies: + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/property-provider": "npm:^3.1.2" + "@smithy/types": "npm:^3.2.0" + "@smithy/url-parser": "npm:^3.0.2" + tslib: "npm:^2.6.2" + checksum: 10/2d023083f12d1a411251d2402e281dbeb6de83d394d900052aacd02188102b4b24fc9c2791a76b669c7800f8a5fb3baf99ea65fddd1e4cc6a467b1f85575987b + languageName: node + linkType: hard + +"@smithy/credential-provider-imds@npm:^4.1.2": + version: 4.1.2 + resolution: "@smithy/credential-provider-imds@npm:4.1.2" + dependencies: + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + tslib: "npm:^2.6.2" + checksum: 10/c10cbea54ba8475d27cd38e956bda9113efa7e90ad46369aa2b3f8bce511ccc89a45f2198efe8bd00a35de16f5ef411723be01093cc02c10511ea89c5ed0131e + languageName: node + linkType: hard + "@smithy/credential-provider-imds@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/credential-provider-imds@npm:4.2.8" @@ -5636,6 +6756,18 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-codec@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/eventstream-codec@npm:4.1.1" + dependencies: + "@aws-crypto/crc32": "npm:5.2.0" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-hex-encoding": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/7921997f85957c17fd5493567777dcfa31b90c84a3cb2a27adfc8218846994dd6ddebb4699c0656e02d25709d44b692b58a0c94296e771257097ab61626ebdd3 + languageName: node + linkType: hard + "@smithy/eventstream-codec@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-codec@npm:4.2.8" @@ -5648,6 +6780,17 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-serde-browser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/eventstream-serde-browser@npm:4.1.1" + dependencies: + "@smithy/eventstream-serde-universal": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/89afea2e1deeb3e771e69e62dbc3d17a4fb366dc0b3edf355069a0d8c429cc09e46c8b78f92456dded8e40e22dd06dade5bc717e17ae197b0fe5997729aac82c + languageName: node + linkType: hard + "@smithy/eventstream-serde-browser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-browser@npm:4.2.8" @@ -5659,6 +6802,16 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-serde-config-resolver@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/eventstream-serde-config-resolver@npm:4.2.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/18e1f0e69bb10b427103113ca14542d6e740e9096cd51d706f890cec78d390f5ccc81513ceef0b861ba05ff0004f0244aaac29d4f3eeff2bc062a16a76331944 + languageName: node + linkType: hard + "@smithy/eventstream-serde-config-resolver@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.8" @@ -5669,6 +6822,17 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-serde-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/eventstream-serde-node@npm:4.1.1" + dependencies: + "@smithy/eventstream-serde-universal": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/9ec402098b3d67d051e92d332afb7ea7ab056d178e206d4e35ca47e9b2d12915373358323681c6183f22680e847101277dbf43abb9703bfda2ec23451cc87c51 + languageName: node + linkType: hard + "@smithy/eventstream-serde-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-node@npm:4.2.8" @@ -5680,6 +6844,17 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-serde-universal@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/eventstream-serde-universal@npm:4.1.1" + dependencies: + "@smithy/eventstream-codec": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/bbe77b9f14d718d18972dc4690c53b6518e0088e0c24d7f0a38b3ede3dd0291fd494112bfe7efb93591ba4b923b0ce9b8598ee72eec4e4481812ef3f4bfb5af7 + languageName: node + linkType: hard + "@smithy/eventstream-serde-universal@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-universal@npm:4.2.8" @@ -5691,6 +6866,32 @@ __metadata: languageName: node linkType: hard +"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/fetch-http-handler@npm:3.1.0" + dependencies: + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/querystring-builder": "npm:^3.0.2" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-base64": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/fcfd98a69798aa5b4c034601c75f125b2c70e24effd5a5137caad4ce24f06d83f8788664cff40b15e205257b055eefba35ec3314f73c0887c1c84fd9c349579f + languageName: node + linkType: hard + +"@smithy/fetch-http-handler@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/fetch-http-handler@npm:5.2.1" + dependencies: + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/querystring-builder": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-base64": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/a7038d20ad2ad64bdfda06b61e6a485b20af2086e94b78dc8f955a5baf270efaca6c9a3f7401114b8e856eed3ff8dda9701119a560455e6d72f8ae1957f50d33 + languageName: node + linkType: hard + "@smithy/fetch-http-handler@npm:^5.3.9": version: 5.3.9 resolution: "@smithy/fetch-http-handler@npm:5.3.9" @@ -5704,6 +6905,18 @@ __metadata: languageName: node linkType: hard +"@smithy/hash-blob-browser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/hash-blob-browser@npm:4.1.1" + dependencies: + "@smithy/chunked-blob-reader": "npm:^5.1.0" + "@smithy/chunked-blob-reader-native": "npm:^4.1.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/8e29bf75da5ceebc571bee17c3e6c28162572105dcdc17b249a5edf3691e0987daf579470cb60799e8f200756cb3bd8fa69e0b299a8435edaff490f14101bc13 + languageName: node + linkType: hard + "@smithy/hash-blob-browser@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/hash-blob-browser@npm:4.2.9" @@ -5716,6 +6929,30 @@ __metadata: languageName: node linkType: hard +"@smithy/hash-node@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/hash-node@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + "@smithy/util-buffer-from": "npm:^3.0.0" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/df5c22224f210741b00bde59922b86354d1f21660bea6b0b3f8e9e87236fd80cb90bc81945ceb4914ae99ce7a7570f8cf59d57bffb3f50c75719e3cc3cdacab7 + languageName: node + linkType: hard + +"@smithy/hash-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/hash-node@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + "@smithy/util-buffer-from": "npm:^4.1.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/234f3d52975f99583ec8e739f70b3ccb1941f57bb47e1d230af954d5b1b3d7ee6c94907079017ef5fbfec4bcb618c0214b26b2ff7d7a01dc57d1f8f5ff414cba + languageName: node + linkType: hard + "@smithy/hash-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-node@npm:4.2.8" @@ -5728,6 +6965,17 @@ __metadata: languageName: node linkType: hard +"@smithy/hash-stream-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/hash-stream-node@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/abdeea567ffb65f41e79c4dec5733c29a419a1de546e968be95113e2d96fc7e870149c1de422ff4fefb4229ee3dd0e29996df14c2c95e42a65027f9cdfa8f03a + languageName: node + linkType: hard + "@smithy/hash-stream-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-stream-node@npm:4.2.8" @@ -5739,6 +6987,26 @@ __metadata: languageName: node linkType: hard +"@smithy/invalid-dependency@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/invalid-dependency@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/e4bc6a79d4f514ae81600b3484025dc788013da690de6f3980121374b65d0d92d42bc50760e9c7b44438e7f5794ffd46bef2976a11d2da16fae47fc25b0ac96a + languageName: node + linkType: hard + +"@smithy/invalid-dependency@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/invalid-dependency@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/665e34379c6b3ad3a6bb0cf14ad646ba2bd9785b6e1b571d41192ad2d5617f5f48cd743d2ad75ce5ba6d5a2c2e312f7f86c2be50d2b8b12c9f2c0e5f42c9633e + languageName: node + linkType: hard + "@smithy/invalid-dependency@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/invalid-dependency@npm:4.2.8" @@ -5758,6 +7026,24 @@ __metadata: languageName: node linkType: hard +"@smithy/is-array-buffer@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/is-array-buffer@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/cab1fd4033d9863dcd95ff058463eb591574bd47e6b61e36aaaf4c0d0da9ed966a54e1d33ec4db7d67aa85df7d274203e934e04dbb40323d01ef4815f63997fc + languageName: node + linkType: hard + +"@smithy/is-array-buffer@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/is-array-buffer@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/5fba7ea13175100d39bc88b480dc70dc04bb62c62dc470e61e09b287f3b4c851c56473bda2ec077eca31675cde184dadc4d50ef11f065fb566e0b88f92d9465a + languageName: node + linkType: hard + "@smithy/is-array-buffer@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/is-array-buffer@npm:4.2.0" @@ -5767,6 +7053,17 @@ __metadata: languageName: node linkType: hard +"@smithy/md5-js@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/md5-js@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/383d9acb06adad67c1089283988195d478475a53fa6e9954f5b237989b5ae15a8f2ec70f8f64557c65ce2984e8503bdc55ea4ff487def8c04822af1132f6746b + languageName: node + linkType: hard + "@smithy/md5-js@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/md5-js@npm:4.2.8" @@ -5778,6 +7075,28 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-content-length@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/middleware-content-length@npm:3.0.2" + dependencies: + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/520c28af22819724fefb8f487d6080b497f64ddf34fb75fd6829df0c1b075e23d0cdcfbbbd265b6556843735ae9721b8b349e2b6c194e3e71a94916c9a929cf6 + languageName: node + linkType: hard + +"@smithy/middleware-content-length@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-content-length@npm:4.1.1" + dependencies: + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/eb2a99c11d01484ff0b17ba9c5d02878b92c61153568080eab011699de4460ff4534a302d9131583deb83963be83494a43e1973235c1e7edbaaaa2ace5e2b202 + languageName: node + linkType: hard + "@smithy/middleware-content-length@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-content-length@npm:4.2.8" @@ -5789,6 +7108,37 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/middleware-endpoint@npm:3.0.3" + dependencies: + "@smithy/middleware-serde": "npm:^3.0.2" + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/shared-ini-file-loader": "npm:^3.1.2" + "@smithy/types": "npm:^3.2.0" + "@smithy/url-parser": "npm:^3.0.2" + "@smithy/util-middleware": "npm:^3.0.2" + tslib: "npm:^2.6.2" + checksum: 10/fd3628405b4970f90448d5c52e7c3b808bbe149d72cbb21001a9a707b5b43a7e4e2275751b9486886bac2e740eaafc9c880800e6c69e02436731629b277bc55b + languageName: node + linkType: hard + +"@smithy/middleware-endpoint@npm:^4.2.4, @smithy/middleware-endpoint@npm:^4.2.5": + version: 4.2.5 + resolution: "@smithy/middleware-endpoint@npm:4.2.5" + dependencies: + "@smithy/core": "npm:^3.13.0" + "@smithy/middleware-serde": "npm:^4.1.1" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + "@smithy/url-parser": "npm:^4.1.1" + "@smithy/util-middleware": "npm:^4.1.1" + tslib: "npm:^2.6.2" + checksum: 10/b9a8a0791cfe79d9507620f66fe4592e6d4586739d295a2cc4dd3b329c05bcc68af7806523ba05647c0bc32a466481ff9f11b9808756e70c41394ed3a0174bc3 + languageName: node + linkType: hard + "@smithy/middleware-endpoint@npm:^4.4.13, @smithy/middleware-endpoint@npm:^4.4.14": version: 4.4.14 resolution: "@smithy/middleware-endpoint@npm:4.4.14" @@ -5805,6 +7155,40 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/middleware-retry@npm:3.0.6" + dependencies: + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/service-error-classification": "npm:^3.0.2" + "@smithy/smithy-client": "npm:^3.1.4" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-middleware": "npm:^3.0.2" + "@smithy/util-retry": "npm:^3.0.2" + tslib: "npm:^2.6.2" + uuid: "npm:^9.0.1" + checksum: 10/8c0d696a840b6d307718e4cfaeb2eae41840be639c91c0653329beb1e4faf2b8f6a31225651c80da3f0b6a130d009fcc4f4f7c6549f9d8e298074b132731c953 + languageName: node + linkType: hard + +"@smithy/middleware-retry@npm:^4.3.0": + version: 4.3.1 + resolution: "@smithy/middleware-retry@npm:4.3.1" + dependencies: + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/service-error-classification": "npm:^4.1.2" + "@smithy/smithy-client": "npm:^4.6.5" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-retry": "npm:^4.1.2" + "@smithy/uuid": "npm:^1.0.0" + tslib: "npm:^2.6.2" + checksum: 10/85b92dbd6c2b72d4fe38d56de69160bd44a3d99b51eb1a66456f75b1a4a3931999d986b58e4426608ca1d2089187a1ab43f6904b24803b0750fbd17226c8900d + languageName: node + linkType: hard + "@smithy/middleware-retry@npm:^4.4.30": version: 4.4.31 resolution: "@smithy/middleware-retry@npm:4.4.31" @@ -5822,6 +7206,27 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-serde@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/ef05cbd0b7a8b5187094ce134620e57dcb50a5c77b7f555f44f050e69a3677aff7f0c05ff02771b2bc92f515df527eef4d10ac5ff515648b8ec6cb92783cd072 + languageName: node + linkType: hard + +"@smithy/middleware-serde@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-serde@npm:4.1.1" + dependencies: + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/01d907751748a4b2806aba43ec4a668d313c89c04ecd6ba3b15663e39b9b447842387e4300e47d8ce7066c415fb70b05b53c11967f98c4d8ea5488891070cad6 + languageName: node + linkType: hard + "@smithy/middleware-serde@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/middleware-serde@npm:4.2.9" @@ -5833,6 +7238,26 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-stack@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/21b7d7d6e73c1628b5ed384f23ac850df3bbca5054ea1e6ba03c3bf1d389fe5a440a4fbdb8aaa210c4b2ba864ac082264bb3c6ec7a2e03f0e6b790c6b23178a6 + languageName: node + linkType: hard + +"@smithy/middleware-stack@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-stack@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/7c07663cb381f785d2bf39ff7fa5ee14e233168021274ede6b86335fff60a23260f42535f5ef32c8fe581c780a80acd06df39fcbcd3634e61c1eae685372a65c + languageName: node + linkType: hard + "@smithy/middleware-stack@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-stack@npm:4.2.8" @@ -5843,6 +7268,30 @@ __metadata: languageName: node linkType: hard +"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/node-config-provider@npm:3.1.2" + dependencies: + "@smithy/property-provider": "npm:^3.1.2" + "@smithy/shared-ini-file-loader": "npm:^3.1.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/b0b9d665efc075803dcf9a26014def9b650270593667d5f01511758d4909387ab820c1fdcaf1a82e1f4fbd6c26a67ecab88ac26cc5450bf815788e4090d4e476 + languageName: node + linkType: hard + +"@smithy/node-config-provider@npm:^4.2.2": + version: 4.2.2 + resolution: "@smithy/node-config-provider@npm:4.2.2" + dependencies: + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/shared-ini-file-loader": "npm:^4.2.0" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/18f290c8be9c5de33b64e7cae847bfbf1b926e7fbb1df31e853a7d04ef3275adb690f5cf3450ffef23ab68fc8f37f45d42bee9c05bf791b8b66c447c97ba2e25 + languageName: node + linkType: hard + "@smithy/node-config-provider@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/node-config-provider@npm:4.3.8" @@ -5855,6 +7304,32 @@ __metadata: languageName: node linkType: hard +"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/node-http-handler@npm:3.1.0" + dependencies: + "@smithy/abort-controller": "npm:^3.1.0" + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/querystring-builder": "npm:^3.0.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/05ff2d9db1f67e08efd8b486c00506163dce70644add50ab3ca4995424bd73f168ee0f1f3b2f9aac77fa46c7775c7d28db558450a36fa641a862f80f957c1aad + languageName: node + linkType: hard + +"@smithy/node-http-handler@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/node-http-handler@npm:4.2.1" + dependencies: + "@smithy/abort-controller": "npm:^4.1.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/querystring-builder": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/71f6551dbd06e2a9eb2b536bf13f11ec32c93da324376bf82ff3614e24241970e9ba4106cbbc8a0ac2867595fad3b12c6b2807366f921561ec41086a90af2ece + languageName: node + linkType: hard + "@smithy/node-http-handler@npm:^4.4.10, @smithy/node-http-handler@npm:^4.4.9": version: 4.4.10 resolution: "@smithy/node-http-handler@npm:4.4.10" @@ -5868,6 +7343,26 @@ __metadata: languageName: node linkType: hard +"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/property-provider@npm:3.1.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/7993be1ae7f2f6779599837a246749b98cb0fc60e685ff7d97f1bd7e7ed1ce9e30bd4ce9e46e4a52f4dbf16cf864611bae72230e5fcb91b0c3a3d4de08ce258e + languageName: node + linkType: hard + +"@smithy/property-provider@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/property-provider@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/f44da66c108b6bb0d9e59a30d8dbde17fc38656890b3ba688cf22db130e93f84d7436003cde473d2636a16d736eb4a8638e069f9a1cb0228a9bb2a5d90f8e40a + languageName: node + linkType: hard + "@smithy/property-provider@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/property-provider@npm:4.2.8" @@ -5878,6 +7373,26 @@ __metadata: languageName: node linkType: hard +"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": + version: 4.0.2 + resolution: "@smithy/protocol-http@npm:4.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/accd46f06a4ab6549b797d52274d98c4b755a87fe2cd3f6c5edf991b8e44d4233fadbe4628d665f404ccd85ad9caa42127cef3db74a38f3d085f2f81b81d9f42 + languageName: node + linkType: hard + +"@smithy/protocol-http@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/protocol-http@npm:5.2.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/7e00b314d6b38d58f4ca692546642b6a641be564d67fc31bae227ec0f0fd8f568522752189727a45828654c6ebcab2784884d4058ce992d2f48fc63ab37f4c2c + languageName: node + linkType: hard + "@smithy/protocol-http@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/protocol-http@npm:5.3.8" @@ -5888,6 +7403,28 @@ __metadata: languageName: node linkType: hard +"@smithy/querystring-builder@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-builder@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + "@smithy/util-uri-escape": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/6a455ee7ce135898e9d19cfd8c614f42f131a1439faddf49c2f72612521398de32dd75eebdde2af00754aa97b9418f3e42cf77e41ac264c1a74bd166c6d1dc0e + languageName: node + linkType: hard + +"@smithy/querystring-builder@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-builder@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + "@smithy/util-uri-escape": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/bbbfd564ccd585273df3829cc5e86572341cf22ed65477fdf31c8b9fc99759e872246ad419863efc259a110fbdab5bac408a5729abc8f883edd8390ae80aaf30 + languageName: node + linkType: hard + "@smithy/querystring-builder@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-builder@npm:4.2.8" @@ -5899,6 +7436,26 @@ __metadata: languageName: node linkType: hard +"@smithy/querystring-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-parser@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/86e5d986df6e0d639d420306a41e444456a8a91457f8e3fc363fb2c9155d3a02f8a651add14f0e341955af5c521a8e6cf1abb920ddf2ce7c89acaafba768299a + languageName: node + linkType: hard + +"@smithy/querystring-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-parser@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/08b81b7e8350d88b5a350cbe55c626c71bb86de06041e8311c44133919accba63b401672f84e65cbdbddce02a08b408da40669161d92af1d4d283dd167863aa5 + languageName: node + linkType: hard + "@smithy/querystring-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-parser@npm:4.2.8" @@ -5909,6 +7466,24 @@ __metadata: languageName: node linkType: hard +"@smithy/service-error-classification@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/service-error-classification@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + checksum: 10/f871ab0a4966a874cae412ff7621a44ab07f31c91070b2fb21f8e5d39f7336e25ad119469ac023861e2d310f0b5739fe308dde89ef5fbc17ec4860e8575f15db + languageName: node + linkType: hard + +"@smithy/service-error-classification@npm:^4.1.2": + version: 4.1.2 + resolution: "@smithy/service-error-classification@npm:4.1.2" + dependencies: + "@smithy/types": "npm:^4.5.0" + checksum: 10/50e8835e9850167093db1a96e9265ee66991f8e03b44fd2f23c44114de5634d9d65dd80fc6f7f94ebba2f2e892f73a270bbfdca5c07bfc97bb36bbf3b95ad4a3 + languageName: node + linkType: hard + "@smithy/service-error-classification@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/service-error-classification@npm:4.2.8" @@ -5918,6 +7493,26 @@ __metadata: languageName: node linkType: hard +"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/f3d7dde145975c626fb2565af8a24308b00e70b70618d7870dd91c2956918945a8bce557d0809416fa047b3792b5e038521b5aa53ac164c1f345da98c4a663fc + languageName: node + linkType: hard + +"@smithy/shared-ini-file-loader@npm:^4.2.0": + version: 4.2.0 + resolution: "@smithy/shared-ini-file-loader@npm:4.2.0" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/ee67bbfbbde59407ef15777118cccc2ef39163f70efc0704044144dcd08019316b08ccdec5e8dc94fb17d2be6aeb256a2d7b790a36c9938b6149e2e4c646db89 + languageName: node + linkType: hard + "@smithy/shared-ini-file-loader@npm:^4.4.3": version: 4.4.3 resolution: "@smithy/shared-ini-file-loader@npm:4.4.3" @@ -5928,6 +7523,37 @@ __metadata: languageName: node linkType: hard +"@smithy/signature-v4@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/signature-v4@npm:3.1.1" + dependencies: + "@smithy/is-array-buffer": "npm:^3.0.0" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-hex-encoding": "npm:^3.0.0" + "@smithy/util-middleware": "npm:^3.0.2" + "@smithy/util-uri-escape": "npm:^3.0.0" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/ad768406d955c038ff0492ecbeec13dd3f5f5ab0c8224a00097a7a8122a17f5cf97fb299cce61d668f27a59003e455dde4b4ab0c1dce27f8946e1af38c0202f7 + languageName: node + linkType: hard + +"@smithy/signature-v4@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/signature-v4@npm:5.2.1" + dependencies: + "@smithy/is-array-buffer": "npm:^4.1.0" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-hex-encoding": "npm:^4.1.0" + "@smithy/util-middleware": "npm:^4.1.1" + "@smithy/util-uri-escape": "npm:^4.1.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/4f22b6f1a1d15c15627af64ea1490ce797f020fca3177b00ec54d89e72ecdce98ed71ec8a96ece638110ac0b331718065a8393687654776e6989a523f03703b0 + languageName: node + linkType: hard + "@smithy/signature-v4@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/signature-v4@npm:5.3.8" @@ -5944,6 +7570,20 @@ __metadata: languageName: node linkType: hard +"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/smithy-client@npm:3.1.4" + dependencies: + "@smithy/middleware-endpoint": "npm:^3.0.3" + "@smithy/middleware-stack": "npm:^3.0.2" + "@smithy/protocol-http": "npm:^4.0.2" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-stream": "npm:^3.0.4" + tslib: "npm:^2.6.2" + checksum: 10/9e85bc7c5205d89d012bdd02c74eb3486709fa9f9442574fd84db5b3bccf9ce9a9aef6d7076e156f75cec257b478162242d4b3d5c44f3f32f087dfeb559e6549 + languageName: node + linkType: hard + "@smithy/smithy-client@npm:^4.11.2, @smithy/smithy-client@npm:^4.11.3": version: 4.11.3 resolution: "@smithy/smithy-client@npm:4.11.3" @@ -5959,6 +7599,30 @@ __metadata: languageName: node linkType: hard +"@smithy/smithy-client@npm:^4.6.4, @smithy/smithy-client@npm:^4.6.5": + version: 4.6.5 + resolution: "@smithy/smithy-client@npm:4.6.5" + dependencies: + "@smithy/core": "npm:^3.13.0" + "@smithy/middleware-endpoint": "npm:^4.2.5" + "@smithy/middleware-stack": "npm:^4.1.1" + "@smithy/protocol-http": "npm:^5.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-stream": "npm:^4.3.2" + tslib: "npm:^2.6.2" + checksum: 10/ac8482d2c6cdd2755fd336ebfe4b6ddba5707a4438f199ce771e37bd9ae71be3ae43e32bcf6655345c1276c84416efe00141166708dea47be35bb78c06a4ea85 + languageName: node + linkType: hard + +"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/types@npm:3.2.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/0590537cc2aaa7c2cd3277b6ec94ab1b7a417e7aae8389424e3b161b878dba3b8879c0bdfd0ad85145320006ecda8395f21196d527696e97bcfb98ffe01441b1 + languageName: node + linkType: hard + "@smithy/types@npm:^4.12.0": version: 4.12.0 resolution: "@smithy/types@npm:4.12.0" @@ -5968,6 +7632,37 @@ __metadata: languageName: node linkType: hard +"@smithy/types@npm:^4.5.0": + version: 4.5.0 + resolution: "@smithy/types@npm:4.5.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/d25275a0f1cb75dd3534a60a637b0202fbe1343703a448c410aa3e3029d5dc1d128c711c005bbda29a111af5a072aaf01bd8314a05c9806857d18e625f41c075 + languageName: node + linkType: hard + +"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/url-parser@npm:3.0.2" + dependencies: + "@smithy/querystring-parser": "npm:^3.0.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/080214bb1ae59472903d26beb71b7641a6ff49787735a8f56561b16d938cca80b8d560c2f679bf04da173c8c899b50aed881b61aef266bed11b570afbe20bc4f + languageName: node + linkType: hard + +"@smithy/url-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/url-parser@npm:4.1.1" + dependencies: + "@smithy/querystring-parser": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/35904bf3561d433f92c318c2f9d1fb8324e7693ea11af3e7570a334944f701e9c6720d5b426d93830e33cfe105dd026cd5fda842b20d14589ff62b9c67b4118b + languageName: node + linkType: hard + "@smithy/url-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/url-parser@npm:4.2.8" @@ -5979,6 +7674,28 @@ __metadata: languageName: node linkType: hard +"@smithy/util-base64@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-base64@npm:3.0.0" + dependencies: + "@smithy/util-buffer-from": "npm:^3.0.0" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/3c883d63a33e1cfeebf7f846f167dfc54c832d1f5514d014fbfff06de3aecd5919f01637fc93668dca8a1029752f3a6fab0a94f455dcb7c88f1d472bde294eef + languageName: node + linkType: hard + +"@smithy/util-base64@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-base64@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": "npm:^4.1.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/980391b462ab5d8a99ce2ac55441b3bcaef73e197926327f32ef09d708535f6d0449eb05fa166d709e27fdeb212a60f201d6678f2c64122fce072ef3d82c0644 + languageName: node + linkType: hard + "@smithy/util-base64@npm:^4.3.0": version: 4.3.0 resolution: "@smithy/util-base64@npm:4.3.0" @@ -5990,6 +7707,24 @@ __metadata: languageName: node linkType: hard +"@smithy/util-body-length-browser@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-browser@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/a0ab6a6d414a62d18e57f3581769379a54bb1fd93606c69bc8d96a3566fdecb8db7b57da9446568d03eef9f004f2a89d7e94bdda79ef280f28b19a71803c0309 + languageName: node + linkType: hard + +"@smithy/util-body-length-browser@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-browser@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/264b1b0f47127b1d215e95e7c66d3717b3f838d674b195e0150c8405e1875779694b3c75ab1932bf1a51c890ed495f7a9560a25c40e635d2f5585e496d9fbf77 + languageName: node + linkType: hard + "@smithy/util-body-length-browser@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-body-length-browser@npm:4.2.0" @@ -5999,6 +7734,24 @@ __metadata: languageName: node linkType: hard +"@smithy/util-body-length-node@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-node@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/aabac66d7111612fd375d67150f8787c5cdc828f7e6acb40ef0b18b4c354e64e0ef2e4b8da2d7f01e8abe931ff2ef8109a408164ce7e5662fd41b470c462f1e4 + languageName: node + linkType: hard + +"@smithy/util-body-length-node@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-node@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/5a6d925afdebdcde7a7f1ce55e69d823c0a9b7a5ed8f899417c402952585784b0ac843932691875381ce389f0e5f543d25c9fe4a3d8addeddbd48124a8985b6b + languageName: node + linkType: hard + "@smithy/util-body-length-node@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/util-body-length-node@npm:4.2.1" @@ -6018,6 +7771,26 @@ __metadata: languageName: node linkType: hard +"@smithy/util-buffer-from@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-buffer-from@npm:3.0.0" + dependencies: + "@smithy/is-array-buffer": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/7e6596b38855c07869f7e8f7b0ad9b70c5e658f4a06c7db71c6134a9a785ac1fdaa84f8b3358c4a572767838498df118daad1fa937237d1fb4b9fce735cf8bb0 + languageName: node + linkType: hard + +"@smithy/util-buffer-from@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-buffer-from@npm:4.1.0" + dependencies: + "@smithy/is-array-buffer": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/b1337ac6874adac67bbc91144c6e0e760b194f44af91a9816812c042c19a83d552cd5c8a94b8ed01af6047d2163a854fc32ebcd957a6053b4fd27dedc8793bb5 + languageName: node + linkType: hard + "@smithy/util-buffer-from@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-buffer-from@npm:4.2.0" @@ -6028,6 +7801,24 @@ __metadata: languageName: node linkType: hard +"@smithy/util-config-provider@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-config-provider@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/614c321c5a5a220d7d72d36359c41b4e390566719f7e01cefebffbe7034aae78b4533b27ab2030f93186c5f22893ddf056a3a2376a077d70ce89275f31e1ac46 + languageName: node + linkType: hard + +"@smithy/util-config-provider@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-config-provider@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/b6daf4d12e721062d7b1888a14a760db23a3df388cced56ba47673cc1a3a24b8933190a7631be1cc548eb62fb5a3b5c34d6de2eb595ffdacdfd7e0dcb7fee5ef + languageName: node + linkType: hard + "@smithy/util-config-provider@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-config-provider@npm:4.2.0" @@ -6037,6 +7828,32 @@ __metadata: languageName: node linkType: hard +"@smithy/util-defaults-mode-browser@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" + dependencies: + "@smithy/property-provider": "npm:^3.1.2" + "@smithy/smithy-client": "npm:^3.1.4" + "@smithy/types": "npm:^3.2.0" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/27cfd517c703fad039086c55c10b15b36f424536526dd92a498cbf539e8d82da7b07e5cf3ae0f5ef4cbce70e4acd0af1d8e811f38391882b91191c0711a3e58c + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-browser@npm:^4.1.4": + version: 4.1.5 + resolution: "@smithy/util-defaults-mode-browser@npm:4.1.5" + dependencies: + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/smithy-client": "npm:^4.6.5" + "@smithy/types": "npm:^4.5.0" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/8afc56f0e18da20ea9e283ef07ec669e4593c4b80642548cb07712ce01203d556f056682e4cab702b420cf61ccf31dc07dcfa79800981a920ca19d6bf30a8198 + languageName: node + linkType: hard + "@smithy/util-defaults-mode-browser@npm:^4.3.29": version: 4.3.30 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.30" @@ -6049,6 +7866,36 @@ __metadata: languageName: node linkType: hard +"@smithy/util-defaults-mode-node@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" + dependencies: + "@smithy/config-resolver": "npm:^3.0.3" + "@smithy/credential-provider-imds": "npm:^3.1.2" + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/property-provider": "npm:^3.1.2" + "@smithy/smithy-client": "npm:^3.1.4" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/20476aae3eb5cb4353e63cc5bf4a91c47f40016981631b1a1150fca0d561907df8dc4c7c4c39c5462febc226e8daedbbcd5468df93326d54127fd31932305ae8 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-node@npm:^4.1.4": + version: 4.1.5 + resolution: "@smithy/util-defaults-mode-node@npm:4.1.5" + dependencies: + "@smithy/config-resolver": "npm:^4.2.2" + "@smithy/credential-provider-imds": "npm:^4.1.2" + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/property-provider": "npm:^4.1.1" + "@smithy/smithy-client": "npm:^4.6.5" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/333739595d1679b54266acbbe558a18754db931e4ec2ecad237a7a0deede6a75b2e11386999b86b39900431d747d7d9188375f9060dc0b613bf68736c2b8fe42 + languageName: node + linkType: hard + "@smithy/util-defaults-mode-node@npm:^4.2.32": version: 4.2.33 resolution: "@smithy/util-defaults-mode-node@npm:4.2.33" @@ -6064,6 +7911,28 @@ __metadata: languageName: node linkType: hard +"@smithy/util-endpoints@npm:^2.0.2": + version: 2.0.3 + resolution: "@smithy/util-endpoints@npm:2.0.3" + dependencies: + "@smithy/node-config-provider": "npm:^3.1.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/145fe25e5ab22ee2214b6ffefc8fa91d77f09e456cf38000565faa96cad4e6da88bbd47e79e6c7c5e8ed1c7e896a3b3c8496706b28c6d2fe748675d467429359 + languageName: node + linkType: hard + +"@smithy/util-endpoints@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/util-endpoints@npm:3.1.2" + dependencies: + "@smithy/node-config-provider": "npm:^4.2.2" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/4310b3ae356d69f5bc6a7b3477ac5c16b0d014fe5c36db3445c010bfcea43f8b5de7abcb118f6935ccf9b41b9dcb6f17ca60792a68074c5b3ac70332dbc3c4b2 + languageName: node + linkType: hard + "@smithy/util-endpoints@npm:^3.2.8": version: 3.2.8 resolution: "@smithy/util-endpoints@npm:3.2.8" @@ -6075,6 +7944,24 @@ __metadata: languageName: node linkType: hard +"@smithy/util-hex-encoding@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-hex-encoding@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/d9f8c4c676410ca51bdbcec5d986883bad0028e26b098fc50e2b57bc81e8a5ce20e160786d08c8552ca0ba662c88ca16f33857ff24a0d183174325b2b40e3c8f + languageName: node + linkType: hard + +"@smithy/util-hex-encoding@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-hex-encoding@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/dc66a330ba5e4a7e034c75ff6bf823e7a3dd9df3283511f0e5e95797063f3a82cd1d68d1bdb2353b33502e7a2ae6806ae195a964c2e3339547e972d917c78ea4 + languageName: node + linkType: hard + "@smithy/util-hex-encoding@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-hex-encoding@npm:4.2.0" @@ -6084,6 +7971,26 @@ __metadata: languageName: node linkType: hard +"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-middleware@npm:3.0.2" + dependencies: + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/1e202038bb332bc8301b5e7b882c917927d9c71aae1aae1d5529c68abbaf8efe4791a29f7d192c24c015b905d7cac3ef5aa867aedf3d9bf9f3557959a6877925 + languageName: node + linkType: hard + +"@smithy/util-middleware@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-middleware@npm:4.1.1" + dependencies: + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/bc80179fb554271dd44a9eb8403f09a2ed4f14de5ee1ba44fea17d8ee2d5b2178a433a24c85ee8898d7a69b45a8cf5978b3ef71866b6b461179a7c4ef4e79b58 + languageName: node + linkType: hard + "@smithy/util-middleware@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-middleware@npm:4.2.8" @@ -6094,6 +8001,28 @@ __metadata: languageName: node linkType: hard +"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-retry@npm:3.0.2" + dependencies: + "@smithy/service-error-classification": "npm:^3.0.2" + "@smithy/types": "npm:^3.2.0" + tslib: "npm:^2.6.2" + checksum: 10/adda2d16b743dd99c5a3dd93da11a7e5e52eede37c936d966ea74aabd32007e2fc375ec47529ea3ea6052fc5c656a620917f87d66232bb4a23a9b252fa7af2eb + languageName: node + linkType: hard + +"@smithy/util-retry@npm:^4.1.2": + version: 4.1.2 + resolution: "@smithy/util-retry@npm:4.1.2" + dependencies: + "@smithy/service-error-classification": "npm:^4.1.2" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/3daf4b560de5dff99c14661b7ae5c4456b7b99642141cd4c7dccb281579435edecd22695a9fe78d47e716c85e25c9bbc555d44598f460f01f2d28d9182834dd4 + languageName: node + linkType: hard + "@smithy/util-retry@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-retry@npm:4.2.8" @@ -6105,6 +8034,38 @@ __metadata: languageName: node linkType: hard +"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/util-stream@npm:3.0.4" + dependencies: + "@smithy/fetch-http-handler": "npm:^3.1.0" + "@smithy/node-http-handler": "npm:^3.1.0" + "@smithy/types": "npm:^3.2.0" + "@smithy/util-base64": "npm:^3.0.0" + "@smithy/util-buffer-from": "npm:^3.0.0" + "@smithy/util-hex-encoding": "npm:^3.0.0" + "@smithy/util-utf8": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/4e53f14fd0b6e32a9b9897193e03f5df969e97f41c28e4f37d3f39082ac0b1b3e8a62117650076e2ea760e14c6b5d2dfd860e69e7c6a7f0145c03b8b6284ce14 + languageName: node + linkType: hard + +"@smithy/util-stream@npm:^4.3.2": + version: 4.3.2 + resolution: "@smithy/util-stream@npm:4.3.2" + dependencies: + "@smithy/fetch-http-handler": "npm:^5.2.1" + "@smithy/node-http-handler": "npm:^4.2.1" + "@smithy/types": "npm:^4.5.0" + "@smithy/util-base64": "npm:^4.1.0" + "@smithy/util-buffer-from": "npm:^4.1.0" + "@smithy/util-hex-encoding": "npm:^4.1.0" + "@smithy/util-utf8": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/244739dcb05c1d1cb3e7b2cad313475605846fb1a264220d97777d35ab4c676a9e71a4443fb9f04b5ed0f6cd28c74f692ce75b14840429b0e28abffb6ab10ebb + languageName: node + linkType: hard + "@smithy/util-stream@npm:^4.5.11, @smithy/util-stream@npm:^4.5.12": version: 4.5.12 resolution: "@smithy/util-stream@npm:4.5.12" @@ -6121,6 +8082,24 @@ __metadata: languageName: node linkType: hard +"@smithy/util-uri-escape@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-uri-escape@npm:3.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/d44522339325b0f1fe2c5bf1a3f01d5a699eb8718d800dee24378a1a1b301683756dcfd4be4c32db4d6a00cad85893494778ae39fb246a03aef27d06c9852a67 + languageName: node + linkType: hard + +"@smithy/util-uri-escape@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-uri-escape@npm:4.1.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/c576cb2b7d365d02338734efd83d8b9d2e5ab7ea5a91444762ace367b6fe46e060a2a85ba51ba84ca5ac73b3e732436b22fb61359af4b731b41c1f803f3055ff + languageName: node + linkType: hard + "@smithy/util-uri-escape@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-uri-escape@npm:4.2.0" @@ -6140,6 +8119,26 @@ __metadata: languageName: node linkType: hard +"@smithy/util-utf8@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-utf8@npm:3.0.0" + dependencies: + "@smithy/util-buffer-from": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: 10/1aead297d835af419f75e0c3113c021aa0da671110d1b498035530d5f35d8030092cad5147edaa7ca458aafe27c9383399ccd8176d342942465a2d8357e5cbf4 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-utf8@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": "npm:^4.1.0" + tslib: "npm:^2.6.2" + checksum: 10/4565df6e64df958d2e45da4344d3206a81e66b6e6a48734a45b5228fe73c5c5982ec52beedc8065ab73d169a278f9028438a60410a6daa1d40aebd9dd6122a07 + languageName: node + linkType: hard + "@smithy/util-utf8@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-utf8@npm:4.2.0" @@ -6150,6 +8149,17 @@ __metadata: languageName: node linkType: hard +"@smithy/util-waiter@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-waiter@npm:4.1.1" + dependencies: + "@smithy/abort-controller": "npm:^4.1.1" + "@smithy/types": "npm:^4.5.0" + tslib: "npm:^2.6.2" + checksum: 10/019eecded24b9244675da3b956f572261e333d8d2b0d0555f9c85c893f2583f113bf0210521876e825943085d2d89e7e4fdb768cdc802627b9660d809734cce3 + languageName: node + linkType: hard + "@smithy/util-waiter@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-waiter@npm:4.2.8" @@ -6161,6 +8171,15 @@ __metadata: languageName: node linkType: hard +"@smithy/uuid@npm:^1.0.0": + version: 1.0.0 + resolution: "@smithy/uuid@npm:1.0.0" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/0c6c1d987bfff8569ac16363f9293b91ebcc62824eaa8ba666a5ca007b0899741b3e472165aa9f2ae1beade9ef7773f24645795a35a3ab09bd58d6e0a32179f2 + languageName: node + linkType: hard + "@smithy/uuid@npm:^1.1.0": version: 1.1.0 resolution: "@smithy/uuid@npm:1.1.0" @@ -7204,19 +9223,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": - version: 5.1.1 - resolution: "@types/express-serve-static-core@npm:5.1.1" - dependencies: - "@types/node": "npm:*" - "@types/qs": "npm:*" - "@types/range-parser": "npm:*" - "@types/send": "npm:*" - checksum: 10/7f3d8cf7e68764c9f3e8f6a12825b69ccf5287347fc1c20b29803d4f08a4abc1153ae11d7258852c61aad50f62ef72d4c1b9c97092b0a90462c3dddec2f6026c - languageName: node - linkType: hard - -"@types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": version: 4.19.6 resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: @@ -7237,18 +9244,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^5.0.0, @types/express@npm:^5.0.6": - version: 5.0.6 - resolution: "@types/express@npm:5.0.6" - dependencies: - "@types/body-parser": "npm:*" - "@types/express-serve-static-core": "npm:^5.0.0" - "@types/serve-static": "npm:^2" - checksum: 10/da2cc3de1b1a4d7f20ed3fb6f0a8ee08e99feb3c2eb5a8d643db77017d8d0e70fee9e95da38a73f51bcdf5eda3bb6435073c0271dc04fb16fda92e55daf911fa - languageName: node - linkType: hard - -"@types/express@npm:^4.17.21": +"@types/express@npm:*, @types/express@npm:^4.17.20, @types/express@npm:^4.17.21": version: 4.17.23 resolution: "@types/express@npm:4.17.23" dependencies: @@ -7515,17 +9511,7 @@ __metadata: languageName: node linkType: hard -"@types/serve-static@npm:*, @types/serve-static@npm:^2": - version: 2.2.0 - resolution: "@types/serve-static@npm:2.2.0" - dependencies: - "@types/http-errors": "npm:*" - "@types/node": "npm:*" - checksum: 10/f2bad1304c7d0d3b7221faff3e490c40129d3803f4fb1b2fb84f31f561071c5e6a4b876c41bbbe82d5645034eea936e946bcaaf993dac1093ce68b56effad6e0 - languageName: node - linkType: hard - -"@types/serve-static@npm:^1.15.5": +"@types/serve-static@npm:*, @types/serve-static@npm:^1.15.5": version: 1.15.7 resolution: "@types/serve-static@npm:1.15.7" dependencies: @@ -7771,9 +9757,9 @@ __metadata: escape-goat: "npm:3.0.0" escape-string-regexp: "npm:4.0.0" execa: "npm:^9.6.0" - express: "npm:^5.2.1" + express: "npm:4.21.2" express-interceptor: "npm:1.2.0" - express-prom-bundle: "npm:^8.0.0" + express-prom-bundle: "npm:7" express-session: "npm:1.18.1" fast-safe-stringify: "npm:^2.1.1" formdata-node: "npm:^6.0.3" @@ -8924,16 +10910,6 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^2.0.0": - version: 2.0.0 - resolution: "accepts@npm:2.0.0" - dependencies: - mime-types: "npm:^3.0.0" - negotiator: "npm:^1.0.0" - checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7 - languageName: node - linkType: hard - "accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -9531,6 +11507,26 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" + dependencies: + bytes: "npm:3.1.2" + content-type: "npm:~1.0.5" + debug: "npm:2.6.9" + depd: "npm:2.0.0" + destroy: "npm:1.2.0" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + on-finished: "npm:2.4.1" + qs: "npm:6.13.0" + raw-body: "npm:2.5.2" + type-is: "npm:~1.6.18" + unpipe: "npm:1.0.0" + checksum: 10/8723e3d7a672eb50854327453bed85ac48d045f4958e81e7d470c56bf111f835b97e5b73ae9f6393d0011cc9e252771f46fd281bbabc57d33d3986edf1e6aeca + languageName: node + linkType: hard + "body-parser@npm:1.20.4, body-parser@npm:^1.19.0, body-parser@npm:^1.20.4, body-parser@npm:~1.20.3": version: 1.20.4 resolution: "body-parser@npm:1.20.4" @@ -9551,23 +11547,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:^2.2.1": - version: 2.2.2 - resolution: "body-parser@npm:2.2.2" - dependencies: - bytes: "npm:^3.1.2" - content-type: "npm:^1.0.5" - debug: "npm:^4.4.3" - http-errors: "npm:^2.0.0" - iconv-lite: "npm:^0.7.0" - on-finished: "npm:^2.4.1" - qs: "npm:^6.14.1" - raw-body: "npm:^3.0.1" - type-is: "npm:^2.0.1" - checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 - languageName: node - linkType: hard - "bonjour-service@npm:^1.2.1": version: 1.2.1 resolution: "bonjour-service@npm:1.2.1" @@ -9716,7 +11695,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:^3.1.2, bytes@npm:~3.1.2": +"bytes@npm:3.1.2, bytes@npm:~3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 @@ -10390,7 +12369,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": +"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -10399,14 +12378,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^1.0.0": - version: 1.1.0 - resolution: "content-disposition@npm:1.1.0" - checksum: 10/c4f65e3c001a4a8eb87d0d24c0f112abb139836fb13b8ea67276715e7dce09570ef666ba7848ee8b660d467e6588d030c8ed7e8d0128db6ca78a0800dcd8c7a8 - languageName: node - linkType: hard - -"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 @@ -10458,14 +12430,21 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.1, cookie-signature@npm:^1.2.2": +"cookie-signature@npm:^1.2.2": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 languageName: node linkType: hard -"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2, cookie@npm:~0.7.1": +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: 10/aec6a6aa0781761bf55d60447d6be08861d381136a0fe94aa084fddd4f0300faa2b064df490c6798adfa1ebaef9e0af9b08a189c823e0811b8b313b3d9a03380 + languageName: node + linkType: hard + +"cookie@npm:0.7.2, cookie@npm:^0.7.2, cookie@npm:~0.7.1": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f @@ -10878,7 +12857,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -11041,7 +13020,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": +"depd@npm:2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca @@ -11099,7 +13078,14 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4, detect-libc@npm:^2.1.2": +"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": + version: 2.0.4 + resolution: "detect-libc@npm:2.0.4" + checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0 + languageName: node + linkType: hard + +"detect-libc@npm:^2.1.2": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10/b736c8d97d5d46164c0d1bed53eb4e6a3b1d8530d460211e2d52f1c552875e706c58a5376854e4e54f8b828c9cada58c855288c968522eb93ac7696d65970766 @@ -11331,13 +13317,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -11345,6 +13324,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -11857,7 +13843,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": +"escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 @@ -11960,7 +13946,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:^1.8.1, etag@npm:~1.8.1": +"etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff @@ -12028,7 +14014,7 @@ __metadata: cookie-parser: "npm:^1.4.7" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^5.2.1" + express: "npm:^4.22.0" express-session: "npm:^1.17.3" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -12044,7 +14030,7 @@ __metadata: "@aws-sdk/s3-request-presigner": "npm:^3.338.0" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.0" - express: "npm:^5.2.1" + express: "npm:^4.22.0" languageName: unknown linkType: soft @@ -12079,7 +14065,7 @@ __metadata: "@uppy/tus": "workspace:*" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.1" - express: "npm:^5.2.1" + express: "npm:^4.22.0" express-session: "npm:^1.15.6" npm-run-all: "npm:^4.1.2" preact: "npm:^10.26.10" @@ -12097,7 +14083,7 @@ __metadata: body-parser: "npm:^1.20.4" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^5.2.1" + express: "npm:^4.22.0" vite: "npm:^7.1.11" languageName: unknown linkType: soft @@ -12108,7 +14094,7 @@ __metadata: dependencies: "@uppy/companion": "workspace:*" body-parser: "npm:^1.20.4" - express: "npm:^5.2.1" + express: "npm:^4.22.0" express-session: "npm:^1.15.6" light-server: "npm:^2.4.0" languageName: unknown @@ -12175,7 +14161,7 @@ __metadata: "@react-router/express": "npm:^7.12.0" "@tus/file-store": "npm:latest" "@tus/server": "npm:latest" - "@types/express": "npm:^5.0.6" + "@types/express": "npm:^4.17.20" "@types/react": "npm:^18.2.20" "@types/react-dom": "npm:^18.2.7" "@uppy/core": "workspace:*" @@ -12184,7 +14170,7 @@ __metadata: "@uppy/transloadit": "workspace:*" "@uppy/tus": "workspace:*" "@uppy/xhr-upload": "workspace:*" - express: "npm:^5.2.1" + express: "npm:^4.22.0" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-router: "npm:^7.12.0" @@ -12234,7 +14220,7 @@ __metadata: "@uppy/remote-sources": "workspace:*" "@uppy/transloadit": "workspace:*" "@uppy/webcam": "workspace:*" - express: "npm:^5.2.1" + express: "npm:^4.22.0" he: "npm:^1.2.0" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -12273,7 +14259,7 @@ __metadata: "@uppy/dashboard": "workspace:*" "@uppy/xhr-upload": "workspace:*" cors: "npm:^2.8.5" - express: "npm:^5.2.1" + express: "npm:^4.22.0" multer: "npm:^2.0.2" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -12377,16 +14363,17 @@ __metadata: languageName: node linkType: hard -"express-prom-bundle@npm:^8.0.0": - version: 8.0.0 - resolution: "express-prom-bundle@npm:8.0.0" +"express-prom-bundle@npm:7": + version: 7.0.2 + resolution: "express-prom-bundle@npm:7.0.2" dependencies: - "@types/express": "npm:^5.0.0" + "@types/express": "npm:^4.17.21" + express: "npm:^4.18.2" on-finished: "npm:^2.3.0" url-value-parser: "npm:^2.0.0" peerDependencies: prom-client: ">=15.0.0" - checksum: 10/63bb4769e1ce6258dece3ac1011fccf81e31974bbbdd7e2c7d85679b4cb9bb5b1fc2294ca1648f043bfe42796b9b89f348ad1dfc2680d41c8655394c50606319 + checksum: 10/19d95252eaaaedae1a05d90bbb96cbcc60e82e7710baa18810bd9c327b864b743f4e16bc2a5b3f7e51dcd505ac86db4fd9391c72c11cf6c0dc2c8df893870e02 languageName: node linkType: hard @@ -12406,7 +14393,46 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.21.2": +"express@npm:4.21.2": + version: 4.21.2 + resolution: "express@npm:4.21.2" + dependencies: + accepts: "npm:~1.3.8" + array-flatten: "npm:1.1.1" + body-parser: "npm:1.20.3" + content-disposition: "npm:0.5.4" + content-type: "npm:~1.0.4" + cookie: "npm:0.7.1" + cookie-signature: "npm:1.0.6" + debug: "npm:2.6.9" + depd: "npm:2.0.0" + encodeurl: "npm:~2.0.0" + escape-html: "npm:~1.0.3" + etag: "npm:~1.8.1" + finalhandler: "npm:1.3.1" + fresh: "npm:0.5.2" + http-errors: "npm:2.0.0" + merge-descriptors: "npm:1.0.3" + methods: "npm:~1.1.2" + on-finished: "npm:2.4.1" + parseurl: "npm:~1.3.3" + path-to-regexp: "npm:0.1.12" + proxy-addr: "npm:~2.0.7" + qs: "npm:6.13.0" + range-parser: "npm:~1.2.1" + safe-buffer: "npm:5.2.1" + send: "npm:0.19.0" + serve-static: "npm:1.16.2" + setprototypeof: "npm:1.2.0" + statuses: "npm:2.0.1" + type-is: "npm:~1.6.18" + utils-merge: "npm:1.0.1" + vary: "npm:~1.1.2" + checksum: 10/34571c442fc8c9f2c4b442d2faa10ea1175cf8559237fc6a278f5ce6254a8ffdbeb9a15d99f77c1a9f2926ab183e3b7ba560e3261f1ad4149799e3412ab66bd1 + languageName: node + linkType: hard + +"express@npm:^4.18.2, express@npm:^4.21.2, express@npm:^4.22.0": version: 4.22.1 resolution: "express@npm:4.22.1" dependencies: @@ -12445,42 +14471,6 @@ __metadata: languageName: node linkType: hard -"express@npm:^5.2.1": - version: 5.2.1 - resolution: "express@npm:5.2.1" - dependencies: - accepts: "npm:^2.0.0" - body-parser: "npm:^2.2.1" - content-disposition: "npm:^1.0.0" - content-type: "npm:^1.0.5" - cookie: "npm:^0.7.1" - cookie-signature: "npm:^1.2.1" - debug: "npm:^4.4.0" - depd: "npm:^2.0.0" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - etag: "npm:^1.8.1" - finalhandler: "npm:^2.1.0" - fresh: "npm:^2.0.0" - http-errors: "npm:^2.0.0" - merge-descriptors: "npm:^2.0.0" - mime-types: "npm:^3.0.0" - on-finished: "npm:^2.4.1" - once: "npm:^1.4.0" - parseurl: "npm:^1.3.3" - proxy-addr: "npm:^2.0.7" - qs: "npm:^6.14.0" - range-parser: "npm:^1.2.1" - router: "npm:^2.2.0" - send: "npm:^1.1.0" - serve-static: "npm:^2.2.0" - statuses: "npm:^2.0.1" - type-is: "npm:^2.0.1" - vary: "npm:^1.1.2" - checksum: 10/4aa545d89702ac83f645c77abda1b57bcabe288f0b380fb5580fac4e323ea0eb533005c8e666b4e19152fb16d4abf11ba87b22aa9a10857a0485cd86b94639bd - languageName: node - linkType: hard - "exsolve@npm:^1.0.7": version: 1.0.8 resolution: "exsolve@npm:1.0.8" @@ -12547,6 +14537,28 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:4.2.5": + version: 4.2.5 + resolution: "fast-xml-parser@npm:4.2.5" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: 10/4be7ebe24d6a9a60c278e1423cd86a7da9a77ec64c95563e2c552363caf7a777e0c87c9de1255c2f4e8dea9bce8905dc2bdc58a34e9f2b73c4693654456ad284 + languageName: node + linkType: hard + +"fast-xml-parser@npm:5.2.5": + version: 5.2.5 + resolution: "fast-xml-parser@npm:5.2.5" + dependencies: + strnum: "npm:^2.1.0" + bin: + fxparser: src/cli/cli.js + checksum: 10/305017cff6968a34cbac597317be1516e85c44f650f30d982c84f8c30043e81fd38d39a8810d570136c921399dd43b9ac4775bdfbbbcfee96456f3c086b48bdd + languageName: node + linkType: hard + "fast-xml-parser@npm:5.3.4": version: 5.3.4 resolution: "fast-xml-parser@npm:5.3.4" @@ -12642,17 +14654,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:^2.1.0": - version: 2.1.1 - resolution: "finalhandler@npm:2.1.1" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: - debug: "npm:^4.4.0" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - on-finished: "npm:^2.4.1" - parseurl: "npm:^1.3.3" - statuses: "npm:^2.0.1" - checksum: 10/f4ba75c23408d8f9d393c3e875b9452e84d68c925411a6e67b7efa678b0bed5075ef33def4bb65ed8e0dd37c92a3ea354bcbde07303cd4dc2550e12b95885067 + debug: "npm:2.6.9" + encodeurl: "npm:~2.0.0" + escape-html: "npm:~1.0.3" + on-finished: "npm:2.4.1" + parseurl: "npm:~1.3.3" + statuses: "npm:2.0.1" + unpipe: "npm:~1.0.0" + checksum: 10/4babe72969b7373b5842bc9f75c3a641a4d0f8eb53af6b89fa714d4460ce03fb92b28de751d12ba415e96e7e02870c436d67412120555e2b382640535697305b languageName: node linkType: hard @@ -12851,13 +14864,6 @@ __metadata: languageName: node linkType: hard -"fresh@npm:^2.0.0": - version: 2.0.0 - resolution: "fresh@npm:2.0.0" - checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc - languageName: node - linkType: hard - "fs-extra@npm:^11.0.0": version: 11.3.0 resolution: "fs-extra@npm:11.3.0" @@ -13546,19 +15552,6 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": - version: 2.0.1 - resolution: "http-errors@npm:2.0.1" - dependencies: - depd: "npm:~2.0.0" - inherits: "npm:~2.0.4" - setprototypeof: "npm:~1.2.0" - statuses: "npm:~2.0.2" - toidentifier: "npm:~1.0.1" - checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 - languageName: node - linkType: hard - "http-errors@npm:~1.6.2": version: 1.6.3 resolution: "http-errors@npm:1.6.3" @@ -13571,6 +15564,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": + version: 2.0.1 + resolution: "http-errors@npm:2.0.1" + dependencies: + depd: "npm:~2.0.0" + inherits: "npm:~2.0.4" + setprototypeof: "npm:~1.2.0" + statuses: "npm:~2.0.2" + toidentifier: "npm:~1.0.1" + checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 + languageName: node + linkType: hard + "http-parser-js@npm:>=0.5.1": version: 0.5.8 resolution: "http-parser-js@npm:0.5.8" @@ -13704,16 +15710,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f - languageName: node - linkType: hard - -"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": +"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -13722,12 +15719,12 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": - version: 0.7.2 - resolution: "iconv-lite@npm:0.7.2" +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24c937b532f868e938386b62410b303b7c767ce3d08dc2829cbe59464d5a26ef86ae5ad1af6b34eec43ddfea39e7d101638644b0178d67262fa87015d59f983a + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f languageName: node linkType: hard @@ -14179,13 +16176,6 @@ __metadata: languageName: node linkType: hard -"is-promise@npm:^4.0.0": - version: 4.0.0 - resolution: "is-promise@npm:4.0.0" - checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a - languageName: node - linkType: hard - "is-reference@npm:^3.0.3": version: 3.0.3 resolution: "is-reference@npm:3.0.3" @@ -15477,7 +17467,14 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.21, lodash@npm:^4.17.23": +"lodash@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 + languageName: node + linkType: hard + +"lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10/82504c88250f58da7a5a4289f57a4f759c44946c005dd232821c7688b5fcfbf4a6268f6a6cdde4b792c91edd2f3b5398c1d2a0998274432cff76def48735e233 @@ -15739,13 +17736,6 @@ __metadata: languageName: node linkType: hard -"media-typer@npm:^1.1.0": - version: 1.1.0 - resolution: "media-typer@npm:1.1.0" - checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd - languageName: node - linkType: hard - "memfs@npm:^4.6.0": version: 4.9.3 resolution: "memfs@npm:4.9.3" @@ -15772,13 +17762,6 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-descriptors@npm:2.0.0" - checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a - languageName: node - linkType: hard - "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -15810,20 +17793,13 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:1.52.0": +"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": version: 1.52.0 resolution: "mime-db@npm:1.52.0" checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 languageName: node linkType: hard -"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": - version: 1.54.0 - resolution: "mime-db@npm:1.54.0" - checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 - languageName: node - linkType: hard - "mime-match@npm:^1.0.2": version: 1.0.2 resolution: "mime-match@npm:1.0.2" @@ -15842,15 +17818,6 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": - version: 3.0.2 - resolution: "mime-types@npm:3.0.2" - dependencies: - mime-db: "npm:^1.54.0" - checksum: 10/9db0ad31f5eff10ee8f848130779b7f2d056ddfdb6bda696cb69be68d486d33a3457b4f3f9bdeb60d0736edb471bd5a7c0a384375c011c51c889fd0d5c3b893e - languageName: node - linkType: hard - "mime@npm:1.6.0, mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -16115,7 +18082,16 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" + dependencies: + minipass: "npm:^7.1.2" + checksum: 10/c075bed1594f68dcc8c35122333520112daefd4d070e5d0a228bd4cf5580e9eed3981b96c0ae1d62488e204e80fd27b2b9d0068ca9a5ef3993e9565faf63ca41 + languageName: node + linkType: hard + +"minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" dependencies: @@ -16144,6 +18120,15 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 10/16fd79c28645759505914561e249b9a1f5fe3362279ad95487a4501e4467abeb714fd35b95307326b8fd03f3c7719065ef11a6f97b7285d7888306d1bd2232ba + languageName: node + linkType: hard + "moment-timezone@npm:^0.5.31": version: 0.5.45 resolution: "moment-timezone@npm:0.5.45" @@ -17480,6 +19465,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:0.1.12, path-to-regexp@npm:~0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e + languageName: node + linkType: hard + "path-to-regexp@npm:^6.3.0": version: 6.3.0 resolution: "path-to-regexp@npm:6.3.0" @@ -17487,20 +19479,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^8.0.0": - version: 8.4.2 - resolution: "path-to-regexp@npm:8.4.2" - checksum: 10/70fd2cbce0b962cbcf4d312af07818bfce2bae11c09cf3bd86be99c0e30168238a1a7b02b18b452e73f075897df04597d30d63e56da7be41eecfc37998693389 - languageName: node - linkType: hard - -"path-to-regexp@npm:~0.1.12": - version: 0.1.12 - resolution: "path-to-regexp@npm:0.1.12" - checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e - languageName: node - linkType: hard - "path-type@npm:^3.0.0": version: 3.0.0 resolution: "path-type@npm:3.0.0" @@ -18334,7 +20312,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": +"proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -18386,16 +20364,16 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.6": - version: 6.15.1 - resolution: "qs@npm:6.15.1" +"qs@npm:6.13.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: - side-channel: "npm:^1.1.0" - checksum: 10/ec10b9957446b3f4a38000940f6374720b4e2985209b89df197066038c951472ea24cd98d6bc6df73a0cbec75bc056f638032e3fb447345017ff7e0f0a2693ac + side-channel: "npm:^1.0.6" + checksum: 10/f548b376e685553d12e461409f0d6e5c59ec7c7d76f308e2a888fd9db3e0c5e89902bedd0754db3a9038eda5f27da2331a6f019c8517dc5e0a16b3c9a6e9cef8 languageName: node linkType: hard -"qs@npm:~6.14.0": +"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.9.6, qs@npm:~6.14.0": version: 6.14.0 resolution: "qs@npm:6.14.0" dependencies: @@ -18455,15 +20433,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:^3.0.1": - version: 3.0.2 - resolution: "raw-body@npm:3.0.2" +"raw-body@npm:2.5.2": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" dependencies: - bytes: "npm:~3.1.2" - http-errors: "npm:~2.0.1" - iconv-lite: "npm:~0.7.0" - unpipe: "npm:~1.0.0" - checksum: 10/4168c82157bd69175d5bd960e59b74e253e237b358213694946a427a6f750a18b8e150f036fed3421b3e83294b071a4e2bb01037a79ccacdac05360c63d3ebba + bytes: "npm:3.1.2" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + unpipe: "npm:1.0.0" + checksum: 10/863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95 languageName: node linkType: hard @@ -19098,19 +21076,6 @@ __metadata: languageName: node linkType: hard -"router@npm:^2.2.0": - version: 2.2.0 - resolution: "router@npm:2.2.0" - dependencies: - debug: "npm:^4.4.0" - depd: "npm:^2.0.0" - is-promise: "npm:^4.0.0" - parseurl: "npm:^1.3.3" - path-to-regexp: "npm:^8.0.0" - checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91 - languageName: node - linkType: hard - "rrweb-cssom@npm:^0.8.0": version: 0.8.0 resolution: "rrweb-cssom@npm:0.8.0" @@ -19344,7 +21309,16 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": + version: 7.7.2 + resolution: "semver@npm:7.7.2" + bin: + semver: bin/semver.js + checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda + languageName: node + linkType: hard + +"semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -19395,25 +21369,6 @@ __metadata: languageName: node linkType: hard -"send@npm:^1.1.0, send@npm:^1.2.0": - version: 1.2.1 - resolution: "send@npm:1.2.1" - dependencies: - debug: "npm:^4.4.3" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - etag: "npm:^1.8.1" - fresh: "npm:^2.0.0" - http-errors: "npm:^2.0.1" - mime-types: "npm:^3.0.2" - ms: "npm:^2.1.3" - on-finished: "npm:^2.4.1" - range-parser: "npm:^1.2.1" - statuses: "npm:^2.0.2" - checksum: 10/274f842d69ccfa49d4940a85598c6825da58dee6cb8ea33b08d5bd3988e6a82267c4d7c32b23d0e4706aad076ee95b1edfa13f859877db9b589829019397e355 - languageName: node - linkType: hard - "send@npm:~0.19.0": version: 0.19.1 resolution: "send@npm:0.19.1" @@ -19468,15 +21423,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:^2.2.0": - version: 2.2.1 - resolution: "serve-static@npm:2.2.1" +"serve-static@npm:1.16.2, serve-static@npm:~1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - parseurl: "npm:^1.3.3" - send: "npm:^1.2.0" - checksum: 10/71500fe80cc7163fec04e4297de7591ad1cb682d137fc030e7a53e57040fda5187e8082a9c1b2ef37f1d3f9c27c9a94d4ba61806ebc28938ba4a7c8947c9f71e + encodeurl: "npm:~2.0.0" + escape-html: "npm:~1.0.3" + parseurl: "npm:~1.3.3" + send: "npm:0.19.0" + checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 languageName: node linkType: hard @@ -19492,18 +21447,6 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:~1.16.2": - version: 1.16.2 - resolution: "serve-static@npm:1.16.2" - dependencies: - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.19.0" - checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 - languageName: node - linkType: hard - "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -19732,7 +21675,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.1.0": +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -20111,7 +22054,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.1, statuses@npm:~2.0.2": +"statuses@npm:^2.0.1, statuses@npm:~2.0.1, statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 @@ -20321,7 +22264,7 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.1.1": +"strnum@npm:^1.0.5, strnum@npm:^1.1.1": version: 1.1.2 resolution: "strnum@npm:1.1.2" checksum: 10/ccd6297a1fdaf0fc8ea0ea904acdae76878d49a4b0d98a70155df4bc081fd88eac5ec99fb150f3d1d1af065c1898d38420705259ba6c39aa850c671bcd54e35d @@ -20551,7 +22494,21 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.4.3, tar@npm:^7.5.7": +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.0.1" + mkdirp: "npm:^3.0.1" + yallist: "npm:^5.0.0" + checksum: 10/12a2a4fc6dee23e07cc47f1aeb3a14a1afd3f16397e1350036a8f4cdfee8dcac7ef5978337a4e7b2ac2c27a9a6d46388fc2088ea7c80cb6878c814b1425f8ecf + languageName: node + linkType: hard + +"tar@npm:^7.5.7": version: 7.5.12 resolution: "tar@npm:7.5.12" dependencies: @@ -20947,17 +22904,6 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^2.0.1": - version: 2.0.1 - resolution: "type-is@npm:2.0.1" - dependencies: - content-type: "npm:^1.0.5" - media-typer: "npm:^1.1.0" - mime-types: "npm:^3.0.0" - checksum: 10/bacdb23c872dacb7bd40fbd9095e6b2fca2895eedbb689160c05534d7d4810a7f4b3fd1ae87e96133c505958f6d602967a68db5ff577b85dd6be76eaa75d58af - languageName: node - linkType: hard - "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -21239,7 +23185,7 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:~1.0.0": +"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10/4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 @@ -21371,6 +23317,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^9.0.1": + version: 9.0.1 + resolution: "uuid@npm:9.0.1" + bin: + uuid: dist/bin/uuid + checksum: 10/9d0b6adb72b736e36f2b1b53da0d559125ba3e39d913b6072f6f033e0c87835b414f0836b45bcfaf2bdf698f92297fea1c3cc19b0b258bc182c9c43cc0fab9f2 + languageName: node + linkType: hard + "valibot@npm:^1.2.0": version: 1.2.0 resolution: "valibot@npm:1.2.0" @@ -21416,7 +23371,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 From d9d44ce5e5dcf694e7dc7ccb04f05bc1ce61dc13 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 21 May 2026 08:44:23 +0530 Subject: [PATCH 21/33] upgrade to express v5 (#6304) exact copy of #6175 - I will point the uppy deps upgrade pr to this PR's branch - no other changes needed in this branch as #6175 was reviewed and all the comments were resolved this should be the order of merge : 1. #6300 2. uppy deps upgrade ( yet to be raised ) 3. merge this to main 4. merge biome changes #6244 @mifi let me know if you think otherwise. --------- Co-authored-by: Mikael Finstad --- .changeset/happy-timers-kick.md | 5 + .changeset/smooth-chefs-occur.md | 5 + examples/aws-companion/package.json | 2 +- examples/aws-nodejs/package.json | 2 +- .../companion-custom-provider/package.json | 2 +- .../package.json | 2 +- examples/companion/package.json | 2 +- examples/reactrouter/package.json | 4 +- examples/reactrouter/server.ts | 6 +- examples/transloadit/package.json | 2 +- examples/xhr-bundle/package.json | 2 +- packages/@uppy/aws-s3/src/index.ts | 9 +- packages/@uppy/companion/package.json | 4 +- packages/@uppy/companion/src/companion.ts | 11 +- .../src/server/controllers/callback.ts | 2 +- .../companion/src/server/controllers/list.ts | 5 +- .../src/server/controllers/preauth.ts | 2 +- .../src/server/controllers/refresh-token.ts | 2 +- .../companion/src/server/controllers/s3.ts | 24 +- .../src/server/controllers/simple-auth.ts | 2 +- .../src/server/controllers/thumbnail.ts | 2 +- .../@uppy/companion/src/server/middlewares.ts | 8 +- .../companion/src/standalone/start-server.ts | 8 +- .../@uppy/companion/test/companion.test.ts | 22 + packages/@uppy/companion/test/cors.test.ts | 2 +- packages/@uppy/companion/test/mockserver.ts | 23 +- yarn.lock | 2611 +++-------------- 27 files changed, 439 insertions(+), 2332 deletions(-) create mode 100644 .changeset/happy-timers-kick.md create mode 100644 .changeset/smooth-chefs-occur.md diff --git a/.changeset/happy-timers-kick.md b/.changeset/happy-timers-kick.md new file mode 100644 index 000000000..d06fc6eb1 --- /dev/null +++ b/.changeset/happy-timers-kick.md @@ -0,0 +1,5 @@ +--- +"@uppy/aws-s3": patch +--- + +Improve type diff --git a/.changeset/smooth-chefs-occur.md b/.changeset/smooth-chefs-occur.md new file mode 100644 index 000000000..66a598445 --- /dev/null +++ b/.changeset/smooth-chefs-occur.md @@ -0,0 +1,5 @@ +--- +"@uppy/companion": major +--- + +Upgrade to express 5 - Companion no longer works when used as a middleware with Express 4. diff --git a/examples/aws-companion/package.json b/examples/aws-companion/package.json index f061bbcdb..0fe81edb2 100644 --- a/examples/aws-companion/package.json +++ b/examples/aws-companion/package.json @@ -15,7 +15,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.17.3", "npm-run-all": "^4.1.5", "vite": "^7.1.11" diff --git a/examples/aws-nodejs/package.json b/examples/aws-nodejs/package.json index cfcbde2a1..bdc013ed0 100644 --- a/examples/aws-nodejs/package.json +++ b/examples/aws-nodejs/package.json @@ -15,6 +15,6 @@ "@aws-sdk/s3-request-presigner": "^3.338.0", "body-parser": "^1.20.4", "dotenv": "^16.0.0", - "express": "^4.22.0" + "express": "^5.2.1" } } diff --git a/examples/companion-custom-provider/package.json b/examples/companion-custom-provider/package.json index 6d6c08c18..fdf0e4205 100644 --- a/examples/companion-custom-provider/package.json +++ b/examples/companion-custom-provider/package.json @@ -19,7 +19,7 @@ "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.15.6", "npm-run-all": "^4.1.2", "vite": "^7.1.11" diff --git a/examples/companion-digitalocean-spaces/package.json b/examples/companion-digitalocean-spaces/package.json index b308f3455..4a99539a7 100644 --- a/examples/companion-digitalocean-spaces/package.json +++ b/examples/companion-digitalocean-spaces/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "dotenv": "^16.0.1", - "express": "^4.22.0", + "express": "^5.2.1", "vite": "^7.1.11" }, "private": true, diff --git a/examples/companion/package.json b/examples/companion/package.json index f517ffb97..a85a0b826 100644 --- a/examples/companion/package.json +++ b/examples/companion/package.json @@ -4,7 +4,7 @@ "dependencies": { "@uppy/companion": "workspace:*", "body-parser": "^1.20.4", - "express": "^4.22.0", + "express": "^5.2.1", "express-session": "^1.15.6", "light-server": "^2.4.0" }, diff --git a/examples/reactrouter/package.json b/examples/reactrouter/package.json index c6849a34e..4420f7540 100644 --- a/examples/reactrouter/package.json +++ b/examples/reactrouter/package.json @@ -20,14 +20,14 @@ "@uppy/transloadit": "workspace:*", "@uppy/tus": "workspace:*", "@uppy/xhr-upload": "workspace:*", - "express": "^4.22.0", + "express": "^5.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router": "^7.12.0" }, "devDependencies": { "@react-router/dev": "^7.12.0", - "@types/express": "^4.17.20", + "@types/express": "^5.0.6", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "tsx": "^4.0.0", diff --git a/examples/reactrouter/server.ts b/examples/reactrouter/server.ts index 80ee0542c..8e9c30392 100644 --- a/examples/reactrouter/server.ts +++ b/examples/reactrouter/server.ts @@ -41,7 +41,9 @@ async function startServer() { // TUS upload endpoints (before React Router) app.all('/api/upload/tus', (req, res) => tusServer.handle(req, res)) - app.all('/api/upload/tus/*', (req, res) => tusServer.handle(req, res)) + app.all('/api/upload/tus/{*splat}', (req, res) => + tusServer.handle(req, res), + ) // Handle Chrome DevTools requests silently app.get('/.well-known/appspecific/com.chrome.devtools.json', (req, res) => { @@ -49,7 +51,7 @@ async function startServer() { }) // React Router handles all other routes - app.all('*', reactRouterHandler) + app.all('/{*splat}', reactRouterHandler) const port = process.env.PORT || 3000 const server = app.listen(port, () => { diff --git a/examples/transloadit/package.json b/examples/transloadit/package.json index 6072b43ab..bb08b521e 100644 --- a/examples/transloadit/package.json +++ b/examples/transloadit/package.json @@ -15,7 +15,7 @@ "@uppy/remote-sources": "workspace:*", "@uppy/transloadit": "workspace:*", "@uppy/webcam": "workspace:*", - "express": "^4.22.0", + "express": "^5.2.1", "he": "^1.2.0" }, "private": true, diff --git a/examples/xhr-bundle/package.json b/examples/xhr-bundle/package.json index 249ae1a63..cd36e6bbb 100644 --- a/examples/xhr-bundle/package.json +++ b/examples/xhr-bundle/package.json @@ -6,7 +6,7 @@ "@uppy/dashboard": "workspace:*", "@uppy/xhr-upload": "workspace:*", "cors": "^2.8.5", - "express": "^4.22.0", + "express": "^5.2.1", "multer": "^2.0.2" }, "devDependencies": { diff --git a/packages/@uppy/aws-s3/src/index.ts b/packages/@uppy/aws-s3/src/index.ts index d248f4c5b..e1afe29c1 100644 --- a/packages/@uppy/aws-s3/src/index.ts +++ b/packages/@uppy/aws-s3/src/index.ts @@ -662,10 +662,11 @@ export default class AwsS3Multipart< querify: true, }) - const query = new URLSearchParams({ filename, type, ...metadata } as Record< - string, - string - >) + const query = new URLSearchParams({ + filename, + ...(type != null && { type }), + ...metadata, + }) return this.#client.get(`s3/params?${query}`, options) } diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 42ed317f6..02e389eec 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -47,9 +47,9 @@ "cors": "^2.8.5", "escape-goat": "3.0.0", "escape-string-regexp": "4.0.0", - "express": "4.21.2", + "express": "^5.2.1", "express-interceptor": "1.2.0", - "express-prom-bundle": "7", + "express-prom-bundle": "^8.0.0", "express-session": "1.18.1", "fast-safe-stringify": "^2.1.1", "formdata-node": "^6.0.3", diff --git a/packages/@uppy/companion/src/companion.ts b/packages/@uppy/companion/src/companion.ts index ab32d7d64..290b66561 100644 --- a/packages/@uppy/companion/src/companion.ts +++ b/packages/@uppy/companion/src/companion.ts @@ -125,6 +125,9 @@ export function app(optionsArg: CompanionInitOptions) { const app = express() + // Needed for e.g. s3 `/params` endpoint metadata, like `metadata[key]=value` to be parsed into a metadata object + app.set('query parser', 'extended') + if (options.metrics) { app.use(middlewares.metrics({ path: options.server.path })) } @@ -136,10 +139,10 @@ export function app(optionsArg: CompanionInitOptions) { app.use(interceptGrantErrorResponse) // override provider credentials at request time - // Making `POST` request to the `/connect/:provider/:override?` route requires a form body parser middleware: + // Making `POST` request to the `/connect/:provider{/:override}` route requires a form body parser middleware: // See https://github.com/simov/grant#dynamic-http app.use( - '/connect/:oauthProvider/:override?', + '/connect/:oauthProvider{/:override}', express.urlencoded({ extended: false }), getCredentialsOverrideMiddleware( providers as Record, @@ -159,7 +162,7 @@ export function app(optionsArg: CompanionInitOptions) { app.use(middlewares.cors(options)) // add uppy options to the request object so it can be accessed by subsequent handlers. - app.use('*', middlewares.getCompanionMiddleware(options)) + app.use(middlewares.getCompanionMiddleware(options)) app.use('/s3', s3(options.s3)) if (options.enableUrlEndpoint) app.use('/url', url()) if (options.enableGooglePickerEndpoint) @@ -232,7 +235,7 @@ export function app(optionsArg: CompanionInitOptions) { ) app.get( - '/:providerName/list/:id?', + '/:providerName/list{/:id}', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.list, diff --git a/packages/@uppy/companion/src/server/controllers/callback.ts b/packages/@uppy/companion/src/server/controllers/callback.ts index 7e1ab3a69..83a2b96e6 100644 --- a/packages/@uppy/companion/src/server/controllers/callback.ts +++ b/packages/@uppy/companion/src/server/controllers/callback.ts @@ -20,7 +20,7 @@ export default function callback( const providerName = req.params['providerName'] const { companion } = req - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/list.ts b/packages/@uppy/companion/src/server/controllers/list.ts index f6acfa4d3..8c7f7e244 100644 --- a/packages/@uppy/companion/src/server/controllers/list.ts +++ b/packages/@uppy/companion/src/server/controllers/list.ts @@ -7,8 +7,9 @@ export default async function list( next: NextFunction, ): Promise { const { query, params, companion } = req + const id = params['id'] const { providerUserSession, provider } = companion - if (!provider) { + if (!provider || (typeof id !== 'string' && id != null)) { res.sendStatus(400) return } @@ -17,7 +18,7 @@ export default async function list( const data = await provider.list({ companion, providerUserSession, - directory: params['id'], + directory: id, query, }) res.json(data) diff --git a/packages/@uppy/companion/src/server/controllers/preauth.ts b/packages/@uppy/companion/src/server/controllers/preauth.ts index e3b30a226..210058e2b 100644 --- a/packages/@uppy/companion/src/server/controllers/preauth.ts +++ b/packages/@uppy/companion/src/server/controllers/preauth.ts @@ -14,7 +14,7 @@ export default function preauth(req: Request, res: Response): void { } const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/refresh-token.ts b/packages/@uppy/companion/src/server/controllers/refresh-token.ts index c6d5ab5ac..e8e513dcb 100644 --- a/packages/@uppy/companion/src/server/controllers/refresh-token.ts +++ b/packages/@uppy/companion/src/server/controllers/refresh-token.ts @@ -12,7 +12,7 @@ export default async function refreshToken( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (providerName == null) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/s3.ts b/packages/@uppy/companion/src/server/controllers/s3.ts index dcfd4c4a1..e9bf0e9fc 100644 --- a/packages/@uppy/companion/src/server/controllers/s3.ts +++ b/packages/@uppy/companion/src/server/controllers/s3.ts @@ -1,3 +1,4 @@ +import assert from 'node:assert' import type { Part, S3Client } from '@aws-sdk/client-s3' import { AbortMultipartUploadCommand, @@ -247,6 +248,11 @@ export default function s3( const { uploadId } = req.params const { key } = req.query + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: @@ -260,7 +266,7 @@ export default function s3( const parts: Part[] = [] - function listPartsPage(startAt?: string) { + const listPartsPage = (startAt?: string) => { s3Client .send( new ListPartsCommand({ @@ -303,7 +309,7 @@ export default function s3( const partNumber = req.params['partNumber'] const key = req.query['key'] - if (uploadId == null || uploadId.length === 0) { + if (typeof uploadId !== 'string' || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -314,7 +320,7 @@ export default function s3( }) return } - if (partNumber == null || !parseInt(partNumber, 10)) { + if (typeof partNumber !== 'string' || !parseInt(partNumber, 10)) { res.status(400).json({ error: 's3: the part number must be a number between 1 and 10000.', }) @@ -363,7 +369,7 @@ export default function s3( const key = req.query['key'] const partNumbers = req.query['partNumbers'] - if (uploadId == null || uploadId.length === 0) { + if (typeof uploadId !== 'string' || uploadId.length === 0) { res.status(400).json({ error: 's3: uploadId must be provided.' }) return } @@ -443,6 +449,11 @@ export default function s3( const { uploadId } = req.params const { key } = req.query + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: @@ -488,6 +499,11 @@ export default function s3( const { key } = req.query const { parts }: { parts: unknown } = req.body + assert( + typeof uploadId === 'string' && uploadId.length > 0, + 's3: uploadId must be provided.', + ) + if (typeof key !== 'string') { res.status(400).json({ error: diff --git a/packages/@uppy/companion/src/server/controllers/simple-auth.ts b/packages/@uppy/companion/src/server/controllers/simple-auth.ts index c1171356c..6ddef8af2 100644 --- a/packages/@uppy/companion/src/server/controllers/simple-auth.ts +++ b/packages/@uppy/companion/src/server/controllers/simple-auth.ts @@ -9,7 +9,7 @@ export default async function simpleAuth( next: NextFunction, ): Promise { const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/controllers/thumbnail.ts b/packages/@uppy/companion/src/server/controllers/thumbnail.ts index bae18cafd..03abf9dea 100644 --- a/packages/@uppy/companion/src/server/controllers/thumbnail.ts +++ b/packages/@uppy/companion/src/server/controllers/thumbnail.ts @@ -7,7 +7,7 @@ async function thumbnail( next: NextFunction, ): Promise { const id = req.params['id'] - if (id == null) { + if (typeof id !== 'string' || id.length === 0) { res.sendStatus(400) return } diff --git a/packages/@uppy/companion/src/server/middlewares.ts b/packages/@uppy/companion/src/server/middlewares.ts index 4dd3103b6..92def8aee 100644 --- a/packages/@uppy/companion/src/server/middlewares.ts +++ b/packages/@uppy/companion/src/server/middlewares.ts @@ -97,7 +97,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { } const { secret } = req.companion.options const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { res.sendStatus(400) return } @@ -124,7 +124,9 @@ export const verifyToken: RequestHandler = (req, res, next) => { const { providerOptions } = req.companion.options const providerName = req.params['providerName'] const providerOption = - providerName != null ? providerOptions?.[providerName] : undefined + typeof providerName === 'string' + ? providerOptions?.[providerName] + : undefined const key = providerOption?.key if (!key) { logger.info( @@ -146,7 +148,7 @@ export const verifyToken: RequestHandler = (req, res, next) => { // does not fail if token is invalid export const gentleVerifyToken: RequestHandler = (req, res, next) => { const providerName = req.params['providerName'] - if (providerName == null || providerName.length === 0) { + if (typeof providerName !== 'string' || providerName.length === 0) { next() return } diff --git a/packages/@uppy/companion/src/standalone/start-server.ts b/packages/@uppy/companion/src/standalone/start-server.ts index ec4dc713b..fcc54347a 100644 --- a/packages/@uppy/companion/src/standalone/start-server.ts +++ b/packages/@uppy/companion/src/standalone/start-server.ts @@ -9,7 +9,9 @@ const port: string | number = const { app, companionOptions } = standalone() -companion.socket(app.listen(port), companionOptions) +const server = app.listen(port, () => { + logger.info(`Welcome to Companion! v${packageJson.version}`) + logger.info(`Listening on http://localhost:${port}`) -logger.info(`Welcome to Companion! v${packageJson.version}`) -logger.info(`Listening on http://localhost:${port}`) + companion.socket(server, companionOptions) +}) diff --git a/packages/@uppy/companion/test/companion.test.ts b/packages/@uppy/companion/test/companion.test.ts index be3f458a6..4eef1110b 100644 --- a/packages/@uppy/companion/test/companion.test.ts +++ b/packages/@uppy/companion/test/companion.test.ts @@ -426,4 +426,26 @@ describe('S3 controller', () => { ), ) }) + + test('getUploadParameters supports bracket metadata query format', async () => { + const server = await getServer({ + COMPANION_AWS_KEY: 'test_key', + COMPANION_AWS_SECRET: 'test_secret', + COMPANION_AWS_BUCKET: 'test-bucket', + COMPANION_AWS_REGION: 'us-east-1', + }) + + return request(server) + .get('/s3/params') + .query({ + filename: 'test.txt', + type: 'text/plain', + 'metadata[name]': 'demo-file', + }) + .expect(200) + .then((res) => { + const fields = res.body.fields as Record + expect(fields['x-amz-meta-name']).toBe('demo-file') + }) + }) }) diff --git a/packages/@uppy/companion/test/cors.test.ts b/packages/@uppy/companion/test/cors.test.ts index 6e3bc58f6..3abb2cff9 100644 --- a/packages/@uppy/companion/test/cors.test.ts +++ b/packages/@uppy/companion/test/cors.test.ts @@ -19,7 +19,7 @@ async function run({ next() }) app.use(cors(corsOptions)) - app.options('*', (_req, res) => { + app.options('/{*splat}', (_req, res) => { res.status(204).end() }) diff --git a/packages/@uppy/companion/test/mockserver.ts b/packages/@uppy/companion/test/mockserver.ts index 1a66514ca..4effa2983 100644 --- a/packages/@uppy/companion/test/mockserver.ts +++ b/packages/@uppy/companion/test/mockserver.ts @@ -101,7 +101,7 @@ export const getServerWithEmitter = async ( authServer.use( session({ secret: 'grant', resave: true, saveUninitialized: true }), ) - authServer.all('*/callback', (req, res, next) => { + authServer.all('{*splat}/callback', (req, res, next) => { if (req.session) { req.session['grant'] = { response: { access_token: grantToken }, @@ -109,16 +109,19 @@ export const getServerWithEmitter = async ( } next() }) - authServer.all(['*/send-token', '*/redirect'], (req, res, next) => { - const state = - typeof req.query['state'] === 'string' ? req.query['state'] : null - if (req.session) { - req.session['grant'] = { - dynamic: { state: state ?? 'non-empty-value' }, + authServer.all( + ['{*splat}/send-token', '{*splat}/redirect'], + (req, res, next) => { + const state = + typeof req.query['state'] === 'string' ? req.query['state'] : null + if (req.session) { + req.session['grant'] = { + dynamic: { state: state ?? 'non-empty-value' }, + } } - } - next() - }) + next() + }, + ) const { app, emitter } = standalone() authServer.use(app) diff --git a/yarn.lock b/yarn.lock index 3f12ff7b1..049829d74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -509,7 +509,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:3.986.0": +"@aws-sdk/client-s3@npm:3.986.0, @aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/client-s3@npm:3.986.0" dependencies: @@ -572,211 +572,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": - version: 3.896.0 - resolution: "@aws-sdk/client-s3@npm:3.896.0" - dependencies: - "@aws-crypto/sha1-browser": "npm:5.2.0" - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/credential-provider-node": "npm:3.896.0" - "@aws-sdk/middleware-bucket-endpoint": "npm:3.893.0" - "@aws-sdk/middleware-expect-continue": "npm:3.893.0" - "@aws-sdk/middleware-flexible-checksums": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-location-constraint": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" - "@aws-sdk/middleware-ssec": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@aws-sdk/xml-builder": "npm:3.894.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/eventstream-serde-browser": "npm:^4.1.1" - "@smithy/eventstream-serde-config-resolver": "npm:^4.2.1" - "@smithy/eventstream-serde-node": "npm:^4.1.1" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-blob-browser": "npm:^4.1.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/hash-stream-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/md5-js": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - "@smithy/util-waiter": "npm:^4.1.1" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/4a65786cd019e0fee172f7da37aab882e39669052e239a284bd1409877c394949779ba909ed5596caa4e12586b9d466099a8d596f8a5019f7eb4bc2dfcf89ba8 - languageName: node - linkType: hard - -"@aws-sdk/client-sso-oidc@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.600.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/client-sts": "npm:3.600.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/credential-provider-node": "npm:3.600.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/66343fc13ffd5d412ca2232a91dce14ee287ed611fb27cd1fe887bb36bf380d585c74473251bd9d688fab51b4f9bd4375bf7d8583effb3d07c6ac5f7cb85c597 - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/client-sso@npm:3.598.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/6571a678ae4e0c42c245a2e7b969d5d2e4713dc5fe7604e5edc883a6f729362d1256f1c144094f8146e0fd85da675533c0e460c5217b1d17aecb2042201e169e - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/client-sso@npm:3.896.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/0358688ecd1ac7ce0d451af66ce9c72ca9f7e750f029f5be4450946b8a07d6f52458262e60fdd6c4817ee94e9337a7235ec9bbe58085c6bfef24ed1641772c81 - languageName: node - linkType: hard - "@aws-sdk/client-sso@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/client-sso@npm:3.985.0" @@ -823,55 +618,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.338.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sts@npm:3.600.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/client-sso-oidc": "npm:3.600.0" - "@aws-sdk/core": "npm:3.598.0" - "@aws-sdk/credential-provider-node": "npm:3.600.0" - "@aws-sdk/middleware-host-header": "npm:3.598.0" - "@aws-sdk/middleware-logger": "npm:3.598.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.598.0" - "@aws-sdk/middleware-user-agent": "npm:3.598.0" - "@aws-sdk/region-config-resolver": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@aws-sdk/util-user-agent-browser": "npm:3.598.0" - "@aws-sdk/util-user-agent-node": "npm:3.598.0" - "@smithy/config-resolver": "npm:^3.0.2" - "@smithy/core": "npm:^2.2.1" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/hash-node": "npm:^3.0.1" - "@smithy/invalid-dependency": "npm:^3.0.1" - "@smithy/middleware-content-length": "npm:^3.0.1" - "@smithy/middleware-endpoint": "npm:^3.0.2" - "@smithy/middleware-retry": "npm:^3.0.4" - "@smithy/middleware-serde": "npm:^3.0.1" - "@smithy/middleware-stack": "npm:^3.0.1" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/url-parser": "npm:^3.0.1" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-body-length-browser": "npm:^3.0.0" - "@smithy/util-body-length-node": "npm:^3.0.0" - "@smithy/util-defaults-mode-browser": "npm:^3.0.4" - "@smithy/util-defaults-mode-node": "npm:^3.0.4" - "@smithy/util-endpoints": "npm:^2.0.2" - "@smithy/util-middleware": "npm:^3.0.1" - "@smithy/util-retry": "npm:^3.0.1" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/1b955f0ceacdb7e0a0a15ce588aa7b0a796eae8591c195a9a1db601d6efeec504d7ad07189c4baedba0e8e888e4cbab770d6d9e54de9d07d166247f6f0df7c9a - languageName: node - linkType: hard - -"@aws-sdk/client-sts@npm:3.986.0": +"@aws-sdk/client-sts@npm:3.986.0, @aws-sdk/client-sts@npm:^3.338.0": version: 3.986.0 resolution: "@aws-sdk/client-sts@npm:3.986.0" dependencies: @@ -918,42 +665,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/core@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/core@npm:3.598.0" - dependencies: - "@smithy/core": "npm:^2.2.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/signature-v4": "npm:^3.1.0" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - fast-xml-parser: "npm:4.2.5" - tslib: "npm:^2.6.2" - checksum: 10/6c27302636d6e4c9382590be9d39e1ff2023c92a7aaa78117428d8af9be614ded56c7db2e9a016452144f4f6d81e6b09c81e29ad53df5fa9d506aa0548211f7c - languageName: node - linkType: hard - -"@aws-sdk/core@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/core@npm:3.896.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/xml-builder": "npm:3.894.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/48576dfb4060e802faec525b8553cbaeed5aa735ac3bdc292e14fae92261978b4f022197863e284c3cb49f86e638b967e0b76f346adc04b56a5d3aa7d5d1f370 - languageName: node - linkType: hard - "@aws-sdk/core@npm:^3.973.7": version: 3.973.7 resolution: "@aws-sdk/core@npm:3.973.7" @@ -985,31 +696,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/79c6391aad109d9749b60516dcc425e923a730bf6239d5b41192612fc2658d6fdbcd48b48277076ca7c6db61103164fe305fdc4271994713128d4ec27d32236a - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/82a771fd5b81f67f56816313ae598496676fad60d147c9adebf7557a0e808129c155f3bf6349a10362a16293ea5290d8c96160ba7fe0598c80756b65e2810278 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-env@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-env@npm:3.972.5" @@ -1023,41 +709,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/fetch-http-handler": "npm:^3.0.2" - "@smithy/node-http-handler": "npm:^3.0.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/smithy-client": "npm:^3.1.2" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-stream": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/e8411e33faec1798a2e50166cd1777b4becd2ff07ec97d044424faf1db3a2e97d8b4ee8c43d0b4e763d94dfb8971f0542b160e69a94ca38b175c8227e4f71904 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-stream": "npm:^4.3.2" - tslib: "npm:^2.6.2" - checksum: 10/c2dfd4ff720d8b6dd1e3f05899c73056a0babe8f7d4b6c45aa6a6bf1afe19d1609db0bfa1e47266e69024f46941b0f35175c76bd3bdbbbd1b3723039a96e20d5 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-http@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/credential-provider-http@npm:3.972.7" @@ -1076,48 +727,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.598.0" - "@aws-sdk/credential-provider-http": "npm:3.598.0" - "@aws-sdk/credential-provider-process": "npm:3.598.0" - "@aws-sdk/credential-provider-sso": "npm:3.598.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/credential-provider-imds": "npm:^3.1.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: 10/2f3aa54850dc1da4732d1dbc5a8e6ec095107ff08c46af4bffec41e1535a9c9a320586386f67358dd0acec83069dbb2b420bbd09412aa56993d088eb08ffef2b - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/credential-provider-env": "npm:3.896.0" - "@aws-sdk/credential-provider-http": "npm:3.896.0" - "@aws-sdk/credential-provider-process": "npm:3.896.0" - "@aws-sdk/credential-provider-sso": "npm:3.896.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b727580a5ad0d8062ad6d374983d49999d68ef19bcd4cb28df66bfb8dba101e4be94f9c7c9f73fabe79519e0d09b4352a19530a9c29165e8357301296f6c435d - languageName: node - linkType: hard - "@aws-sdk/credential-provider-ini@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-ini@npm:3.972.5" @@ -1156,46 +765,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.598.0" - "@aws-sdk/credential-provider-http": "npm:3.598.0" - "@aws-sdk/credential-provider-ini": "npm:3.598.0" - "@aws-sdk/credential-provider-process": "npm:3.598.0" - "@aws-sdk/credential-provider-sso": "npm:3.598.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/credential-provider-imds": "npm:^3.1.1" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/b5ab56a5c8acd566f41ba834214718a0ab8825090fe71b0ecc4ebec5e76de3afa47387ab99d061f3ac6ecd5ead9af621d7311ffa0a6b16df312f3c9de311747d - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.896.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.896.0" - "@aws-sdk/credential-provider-http": "npm:3.896.0" - "@aws-sdk/credential-provider-ini": "npm:3.896.0" - "@aws-sdk/credential-provider-process": "npm:3.896.0" - "@aws-sdk/credential-provider-sso": "npm:3.896.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/161f6bab93a3980deed49e328bdfd9a98ef0c998f0258caa4b3bfd26c436d9d4db56d9b6ef9bf7aa6012e4f8b1891d7cf5a3c0df8c5ca90d1eddb95fae28697f - languageName: node - linkType: hard - "@aws-sdk/credential-provider-node@npm:^3.972.6": version: 3.972.6 resolution: "@aws-sdk/credential-provider-node@npm:3.972.6" @@ -1216,33 +785,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/c0f9aa2304e273460b93efa7a09664d69e3dcdf6983d789a83bbc77a7975dddc7db915caaccf922f459eaad7b0ed546d1d79bcf0354898bca7c141fc49f5809b - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/1ea8e99cf5fc37c5c11330bf6e1cbb2a879ff61a335bdc6bf0d4dbeb64366e7232b6dd6f4dfe88718790ab07ecb0bb0814c67f59ed4d0a489b7074833e1defa5 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-process@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-process@npm:3.972.5" @@ -1257,37 +799,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" - dependencies: - "@aws-sdk/client-sso": "npm:3.598.0" - "@aws-sdk/token-providers": "npm:3.598.0" - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/19e6d8390a7824f921ee63105563857171404a09b7e7df1e9ad99a2ef334cc05cd1ae6d95f5a975fb328f5b53713cb1cb228d92b4966a7a8e9afc15637de66de - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.896.0" - dependencies: - "@aws-sdk/client-sso": "npm:3.896.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/token-providers": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f4c0dcc6efa354d3f151bdb73f6b5f6a68a45e90290621b9b70dd9a7d0e59e911b685cad597d6da2ed170d399ec7d469afc7a70f0d00c5ae409153231aee3c60 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-sso@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.5" @@ -1304,35 +815,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: 10/76cf4e389dc565402f1ba0b9c65983590e98435a17ed291d6b15412dac27aea7e35f23036675f76f2a267f8375de616550be759136bf2ff7d63211a22535bbf2 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/460c098de6f26a86b394a4241abf9f93a61d40ac5898f667716c0a3dbb1d6214ba42f3fdefc6a5e40a4d730eb1b0c6ff51d2b3fd10099670734e44bc133d20d6 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-web-identity@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.5" @@ -1365,21 +847,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-arn-parser": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/214fa89d2ed8b699c18d967cc158a77ec24f14b7d70fac80bdaa32940d8d737398a633787fee8efd7456a821f7f3c17f25a4d5db93f274ed071a428c04ad76e9 - languageName: node - linkType: hard - "@aws-sdk/middleware-bucket-endpoint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.3" @@ -1395,18 +862,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/722f38a646b302ae238d254c8a55a5d6fb124ad8b30f29d226c06761cfbc050c798595891c16a2fd78d4ec5e7a0431eef9c8a20c28c73fcb118db66afa9c3491 - languageName: node - linkType: hard - "@aws-sdk/middleware-expect-continue@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.3" @@ -1419,27 +874,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.896.0" - dependencies: - "@aws-crypto/crc32": "npm:5.2.0" - "@aws-crypto/crc32c": "npm:5.2.0" - "@aws-crypto/util": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/is-array-buffer": "npm:^4.1.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/16918d316a8cac38742889065c254c6f5ec33da6dbba6667409ee5fd84b3aeb90161405b4098ec98a9f60f769944e3394eae3bce01e7de51797940b12449889d - languageName: node - linkType: hard - "@aws-sdk/middleware-flexible-checksums@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.972.5" @@ -1462,30 +896,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/53498c94fd769dbee727ba4148d67578d2073fd83217695106e9dd3b572e56aa0362c329da4c13e39a0aaef45597cc7988b8951f2df4d28dc7c29461fa3791cc - languageName: node - linkType: hard - -"@aws-sdk/middleware-host-header@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/600afe3361abab4e6448a6c61ad94623be0c52169cc7e972d7dc8c7c0c6dc68a2f39b41ffafa5dc6b7f847277d4871517cfadbef185c75b63084c6d44b0ab0e2 - languageName: node - linkType: hard - "@aws-sdk/middleware-host-header@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-host-header@npm:3.972.3" @@ -1498,17 +908,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/e97592e4f08c8abdfb63a359a8c89eaffc128e221ed27db309840ecf9b4c1cbe757c394f218db99d200fc0afbc2c215fed47d428735d707144f19ab90476ee4e - languageName: node - linkType: hard - "@aws-sdk/middleware-location-constraint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.3" @@ -1520,28 +919,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-logger@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/e6db8b4e861cc8cc85f4e1b83fd73dc902beece1210fcfa6f2ebd7e78f9ee88f9a1584cdb584358b81c22c5c23b5b3bc58a6a57de2bfc33fb07684d9b9f8dad5 - languageName: node - linkType: hard - -"@aws-sdk/middleware-logger@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-logger@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7deb41cefde575dbc4f0a845fa535b88e52bacde2778b0f4545c3044bf87d70e0981c9dc3e65f5385d1b3d9de1afc06aae763295d2a3b33da02477c527e8bd64 - languageName: node - linkType: hard - "@aws-sdk/middleware-logger@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-logger@npm:3.972.3" @@ -1553,31 +930,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/2bc64666c08ee7f46a2918ac70773d7244f5c7866d0e3521c8734286c0b1bd5e4e64ea2bb4ec656e683dfecb7d44d43cd15283c4ec4cfe16b7aa7f4e19a586b8 - languageName: node - linkType: hard - -"@aws-sdk/middleware-recursion-detection@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@aws/lambda-invoke-store": "npm:^0.0.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/1d599f38cb269a9a27c2a63c8c6ec0790b38946a27fb06d003aa9b7247466151dab178bb35569740bd6725e25c9d5c733ee272d0de8bd382b1c3f7919bdb4978 - languageName: node - linkType: hard - "@aws-sdk/middleware-recursion-detection@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.3" @@ -1591,28 +943,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-arn-parser": "npm:3.893.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/591d2853276a911acc850742ec60f4d178565067bd3a87525cdb0c6c44487cd0f25ffec2f5afb4e273ab0b7b33bedeaa9f617d483967383f74dac4740807b1d1 - languageName: node - linkType: hard - "@aws-sdk/middleware-sdk-s3@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.7" @@ -1635,17 +965,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f5fe75e0facfbcabbfea296dacc8add47368707e9fa53181f7693f70a8735a22a2926c1c9785c99291ce3e44e173184a977940e7cd8e5e1cea25f16e3e8d17c4 - languageName: node - linkType: hard - "@aws-sdk/middleware-ssec@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-ssec@npm:3.972.3" @@ -1657,34 +976,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@aws-sdk/util-endpoints": "npm:3.598.0" - "@smithy/protocol-http": "npm:^4.0.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/3ed35495781284c3969374c2a53f02863cc433a8d139d5e85d7e1181c138c2ec743ee77a82efe780a0902a24ce524fc8946429939ed1368fec9f4635afb3d7f4 - languageName: node - linkType: hard - -"@aws-sdk/middleware-user-agent@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@smithy/core": "npm:^3.12.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/9d781950484f900998f9c842ddbeb6820b808470fc01c0b0a3c30083758cc82fe28aa8f844843b9de52f789ba17f109ec8af64c1c499088cfa57566308bbd76e - languageName: node - linkType: hard - "@aws-sdk/middleware-user-agent@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-user-agent@npm:3.972.7" @@ -1700,52 +991,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/nested-clients@npm:3.896.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/middleware-host-header": "npm:3.893.0" - "@aws-sdk/middleware-logger": "npm:3.893.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.893.0" - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/region-config-resolver": "npm:3.893.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-endpoints": "npm:3.895.0" - "@aws-sdk/util-user-agent-browser": "npm:3.893.0" - "@aws-sdk/util-user-agent-node": "npm:3.896.0" - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/core": "npm:^3.12.0" - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/hash-node": "npm:^4.1.1" - "@smithy/invalid-dependency": "npm:^4.1.1" - "@smithy/middleware-content-length": "npm:^4.1.1" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/middleware-retry": "npm:^4.3.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-body-length-node": "npm:^4.1.0" - "@smithy/util-defaults-mode-browser": "npm:^4.1.4" - "@smithy/util-defaults-mode-node": "npm:^4.1.4" - "@smithy/util-endpoints": "npm:^3.1.2" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/7abe22d7ea6878197f9ec90e56778a6871e5b452ac53dc821c4c346a3c970ba183445bd02603352d7cf04eaba713be7d6c6852d4f3b00c5ef41810a7b1cf8a99 - languageName: node - linkType: hard - "@aws-sdk/nested-clients@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/nested-clients@npm:3.985.0" @@ -1792,34 +1037,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-config-provider": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.1" - tslib: "npm:^2.6.2" - checksum: 10/26f7b0225f006e8630db3e86e8cf304ba1a9fae69186f3902ebc3500145cb35af2bde1b83a9abac634e1ca981c4f39258b10be645066f7d3355d53991c3b1b3b - languageName: node - linkType: hard - -"@aws-sdk/region-config-resolver@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/8fe6e40f37c97cafaf2f3f22bdeb1e015da955f75a5e54754301f3a0a98fca126a0f5745cfa07cd25b6e9f574cf4a3e359efc8c71dd12ee7920a0d493b258627 - languageName: node - linkType: hard - "@aws-sdk/region-config-resolver@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/region-config-resolver@npm:3.972.3" @@ -1850,7 +1067,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:3.986.0": +"@aws-sdk/s3-request-presigner@npm:3.986.0, @aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/s3-request-presigner@npm:3.986.0" dependencies: @@ -1866,36 +1083,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": - version: 3.896.0 - resolution: "@aws-sdk/s3-request-presigner@npm:3.896.0" - dependencies: - "@aws-sdk/signature-v4-multi-region": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@aws-sdk/util-format-url": "npm:3.893.0" - "@smithy/middleware-endpoint": "npm:^4.2.4" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/smithy-client": "npm:^4.6.4" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/a20d4ed2a558b41517cb6342d9f36ac678ab0fabb2c754354d5afd576719754fb5d6e22574b88817f7e61853e1ee9ac1d437513d8933ad773fcc7e90bc3ab298 - languageName: node - linkType: hard - -"@aws-sdk/signature-v4-multi-region@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.896.0" - dependencies: - "@aws-sdk/middleware-sdk-s3": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/signature-v4": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b1b3926c6ec9f54afb2eb43af559cb54dbf7d47012c8e6709c495a9292e9c8f9f61c86300d784fa14743a634210f216bc21ee2da976b5bf82db18d5a3f0abe16 - languageName: node - linkType: hard - "@aws-sdk/signature-v4-multi-region@npm:3.986.0": version: 3.986.0 resolution: "@aws-sdk/signature-v4-multi-region@npm:3.986.0" @@ -1910,36 +1097,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/token-providers@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/property-provider": "npm:^3.1.1" - "@smithy/shared-ini-file-loader": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - "@aws-sdk/client-sso-oidc": ^3.598.0 - checksum: 10/8542937e6d010ebd6b3dd70390685fa4553b0e01ed4fb8e6dc7bd6395e853162758e8d7a6c251fb56309d36beebc393981788ca112bfb3b1de7e23e599d2476e - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/token-providers@npm:3.896.0" - dependencies: - "@aws-sdk/core": "npm:3.896.0" - "@aws-sdk/nested-clients": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/b50abe20a20aabaac857bb606b694036d693187ab2dd6d6836f1caad008314784f7a2a6c566bf3966f699d59b3a035ed7897c4fff37a828cc47d55c6076dbda4 - languageName: node - linkType: hard - "@aws-sdk/token-providers@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/token-providers@npm:3.985.0" @@ -1955,27 +1112,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/types@npm:3.598.0" - dependencies: - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - checksum: 10/29384fbe79ec8693cae00b3082379559e7bbea5fd70de1705e94e93ed1ec57ddb930bb41102f9b229869a9a7ba790deeb1161bc81e2f87a031d37dff2fa73dd0 - languageName: node - linkType: hard - -"@aws-sdk/types@npm:3.893.0, @aws-sdk/types@npm:^3.222.0": - version: 3.893.0 - resolution: "@aws-sdk/types@npm:3.893.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/c7edea067ee8179732b9750b4090d0cc5ca07e954b92cec25c4f55c8e1e9a1ad62df2799e2a82ad24b59ee25a2a4188a5e429db59aa168b10d0ba62347800d5b - languageName: node - linkType: hard - -"@aws-sdk/types@npm:^3.973.1": +"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.973.1": version: 3.973.1 resolution: "@aws-sdk/types@npm:3.973.1" dependencies: @@ -1985,15 +1122,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.893.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/f809777714618c63e92fd5881c9573081bc94df9c5cce53917b8e1db4efa1d44f1132f6c9179f9babc4964c648d42ebee5c1ad75641c6b336007be3df561053f - languageName: node - linkType: hard - "@aws-sdk/util-arn-parser@npm:^3.972.2": version: 3.972.2 resolution: "@aws-sdk/util-arn-parser@npm:3.972.2" @@ -2003,31 +1131,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-endpoints@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - "@smithy/util-endpoints": "npm:^2.0.2" - tslib: "npm:^2.6.2" - checksum: 10/753c5629e7f9e0abd3b2d8578ffa038089e18e80d8b2a3f49f2321dc565480c2d6dc5ecbfae799f35cb88fbc247018887f2c3b325853af6246547293973c7d45 - languageName: node - linkType: hard - -"@aws-sdk/util-endpoints@npm:3.895.0": - version: 3.895.0 - resolution: "@aws-sdk/util-endpoints@npm:3.895.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-endpoints": "npm:^3.1.2" - tslib: "npm:^2.6.2" - checksum: 10/14f39c2f0f085640cb8f1f178bc710aa237fbd0d856c9081dbf4d5514bfb8aff96c97fdb006450f1cbe839f7604ba19832daa95b1f6dccc65094e52a6e388e6f - languageName: node - linkType: hard - "@aws-sdk/util-endpoints@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/util-endpoints@npm:3.985.0" @@ -2054,18 +1157,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-format-url@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-format-url@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/0cc12a660aaa0fa34294727caa0f52bef97b85f4f7d46aebdc609f176330658275e1177317e06adc559f6ee3f9a7fa5c86be75d18353a7b4311589cfca161a48 - languageName: node - linkType: hard - "@aws-sdk/util-format-url@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-format-url@npm:3.972.3" @@ -2087,30 +1178,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/types": "npm:^3.1.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/2c7bb1ec527ae1df15bf8c58320912c2cf41cecbfcf41a84fdb5d2c7b2ed53245d8748607b05445d0aac31ca1fb66280b38199fd457eb1f5650b60668c956f25 - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-browser@npm:3.893.0": - version: 3.893.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.893.0" - dependencies: - "@aws-sdk/types": "npm:3.893.0" - "@smithy/types": "npm:^4.5.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/b268fc03a2afb2741e64175e5bd28b34315314ff55e82fa00e3d98f35a955a681568b1595f7e18b05f0172915244be7fe0cf5e1e90cf6e971bae3a946e3dfa63 - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-browser@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.3" @@ -2123,41 +1190,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" - dependencies: - "@aws-sdk/types": "npm:3.598.0" - "@smithy/node-config-provider": "npm:^3.1.1" - "@smithy/types": "npm:^3.1.0" - tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/19de8df5e26560f9fc99acd73dd5c5f7890ec62b876568f15132dc1141eab280ec7ad44aeb0b095f765c2329f06fc8babf124e2708d6ccee1c541a9f62b51f5f - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-node@npm:3.896.0": - version: 3.896.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.896.0" - dependencies: - "@aws-sdk/middleware-user-agent": "npm:3.896.0" - "@aws-sdk/types": "npm:3.893.0" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/4453a1989deb1a2ad6e087914642760206b4a77a8da4976c74225ed47400812595e6bfa1ad27f42277b561b8d8b8a2dcaf248b3bd8a0c1b0ef2f1e790320d8a9 - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-node@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/util-user-agent-node@npm:3.972.5" @@ -2176,17 +1208,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.894.0": - version: 3.894.0 - resolution: "@aws-sdk/xml-builder@npm:3.894.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - fast-xml-parser: "npm:5.2.5" - tslib: "npm:^2.6.2" - checksum: 10/60a32a4fcc0466fa6eb61e165146bf7c9559252e0adc5f232d7f73237b4dab28ae92dadaf4ee039629b1d8ce47f4731348908e5e7de4e2abcf22f0c19597caf5 - languageName: node - linkType: hard - "@aws-sdk/xml-builder@npm:^3.972.4": version: 3.972.4 resolution: "@aws-sdk/xml-builder@npm:3.972.4" @@ -2198,13 +1219,6 @@ __metadata: languageName: node linkType: hard -"@aws/lambda-invoke-store@npm:^0.0.1": - version: 0.0.1 - resolution: "@aws/lambda-invoke-store@npm:0.0.1" - checksum: 10/e8f54d28aade8828962f2871a22aa4e960ebc40c8fa551414181dd9dd32d6258279013c42f88e57d17aa4252cb5ed00df6a49fc35185f9fa6b6f351ccf821bd6 - languageName: node - linkType: hard - "@aws/lambda-invoke-store@npm:^0.2.2": version: 0.2.3 resolution: "@aws/lambda-invoke-store@npm:0.2.3" @@ -3972,16 +2986,7 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5": - version: 1.5.0 - resolution: "@emnapi/runtime@npm:1.5.0" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10/5311ce854306babc77f4bd94c2f973722714a0fab93c126239104ad52dea16a147bfed4c4cff3ca1eb32709607221c25d2f747ae8524cbeb9088058f02ff962b - languageName: node - linkType: hard - -"@emnapi/runtime@npm:^1.7.0": +"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5, @emnapi/runtime@npm:^1.7.0": version: 1.8.1 resolution: "@emnapi/runtime@npm:1.8.1" dependencies: @@ -6557,26 +5562,6 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/abort-controller@npm:3.1.0" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/1a7459471db6a624bec0a3235251c067b813a47c2bc15145977ebca76894a491974575d9c9c515120259b206cf3d613baa1a61b8da96a7a0233c8c5d7c04e725 - languageName: node - linkType: hard - -"@smithy/abort-controller@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/abort-controller@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/d2a007a4a41afd3ac13c291f2683d1da57709e75db0a09f502225983c097c8169e3b1b78fc01ee691fb12980492fb3ca49628b3f34ece0a66806bd0caf701710 - languageName: node - linkType: hard - "@smithy/abort-controller@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/abort-controller@npm:4.2.8" @@ -6587,16 +5572,6 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/chunked-blob-reader-native@npm:4.1.0" - dependencies: - "@smithy/util-base64": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/5ddca9cb700392ff0e6025726528e2c2e20e189b974af0eb8286b2b7bfa248c10c479c99ff09d0fbf0c3c5feefa98ce5da78f4273bbdae0b85e064d753fdecc9 - languageName: node - linkType: hard - "@smithy/chunked-blob-reader-native@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/chunked-blob-reader-native@npm:4.2.1" @@ -6607,15 +5582,6 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^5.1.0": - version: 5.1.0 - resolution: "@smithy/chunked-blob-reader@npm:5.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/a7d1d7d5b45499dc6e2c6a4bbfd1ac8cfbaf85b5b28db060c8d3cb1f331432cdada0e5586d57d949a3e521d7eb7b88c425d66cd2ee7ab9d1cf4fbff9a1f830e0 - languageName: node - linkType: hard - "@smithy/chunked-blob-reader@npm:^5.2.0": version: 5.2.0 resolution: "@smithy/chunked-blob-reader@npm:5.2.0" @@ -6625,32 +5591,6 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/config-resolver@npm:3.0.3" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-config-provider": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/e1e88d334177f6481ddba3a805e8e2e6513654a581aee500a1a74a0f206379ddbdec9eb48b2f4a1ae1c84b330d122f84cbbba0f0ffbe4c9ebdeeaac872cfee7e - languageName: node - linkType: hard - -"@smithy/config-resolver@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/config-resolver@npm:4.2.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-config-provider": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/8b489420646c61c4ac57e2754ad6e4012de27aa6d0bca18d69f1916085908d58d8ba4d8d963e24ba55c9a797996b95cedff18e3fa2674136c6eb14044f942da0 - languageName: node - linkType: hard - "@smithy/config-resolver@npm:^4.4.6": version: 4.4.6 resolution: "@smithy/config-resolver@npm:4.4.6" @@ -6665,40 +5605,6 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^2.2.1": - version: 2.2.3 - resolution: "@smithy/core@npm:2.2.3" - dependencies: - "@smithy/middleware-endpoint": "npm:^3.0.3" - "@smithy/middleware-retry": "npm:^3.0.6" - "@smithy/middleware-serde": "npm:^3.0.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/d1e4885b3800e97bd119a66b2cd75c3bfdcfa5af420db20b4360a6bd9f7a7f31cee0b35edf06ecb61c210fcf042e3f2bf82e6650e571e2a63879082a5805c9cd - languageName: node - linkType: hard - -"@smithy/core@npm:^3.12.0, @smithy/core@npm:^3.13.0": - version: 3.13.0 - resolution: "@smithy/core@npm:3.13.0" - dependencies: - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-body-length-browser": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-stream": "npm:^4.3.2" - "@smithy/util-utf8": "npm:^4.1.0" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/75b7045fae55b732e0420b2990255b7f8c962a66a6f9e77bd1509534428434190823bf1e68eabdda927d5abfb5d6d7783f49fa2d08268610ac4cd33c6c3f5594 - languageName: node - linkType: hard - "@smithy/core@npm:^3.22.1, @smithy/core@npm:^3.23.0": version: 3.23.0 resolution: "@smithy/core@npm:3.23.0" @@ -6717,32 +5623,6 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/credential-provider-imds@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/url-parser": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/2d023083f12d1a411251d2402e281dbeb6de83d394d900052aacd02188102b4b24fc9c2791a76b669c7800f8a5fb3baf99ea65fddd1e4cc6a467b1f85575987b - languageName: node - linkType: hard - -"@smithy/credential-provider-imds@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/credential-provider-imds@npm:4.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/c10cbea54ba8475d27cd38e956bda9113efa7e90ad46369aa2b3f8bce511ccc89a45f2198efe8bd00a35de16f5ef411723be01093cc02c10511ea89c5ed0131e - languageName: node - linkType: hard - "@smithy/credential-provider-imds@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/credential-provider-imds@npm:4.2.8" @@ -6756,18 +5636,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-codec@npm:4.1.1" - dependencies: - "@aws-crypto/crc32": "npm:5.2.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/7921997f85957c17fd5493567777dcfa31b90c84a3cb2a27adfc8218846994dd6ddebb4699c0656e02d25709d44b692b58a0c94296e771257097ab61626ebdd3 - languageName: node - linkType: hard - "@smithy/eventstream-codec@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-codec@npm:4.2.8" @@ -6780,17 +5648,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-browser@npm:4.1.1" - dependencies: - "@smithy/eventstream-serde-universal": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/89afea2e1deeb3e771e69e62dbc3d17a4fb366dc0b3edf355069a0d8c429cc09e46c8b78f92456dded8e40e22dd06dade5bc717e17ae197b0fe5997729aac82c - languageName: node - linkType: hard - "@smithy/eventstream-serde-browser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-browser@npm:4.2.8" @@ -6802,16 +5659,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/eventstream-serde-config-resolver@npm:4.2.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/18e1f0e69bb10b427103113ca14542d6e740e9096cd51d706f890cec78d390f5ccc81513ceef0b861ba05ff0004f0244aaac29d4f3eeff2bc062a16a76331944 - languageName: node - linkType: hard - "@smithy/eventstream-serde-config-resolver@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.8" @@ -6822,17 +5669,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-node@npm:4.1.1" - dependencies: - "@smithy/eventstream-serde-universal": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/9ec402098b3d67d051e92d332afb7ea7ab056d178e206d4e35ca47e9b2d12915373358323681c6183f22680e847101277dbf43abb9703bfda2ec23451cc87c51 - languageName: node - linkType: hard - "@smithy/eventstream-serde-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-node@npm:4.2.8" @@ -6844,17 +5680,6 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/eventstream-serde-universal@npm:4.1.1" - dependencies: - "@smithy/eventstream-codec": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/bbe77b9f14d718d18972dc4690c53b6518e0088e0c24d7f0a38b3ede3dd0291fd494112bfe7efb93591ba4b923b0ce9b8598ee72eec4e4481812ef3f4bfb5af7 - languageName: node - linkType: hard - "@smithy/eventstream-serde-universal@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-serde-universal@npm:4.2.8" @@ -6866,32 +5691,6 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/fetch-http-handler@npm:3.1.0" - dependencies: - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/querystring-builder": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-base64": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/fcfd98a69798aa5b4c034601c75f125b2c70e24effd5a5137caad4ce24f06d83f8788664cff40b15e205257b055eefba35ec3314f73c0887c1c84fd9c349579f - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/fetch-http-handler@npm:5.2.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/a7038d20ad2ad64bdfda06b61e6a485b20af2086e94b78dc8f955a5baf270efaca6c9a3f7401114b8e856eed3ff8dda9701119a560455e6d72f8ae1957f50d33 - languageName: node - linkType: hard - "@smithy/fetch-http-handler@npm:^5.3.9": version: 5.3.9 resolution: "@smithy/fetch-http-handler@npm:5.3.9" @@ -6905,18 +5704,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-blob-browser@npm:4.1.1" - dependencies: - "@smithy/chunked-blob-reader": "npm:^5.1.0" - "@smithy/chunked-blob-reader-native": "npm:^4.1.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/8e29bf75da5ceebc571bee17c3e6c28162572105dcdc17b249a5edf3691e0987daf579470cb60799e8f200756cb3bd8fa69e0b299a8435edaff490f14101bc13 - languageName: node - linkType: hard - "@smithy/hash-blob-browser@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/hash-blob-browser@npm:4.2.9" @@ -6929,30 +5716,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/hash-node@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/df5c22224f210741b00bde59922b86354d1f21660bea6b0b3f8e9e87236fd80cb90bc81945ceb4914ae99ce7a7570f8cf59d57bffb3f50c75719e3cc3cdacab7 - languageName: node - linkType: hard - -"@smithy/hash-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-node@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/234f3d52975f99583ec8e739f70b3ccb1941f57bb47e1d230af954d5b1b3d7ee6c94907079017ef5fbfec4bcb618c0214b26b2ff7d7a01dc57d1f8f5ff414cba - languageName: node - linkType: hard - "@smithy/hash-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-node@npm:4.2.8" @@ -6965,17 +5728,6 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-stream-node@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/abdeea567ffb65f41e79c4dec5733c29a419a1de546e968be95113e2d96fc7e870149c1de422ff4fefb4229ee3dd0e29996df14c2c95e42a65027f9cdfa8f03a - languageName: node - linkType: hard - "@smithy/hash-stream-node@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/hash-stream-node@npm:4.2.8" @@ -6987,26 +5739,6 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/invalid-dependency@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/e4bc6a79d4f514ae81600b3484025dc788013da690de6f3980121374b65d0d92d42bc50760e9c7b44438e7f5794ffd46bef2976a11d2da16fae47fc25b0ac96a - languageName: node - linkType: hard - -"@smithy/invalid-dependency@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/invalid-dependency@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/665e34379c6b3ad3a6bb0cf14ad646ba2bd9785b6e1b571d41192ad2d5617f5f48cd743d2ad75ce5ba6d5a2c2e312f7f86c2be50d2b8b12c9f2c0e5f42c9633e - languageName: node - linkType: hard - "@smithy/invalid-dependency@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/invalid-dependency@npm:4.2.8" @@ -7026,24 +5758,6 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/is-array-buffer@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/cab1fd4033d9863dcd95ff058463eb591574bd47e6b61e36aaaf4c0d0da9ed966a54e1d33ec4db7d67aa85df7d274203e934e04dbb40323d01ef4815f63997fc - languageName: node - linkType: hard - -"@smithy/is-array-buffer@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/is-array-buffer@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/5fba7ea13175100d39bc88b480dc70dc04bb62c62dc470e61e09b287f3b4c851c56473bda2ec077eca31675cde184dadc4d50ef11f065fb566e0b88f92d9465a - languageName: node - linkType: hard - "@smithy/is-array-buffer@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/is-array-buffer@npm:4.2.0" @@ -7053,17 +5767,6 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/md5-js@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/383d9acb06adad67c1089283988195d478475a53fa6e9954f5b237989b5ae15a8f2ec70f8f64557c65ce2984e8503bdc55ea4ff487def8c04822af1132f6746b - languageName: node - linkType: hard - "@smithy/md5-js@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/md5-js@npm:4.2.8" @@ -7075,28 +5778,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/middleware-content-length@npm:3.0.2" - dependencies: - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/520c28af22819724fefb8f487d6080b497f64ddf34fb75fd6829df0c1b075e23d0cdcfbbbd265b6556843735ae9721b8b349e2b6c194e3e71a94916c9a929cf6 - languageName: node - linkType: hard - -"@smithy/middleware-content-length@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-content-length@npm:4.1.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/eb2a99c11d01484ff0b17ba9c5d02878b92c61153568080eab011699de4460ff4534a302d9131583deb83963be83494a43e1973235c1e7edbaaaa2ace5e2b202 - languageName: node - linkType: hard - "@smithy/middleware-content-length@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-content-length@npm:4.2.8" @@ -7108,37 +5789,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/middleware-endpoint@npm:3.0.3" - dependencies: - "@smithy/middleware-serde": "npm:^3.0.2" - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/shared-ini-file-loader": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/url-parser": "npm:^3.0.2" - "@smithy/util-middleware": "npm:^3.0.2" - tslib: "npm:^2.6.2" - checksum: 10/fd3628405b4970f90448d5c52e7c3b808bbe149d72cbb21001a9a707b5b43a7e4e2275751b9486886bac2e740eaafc9c880800e6c69e02436731629b277bc55b - languageName: node - linkType: hard - -"@smithy/middleware-endpoint@npm:^4.2.4, @smithy/middleware-endpoint@npm:^4.2.5": - version: 4.2.5 - resolution: "@smithy/middleware-endpoint@npm:4.2.5" - dependencies: - "@smithy/core": "npm:^3.13.0" - "@smithy/middleware-serde": "npm:^4.1.1" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - "@smithy/url-parser": "npm:^4.1.1" - "@smithy/util-middleware": "npm:^4.1.1" - tslib: "npm:^2.6.2" - checksum: 10/b9a8a0791cfe79d9507620f66fe4592e6d4586739d295a2cc4dd3b329c05bcc68af7806523ba05647c0bc32a466481ff9f11b9808756e70c41394ed3a0174bc3 - languageName: node - linkType: hard - "@smithy/middleware-endpoint@npm:^4.4.13, @smithy/middleware-endpoint@npm:^4.4.14": version: 4.4.14 resolution: "@smithy/middleware-endpoint@npm:4.4.14" @@ -7155,40 +5805,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": - version: 3.0.6 - resolution: "@smithy/middleware-retry@npm:3.0.6" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/service-error-classification": "npm:^3.0.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-middleware": "npm:^3.0.2" - "@smithy/util-retry": "npm:^3.0.2" - tslib: "npm:^2.6.2" - uuid: "npm:^9.0.1" - checksum: 10/8c0d696a840b6d307718e4cfaeb2eae41840be639c91c0653329beb1e4faf2b8f6a31225651c80da3f0b6a130d009fcc4f4f7c6549f9d8e298074b132731c953 - languageName: node - linkType: hard - -"@smithy/middleware-retry@npm:^4.3.0": - version: 4.3.1 - resolution: "@smithy/middleware-retry@npm:4.3.1" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/service-error-classification": "npm:^4.1.2" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-retry": "npm:^4.1.2" - "@smithy/uuid": "npm:^1.0.0" - tslib: "npm:^2.6.2" - checksum: 10/85b92dbd6c2b72d4fe38d56de69160bd44a3d99b51eb1a66456f75b1a4a3931999d986b58e4426608ca1d2089187a1ab43f6904b24803b0750fbd17226c8900d - languageName: node - linkType: hard - "@smithy/middleware-retry@npm:^4.4.30": version: 4.4.31 resolution: "@smithy/middleware-retry@npm:4.4.31" @@ -7206,27 +5822,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-serde@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/ef05cbd0b7a8b5187094ce134620e57dcb50a5c77b7f555f44f050e69a3677aff7f0c05ff02771b2bc92f515df527eef4d10ac5ff515648b8ec6cb92783cd072 - languageName: node - linkType: hard - -"@smithy/middleware-serde@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-serde@npm:4.1.1" - dependencies: - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/01d907751748a4b2806aba43ec4a668d313c89c04ecd6ba3b15663e39b9b447842387e4300e47d8ce7066c415fb70b05b53c11967f98c4d8ea5488891070cad6 - languageName: node - linkType: hard - "@smithy/middleware-serde@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/middleware-serde@npm:4.2.9" @@ -7238,26 +5833,6 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-stack@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/21b7d7d6e73c1628b5ed384f23ac850df3bbca5054ea1e6ba03c3bf1d389fe5a440a4fbdb8aaa210c4b2ba864ac082264bb3c6ec7a2e03f0e6b790c6b23178a6 - languageName: node - linkType: hard - -"@smithy/middleware-stack@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-stack@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7c07663cb381f785d2bf39ff7fa5ee14e233168021274ede6b86335fff60a23260f42535f5ef32c8fe581c780a80acd06df39fcbcd3634e61c1eae685372a65c - languageName: node - linkType: hard - "@smithy/middleware-stack@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/middleware-stack@npm:4.2.8" @@ -7268,30 +5843,6 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/node-config-provider@npm:3.1.2" - dependencies: - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/shared-ini-file-loader": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/b0b9d665efc075803dcf9a26014def9b650270593667d5f01511758d4909387ab820c1fdcaf1a82e1f4fbd6c26a67ecab88ac26cc5450bf815788e4090d4e476 - languageName: node - linkType: hard - -"@smithy/node-config-provider@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/node-config-provider@npm:4.2.2" - dependencies: - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/shared-ini-file-loader": "npm:^4.2.0" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/18f290c8be9c5de33b64e7cae847bfbf1b926e7fbb1df31e853a7d04ef3275adb690f5cf3450ffef23ab68fc8f37f45d42bee9c05bf791b8b66c447c97ba2e25 - languageName: node - linkType: hard - "@smithy/node-config-provider@npm:^4.3.8": version: 4.3.8 resolution: "@smithy/node-config-provider@npm:4.3.8" @@ -7304,32 +5855,6 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/node-http-handler@npm:3.1.0" - dependencies: - "@smithy/abort-controller": "npm:^3.1.0" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/querystring-builder": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/05ff2d9db1f67e08efd8b486c00506163dce70644add50ab3ca4995424bd73f168ee0f1f3b2f9aac77fa46c7775c7d28db558450a36fa641a862f80f957c1aad - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/node-http-handler@npm:4.2.1" - dependencies: - "@smithy/abort-controller": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/querystring-builder": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/71f6551dbd06e2a9eb2b536bf13f11ec32c93da324376bf82ff3614e24241970e9ba4106cbbc8a0ac2867595fad3b12c6b2807366f921561ec41086a90af2ece - languageName: node - linkType: hard - "@smithy/node-http-handler@npm:^4.4.10, @smithy/node-http-handler@npm:^4.4.9": version: 4.4.10 resolution: "@smithy/node-http-handler@npm:4.4.10" @@ -7343,26 +5868,6 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/property-provider@npm:3.1.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/7993be1ae7f2f6779599837a246749b98cb0fc60e685ff7d97f1bd7e7ed1ce9e30bd4ce9e46e4a52f4dbf16cf864611bae72230e5fcb91b0c3a3d4de08ce258e - languageName: node - linkType: hard - -"@smithy/property-provider@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/property-provider@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/f44da66c108b6bb0d9e59a30d8dbde17fc38656890b3ba688cf22db130e93f84d7436003cde473d2636a16d736eb4a8638e069f9a1cb0228a9bb2a5d90f8e40a - languageName: node - linkType: hard - "@smithy/property-provider@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/property-provider@npm:4.2.8" @@ -7373,26 +5878,6 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": - version: 4.0.2 - resolution: "@smithy/protocol-http@npm:4.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/accd46f06a4ab6549b797d52274d98c4b755a87fe2cd3f6c5edf991b8e44d4233fadbe4628d665f404ccd85ad9caa42127cef3db74a38f3d085f2f81b81d9f42 - languageName: node - linkType: hard - -"@smithy/protocol-http@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/protocol-http@npm:5.2.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/7e00b314d6b38d58f4ca692546642b6a641be564d67fc31bae227ec0f0fd8f568522752189727a45828654c6ebcab2784884d4058ce992d2f48fc63ab37f4c2c - languageName: node - linkType: hard - "@smithy/protocol-http@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/protocol-http@npm:5.3.8" @@ -7403,28 +5888,6 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-builder@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-builder@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - "@smithy/util-uri-escape": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/6a455ee7ce135898e9d19cfd8c614f42f131a1439faddf49c2f72612521398de32dd75eebdde2af00754aa97b9418f3e42cf77e41ac264c1a74bd166c6d1dc0e - languageName: node - linkType: hard - -"@smithy/querystring-builder@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-builder@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - "@smithy/util-uri-escape": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/bbbfd564ccd585273df3829cc5e86572341cf22ed65477fdf31c8b9fc99759e872246ad419863efc259a110fbdab5bac408a5729abc8f883edd8390ae80aaf30 - languageName: node - linkType: hard - "@smithy/querystring-builder@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-builder@npm:4.2.8" @@ -7436,26 +5899,6 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-parser@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/86e5d986df6e0d639d420306a41e444456a8a91457f8e3fc363fb2c9155d3a02f8a651add14f0e341955af5c521a8e6cf1abb920ddf2ce7c89acaafba768299a - languageName: node - linkType: hard - -"@smithy/querystring-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-parser@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/08b81b7e8350d88b5a350cbe55c626c71bb86de06041e8311c44133919accba63b401672f84e65cbdbddce02a08b408da40669161d92af1d4d283dd167863aa5 - languageName: node - linkType: hard - "@smithy/querystring-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/querystring-parser@npm:4.2.8" @@ -7466,24 +5909,6 @@ __metadata: languageName: node linkType: hard -"@smithy/service-error-classification@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/service-error-classification@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - checksum: 10/f871ab0a4966a874cae412ff7621a44ab07f31c91070b2fb21f8e5d39f7336e25ad119469ac023861e2d310f0b5739fe308dde89ef5fbc17ec4860e8575f15db - languageName: node - linkType: hard - -"@smithy/service-error-classification@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/service-error-classification@npm:4.1.2" - dependencies: - "@smithy/types": "npm:^4.5.0" - checksum: 10/50e8835e9850167093db1a96e9265ee66991f8e03b44fd2f23c44114de5634d9d65dd80fc6f7f94ebba2f2e892f73a270bbfdca5c07bfc97bb36bbf3b95ad4a3 - languageName: node - linkType: hard - "@smithy/service-error-classification@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/service-error-classification@npm:4.2.8" @@ -7493,26 +5918,6 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/f3d7dde145975c626fb2565af8a24308b00e70b70618d7870dd91c2956918945a8bce557d0809416fa047b3792b5e038521b5aa53ac164c1f345da98c4a663fc - languageName: node - linkType: hard - -"@smithy/shared-ini-file-loader@npm:^4.2.0": - version: 4.2.0 - resolution: "@smithy/shared-ini-file-loader@npm:4.2.0" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/ee67bbfbbde59407ef15777118cccc2ef39163f70efc0704044144dcd08019316b08ccdec5e8dc94fb17d2be6aeb256a2d7b790a36c9938b6149e2e4c646db89 - languageName: node - linkType: hard - "@smithy/shared-ini-file-loader@npm:^4.4.3": version: 4.4.3 resolution: "@smithy/shared-ini-file-loader@npm:4.4.3" @@ -7523,37 +5928,6 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^3.1.0": - version: 3.1.1 - resolution: "@smithy/signature-v4@npm:3.1.1" - dependencies: - "@smithy/is-array-buffer": "npm:^3.0.0" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-hex-encoding": "npm:^3.0.0" - "@smithy/util-middleware": "npm:^3.0.2" - "@smithy/util-uri-escape": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/ad768406d955c038ff0492ecbeec13dd3f5f5ab0c8224a00097a7a8122a17f5cf97fb299cce61d668f27a59003e455dde4b4ab0c1dce27f8946e1af38c0202f7 - languageName: node - linkType: hard - -"@smithy/signature-v4@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/signature-v4@npm:5.2.1" - dependencies: - "@smithy/is-array-buffer": "npm:^4.1.0" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - "@smithy/util-middleware": "npm:^4.1.1" - "@smithy/util-uri-escape": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/4f22b6f1a1d15c15627af64ea1490ce797f020fca3177b00ec54d89e72ecdce98ed71ec8a96ece638110ac0b331718065a8393687654776e6989a523f03703b0 - languageName: node - linkType: hard - "@smithy/signature-v4@npm:^5.3.8": version: 5.3.8 resolution: "@smithy/signature-v4@npm:5.3.8" @@ -7570,20 +5944,6 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/smithy-client@npm:3.1.4" - dependencies: - "@smithy/middleware-endpoint": "npm:^3.0.3" - "@smithy/middleware-stack": "npm:^3.0.2" - "@smithy/protocol-http": "npm:^4.0.2" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-stream": "npm:^3.0.4" - tslib: "npm:^2.6.2" - checksum: 10/9e85bc7c5205d89d012bdd02c74eb3486709fa9f9442574fd84db5b3bccf9ce9a9aef6d7076e156f75cec257b478162242d4b3d5c44f3f32f087dfeb559e6549 - languageName: node - linkType: hard - "@smithy/smithy-client@npm:^4.11.2, @smithy/smithy-client@npm:^4.11.3": version: 4.11.3 resolution: "@smithy/smithy-client@npm:4.11.3" @@ -7599,30 +5959,6 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.6.4, @smithy/smithy-client@npm:^4.6.5": - version: 4.6.5 - resolution: "@smithy/smithy-client@npm:4.6.5" - dependencies: - "@smithy/core": "npm:^3.13.0" - "@smithy/middleware-endpoint": "npm:^4.2.5" - "@smithy/middleware-stack": "npm:^4.1.1" - "@smithy/protocol-http": "npm:^5.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-stream": "npm:^4.3.2" - tslib: "npm:^2.6.2" - checksum: 10/ac8482d2c6cdd2755fd336ebfe4b6ddba5707a4438f199ce771e37bd9ae71be3ae43e32bcf6655345c1276c84416efe00141166708dea47be35bb78c06a4ea85 - languageName: node - linkType: hard - -"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": - version: 3.2.0 - resolution: "@smithy/types@npm:3.2.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/0590537cc2aaa7c2cd3277b6ec94ab1b7a417e7aae8389424e3b161b878dba3b8879c0bdfd0ad85145320006ecda8395f21196d527696e97bcfb98ffe01441b1 - languageName: node - linkType: hard - "@smithy/types@npm:^4.12.0": version: 4.12.0 resolution: "@smithy/types@npm:4.12.0" @@ -7632,37 +5968,6 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^4.5.0": - version: 4.5.0 - resolution: "@smithy/types@npm:4.5.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d25275a0f1cb75dd3534a60a637b0202fbe1343703a448c410aa3e3029d5dc1d128c711c005bbda29a111af5a072aaf01bd8314a05c9806857d18e625f41c075 - languageName: node - linkType: hard - -"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/url-parser@npm:3.0.2" - dependencies: - "@smithy/querystring-parser": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/080214bb1ae59472903d26beb71b7641a6ff49787735a8f56561b16d938cca80b8d560c2f679bf04da173c8c899b50aed881b61aef266bed11b570afbe20bc4f - languageName: node - linkType: hard - -"@smithy/url-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/url-parser@npm:4.1.1" - dependencies: - "@smithy/querystring-parser": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/35904bf3561d433f92c318c2f9d1fb8324e7693ea11af3e7570a334944f701e9c6720d5b426d93830e33cfe105dd026cd5fda842b20d14589ff62b9c67b4118b - languageName: node - linkType: hard - "@smithy/url-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/url-parser@npm:4.2.8" @@ -7674,28 +5979,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-base64@npm:3.0.0" - dependencies: - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/3c883d63a33e1cfeebf7f846f167dfc54c832d1f5514d014fbfff06de3aecd5919f01637fc93668dca8a1029752f3a6fab0a94f455dcb7c88f1d472bde294eef - languageName: node - linkType: hard - -"@smithy/util-base64@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-base64@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/980391b462ab5d8a99ce2ac55441b3bcaef73e197926327f32ef09d708535f6d0449eb05fa166d709e27fdeb212a60f201d6678f2c64122fce072ef3d82c0644 - languageName: node - linkType: hard - "@smithy/util-base64@npm:^4.3.0": version: 4.3.0 resolution: "@smithy/util-base64@npm:4.3.0" @@ -7707,24 +5990,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-body-length-browser@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/a0ab6a6d414a62d18e57f3581769379a54bb1fd93606c69bc8d96a3566fdecb8db7b57da9446568d03eef9f004f2a89d7e94bdda79ef280f28b19a71803c0309 - languageName: node - linkType: hard - -"@smithy/util-body-length-browser@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-browser@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/264b1b0f47127b1d215e95e7c66d3717b3f838d674b195e0150c8405e1875779694b3c75ab1932bf1a51c890ed495f7a9560a25c40e635d2f5585e496d9fbf77 - languageName: node - linkType: hard - "@smithy/util-body-length-browser@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-body-length-browser@npm:4.2.0" @@ -7734,24 +5999,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-body-length-node@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/aabac66d7111612fd375d67150f8787c5cdc828f7e6acb40ef0b18b4c354e64e0ef2e4b8da2d7f01e8abe931ff2ef8109a408164ce7e5662fd41b470c462f1e4 - languageName: node - linkType: hard - -"@smithy/util-body-length-node@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-node@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/5a6d925afdebdcde7a7f1ce55e69d823c0a9b7a5ed8f899417c402952585784b0ac843932691875381ce389f0e5f543d25c9fe4a3d8addeddbd48124a8985b6b - languageName: node - linkType: hard - "@smithy/util-body-length-node@npm:^4.2.1": version: 4.2.1 resolution: "@smithy/util-body-length-node@npm:4.2.1" @@ -7771,26 +6018,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-buffer-from@npm:3.0.0" - dependencies: - "@smithy/is-array-buffer": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/7e6596b38855c07869f7e8f7b0ad9b70c5e658f4a06c7db71c6134a9a785ac1fdaa84f8b3358c4a572767838498df118daad1fa937237d1fb4b9fce735cf8bb0 - languageName: node - linkType: hard - -"@smithy/util-buffer-from@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-buffer-from@npm:4.1.0" - dependencies: - "@smithy/is-array-buffer": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/b1337ac6874adac67bbc91144c6e0e760b194f44af91a9816812c042c19a83d552cd5c8a94b8ed01af6047d2163a854fc32ebcd957a6053b4fd27dedc8793bb5 - languageName: node - linkType: hard - "@smithy/util-buffer-from@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-buffer-from@npm:4.2.0" @@ -7801,24 +6028,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-config-provider@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/614c321c5a5a220d7d72d36359c41b4e390566719f7e01cefebffbe7034aae78b4533b27ab2030f93186c5f22893ddf056a3a2376a077d70ce89275f31e1ac46 - languageName: node - linkType: hard - -"@smithy/util-config-provider@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-config-provider@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/b6daf4d12e721062d7b1888a14a760db23a3df388cced56ba47673cc1a3a24b8933190a7631be1cc548eb62fb5a3b5c34d6de2eb595ffdacdfd7e0dcb7fee5ef - languageName: node - linkType: hard - "@smithy/util-config-provider@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-config-provider@npm:4.2.0" @@ -7828,32 +6037,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" - dependencies: - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/27cfd517c703fad039086c55c10b15b36f424536526dd92a498cbf539e8d82da7b07e5cf3ae0f5ef4cbce70e4acd0af1d8e811f38391882b91191c0711a3e58c - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-browser@npm:^4.1.4": - version: 4.1.5 - resolution: "@smithy/util-defaults-mode-browser@npm:4.1.5" - dependencies: - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/8afc56f0e18da20ea9e283ef07ec669e4593c4b80642548cb07712ce01203d556f056682e4cab702b420cf61ccf31dc07dcfa79800981a920ca19d6bf30a8198 - languageName: node - linkType: hard - "@smithy/util-defaults-mode-browser@npm:^4.3.29": version: 4.3.30 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.30" @@ -7866,36 +6049,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" - dependencies: - "@smithy/config-resolver": "npm:^3.0.3" - "@smithy/credential-provider-imds": "npm:^3.1.2" - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/property-provider": "npm:^3.1.2" - "@smithy/smithy-client": "npm:^3.1.4" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/20476aae3eb5cb4353e63cc5bf4a91c47f40016981631b1a1150fca0d561907df8dc4c7c4c39c5462febc226e8daedbbcd5468df93326d54127fd31932305ae8 - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-node@npm:^4.1.4": - version: 4.1.5 - resolution: "@smithy/util-defaults-mode-node@npm:4.1.5" - dependencies: - "@smithy/config-resolver": "npm:^4.2.2" - "@smithy/credential-provider-imds": "npm:^4.1.2" - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/property-provider": "npm:^4.1.1" - "@smithy/smithy-client": "npm:^4.6.5" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/333739595d1679b54266acbbe558a18754db931e4ec2ecad237a7a0deede6a75b2e11386999b86b39900431d747d7d9188375f9060dc0b613bf68736c2b8fe42 - languageName: node - linkType: hard - "@smithy/util-defaults-mode-node@npm:^4.2.32": version: 4.2.33 resolution: "@smithy/util-defaults-mode-node@npm:4.2.33" @@ -7911,28 +6064,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^2.0.2": - version: 2.0.3 - resolution: "@smithy/util-endpoints@npm:2.0.3" - dependencies: - "@smithy/node-config-provider": "npm:^3.1.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/145fe25e5ab22ee2214b6ffefc8fa91d77f09e456cf38000565faa96cad4e6da88bbd47e79e6c7c5e8ed1c7e896a3b3c8496706b28c6d2fe748675d467429359 - languageName: node - linkType: hard - -"@smithy/util-endpoints@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/util-endpoints@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": "npm:^4.2.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/4310b3ae356d69f5bc6a7b3477ac5c16b0d014fe5c36db3445c010bfcea43f8b5de7abcb118f6935ccf9b41b9dcb6f17ca60792a68074c5b3ac70332dbc3c4b2 - languageName: node - linkType: hard - "@smithy/util-endpoints@npm:^3.2.8": version: 3.2.8 resolution: "@smithy/util-endpoints@npm:3.2.8" @@ -7944,24 +6075,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-hex-encoding@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d9f8c4c676410ca51bdbcec5d986883bad0028e26b098fc50e2b57bc81e8a5ce20e160786d08c8552ca0ba662c88ca16f33857ff24a0d183174325b2b40e3c8f - languageName: node - linkType: hard - -"@smithy/util-hex-encoding@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-hex-encoding@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/dc66a330ba5e4a7e034c75ff6bf823e7a3dd9df3283511f0e5e95797063f3a82cd1d68d1bdb2353b33502e7a2ae6806ae195a964c2e3339547e972d917c78ea4 - languageName: node - linkType: hard - "@smithy/util-hex-encoding@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-hex-encoding@npm:4.2.0" @@ -7971,26 +6084,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-middleware@npm:3.0.2" - dependencies: - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/1e202038bb332bc8301b5e7b882c917927d9c71aae1aae1d5529c68abbaf8efe4791a29f7d192c24c015b905d7cac3ef5aa867aedf3d9bf9f3557959a6877925 - languageName: node - linkType: hard - -"@smithy/util-middleware@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-middleware@npm:4.1.1" - dependencies: - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/bc80179fb554271dd44a9eb8403f09a2ed4f14de5ee1ba44fea17d8ee2d5b2178a433a24c85ee8898d7a69b45a8cf5978b3ef71866b6b461179a7c4ef4e79b58 - languageName: node - linkType: hard - "@smithy/util-middleware@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-middleware@npm:4.2.8" @@ -8001,28 +6094,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-retry@npm:3.0.2" - dependencies: - "@smithy/service-error-classification": "npm:^3.0.2" - "@smithy/types": "npm:^3.2.0" - tslib: "npm:^2.6.2" - checksum: 10/adda2d16b743dd99c5a3dd93da11a7e5e52eede37c936d966ea74aabd32007e2fc375ec47529ea3ea6052fc5c656a620917f87d66232bb4a23a9b252fa7af2eb - languageName: node - linkType: hard - -"@smithy/util-retry@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/util-retry@npm:4.1.2" - dependencies: - "@smithy/service-error-classification": "npm:^4.1.2" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/3daf4b560de5dff99c14661b7ae5c4456b7b99642141cd4c7dccb281579435edecd22695a9fe78d47e716c85e25c9bbc555d44598f460f01f2d28d9182834dd4 - languageName: node - linkType: hard - "@smithy/util-retry@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-retry@npm:4.2.8" @@ -8034,38 +6105,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": - version: 3.0.4 - resolution: "@smithy/util-stream@npm:3.0.4" - dependencies: - "@smithy/fetch-http-handler": "npm:^3.1.0" - "@smithy/node-http-handler": "npm:^3.1.0" - "@smithy/types": "npm:^3.2.0" - "@smithy/util-base64": "npm:^3.0.0" - "@smithy/util-buffer-from": "npm:^3.0.0" - "@smithy/util-hex-encoding": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/4e53f14fd0b6e32a9b9897193e03f5df969e97f41c28e4f37d3f39082ac0b1b3e8a62117650076e2ea760e14c6b5d2dfd860e69e7c6a7f0145c03b8b6284ce14 - languageName: node - linkType: hard - -"@smithy/util-stream@npm:^4.3.2": - version: 4.3.2 - resolution: "@smithy/util-stream@npm:4.3.2" - dependencies: - "@smithy/fetch-http-handler": "npm:^5.2.1" - "@smithy/node-http-handler": "npm:^4.2.1" - "@smithy/types": "npm:^4.5.0" - "@smithy/util-base64": "npm:^4.1.0" - "@smithy/util-buffer-from": "npm:^4.1.0" - "@smithy/util-hex-encoding": "npm:^4.1.0" - "@smithy/util-utf8": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/244739dcb05c1d1cb3e7b2cad313475605846fb1a264220d97777d35ab4c676a9e71a4443fb9f04b5ed0f6cd28c74f692ce75b14840429b0e28abffb6ab10ebb - languageName: node - linkType: hard - "@smithy/util-stream@npm:^4.5.11, @smithy/util-stream@npm:^4.5.12": version: 4.5.12 resolution: "@smithy/util-stream@npm:4.5.12" @@ -8082,24 +6121,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-uri-escape@npm:3.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/d44522339325b0f1fe2c5bf1a3f01d5a699eb8718d800dee24378a1a1b301683756dcfd4be4c32db4d6a00cad85893494778ae39fb246a03aef27d06c9852a67 - languageName: node - linkType: hard - -"@smithy/util-uri-escape@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-uri-escape@npm:4.1.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/c576cb2b7d365d02338734efd83d8b9d2e5ab7ea5a91444762ace367b6fe46e060a2a85ba51ba84ca5ac73b3e732436b22fb61359af4b731b41c1f803f3055ff - languageName: node - linkType: hard - "@smithy/util-uri-escape@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-uri-escape@npm:4.2.0" @@ -8119,26 +6140,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^3.0.0": - version: 3.0.0 - resolution: "@smithy/util-utf8@npm:3.0.0" - dependencies: - "@smithy/util-buffer-from": "npm:^3.0.0" - tslib: "npm:^2.6.2" - checksum: 10/1aead297d835af419f75e0c3113c021aa0da671110d1b498035530d5f35d8030092cad5147edaa7ca458aafe27c9383399ccd8176d342942465a2d8357e5cbf4 - languageName: node - linkType: hard - -"@smithy/util-utf8@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-utf8@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": "npm:^4.1.0" - tslib: "npm:^2.6.2" - checksum: 10/4565df6e64df958d2e45da4344d3206a81e66b6e6a48734a45b5228fe73c5c5982ec52beedc8065ab73d169a278f9028438a60410a6daa1d40aebd9dd6122a07 - languageName: node - linkType: hard - "@smithy/util-utf8@npm:^4.2.0": version: 4.2.0 resolution: "@smithy/util-utf8@npm:4.2.0" @@ -8149,17 +6150,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-waiter@npm:4.1.1" - dependencies: - "@smithy/abort-controller": "npm:^4.1.1" - "@smithy/types": "npm:^4.5.0" - tslib: "npm:^2.6.2" - checksum: 10/019eecded24b9244675da3b956f572261e333d8d2b0d0555f9c85c893f2583f113bf0210521876e825943085d2d89e7e4fdb768cdc802627b9660d809734cce3 - languageName: node - linkType: hard - "@smithy/util-waiter@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/util-waiter@npm:4.2.8" @@ -8171,15 +6161,6 @@ __metadata: languageName: node linkType: hard -"@smithy/uuid@npm:^1.0.0": - version: 1.0.0 - resolution: "@smithy/uuid@npm:1.0.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/0c6c1d987bfff8569ac16363f9293b91ebcc62824eaa8ba666a5ca007b0899741b3e472165aa9f2ae1beade9ef7773f24645795a35a3ab09bd58d6e0a32179f2 - languageName: node - linkType: hard - "@smithy/uuid@npm:^1.1.0": version: 1.1.0 resolution: "@smithy/uuid@npm:1.1.0" @@ -9223,7 +7204,19 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": + version: 5.1.1 + resolution: "@types/express-serve-static-core@npm:5.1.1" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 10/7f3d8cf7e68764c9f3e8f6a12825b69ccf5287347fc1c20b29803d4f08a4abc1153ae11d7258852c61aad50f62ef72d4c1b9c97092b0a90462c3dddec2f6026c + languageName: node + linkType: hard + +"@types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": version: 4.19.6 resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: @@ -9244,7 +7237,18 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.20, @types/express@npm:^4.17.21": +"@types/express@npm:*, @types/express@npm:^5.0.0, @types/express@npm:^5.0.6": + version: 5.0.6 + resolution: "@types/express@npm:5.0.6" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/serve-static": "npm:^2" + checksum: 10/da2cc3de1b1a4d7f20ed3fb6f0a8ee08e99feb3c2eb5a8d643db77017d8d0e70fee9e95da38a73f51bcdf5eda3bb6435073c0271dc04fb16fda92e55daf911fa + languageName: node + linkType: hard + +"@types/express@npm:^4.17.21": version: 4.17.23 resolution: "@types/express@npm:4.17.23" dependencies: @@ -9511,7 +7515,17 @@ __metadata: languageName: node linkType: hard -"@types/serve-static@npm:*, @types/serve-static@npm:^1.15.5": +"@types/serve-static@npm:*, @types/serve-static@npm:^2": + version: 2.2.0 + resolution: "@types/serve-static@npm:2.2.0" + dependencies: + "@types/http-errors": "npm:*" + "@types/node": "npm:*" + checksum: 10/f2bad1304c7d0d3b7221faff3e490c40129d3803f4fb1b2fb84f31f561071c5e6a4b876c41bbbe82d5645034eea936e946bcaaf993dac1093ce68b56effad6e0 + languageName: node + linkType: hard + +"@types/serve-static@npm:^1.15.5": version: 1.15.7 resolution: "@types/serve-static@npm:1.15.7" dependencies: @@ -9757,9 +7771,9 @@ __metadata: escape-goat: "npm:3.0.0" escape-string-regexp: "npm:4.0.0" execa: "npm:^9.6.0" - express: "npm:4.21.2" + express: "npm:^5.2.1" express-interceptor: "npm:1.2.0" - express-prom-bundle: "npm:7" + express-prom-bundle: "npm:^8.0.0" express-session: "npm:1.18.1" fast-safe-stringify: "npm:^2.1.1" formdata-node: "npm:^6.0.3" @@ -10910,6 +8924,16 @@ __metadata: languageName: node linkType: hard +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7 + languageName: node + linkType: hard + "accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -11507,26 +9531,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.3": - version: 1.20.3 - resolution: "body-parser@npm:1.20.3" - dependencies: - bytes: "npm:3.1.2" - content-type: "npm:~1.0.5" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - on-finished: "npm:2.4.1" - qs: "npm:6.13.0" - raw-body: "npm:2.5.2" - type-is: "npm:~1.6.18" - unpipe: "npm:1.0.0" - checksum: 10/8723e3d7a672eb50854327453bed85ac48d045f4958e81e7d470c56bf111f835b97e5b73ae9f6393d0011cc9e252771f46fd281bbabc57d33d3986edf1e6aeca - languageName: node - linkType: hard - "body-parser@npm:1.20.4, body-parser@npm:^1.19.0, body-parser@npm:^1.20.4, body-parser@npm:~1.20.3": version: 1.20.4 resolution: "body-parser@npm:1.20.4" @@ -11547,6 +9551,23 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:^2.2.1": + version: 2.2.2 + resolution: "body-parser@npm:2.2.2" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.3" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.7.0" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.1" + raw-body: "npm:^3.0.1" + type-is: "npm:^2.0.1" + checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 + languageName: node + linkType: hard + "bonjour-service@npm:^1.2.1": version: 1.2.1 resolution: "bonjour-service@npm:1.2.1" @@ -11695,7 +9716,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2, bytes@npm:~3.1.2": +"bytes@npm:^3.1.2, bytes@npm:~3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 @@ -12369,7 +10390,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": +"content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -12378,7 +10399,14 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-disposition@npm:^1.0.0": + version: 1.1.0 + resolution: "content-disposition@npm:1.1.0" + checksum: 10/c4f65e3c001a4a8eb87d0d24c0f112abb139836fb13b8ea67276715e7dce09570ef666ba7848ee8b660d467e6588d030c8ed7e8d0128db6ca78a0800dcd8c7a8 + languageName: node + linkType: hard + +"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 @@ -12430,21 +10458,14 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.2": +"cookie-signature@npm:^1.2.1, cookie-signature@npm:^1.2.2": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 languageName: node linkType: hard -"cookie@npm:0.7.1": - version: 0.7.1 - resolution: "cookie@npm:0.7.1" - checksum: 10/aec6a6aa0781761bf55d60447d6be08861d381136a0fe94aa084fddd4f0300faa2b064df490c6798adfa1ebaef9e0af9b08a189c823e0811b8b313b3d9a03380 - languageName: node - linkType: hard - -"cookie@npm:0.7.2, cookie@npm:^0.7.2, cookie@npm:~0.7.1": +"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2, cookie@npm:~0.7.1": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f @@ -12857,7 +10878,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -13020,7 +11041,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0, depd@npm:~2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca @@ -13078,14 +11099,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": - version: 2.0.4 - resolution: "detect-libc@npm:2.0.4" - checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0 - languageName: node - linkType: hard - -"detect-libc@npm:^2.1.2": +"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4, detect-libc@npm:^2.1.2": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10/b736c8d97d5d46164c0d1bed53eb4e6a3b1d8530d460211e2d52f1c552875e706c58a5376854e4e54f8b828c9cada58c855288c968522eb93ac7696d65970766 @@ -13317,6 +11331,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -13324,13 +11345,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -13843,7 +11857,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:~1.0.3": +"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 @@ -13946,7 +11960,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1, etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff @@ -14014,7 +12028,7 @@ __metadata: cookie-parser: "npm:^1.4.7" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.17.3" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14030,7 +12044,7 @@ __metadata: "@aws-sdk/s3-request-presigner": "npm:^3.338.0" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.0" - express: "npm:^4.22.0" + express: "npm:^5.2.1" languageName: unknown linkType: soft @@ -14065,7 +12079,7 @@ __metadata: "@uppy/tus": "workspace:*" body-parser: "npm:^1.20.4" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.15.6" npm-run-all: "npm:^4.1.2" preact: "npm:^10.26.10" @@ -14083,7 +12097,7 @@ __metadata: body-parser: "npm:^1.20.4" cors: "npm:^2.8.5" dotenv: "npm:^16.0.1" - express: "npm:^4.22.0" + express: "npm:^5.2.1" vite: "npm:^7.1.11" languageName: unknown linkType: soft @@ -14094,7 +12108,7 @@ __metadata: dependencies: "@uppy/companion": "workspace:*" body-parser: "npm:^1.20.4" - express: "npm:^4.22.0" + express: "npm:^5.2.1" express-session: "npm:^1.15.6" light-server: "npm:^2.4.0" languageName: unknown @@ -14161,7 +12175,7 @@ __metadata: "@react-router/express": "npm:^7.12.0" "@tus/file-store": "npm:latest" "@tus/server": "npm:latest" - "@types/express": "npm:^4.17.20" + "@types/express": "npm:^5.0.6" "@types/react": "npm:^18.2.20" "@types/react-dom": "npm:^18.2.7" "@uppy/core": "workspace:*" @@ -14170,7 +12184,7 @@ __metadata: "@uppy/transloadit": "workspace:*" "@uppy/tus": "workspace:*" "@uppy/xhr-upload": "workspace:*" - express: "npm:^4.22.0" + express: "npm:^5.2.1" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-router: "npm:^7.12.0" @@ -14220,7 +12234,7 @@ __metadata: "@uppy/remote-sources": "workspace:*" "@uppy/transloadit": "workspace:*" "@uppy/webcam": "workspace:*" - express: "npm:^4.22.0" + express: "npm:^5.2.1" he: "npm:^1.2.0" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14259,7 +12273,7 @@ __metadata: "@uppy/dashboard": "workspace:*" "@uppy/xhr-upload": "workspace:*" cors: "npm:^2.8.5" - express: "npm:^4.22.0" + express: "npm:^5.2.1" multer: "npm:^2.0.2" npm-run-all: "npm:^4.1.5" vite: "npm:^7.1.11" @@ -14363,17 +12377,16 @@ __metadata: languageName: node linkType: hard -"express-prom-bundle@npm:7": - version: 7.0.2 - resolution: "express-prom-bundle@npm:7.0.2" +"express-prom-bundle@npm:^8.0.0": + version: 8.0.0 + resolution: "express-prom-bundle@npm:8.0.0" dependencies: - "@types/express": "npm:^4.17.21" - express: "npm:^4.18.2" + "@types/express": "npm:^5.0.0" on-finished: "npm:^2.3.0" url-value-parser: "npm:^2.0.0" peerDependencies: prom-client: ">=15.0.0" - checksum: 10/19d95252eaaaedae1a05d90bbb96cbcc60e82e7710baa18810bd9c327b864b743f4e16bc2a5b3f7e51dcd505ac86db4fd9391c72c11cf6c0dc2c8df893870e02 + checksum: 10/63bb4769e1ce6258dece3ac1011fccf81e31974bbbdd7e2c7d85679b4cb9bb5b1fc2294ca1648f043bfe42796b9b89f348ad1dfc2680d41c8655394c50606319 languageName: node linkType: hard @@ -14393,46 +12406,7 @@ __metadata: languageName: node linkType: hard -"express@npm:4.21.2": - version: 4.21.2 - resolution: "express@npm:4.21.2" - dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.3" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.7.1" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.3.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.3" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.12" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.13.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.19.0" - serve-static: "npm:1.16.2" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 10/34571c442fc8c9f2c4b442d2faa10ea1175cf8559237fc6a278f5ce6254a8ffdbeb9a15d99f77c1a9f2926ab183e3b7ba560e3261f1ad4149799e3412ab66bd1 - languageName: node - linkType: hard - -"express@npm:^4.18.2, express@npm:^4.21.2, express@npm:^4.22.0": +"express@npm:^4.21.2": version: 4.22.1 resolution: "express@npm:4.22.1" dependencies: @@ -14471,6 +12445,42 @@ __metadata: languageName: node linkType: hard +"express@npm:^5.2.1": + version: 5.2.1 + resolution: "express@npm:5.2.1" + dependencies: + accepts: "npm:^2.0.0" + body-parser: "npm:^2.2.1" + content-disposition: "npm:^1.0.0" + content-type: "npm:^1.0.5" + cookie: "npm:^0.7.1" + cookie-signature: "npm:^1.2.1" + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + finalhandler: "npm:^2.1.0" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + merge-descriptors: "npm:^2.0.0" + mime-types: "npm:^3.0.0" + on-finished: "npm:^2.4.1" + once: "npm:^1.4.0" + parseurl: "npm:^1.3.3" + proxy-addr: "npm:^2.0.7" + qs: "npm:^6.14.0" + range-parser: "npm:^1.2.1" + router: "npm:^2.2.0" + send: "npm:^1.1.0" + serve-static: "npm:^2.2.0" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10/4aa545d89702ac83f645c77abda1b57bcabe288f0b380fb5580fac4e323ea0eb533005c8e666b4e19152fb16d4abf11ba87b22aa9a10857a0485cd86b94639bd + languageName: node + linkType: hard + "exsolve@npm:^1.0.7": version: 1.0.8 resolution: "exsolve@npm:1.0.8" @@ -14537,28 +12547,6 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.2.5": - version: 4.2.5 - resolution: "fast-xml-parser@npm:4.2.5" - dependencies: - strnum: "npm:^1.0.5" - bin: - fxparser: src/cli/cli.js - checksum: 10/4be7ebe24d6a9a60c278e1423cd86a7da9a77ec64c95563e2c552363caf7a777e0c87c9de1255c2f4e8dea9bce8905dc2bdc58a34e9f2b73c4693654456ad284 - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.2.5": - version: 5.2.5 - resolution: "fast-xml-parser@npm:5.2.5" - dependencies: - strnum: "npm:^2.1.0" - bin: - fxparser: src/cli/cli.js - checksum: 10/305017cff6968a34cbac597317be1516e85c44f650f30d982c84f8c30043e81fd38d39a8810d570136c921399dd43b9ac4775bdfbbbcfee96456f3c086b48bdd - languageName: node - linkType: hard - "fast-xml-parser@npm:5.3.4": version: 5.3.4 resolution: "fast-xml-parser@npm:5.3.4" @@ -14654,18 +12642,17 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.3.1": - version: 1.3.1 - resolution: "finalhandler@npm:1.3.1" +"finalhandler@npm:^2.1.0": + version: 2.1.1 + resolution: "finalhandler@npm:2.1.1" dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 10/4babe72969b7373b5842bc9f75c3a641a4d0f8eb53af6b89fa714d4460ce03fb92b28de751d12ba415e96e7e02870c436d67412120555e2b382640535697305b + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + on-finished: "npm:^2.4.1" + parseurl: "npm:^1.3.3" + statuses: "npm:^2.0.1" + checksum: 10/f4ba75c23408d8f9d393c3e875b9452e84d68c925411a6e67b7efa678b0bed5075ef33def4bb65ed8e0dd37c92a3ea354bcbde07303cd4dc2550e12b95885067 languageName: node linkType: hard @@ -14864,6 +12851,13 @@ __metadata: languageName: node linkType: hard +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc + languageName: node + linkType: hard + "fs-extra@npm:^11.0.0": version: 11.3.0 resolution: "fs-extra@npm:11.3.0" @@ -15552,19 +13546,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:~1.6.2": - version: 1.6.3 - resolution: "http-errors@npm:1.6.3" - dependencies: - depd: "npm:~1.1.2" - inherits: "npm:2.0.3" - setprototypeof: "npm:1.1.0" - statuses: "npm:>= 1.4.0 < 2" - checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb - languageName: node - linkType: hard - -"http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": +"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": version: 2.0.1 resolution: "http-errors@npm:2.0.1" dependencies: @@ -15577,6 +13559,18 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:~1.6.2": + version: 1.6.3 + resolution: "http-errors@npm:1.6.3" + dependencies: + depd: "npm:~1.1.2" + inherits: "npm:2.0.3" + setprototypeof: "npm:1.1.0" + statuses: "npm:>= 1.4.0 < 2" + checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb + languageName: node + linkType: hard + "http-parser-js@npm:>=0.5.1": version: 0.5.8 resolution: "http-parser-js@npm:0.5.8" @@ -15710,7 +13704,16 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -15719,12 +13722,12 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" +"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + checksum: 10/24c937b532f868e938386b62410b303b7c767ce3d08dc2829cbe59464d5a26ef86ae5ad1af6b34eec43ddfea39e7d101638644b0178d67262fa87015d59f983a languageName: node linkType: hard @@ -16176,6 +14179,13 @@ __metadata: languageName: node linkType: hard +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a + languageName: node + linkType: hard + "is-reference@npm:^3.0.3": version: 3.0.3 resolution: "is-reference@npm:3.0.3" @@ -17467,14 +15477,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 - languageName: node - linkType: hard - -"lodash@npm:^4.17.23": +"lodash@npm:^4.17.21, lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10/82504c88250f58da7a5a4289f57a4f759c44946c005dd232821c7688b5fcfbf4a6268f6a6cdde4b792c91edd2f3b5398c1d2a0998274432cff76def48735e233 @@ -17736,6 +15739,13 @@ __metadata: languageName: node linkType: hard +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd + languageName: node + linkType: hard + "memfs@npm:^4.6.0": version: 4.9.3 resolution: "memfs@npm:4.9.3" @@ -17762,6 +15772,13 @@ __metadata: languageName: node linkType: hard +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -17793,13 +15810,20 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": +"mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 languageName: node linkType: hard +"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 + languageName: node + linkType: hard + "mime-match@npm:^1.0.2": version: 1.0.2 resolution: "mime-match@npm:1.0.2" @@ -17818,6 +15842,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": + version: 3.0.2 + resolution: "mime-types@npm:3.0.2" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10/9db0ad31f5eff10ee8f848130779b7f2d056ddfdb6bda696cb69be68d486d33a3457b4f3f9bdeb60d0736edb471bd5a7c0a384375c011c51c889fd0d5c3b893e + languageName: node + linkType: hard + "mime@npm:1.6.0, mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -18082,16 +16115,7 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:^3.0.1": - version: 3.0.2 - resolution: "minizlib@npm:3.0.2" - dependencies: - minipass: "npm:^7.1.2" - checksum: 10/c075bed1594f68dcc8c35122333520112daefd4d070e5d0a228bd4cf5580e9eed3981b96c0ae1d62488e204e80fd27b2b9d0068ca9a5ef3993e9565faf63ca41 - languageName: node - linkType: hard - -"minizlib@npm:^3.1.0": +"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" dependencies: @@ -18120,15 +16144,6 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^3.0.1": - version: 3.0.1 - resolution: "mkdirp@npm:3.0.1" - bin: - mkdirp: dist/cjs/src/bin.js - checksum: 10/16fd79c28645759505914561e249b9a1f5fe3362279ad95487a4501e4467abeb714fd35b95307326b8fd03f3c7719065ef11a6f97b7285d7888306d1bd2232ba - languageName: node - linkType: hard - "moment-timezone@npm:^0.5.31": version: 0.5.45 resolution: "moment-timezone@npm:0.5.45" @@ -19465,13 +17480,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.12, path-to-regexp@npm:~0.1.12": - version: 0.1.12 - resolution: "path-to-regexp@npm:0.1.12" - checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e - languageName: node - linkType: hard - "path-to-regexp@npm:^6.3.0": version: 6.3.0 resolution: "path-to-regexp@npm:6.3.0" @@ -19479,6 +17487,20 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^8.0.0": + version: 8.4.2 + resolution: "path-to-regexp@npm:8.4.2" + checksum: 10/70fd2cbce0b962cbcf4d312af07818bfce2bae11c09cf3bd86be99c0e30168238a1a7b02b18b452e73f075897df04597d30d63e56da7be41eecfc37998693389 + languageName: node + linkType: hard + +"path-to-regexp@npm:~0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e + languageName: node + linkType: hard + "path-type@npm:^3.0.0": version: 3.0.0 resolution: "path-type@npm:3.0.0" @@ -20312,7 +18334,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -20364,16 +18386,16 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.13.0": - version: 6.13.0 - resolution: "qs@npm:6.13.0" +"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.6": + version: 6.15.1 + resolution: "qs@npm:6.15.1" dependencies: - side-channel: "npm:^1.0.6" - checksum: 10/f548b376e685553d12e461409f0d6e5c59ec7c7d76f308e2a888fd9db3e0c5e89902bedd0754db3a9038eda5f27da2331a6f019c8517dc5e0a16b3c9a6e9cef8 + side-channel: "npm:^1.1.0" + checksum: 10/ec10b9957446b3f4a38000940f6374720b4e2985209b89df197066038c951472ea24cd98d6bc6df73a0cbec75bc056f638032e3fb447345017ff7e0f0a2693ac languageName: node linkType: hard -"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.9.6, qs@npm:~6.14.0": +"qs@npm:~6.14.0": version: 6.14.0 resolution: "qs@npm:6.14.0" dependencies: @@ -20433,15 +18455,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.2": - version: 2.5.2 - resolution: "raw-body@npm:2.5.2" +"raw-body@npm:^3.0.1": + version: 3.0.2 + resolution: "raw-body@npm:3.0.2" dependencies: - bytes: "npm:3.1.2" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - unpipe: "npm:1.0.0" - checksum: 10/863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95 + bytes: "npm:~3.1.2" + http-errors: "npm:~2.0.1" + iconv-lite: "npm:~0.7.0" + unpipe: "npm:~1.0.0" + checksum: 10/4168c82157bd69175d5bd960e59b74e253e237b358213694946a427a6f750a18b8e150f036fed3421b3e83294b071a4e2bb01037a79ccacdac05360c63d3ebba languageName: node linkType: hard @@ -21076,6 +19098,19 @@ __metadata: languageName: node linkType: hard +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + is-promise: "npm:^4.0.0" + parseurl: "npm:^1.3.3" + path-to-regexp: "npm:^8.0.0" + checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91 + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.8.0": version: 0.8.0 resolution: "rrweb-cssom@npm:0.8.0" @@ -21309,16 +19344,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": - version: 7.7.2 - resolution: "semver@npm:7.7.2" - bin: - semver: bin/semver.js - checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda - languageName: node - linkType: hard - -"semver@npm:^7.7.3": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -21369,6 +19395,25 @@ __metadata: languageName: node linkType: hard +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.1 + resolution: "send@npm:1.2.1" + dependencies: + debug: "npm:^4.4.3" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.1" + mime-types: "npm:^3.0.2" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.2" + checksum: 10/274f842d69ccfa49d4940a85598c6825da58dee6cb8ea33b08d5bd3988e6a82267c4d7c32b23d0e4706aad076ee95b1edfa13f859877db9b589829019397e355 + languageName: node + linkType: hard + "send@npm:~0.19.0": version: 0.19.1 resolution: "send@npm:0.19.1" @@ -21423,15 +19468,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.16.2, serve-static@npm:~1.16.2": - version: 1.16.2 - resolution: "serve-static@npm:1.16.2" +"serve-static@npm:^2.2.0": + version: 2.2.1 + resolution: "serve-static@npm:2.2.1" dependencies: - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.19.0" - checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + parseurl: "npm:^1.3.3" + send: "npm:^1.2.0" + checksum: 10/71500fe80cc7163fec04e4297de7591ad1cb682d137fc030e7a53e57040fda5187e8082a9c1b2ef37f1d3f9c27c9a94d4ba61806ebc28938ba4a7c8947c9f71e languageName: node linkType: hard @@ -21447,6 +19492,18 @@ __metadata: languageName: node linkType: hard +"serve-static@npm:~1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" + dependencies: + encodeurl: "npm:~2.0.0" + escape-html: "npm:~1.0.3" + parseurl: "npm:~1.3.3" + send: "npm:0.19.0" + checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 + languageName: node + linkType: hard + "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -21675,7 +19732,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": +"side-channel@npm:^1.0.4, side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -22054,7 +20111,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:^2.0.1, statuses@npm:~2.0.1, statuses@npm:~2.0.2": +"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.1, statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 @@ -22264,7 +20321,7 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.0.5, strnum@npm:^1.1.1": +"strnum@npm:^1.1.1": version: 1.1.2 resolution: "strnum@npm:1.1.2" checksum: 10/ccd6297a1fdaf0fc8ea0ea904acdae76878d49a4b0d98a70155df4bc081fd88eac5ec99fb150f3d1d1af065c1898d38420705259ba6c39aa850c671bcd54e35d @@ -22494,21 +20551,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.4.3": - version: 7.4.3 - resolution: "tar@npm:7.4.3" - dependencies: - "@isaacs/fs-minipass": "npm:^4.0.0" - chownr: "npm:^3.0.0" - minipass: "npm:^7.1.2" - minizlib: "npm:^3.0.1" - mkdirp: "npm:^3.0.1" - yallist: "npm:^5.0.0" - checksum: 10/12a2a4fc6dee23e07cc47f1aeb3a14a1afd3f16397e1350036a8f4cdfee8dcac7ef5978337a4e7b2ac2c27a9a6d46388fc2088ea7c80cb6878c814b1425f8ecf - languageName: node - linkType: hard - -"tar@npm:^7.5.7": +"tar@npm:^7.4.3, tar@npm:^7.5.7": version: 7.5.12 resolution: "tar@npm:7.5.12" dependencies: @@ -22904,6 +20947,17 @@ __metadata: languageName: node linkType: hard +"type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" + dependencies: + content-type: "npm:^1.0.5" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10/bacdb23c872dacb7bd40fbd9095e6b2fca2895eedbb689160c05534d7d4810a7f4b3fd1ae87e96133c505958f6d602967a68db5ff577b85dd6be76eaa75d58af + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -23185,7 +21239,7 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": +"unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10/4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 @@ -23317,15 +21371,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.1": - version: 9.0.1 - resolution: "uuid@npm:9.0.1" - bin: - uuid: dist/bin/uuid - checksum: 10/9d0b6adb72b736e36f2b1b53da0d559125ba3e39d913b6072f6f033e0c87835b414f0836b45bcfaf2bdf698f92297fea1c3cc19b0b258bc182c9c43cc0fab9f2 - languageName: node - linkType: hard - "valibot@npm:^1.2.0": version: 1.2.0 resolution: "valibot@npm:1.2.0" @@ -23371,7 +21416,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 From 3c537e278068177ba7d77749ee106bbcc2ff6b55 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Thu, 21 May 2026 12:07:05 +0800 Subject: [PATCH 22/33] Companion upgrade deps (#6305) recreates #6296 --------- Co-authored-by: Prakash --- packages/@uppy/companion/package.json | 60 +- .../src/server/provider/webdav/index.ts | 3 +- yarn.lock | 1141 ++++++++++++++--- 3 files changed, 978 insertions(+), 226 deletions(-) diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 02e389eec..4774eed9e 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -34,48 +34,48 @@ ], "bin": "./dist/bin/companion.js", "dependencies": { - "@aws-sdk/client-s3": "3.986.0", - "@aws-sdk/client-sts": "3.986.0", - "@aws-sdk/lib-storage": "3.986.0", - "@aws-sdk/s3-presigned-post": "3.986.0", - "@aws-sdk/s3-request-presigner": "3.986.0", - "body-parser": "1.20.4", + "@aws-sdk/client-s3": "3.1047.0", + "@aws-sdk/client-sts": "3.1047.0", + "@aws-sdk/lib-storage": "3.1047.0", + "@aws-sdk/s3-presigned-post": "3.1047.0", + "@aws-sdk/s3-request-presigner": "3.1047.0", + "body-parser": "2.2.2", "common-tags": "1.8.2", "connect-redis": "7.1.1", - "content-disposition": "^0.5.4", + "content-disposition": "2.0.0", "cookie-parser": "1.4.7", - "cors": "^2.8.5", - "escape-goat": "3.0.0", - "escape-string-regexp": "4.0.0", + "cors": "2.8.6", + "escape-goat": "4.0.0", + "escape-string-regexp": "5.0.0", "express": "^5.2.1", "express-interceptor": "1.2.0", "express-prom-bundle": "^8.0.0", - "express-session": "1.18.1", + "express-session": "1.19.0", "fast-safe-stringify": "^2.1.1", "formdata-node": "^6.0.3", "got": "^13.0.0", "grant": "^5.4.24", - "helmet": "^7.1.0", - "ioredis": "^5.3.2", - "ipaddr.js": "^2.0.1", - "jsonwebtoken": "9.0.2", - "lodash": "^4.17.23", - "mime-types": "2.1.35", - "moment": "^2.29.2", - "moment-timezone": "^0.5.31", - "morgan": "1.10.0", + "helmet": "8.1.0", + "ioredis": "5.10.1", + "ipaddr.js": "2.4.0", + "jsonwebtoken": "9.0.3", + "lodash": "4.18.1", + "mime-types": "3.0.2", + "moment": "2.30.1", + "moment-timezone": "0.6.2", + "morgan": "1.10.1", "ms": "2.1.3", "node-schedule": "2.1.1", - "p-map": "^7.0.3", - "prom-client": "15.1.2", - "serialize-error": "^11.0.0", - "serialize-javascript": "^6.0.0", - "supports-color": "8.x", - "tus-js-client": "^4.1.0", - "validator": "^13.15.22", - "webdav": "^5.8.0", - "ws": "8.17.1", - "zod": "^3.24.0" + "p-map": "7.0.4", + "prom-client": "15.1.3", + "serialize-error": "13.0.1", + "serialize-javascript": "7.0.5", + "supports-color": "10.2.2", + "tus-js-client": "4.3.1", + "validator": "13.15.35", + "webdav": "5.10.0", + "ws": "8.20.1", + "zod": "4.4.3" }, "devDependencies": { "@types/common-tags": "^1.8.4", diff --git a/packages/@uppy/companion/src/server/provider/webdav/index.ts b/packages/@uppy/companion/src/server/provider/webdav/index.ts index e8ec83416..c932b9691 100644 --- a/packages/@uppy/companion/src/server/provider/webdav/index.ts +++ b/packages/@uppy/companion/src/server/provider/webdav/index.ts @@ -159,12 +159,11 @@ export default class WebdavProvider extends Provider { const data: { items: WebdavListItem[] } = { items: [] } const client = await this.getClient({ providerUserSession }) - const dirResult = await client.getDirectoryContents( + const dir = await client.getDirectoryContents( (typeof query?.['directory'] === 'string' ? query?.['directory'] : undefined) || '/', ) - const dir = Array.isArray(dirResult) ? dirResult : dirResult.data dir.forEach((item) => { const isFolder = item.type === 'directory' diff --git a/yarn.lock b/yarn.lock index 049829d74..5bae0ea9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -509,7 +509,41 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:3.986.0, @aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": +"@aws-sdk/client-s3@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/client-s3@npm:3.1047.0" + dependencies: + "@aws-crypto/sha1-browser": "npm:5.2.0" + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/credential-provider-node": "npm:^3.972.41" + "@aws-sdk/middleware-bucket-endpoint": "npm:^3.972.12" + "@aws-sdk/middleware-expect-continue": "npm:^3.972.11" + "@aws-sdk/middleware-flexible-checksums": "npm:^3.974.18" + "@aws-sdk/middleware-host-header": "npm:^3.972.11" + "@aws-sdk/middleware-location-constraint": "npm:^3.972.10" + "@aws-sdk/middleware-logger": "npm:^3.972.10" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.12" + "@aws-sdk/middleware-sdk-s3": "npm:^3.972.39" + "@aws-sdk/middleware-ssec": "npm:^3.972.10" + "@aws-sdk/middleware-user-agent": "npm:^3.972.40" + "@aws-sdk/region-config-resolver": "npm:^3.972.14" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.26" + "@aws-sdk/types": "npm:^3.973.8" + "@aws-sdk/util-endpoints": "npm:^3.996.9" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.11" + "@aws-sdk/util-user-agent-node": "npm:^3.973.26" + "@smithy/core": "npm:^3.24.1" + "@smithy/fetch-http-handler": "npm:^5.4.1" + "@smithy/node-http-handler": "npm:^4.7.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/5331fdd175032c21cd7a4c05c5583833a1a802a0c3f23a168b68fd7b469d0882406ed7d73e7b8d80ef3a7eacc5090853c926da4fa73b7429196f00afc59950f4 + languageName: node + linkType: hard + +"@aws-sdk/client-s3@npm:^3.338.0, @aws-sdk/client-s3@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/client-s3@npm:3.986.0" dependencies: @@ -618,7 +652,34 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.986.0, @aws-sdk/client-sts@npm:^3.338.0": +"@aws-sdk/client-sts@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/client-sts@npm:3.1047.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/credential-provider-node": "npm:^3.972.41" + "@aws-sdk/middleware-host-header": "npm:^3.972.11" + "@aws-sdk/middleware-logger": "npm:^3.972.10" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.12" + "@aws-sdk/middleware-user-agent": "npm:^3.972.40" + "@aws-sdk/region-config-resolver": "npm:^3.972.14" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.26" + "@aws-sdk/types": "npm:^3.973.8" + "@aws-sdk/util-endpoints": "npm:^3.996.9" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.11" + "@aws-sdk/util-user-agent-node": "npm:^3.973.26" + "@smithy/core": "npm:^3.24.1" + "@smithy/fetch-http-handler": "npm:^5.4.1" + "@smithy/node-http-handler": "npm:^4.7.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/ebff5b42c0fbc9fbc94c3ae30b55d8244918805f3d63350ec2f7556b415a108a153fc63ae7af92606ea68bacf1f74f7319b3284b90e1cc3e9ba830ebe99de68f + languageName: node + linkType: hard + +"@aws-sdk/client-sts@npm:^3.338.0": version: 3.986.0 resolution: "@aws-sdk/client-sts@npm:3.986.0" dependencies: @@ -686,6 +747,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:^3.974.10": + version: 3.974.10 + resolution: "@aws-sdk/core@npm:3.974.10" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@aws-sdk/xml-builder": "npm:^3.972.24" + "@smithy/core": "npm:^3.24.1" + "@smithy/signature-v4": "npm:^5.4.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/9ca6f7af88ad78e066bf22b66613bbf1b6d6252653143f9e804ea40f5ab6d2af3cf676957c447c1ef265fd8bedf0eb55a5c2580f2780f7b328277a9526f4b266 + languageName: node + linkType: hard + "@aws-sdk/crc64-nvme@npm:3.972.0": version: 3.972.0 resolution: "@aws-sdk/crc64-nvme@npm:3.972.0" @@ -696,6 +771,29 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/crc64-nvme@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/crc64-nvme@npm:3.972.8" + dependencies: + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/2b2fd4acf0c0152f79f84b835125b4e82b72837cfb6e47de8922757a48adf17b827299eca294d151f67c30e1436dfd8a9109d5e5b43392caf3954a2c90767ebd + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:^3.972.36": + version: 3.972.36 + resolution: "@aws-sdk/credential-provider-env@npm:3.972.36" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/657a03d2ef3be9e9956259f614a2dbbcfe35fc6e3bba0937e0dc90580d51ce19ee6481750beb258765bd8344d2542386d443765605551cd5569ec163e11826b9 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-env@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-env@npm:3.972.5" @@ -709,6 +807,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:^3.972.38": + version: 3.972.38 + resolution: "@aws-sdk/credential-provider-http@npm:3.972.38" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/fetch-http-handler": "npm:^5.4.1" + "@smithy/node-http-handler": "npm:^4.7.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/f068ff64445b147946981dd9516166d45579a17ed64f146a8820a0829ed68b8950b3ad782a57d0ca5c20dd9850fd2668102340d5a0f5f6851af703b61fcd7818 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/credential-provider-http@npm:3.972.7" @@ -727,6 +840,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:^3.972.40": + version: 3.972.40 + resolution: "@aws-sdk/credential-provider-ini@npm:3.972.40" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/credential-provider-env": "npm:^3.972.36" + "@aws-sdk/credential-provider-http": "npm:^3.972.38" + "@aws-sdk/credential-provider-login": "npm:^3.972.40" + "@aws-sdk/credential-provider-process": "npm:^3.972.36" + "@aws-sdk/credential-provider-sso": "npm:^3.972.40" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.40" + "@aws-sdk/nested-clients": "npm:^3.997.8" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/credential-provider-imds": "npm:^4.3.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/5082af14575fc51b022a31f34463115f01827e7f3e1519dba5dfce337f84dd427e5d6a4b3844e193b1afe816ca44b650ed7daf129ffbc342241669bc9cb8c4d9 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-ini@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-ini@npm:3.972.5" @@ -749,6 +883,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-login@npm:^3.972.40": + version: 3.972.40 + resolution: "@aws-sdk/credential-provider-login@npm:3.972.40" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/nested-clients": "npm:^3.997.8" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/6b30910e375e46e0d23006e4e4dfcd0b82d6cec836dd5540d68dd8eb1d698611ba670fe0f4719c6f0bb66b4ac70ca872707eb48f27411006fee68496bfbc21e1 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-login@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-login@npm:3.972.5" @@ -765,6 +913,25 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:^3.972.41": + version: 3.972.41 + resolution: "@aws-sdk/credential-provider-node@npm:3.972.41" + dependencies: + "@aws-sdk/credential-provider-env": "npm:^3.972.36" + "@aws-sdk/credential-provider-http": "npm:^3.972.38" + "@aws-sdk/credential-provider-ini": "npm:^3.972.40" + "@aws-sdk/credential-provider-process": "npm:^3.972.36" + "@aws-sdk/credential-provider-sso": "npm:^3.972.40" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.40" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/credential-provider-imds": "npm:^4.3.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/72509436051e7737d4345c75f64d4c2621961fb3a631f330980433677dea3da3df4a0eeaf0eb7b9e8b074963fc91bf6c5dae667f350b9e02731dbaf766ca4232 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:^3.972.6": version: 3.972.6 resolution: "@aws-sdk/credential-provider-node@npm:3.972.6" @@ -785,6 +952,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:^3.972.36": + version: 3.972.36 + resolution: "@aws-sdk/credential-provider-process@npm:3.972.36" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/77f4e1d6512a49ea9f78c17766287df9883ce3f1f7451b6c3e6b1c57d3394244d9aa6874d0d119e8711b72ba70ffdc326030870e6db57510cd2d3f226793b8c8 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-process@npm:3.972.5" @@ -799,6 +979,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:^3.972.40": + version: 3.972.40 + resolution: "@aws-sdk/credential-provider-sso@npm:3.972.40" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/nested-clients": "npm:^3.997.8" + "@aws-sdk/token-providers": "npm:3.1047.0" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/f2e43c362d14f7ec0fbfd89860dbcf7d7a0f6fb8788f9fb774c21016b67da86187a6d6734cdd042c8a2423b614d4bd5f0d78409bbe88be57182c22cb14456bc5 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.5" @@ -815,6 +1010,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:^3.972.40": + version: 3.972.40 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.40" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/nested-clients": "npm:^3.997.8" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/166a68234616b4b00de4808dc6bd8d443c133c78ae6c1393d00557619ce600e89a3e9e58f3e48cd3c48fd532cd36bdbcad2949696447367b310d45a01cc4a2fa + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:^3.972.5": version: 3.972.5 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.5" @@ -830,20 +1039,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/lib-storage@npm:3.986.0": - version: 3.986.0 - resolution: "@aws-sdk/lib-storage@npm:3.986.0" +"@aws-sdk/lib-storage@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/lib-storage@npm:3.1047.0" dependencies: - "@smithy/abort-controller": "npm:^4.2.8" - "@smithy/middleware-endpoint": "npm:^4.4.13" - "@smithy/smithy-client": "npm:^4.11.2" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" buffer: "npm:5.6.0" events: "npm:3.3.0" stream-browserify: "npm:3.0.0" tslib: "npm:^2.6.2" peerDependencies: - "@aws-sdk/client-s3": ^3.986.0 - checksum: 10/7b4a13a6e99263efd558a45fbc1733b54627ca6f80c44113671b39ab9fba8e39d13dc139d14c57c0bf5ee3f69322b0b4697974d6b65eee0b936cc4c754e7f98e + "@aws-sdk/client-s3": ^3.1047.0 + checksum: 10/df30f626230074108b99e6243915ad1786b883310ceae089a981f770864d2e9d7cefe2ff378ce71c52c3e7f2bf20687df7deb6d4ddcda7aa282cf44f411c5788 + languageName: node + linkType: hard + +"@aws-sdk/middleware-bucket-endpoint@npm:^3.972.12": + version: 3.972.12 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.12" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/3df27df729dc420716f17d62b25f35db101818322c8ce1060baa39fbc5ea134a594c56eb770840b4938d3d28bf654f0eab201f1ec5760e33ec177c578da881d3 languageName: node linkType: hard @@ -862,6 +1083,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-expect-continue@npm:^3.972.11": + version: 3.972.11 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.11" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/7b041e22cb4da0261635b0265f1e87530b78037475bb304aff44829af3eabc8c9577ddf0104e5b6be818f01df1ab408ad9348de392845588d15885ba03c9c76d + languageName: node + linkType: hard + "@aws-sdk/middleware-expect-continue@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.3" @@ -896,6 +1129,35 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-flexible-checksums@npm:^3.974.18": + version: 3.974.18 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.974.18" + dependencies: + "@aws-crypto/crc32": "npm:5.2.0" + "@aws-crypto/crc32c": "npm:5.2.0" + "@aws-crypto/util": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/crc64-nvme": "npm:^3.972.8" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/2d1e9dc8b234fe6384e3e7853aa008a4d2b18430c10aafb70d6e7395b1f12862b6fb5f93643d41301ce197bf822b728373ee1bd5a9d8bce4d337c435dcac1299 + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:^3.972.11": + version: 3.972.11 + resolution: "@aws-sdk/middleware-host-header@npm:3.972.11" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/81efc4a858a964a9afb24e7b3de0d2f798538755fab8290ff21e40933e06adc01e47a00b46b1c75d35e94a224215917f979750ebe431f2564948a46699d67ba8 + languageName: node + linkType: hard + "@aws-sdk/middleware-host-header@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-host-header@npm:3.972.3" @@ -908,6 +1170,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-location-constraint@npm:^3.972.10": + version: 3.972.10 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.10" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/fdea046ce797560de73fb5b59c9df2cc8f682ff35f3a432201daab261c04cdf5d90be2bc2f9ca1f136d32b636ef19371cadc00e227d1c614532c0319964fcc83 + languageName: node + linkType: hard + "@aws-sdk/middleware-location-constraint@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.3" @@ -919,6 +1192,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:^3.972.10": + version: 3.972.10 + resolution: "@aws-sdk/middleware-logger@npm:3.972.10" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/a5ccf69d05be4288448d6285640b693c7c2182c63a8a8c4474c83b5c020011ae538ed6bf34928eea2ee9edae3a73b49f45b5db828d65f346e660609c8add739b + languageName: node + linkType: hard + "@aws-sdk/middleware-logger@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-logger@npm:3.972.3" @@ -930,6 +1214,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:^3.972.12": + version: 3.972.12 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.12" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@aws/lambda-invoke-store": "npm:^0.2.2" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/aa76d54bf393780fcc936b30ce87df579473a393059a5a183d27e152f8ebdbe83f46f3a4e289101558c966d40b9b5151337f841647b30bc5a6db5942a8883223 + languageName: node + linkType: hard + "@aws-sdk/middleware-recursion-detection@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.3" @@ -943,6 +1240,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-sdk-s3@npm:^3.972.39": + version: 3.972.39 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.39" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.26" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/signature-v4": "npm:^5.4.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/e93277d74baac47dbd863e98c1904eff77d7fb3d3029ee2970fbc0fd803e16437d4b26714b21307a0a5558483d79aea665391f6d7220f3807ca3987cca4910e7 + languageName: node + linkType: hard + "@aws-sdk/middleware-sdk-s3@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.7" @@ -965,6 +1277,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-ssec@npm:^3.972.10": + version: 3.972.10 + resolution: "@aws-sdk/middleware-ssec@npm:3.972.10" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/43f6238dca3b48ee01702a6b57b56ca6e1ffaeb08792bb87345acef723c530eb440febccdd9b33db0b48e879ef927fb9886227119a9710de2802ddc17c56df81 + languageName: node + linkType: hard + "@aws-sdk/middleware-ssec@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/middleware-ssec@npm:3.972.3" @@ -976,6 +1299,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:^3.972.40": + version: 3.972.40 + resolution: "@aws-sdk/middleware-user-agent@npm:3.972.40" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@aws-sdk/util-endpoints": "npm:^3.996.9" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/15851233be92fd40e01a5d7150d98511f981dd1ca8b437f25d6f260b8aeb49482d18ca689f7fa81eba71f0d3804af42b1209f9d51fa08df67706c8192143c322 + languageName: node + linkType: hard + "@aws-sdk/middleware-user-agent@npm:^3.972.7": version: 3.972.7 resolution: "@aws-sdk/middleware-user-agent@npm:3.972.7" @@ -1037,6 +1374,44 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:^3.997.8": + version: 3.997.8 + resolution: "@aws-sdk/nested-clients@npm:3.997.8" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/middleware-host-header": "npm:^3.972.11" + "@aws-sdk/middleware-logger": "npm:^3.972.10" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.12" + "@aws-sdk/middleware-user-agent": "npm:^3.972.40" + "@aws-sdk/region-config-resolver": "npm:^3.972.14" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.26" + "@aws-sdk/types": "npm:^3.973.8" + "@aws-sdk/util-endpoints": "npm:^3.996.9" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.11" + "@aws-sdk/util-user-agent-node": "npm:^3.973.26" + "@smithy/core": "npm:^3.24.1" + "@smithy/fetch-http-handler": "npm:^5.4.1" + "@smithy/node-http-handler": "npm:^4.7.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/854c375b13e0c114997fc9912a769b343cfa5df60e2d55ec5194a63219181318e28fd2e74f5361562222b1841c8e778a349031cd89f7c42e51b867fb13970700 + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:^3.972.14": + version: 3.972.14 + resolution: "@aws-sdk/region-config-resolver@npm:3.972.14" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/d85c1a9f471e9f06aab3d08f13f4dd03ff96c93e589b81c55c81578e641c627489544a5a2f9b9f952954f3d65e245b40136011fc709d07b091c55177be678db9 + languageName: node + linkType: hard + "@aws-sdk/region-config-resolver@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/region-config-resolver@npm:3.972.3" @@ -1050,24 +1425,36 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/s3-presigned-post@npm:3.986.0": - version: 3.986.0 - resolution: "@aws-sdk/s3-presigned-post@npm:3.986.0" +"@aws-sdk/s3-presigned-post@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/s3-presigned-post@npm:3.1047.0" dependencies: - "@aws-sdk/client-s3": "npm:3.986.0" - "@aws-sdk/types": "npm:^3.973.1" - "@aws-sdk/util-format-url": "npm:^3.972.3" - "@smithy/middleware-endpoint": "npm:^4.4.13" - "@smithy/signature-v4": "npm:^5.3.8" - "@smithy/types": "npm:^4.12.0" - "@smithy/util-hex-encoding": "npm:^4.2.0" - "@smithy/util-utf8": "npm:^4.2.0" + "@aws-sdk/client-s3": "npm:3.1047.0" + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/signature-v4": "npm:^5.4.1" + "@smithy/types": "npm:^4.14.1" tslib: "npm:^2.6.2" - checksum: 10/c88342011c77f29264330ca7bef66d4f57f2902f80f277dd3762cf7ae87f43a4dbcb22f78cb02cd0c13350c756f9caa2fad4f5f494a603d20d6f6c039a4f3bd3 + checksum: 10/1d9f3ace2a56d1fbee28cecd0049b8ea062c2e0522beebf980ea7bcf379a67233b1a56f205f0d77cee3e8483e27c5932ffe114a92aea88f2b82b62f618216e6b languageName: node linkType: hard -"@aws-sdk/s3-request-presigner@npm:3.986.0, @aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": +"@aws-sdk/s3-request-presigner@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/s3-request-presigner@npm:3.1047.0" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/signature-v4-multi-region": "npm:^3.996.26" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/3d63701e002abda1001212a1a0cafde0d0fbda4ce6ba1a726ca29949b75e5f81e879c612646ebc98df4d8fd2063c6e6e976fef86d12a3d4712debc76967cc4e2 + languageName: node + linkType: hard + +"@aws-sdk/s3-request-presigner@npm:^3.338.0, @aws-sdk/s3-request-presigner@npm:^3.362.0": version: 3.986.0 resolution: "@aws-sdk/s3-request-presigner@npm:3.986.0" dependencies: @@ -1097,6 +1484,33 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/signature-v4-multi-region@npm:^3.996.26": + version: 3.996.26 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.996.26" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/signature-v4": "npm:^5.4.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/ef957b448433880e2222a183bd70b4f11857bfaa6038602369ebc0738db0daa0140390700cf4aad38acd4bf6325ac4eaa35887c8e106070ed429fbabf0cca603 + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.1047.0": + version: 3.1047.0 + resolution: "@aws-sdk/token-providers@npm:3.1047.0" + dependencies: + "@aws-sdk/core": "npm:^3.974.10" + "@aws-sdk/nested-clients": "npm:^3.997.8" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/a580c81a5ced77a46ee48f58fd516eac50f1ef501f9dcad9930e7aed433fa5f55a1b11772ad95b42c69b1c103d774402604ea1095a0cbe5d8852607ea6a95a48 + languageName: node + linkType: hard + "@aws-sdk/token-providers@npm:3.985.0": version: 3.985.0 resolution: "@aws-sdk/token-providers@npm:3.985.0" @@ -1122,6 +1536,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/types@npm:^3.973.8": + version: 3.973.8 + resolution: "@aws-sdk/types@npm:3.973.8" + dependencies: + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/76f613d0dfcb9fd3f66aa39aaba81d9d0a0e20d09ad1c8dff9c0c990c69f5d5ee758dfbbb4cf7445ed0d30f96454369282ede7a4a9e64b7e7be95c7b5e34ebc3 + languageName: node + linkType: hard + "@aws-sdk/util-arn-parser@npm:^3.972.2": version: 3.972.2 resolution: "@aws-sdk/util-arn-parser@npm:3.972.2" @@ -1157,6 +1581,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:^3.996.9": + version: 3.996.9 + resolution: "@aws-sdk/util-endpoints@npm:3.996.9" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + checksum: 10/31ae9cfa931e2d50f426b5b00ef63b3666d0da6de5e49aea380ec1110a2ba4ef7ee9ca91d62c3726ab5f91041608a7f439505201a68a3fe3405bfa02620c487c + languageName: node + linkType: hard + "@aws-sdk/util-format-url@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-format-url@npm:3.972.3" @@ -1178,6 +1614,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:^3.972.11": + version: 3.972.11 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.11" + dependencies: + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/types": "npm:^4.14.1" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/f61443463f810e57719aae99179b03d77741cb2ae3b085972e904172a737f86f1f1b1eee18713306a74cb1456770e421eb03fdf88e4976b757f8e8537826b35b + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-browser@npm:^3.972.3": version: 3.972.3 resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.3" @@ -1208,6 +1656,36 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:^3.973.26": + version: 3.973.26 + resolution: "@aws-sdk/util-user-agent-node@npm:3.973.26" + dependencies: + "@aws-sdk/middleware-user-agent": "npm:^3.972.40" + "@aws-sdk/types": "npm:^3.973.8" + "@smithy/core": "npm:^3.24.1" + "@smithy/types": "npm:^4.14.1" + tslib: "npm:^2.6.2" + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 10/2a7efdfbe1e0da21747c3bb0f16596f297ebab63b77d7092ca330fd10052f3cfead7f37a92cf51d118975e391fef51cc133a9d69d2e64c0ebc4caca40b27203e + languageName: node + linkType: hard + +"@aws-sdk/xml-builder@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/xml-builder@npm:3.972.24" + dependencies: + "@nodable/entities": "npm:2.1.0" + "@smithy/types": "npm:^4.14.1" + fast-xml-parser: "npm:5.7.3" + tslib: "npm:^2.6.2" + checksum: 10/243e349ea8d848da53dc40ac79761ffbc921acd3f95c0bd42d14e4fae0724ed84bf868675e96452e0cae95f9f50991b5abf40620e2a1dd47318eaff32e63cd96 + languageName: node + linkType: hard + "@aws-sdk/xml-builder@npm:^3.972.4": version: 3.972.4 resolution: "@aws-sdk/xml-builder@npm:3.972.4" @@ -4026,6 +4504,13 @@ __metadata: languageName: node linkType: hard +"@ioredis/commands@npm:1.5.1": + version: 1.5.1 + resolution: "@ioredis/commands@npm:1.5.1" + checksum: 10/7efb0339302094aed30903ccbf8ca24d6048cff0d556114f43004c2e02d0808e6619a814ca72d6ea00586972fab7aae6c18892f9feabea56e632fb2db34b09db + languageName: node + linkType: hard + "@ioredis/commands@npm:^1.3.0": version: 1.3.1 resolution: "@ioredis/commands@npm:1.3.1" @@ -4595,6 +5080,13 @@ __metadata: languageName: node linkType: hard +"@nodable/entities@npm:2.1.0, @nodable/entities@npm:^2.1.0": + version: 2.1.0 + resolution: "@nodable/entities@npm:2.1.0" + checksum: 10/355c55e82aebe45d4b962d16530951df51e19e3e63a27ea61ad3260c0807064619b270b9c83db10e8394f42760abd5b7f7c5b5117678c4246ce8364a4aafc637 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -5623,6 +6115,17 @@ __metadata: languageName: node linkType: hard +"@smithy/core@npm:^3.24.1, @smithy/core@npm:^3.24.3": + version: 3.24.3 + resolution: "@smithy/core@npm:3.24.3" + dependencies: + "@aws-crypto/crc32": "npm:5.2.0" + "@smithy/types": "npm:^4.14.2" + tslib: "npm:^2.6.2" + checksum: 10/9c0e5dc6fbfb8b51dc23631585e4851dc604c8cab6ca2ee8190c45844ccaec1d040af416a4d656620196f303b4acdadf6dbefaaffba81658fc66db7be2f39dea + languageName: node + linkType: hard + "@smithy/credential-provider-imds@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/credential-provider-imds@npm:4.2.8" @@ -5636,6 +6139,17 @@ __metadata: languageName: node linkType: hard +"@smithy/credential-provider-imds@npm:^4.3.1": + version: 4.3.3 + resolution: "@smithy/credential-provider-imds@npm:4.3.3" + dependencies: + "@smithy/core": "npm:^3.24.3" + "@smithy/types": "npm:^4.14.2" + tslib: "npm:^2.6.2" + checksum: 10/5fd0d5a3f9448e880ff0e38bf8e9dc8b9d588098475c6f7ba3f50cd4482e0616756e8d78d8d2ab7e1ca11674c86e96c265d2335953c2b2557918fad20516558d + languageName: node + linkType: hard + "@smithy/eventstream-codec@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/eventstream-codec@npm:4.2.8" @@ -5704,6 +6218,17 @@ __metadata: languageName: node linkType: hard +"@smithy/fetch-http-handler@npm:^5.4.1": + version: 5.4.3 + resolution: "@smithy/fetch-http-handler@npm:5.4.3" + dependencies: + "@smithy/core": "npm:^3.24.3" + "@smithy/types": "npm:^4.14.2" + tslib: "npm:^2.6.2" + checksum: 10/02fe4736bb4546f0800f32f706896055d89a6410ac6380acd3fab439056629bd4d5ed9ff335457a1e46ce7b82ecbbc14f1e2ea6c63edd21b336590b19303c5ad + languageName: node + linkType: hard + "@smithy/hash-blob-browser@npm:^4.2.9": version: 4.2.9 resolution: "@smithy/hash-blob-browser@npm:4.2.9" @@ -5868,6 +6393,17 @@ __metadata: languageName: node linkType: hard +"@smithy/node-http-handler@npm:^4.7.1": + version: 4.7.3 + resolution: "@smithy/node-http-handler@npm:4.7.3" + dependencies: + "@smithy/core": "npm:^3.24.3" + "@smithy/types": "npm:^4.14.2" + tslib: "npm:^2.6.2" + checksum: 10/2050c04aefbc90095bd111ce12a77572da1391d6e10e9feca010c5f151e652152dce25e330b047380d539643ba823eb0c504659b1f152282ca42f4d9dfa220c4 + languageName: node + linkType: hard + "@smithy/property-provider@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/property-provider@npm:4.2.8" @@ -5944,6 +6480,17 @@ __metadata: languageName: node linkType: hard +"@smithy/signature-v4@npm:^5.4.1": + version: 5.4.3 + resolution: "@smithy/signature-v4@npm:5.4.3" + dependencies: + "@smithy/core": "npm:^3.24.3" + "@smithy/types": "npm:^4.14.2" + tslib: "npm:^2.6.2" + checksum: 10/78cce6f52d6ca59cebb467da6084471c1d6d8cd482cbacd625c5d180a583138492d7080026484ed9a595324f638c1436d63dd27de18ec9f9a7a0eda305c13772 + languageName: node + linkType: hard + "@smithy/smithy-client@npm:^4.11.2, @smithy/smithy-client@npm:^4.11.3": version: 4.11.3 resolution: "@smithy/smithy-client@npm:4.11.3" @@ -5968,6 +6515,15 @@ __metadata: languageName: node linkType: hard +"@smithy/types@npm:^4.14.1, @smithy/types@npm:^4.14.2": + version: 4.14.2 + resolution: "@smithy/types@npm:4.14.2" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/bd5b81b5b35f129e443e571adb2d856fdeb4e216966272600635c6b5ec951b8392e63f977d1464cfe7c0e0d3f6c931730720803933f97891f2a2aa2c76cde15f + languageName: node + linkType: hard + "@smithy/url-parser@npm:^4.2.8": version: 4.2.8 resolution: "@smithy/url-parser@npm:4.2.8" @@ -7736,11 +8292,11 @@ __metadata: version: 0.0.0-use.local resolution: "@uppy/companion@workspace:packages/@uppy/companion" dependencies: - "@aws-sdk/client-s3": "npm:3.986.0" - "@aws-sdk/client-sts": "npm:3.986.0" - "@aws-sdk/lib-storage": "npm:3.986.0" - "@aws-sdk/s3-presigned-post": "npm:3.986.0" - "@aws-sdk/s3-request-presigner": "npm:3.986.0" + "@aws-sdk/client-s3": "npm:3.1047.0" + "@aws-sdk/client-sts": "npm:3.1047.0" + "@aws-sdk/lib-storage": "npm:3.1047.0" + "@aws-sdk/s3-presigned-post": "npm:3.1047.0" + "@aws-sdk/s3-request-presigner": "npm:3.1047.0" "@types/common-tags": "npm:^1.8.4" "@types/compression": "npm:1.7.0" "@types/content-disposition": "npm:^0.5.9" @@ -7762,49 +8318,49 @@ __metadata: "@types/validator": "npm:^13.15.10" "@types/webpack": "npm:^5.28.0" "@types/ws": "npm:8.5.3" - body-parser: "npm:1.20.4" + body-parser: "npm:2.2.2" common-tags: "npm:1.8.2" connect-redis: "npm:7.1.1" - content-disposition: "npm:^0.5.4" + content-disposition: "npm:2.0.0" cookie-parser: "npm:1.4.7" - cors: "npm:^2.8.5" - escape-goat: "npm:3.0.0" - escape-string-regexp: "npm:4.0.0" + cors: "npm:2.8.6" + escape-goat: "npm:4.0.0" + escape-string-regexp: "npm:5.0.0" execa: "npm:^9.6.0" express: "npm:^5.2.1" express-interceptor: "npm:1.2.0" express-prom-bundle: "npm:^8.0.0" - express-session: "npm:1.18.1" + express-session: "npm:1.19.0" fast-safe-stringify: "npm:^2.1.1" formdata-node: "npm:^6.0.3" got: "npm:^13.0.0" grant: "npm:^5.4.24" - helmet: "npm:^7.1.0" + helmet: "npm:8.1.0" http-proxy: "npm:^1.18.1" - ioredis: "npm:^5.3.2" - ipaddr.js: "npm:^2.0.1" - jsonwebtoken: "npm:9.0.2" - lodash: "npm:^4.17.23" - mime-types: "npm:2.1.35" - moment: "npm:^2.29.2" - moment-timezone: "npm:^0.5.31" - morgan: "npm:1.10.0" + ioredis: "npm:5.10.1" + ipaddr.js: "npm:2.4.0" + jsonwebtoken: "npm:9.0.3" + lodash: "npm:4.18.1" + mime-types: "npm:3.0.2" + moment: "npm:2.30.1" + moment-timezone: "npm:0.6.2" + morgan: "npm:1.10.1" ms: "npm:2.1.3" nock: "npm:^13.1.3" node-schedule: "npm:2.1.1" - p-map: "npm:^7.0.3" - prom-client: "npm:15.1.2" - serialize-error: "npm:^11.0.0" - serialize-javascript: "npm:^6.0.0" + p-map: "npm:7.0.4" + prom-client: "npm:15.1.3" + serialize-error: "npm:13.0.1" + serialize-javascript: "npm:7.0.5" supertest: "npm:6.2.4" - supports-color: "npm:8.x" - tus-js-client: "npm:^4.1.0" + supports-color: "npm:10.2.2" + tus-js-client: "npm:4.3.1" typescript: "npm:^5.8.3" - validator: "npm:^13.15.22" + validator: "npm:13.15.35" vitest: "npm:^3.2.4" - webdav: "npm:^5.8.0" - ws: "npm:8.17.1" - zod: "npm:^3.24.0" + webdav: "npm:5.10.0" + ws: "npm:8.20.1" + zod: "npm:4.4.3" bin: companion: ./dist/bin/companion.js languageName: unknown @@ -9531,7 +10087,24 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.4, body-parser@npm:^1.19.0, body-parser@npm:^1.20.4, body-parser@npm:~1.20.3": +"body-parser@npm:2.2.2, body-parser@npm:^2.2.1": + version: 2.2.2 + resolution: "body-parser@npm:2.2.2" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.3" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.7.0" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.1" + raw-body: "npm:^3.0.1" + type-is: "npm:^2.0.1" + checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 + languageName: node + linkType: hard + +"body-parser@npm:^1.19.0, body-parser@npm:^1.20.4, body-parser@npm:~1.20.3": version: 1.20.4 resolution: "body-parser@npm:1.20.4" dependencies: @@ -9551,23 +10124,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:^2.2.1": - version: 2.2.2 - resolution: "body-parser@npm:2.2.2" - dependencies: - bytes: "npm:^3.1.2" - content-type: "npm:^1.0.5" - debug: "npm:^4.4.3" - http-errors: "npm:^2.0.0" - iconv-lite: "npm:^0.7.0" - on-finished: "npm:^2.4.1" - qs: "npm:^6.14.1" - raw-body: "npm:^3.0.1" - type-is: "npm:^2.0.1" - checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 - languageName: node - linkType: hard - "bonjour-service@npm:^1.2.1": version: 1.2.1 resolution: "bonjour-service@npm:1.2.1" @@ -9611,6 +10167,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^2.0.2": + version: 2.1.0 + resolution: "brace-expansion@npm:2.1.0" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10/c77a7a64aabf94b8d5913955adb4f36957917565374461355bb4276830c027a313d981f32410cea9e38f52573e7eb776d02fe05091c3a79a061958d97e4d2b43 + languageName: node + linkType: hard + "braces@npm:^3.0.2, braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -10390,12 +10955,10 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^0.5.4, content-disposition@npm:~0.5.4": - version: 0.5.4 - resolution: "content-disposition@npm:0.5.4" - dependencies: - safe-buffer: "npm:5.2.1" - checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 +"content-disposition@npm:2.0.0": + version: 2.0.0 + resolution: "content-disposition@npm:2.0.0" + checksum: 10/8217c83d228520411136c0cb835309cde9fc2c0366f0c8bf96469aa50645965e7cc49e9209a35ad24088cdca201dfbabe519627dcb17f55fb098c5feeee6be5d languageName: node linkType: hard @@ -10406,6 +10969,15 @@ __metadata: languageName: node linkType: hard +"content-disposition@npm:~0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + "content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" @@ -10451,7 +11023,7 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:1.0.7, cookie-signature@npm:~1.0.6": +"cookie-signature@npm:1.0.7, cookie-signature@npm:~1.0.6, cookie-signature@npm:~1.0.7": version: 1.0.7 resolution: "cookie-signature@npm:1.0.7" checksum: 10/1a62808cd30d15fb43b70e19829b64d04b0802d8ef00275b57d152de4ae6a3208ca05c197b6668d104c4d9de389e53ccc2d3bc6bcaaffd9602461417d8c40710 @@ -10465,7 +11037,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2, cookie@npm:~0.7.1": +"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2, cookie@npm:~0.7.1, cookie@npm:~0.7.2": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f @@ -10541,6 +11113,16 @@ __metadata: languageName: node linkType: hard +"cors@npm:2.8.6": + version: 2.8.6 + resolution: "cors@npm:2.8.6" + dependencies: + object-assign: "npm:^4" + vary: "npm:^1" + checksum: 10/aa7174305b21ceb90f9c84f4eaa32f04432d333addbfdc0d1eb7310393c48902e5364aada5ac2f5d054528d63b3179238444475426fcb74e1e345077de485727 + languageName: node + linkType: hard + "cors@npm:^2.8.5, cors@npm:~2.8.5": version: 2.8.5 resolution: "cors@npm:2.8.5" @@ -10869,7 +11451,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.0.0, debug@npm:^2.2.0": +"debug@npm:2.6.9, debug@npm:^2.0.0, debug@npm:^2.2.0, debug@npm:~2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -11415,7 +11997,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^6.0.0": +"entities@npm:^6.0.0, entities@npm:^6.0.1": version: 6.0.1 resolution: "entities@npm:6.0.1" checksum: 10/62af1307202884349d2867f0aac5c60d8b57102ea0b0e768b16246099512c28e239254ad772d6834e7e14cb1b6f153fc3d0c031934e3183b086c86d3838d874a @@ -11850,10 +12432,10 @@ __metadata: languageName: node linkType: hard -"escape-goat@npm:3.0.0": - version: 3.0.0 - resolution: "escape-goat@npm:3.0.0" - checksum: 10/6719196d073cc72d0bbe079646d6fa32f226f24fd7d00c1a71fa375bd4c5b8999050021d9e62c232a8874230328ebf89a5c8bd76fb72f7ccd6229efbe5abd04e +"escape-goat@npm:4.0.0": + version: 4.0.0 + resolution: "escape-goat@npm:4.0.0" + checksum: 10/515f4c5427118a8513ef12ad3fbc194b2a0239a6bc8d923b8ebd885c97f3518ce54f911007e6c9424387d68b0f54cd72aa277cfc2ca44da8cb1bd6a880cfd13c languageName: node linkType: hard @@ -11864,10 +12446,10 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 +"escape-string-regexp@npm:5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 10/20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e languageName: node linkType: hard @@ -12390,7 +12972,23 @@ __metadata: languageName: node linkType: hard -"express-session@npm:1.18.1, express-session@npm:^1.15.6, express-session@npm:^1.17.3": +"express-session@npm:1.19.0": + version: 1.19.0 + resolution: "express-session@npm:1.19.0" + dependencies: + cookie: "npm:~0.7.2" + cookie-signature: "npm:~1.0.7" + debug: "npm:~2.6.9" + depd: "npm:~2.0.0" + on-headers: "npm:~1.1.0" + parseurl: "npm:~1.3.3" + safe-buffer: "npm:~5.2.1" + uid-safe: "npm:~2.1.5" + checksum: 10/5f36b51d344ec40adb5b9cd8a915fd694cdaf64832632411d4f6e6de8e9a83d873a20389e9c3cce966fece76a18c0384c5f2763b3ac089f801e8d6e92cb543e6 + languageName: node + linkType: hard + +"express-session@npm:^1.15.6, express-session@npm:^1.17.3": version: 1.18.1 resolution: "express-session@npm:1.18.1" dependencies: @@ -12547,6 +13145,16 @@ __metadata: languageName: node linkType: hard +"fast-xml-builder@npm:^1.1.7, fast-xml-builder@npm:^1.2.0": + version: 1.2.0 + resolution: "fast-xml-builder@npm:1.2.0" + dependencies: + path-expression-matcher: "npm:^1.5.0" + xml-naming: "npm:^0.1.0" + checksum: 10/5948add7796879d03b6c779cbb17f2f203a41cdf23dfaaa4789c65078a36376cd0709a6586701e980e3d244ebd5fdb35db1235ccb5e4fb9e9abfd8c51e7b8813 + languageName: node + linkType: hard + "fast-xml-parser@npm:5.3.4": version: 5.3.4 resolution: "fast-xml-parser@npm:5.3.4" @@ -12558,14 +13166,32 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.5.1": - version: 4.5.3 - resolution: "fast-xml-parser@npm:4.5.3" +"fast-xml-parser@npm:5.7.3": + version: 5.7.3 + resolution: "fast-xml-parser@npm:5.7.3" dependencies: - strnum: "npm:^1.1.1" + "@nodable/entities": "npm:^2.1.0" + fast-xml-builder: "npm:^1.1.7" + path-expression-matcher: "npm:^1.5.0" + strnum: "npm:^2.2.3" bin: fxparser: src/cli/cli.js - checksum: 10/ca22bf9d65c10b8447c1034c13403e90ecee210e2b3852690df3d8a42b8a46ec655fae7356096abd98a15b89ddaf11878587b1773e0c3be4cbc2ac4af4c7bf95 + checksum: 10/00a58655d0d58c1f914c7fd8e3a94e88799c3d473e29a6d2231dc02103df069e8c6043137cbec8df1cda6525a39914d1b84455a79530f63be266876a2211251c + languageName: node + linkType: hard + +"fast-xml-parser@npm:^5.7.2": + version: 5.8.0 + resolution: "fast-xml-parser@npm:5.8.0" + dependencies: + "@nodable/entities": "npm:^2.1.0" + fast-xml-builder: "npm:^1.2.0" + path-expression-matcher: "npm:^1.5.0" + strnum: "npm:^2.3.0" + xml-naming: "npm:^0.1.0" + bin: + fxparser: src/cli/cli.js + checksum: 10/0167d17d5275c95e005639f8fca7b4d88fec3fd013063725280f4e982313b1c798e4565d5ced7f61ce10e8f0d876a1976492cc8ac27da3080915ff549fd00705 languageName: node linkType: hard @@ -13409,10 +14035,10 @@ __metadata: languageName: node linkType: hard -"helmet@npm:^7.1.0": - version: 7.1.0 - resolution: "helmet@npm:7.1.0" - checksum: 10/aa13b0907d9d31b65e4ec73093b58d7e94e83c06818cc06869f5eb95d205574a14f01ed71cadfac4a68b736a1a6d7ef2290f3f6ef77ac664c7e75b8f9eddf88c +"helmet@npm:8.1.0": + version: 8.1.0 + resolution: "helmet@npm:8.1.0" + checksum: 10/262e678d340bb102158f4e6ba1469a7cda1643329a50863f8fe704d5b60d9ebe6ea1e7793ed51224ae464f197dedf2fe8035df278c042e32ebc95b237fa41ad0 languageName: node linkType: hard @@ -13891,7 +14517,24 @@ __metadata: languageName: node linkType: hard -"ioredis@npm:^5.3.2, ioredis@npm:^5.4.1": +"ioredis@npm:5.10.1": + version: 5.10.1 + resolution: "ioredis@npm:5.10.1" + dependencies: + "@ioredis/commands": "npm:1.5.1" + cluster-key-slot: "npm:^1.1.0" + debug: "npm:^4.3.4" + denque: "npm:^2.1.0" + lodash.defaults: "npm:^4.2.0" + lodash.isarguments: "npm:^3.1.0" + redis-errors: "npm:^1.2.0" + redis-parser: "npm:^3.0.0" + standard-as-callback: "npm:^2.1.0" + checksum: 10/a85786fc17e7180ac342219ebef5c138b82d056c44c00470a1827f7a4b2499041fa13f253b337aeca2ab6681a2bf52b622ca541e9c9a993d81f1b1e6f21ab59a + languageName: node + linkType: hard + +"ioredis@npm:^5.4.1": version: 5.7.0 resolution: "ioredis@npm:5.7.0" dependencies: @@ -13925,7 +14568,14 @@ __metadata: languageName: node linkType: hard -"ipaddr.js@npm:^2.0.1, ipaddr.js@npm:^2.1.0": +"ipaddr.js@npm:2.4.0": + version: 2.4.0 + resolution: "ipaddr.js@npm:2.4.0" + checksum: 10/e29cd15cd1f3c177f1671a74ed5dc2d7908088294850a7dbc000969a370cf02d6cdd81f8ab35a4fb0397247cd93999528eb4506277cd7db52fa2a487015207cf + languageName: node + linkType: hard + +"ipaddr.js@npm:^2.1.0": version: 2.2.0 resolution: "ipaddr.js@npm:2.2.0" checksum: 10/9e1cdd9110b3bca5d910ab70d7fb1933e9c485d9b92cb14ef39f30c412ba3fe02a553921bf696efc7149cc653453c48ccf173adb996ec27d925f1f340f872986 @@ -14687,11 +15337,11 @@ __metadata: languageName: node linkType: hard -"jsonwebtoken@npm:9.0.2": - version: 9.0.2 - resolution: "jsonwebtoken@npm:9.0.2" +"jsonwebtoken@npm:9.0.3": + version: 9.0.3 + resolution: "jsonwebtoken@npm:9.0.3" dependencies: - jws: "npm:^3.2.2" + jws: "npm:^4.0.1" lodash.includes: "npm:^4.3.0" lodash.isboolean: "npm:^3.0.3" lodash.isinteger: "npm:^4.0.4" @@ -14701,18 +15351,7 @@ __metadata: lodash.once: "npm:^4.0.0" ms: "npm:^2.1.1" semver: "npm:^7.5.4" - checksum: 10/6e9b6d879cec2b27f2f3a88a0c0973edc7ba956a5d9356b2626c4fddfda969e34a3832deaf79c3e1c6c9a525bc2c4f2c2447fa477f8ac660f0017c31a59ae96b - languageName: node - linkType: hard - -"jwa@npm:^1.4.2": - version: 1.4.2 - resolution: "jwa@npm:1.4.2" - dependencies: - buffer-equal-constant-time: "npm:^1.0.1" - ecdsa-sig-formatter: "npm:1.0.11" - safe-buffer: "npm:^5.0.1" - checksum: 10/a46c9ddbcc226d9e85e13ef96328c7d331abddd66b5a55ec44bcf4350464a6125385ac9c1e64faa0fae8d586d90a14d6b5e96c73f0388970a3918d5252efb0f3 + checksum: 10/a67a276db41fbfb458ebdc4938d5d7b01d4743e16bda0f25ac01996fe5b5819d66656153f6cfce19b4680b79ae9f9ca185965defc22e77e0abddf443573238d6 languageName: node linkType: hard @@ -14727,6 +15366,17 @@ __metadata: languageName: node linkType: hard +"jwa@npm:^2.0.1": + version: 2.0.1 + resolution: "jwa@npm:2.0.1" + dependencies: + buffer-equal-constant-time: "npm:^1.0.1" + ecdsa-sig-formatter: "npm:1.0.11" + safe-buffer: "npm:^5.0.1" + checksum: 10/b04312a1de85f912b96aa3a7211717b8336945fab5b4f7cbc7800f4c80934060c0a3111576fad8d76e41ad62887d6da4b21fd4c47e45c174197f8be7dc0c1694 + languageName: node + linkType: hard + "jwk-to-pem@npm:^2.0.7": version: 2.0.7 resolution: "jwk-to-pem@npm:2.0.7" @@ -14738,16 +15388,6 @@ __metadata: languageName: node linkType: hard -"jws@npm:^3.2.2": - version: 3.2.3 - resolution: "jws@npm:3.2.3" - dependencies: - jwa: "npm:^1.4.2" - safe-buffer: "npm:^5.0.1" - checksum: 10/707387dd1cabcc3d9c2818f773cfaac7ede66e79ca11bbd159285a88cf5d8e8f355afcb8ee373e7bb0fcf9b7a2df015b22c50f27842f2c77453f04cd9f8f4009 - languageName: node - linkType: hard - "jws@npm:^4.0.0": version: 4.0.0 resolution: "jws@npm:4.0.0" @@ -14758,6 +15398,16 @@ __metadata: languageName: node linkType: hard +"jws@npm:^4.0.1": + version: 4.0.1 + resolution: "jws@npm:4.0.1" + dependencies: + jwa: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + checksum: 10/75d7b157489fa9a72023712c58a7a7706c7e2b10eec27fabd3bb9cae0c9e492251ab72527d20a8a5f5726196f0508c320c643fddff7076657f6bca16d0ceeeeb + languageName: node + linkType: hard + "karma-chrome-launcher@npm:~3.2.0": version: 3.2.0 resolution: "karma-chrome-launcher@npm:3.2.0" @@ -15477,6 +16127,13 @@ __metadata: languageName: node linkType: hard +"lodash@npm:4.18.1": + version: 4.18.1 + resolution: "lodash@npm:4.18.1" + checksum: 10/306fea53dfd39dad1f03d45ba654a2405aebd35797b673077f401edb7df2543623dc44b9effbb98f69b32152295fff725a4cec99c684098947430600c6af0c3f + languageName: node + linkType: hard + "lodash@npm:^4.17.21, lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" @@ -15833,16 +16490,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.26, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": - version: 2.1.35 - resolution: "mime-types@npm:2.1.35" - dependencies: - mime-db: "npm:1.52.0" - checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a - languageName: node - linkType: hard - -"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": +"mime-types@npm:3.0.2, mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": version: 3.0.2 resolution: "mime-types@npm:3.0.2" dependencies: @@ -15851,6 +16499,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.26, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a + languageName: node + linkType: hard + "mime@npm:1.6.0, mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -15966,6 +16623,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^9.0.9": + version: 9.0.9 + resolution: "minimatch@npm:9.0.9" + dependencies: + brace-expansion: "npm:^2.0.2" + checksum: 10/b91fad937deaffb68a45a2cb731ff3cff1c3baf9b6469c879477ed16f15c8f4ce39d63a3f75c2455107c2fdff0f3ab597d97dc09e2e93b883aafcf926ef0c8f9 + languageName: node + linkType: hard + "minimatch@npm:~3.0.2": version: 3.0.8 resolution: "minimatch@npm:3.0.8" @@ -16144,23 +16810,36 @@ __metadata: languageName: node linkType: hard -"moment-timezone@npm:^0.5.31": - version: 0.5.45 - resolution: "moment-timezone@npm:0.5.45" +"moment-timezone@npm:0.6.2": + version: 0.6.2 + resolution: "moment-timezone@npm:0.6.2" dependencies: moment: "npm:^2.29.4" - checksum: 10/45e3793d44bea8e826c934a335ebf0b92c6d6dae562fdb59d8c45a16d5c11de4d6692b5fa7eebca969881f06b81b55f8535883bfbc727b597d601709fa5a2bb2 + checksum: 10/021f908742a392ff7234b3814fb20c786cb086d0fa3f98a58f6810181c71a305244e908e913d8bd6750c4a7e09300eda2c869cd77ef0b3f83e58028fa75f84de languageName: node linkType: hard -"moment@npm:^2.29.2, moment@npm:^2.29.4": +"moment@npm:2.30.1, moment@npm:^2.29.4": version: 2.30.1 resolution: "moment@npm:2.30.1" checksum: 10/ae42d876d4ec831ef66110bdc302c0657c664991e45cf2afffc4b0f6cd6d251dde11375c982a5c0564ccc0fa593fc564576ddceb8c8845e87c15f58aa6baca69 languageName: node linkType: hard -"morgan@npm:1.10.0, morgan@npm:~1.10.0": +"morgan@npm:1.10.1": + version: 1.10.1 + resolution: "morgan@npm:1.10.1" + dependencies: + basic-auth: "npm:~2.0.1" + debug: "npm:2.6.9" + depd: "npm:~2.0.0" + on-finished: "npm:~2.3.0" + on-headers: "npm:~1.1.0" + checksum: 10/f6a611bdcb9bebe8283381c49efedee81f50b75f6cbc52430cda1743ec35443c92d5e5d4384ce38b102d8c102162c92da563471def3cf840b4980160f278f8ba + languageName: node + linkType: hard + +"morgan@npm:~1.10.0": version: 1.10.0 resolution: "morgan@npm:1.10.0" dependencies: @@ -16669,6 +17348,13 @@ __metadata: languageName: node linkType: hard +"non-error@npm:^0.1.0": + version: 0.1.0 + resolution: "non-error@npm:0.1.0" + checksum: 10/c8140db92f2054f1789e2523cb1ac872adbe231642b8ab9c6a2c6295ea33f9ad7093a5adfc54ac07ac8cd86c245ee186ecc918d11c9b9ae3c6fa9b2e0ec7197c + languageName: node + linkType: hard + "nopt@npm:^6.0.0": version: 6.0.0 resolution: "nopt@npm:6.0.0" @@ -17046,6 +17732,13 @@ __metadata: languageName: node linkType: hard +"on-headers@npm:~1.1.0": + version: 1.1.0 + resolution: "on-headers@npm:1.1.0" + checksum: 10/98aa64629f986fb8cc4517dd8bede73c980e31208cba97f4442c330959f60ced3dc6214b83420491f5111fc7c4f4343abe2ea62c85f505cf041d67850f238776 + languageName: node + linkType: hard + "once@npm:^1.3.0, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -17191,6 +17884,13 @@ __metadata: languageName: node linkType: hard +"p-map@npm:7.0.4": + version: 7.0.4 + resolution: "p-map@npm:7.0.4" + checksum: 10/ef48c3b2e488f31c693c9fcc0df0ef76518cf6426a495cf9486ebbb0fd7f31aef7f90e96f72e0070c0ff6e3177c9318f644b512e2c29e3feee8d7153fcb6782e + languageName: node + linkType: hard + "p-map@npm:^2.0.0": version: 2.1.0 resolution: "p-map@npm:2.1.0" @@ -17428,6 +18128,13 @@ __metadata: languageName: node linkType: hard +"path-expression-matcher@npm:^1.5.0": + version: 1.5.0 + resolution: "path-expression-matcher@npm:1.5.0" + checksum: 10/28303bb9ee6831e6df14c10cd3f3f7b2d7c8d7f788d8bdb7440136fd696064c82a3e264999a0764d28e39f698275fc03a5493bec93c57ef4a22566280367dd64 + languageName: node + linkType: hard + "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -18275,13 +18982,13 @@ __metadata: languageName: node linkType: hard -"prom-client@npm:15.1.2": - version: 15.1.2 - resolution: "prom-client@npm:15.1.2" +"prom-client@npm:15.1.3": + version: 15.1.3 + resolution: "prom-client@npm:15.1.3" dependencies: "@opentelemetry/api": "npm:^1.4.0" tdigest: "npm:^0.1.1" - checksum: 10/f7edcba54d27eff4066ae7ebfe5692e6bb1914cf728efa89f7ab63766fef62679782c41c97d55b6fd6b2a8bb35b0d168ac8f1b9513c9a5770ea35c170691e24c + checksum: 10/eba75e15ab896845d39359e3a4d6f7913ea05339b3122d8dde8c8c374669ad1a1d1ab2694ab2101c420bd98086a564e4f2a18aa29018fc14a4732e57c1c19aec languageName: node linkType: hard @@ -19171,7 +19878,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0, safe-buffer@npm:~5.2.1": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10/32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 @@ -19435,16 +20142,24 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^11.0.0": - version: 11.0.3 - resolution: "serialize-error@npm:11.0.3" +"serialize-error@npm:13.0.1": + version: 13.0.1 + resolution: "serialize-error@npm:13.0.1" dependencies: - type-fest: "npm:^2.12.2" - checksum: 10/5fe19e120e9ad8488c0abe27517e60da75bd65f56ae1cb48d8524e013d0e07f18bb9d05eca72898c5244e1168576f3131f29145c9f785e735e10742ee9c86c08 + non-error: "npm:^0.1.0" + type-fest: "npm:^5.4.1" + checksum: 10/a31fd603d2b4f6f33f11acc2cabfa451f2efb2257c5bcbb2ea7fd9b2016da5ea4b4c3a81152481740e54c575ef6e351ddd262b68793c09d9b8fd396ce4a5c52c languageName: node linkType: hard -"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.2": +"serialize-javascript@npm:7.0.5": + version: 7.0.5 + resolution: "serialize-javascript@npm:7.0.5" + checksum: 10/6237c76ef6df3d1ad61dd4a393b71ca758c7654f4d1cf77529e513134c0f0660302e03b7ec88a8f3a3daa79e1f93d6de8218ecbc45e073d7cc6b66284a1d3e83 + languageName: node + linkType: hard + +"serialize-javascript@npm:^6.0.2": version: 6.0.2 resolution: "serialize-javascript@npm:6.0.2" dependencies: @@ -20321,13 +21036,6 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.1.1": - version: 1.1.2 - resolution: "strnum@npm:1.1.2" - checksum: 10/ccd6297a1fdaf0fc8ea0ea904acdae76878d49a4b0d98a70155df4bc081fd88eac5ec99fb150f3d1d1af065c1898d38420705259ba6c39aa850c671bcd54e35d - languageName: node - linkType: hard - "strnum@npm:^2.1.0": version: 2.1.1 resolution: "strnum@npm:2.1.1" @@ -20335,6 +21043,13 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^2.2.3, strnum@npm:^2.3.0": + version: 2.3.0 + resolution: "strnum@npm:2.3.0" + checksum: 10/ce79c86bb2b96f053eb28e14924c13604e22977dcdece9aa914c25e16cc5c4bbe048976fe0b2a4decf08a1e13600b820749cea25463fc0e5fee3078339e0a457 + languageName: node + linkType: hard + "styled-jsx@npm:5.1.6": version: 5.1.6 resolution: "styled-jsx@npm:5.1.6" @@ -20391,12 +21106,10 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:8.x, supports-color@npm:^8.0.0": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 +"supports-color@npm:10.2.2": + version: 10.2.2 + resolution: "supports-color@npm:10.2.2" + checksum: 10/bd132705fc07213a4024131fb061f0a46a48b49ecaf434bb029c0a5aa0339b969236d496d63969e3c248a90fdcac16d4f9c5bf187e7be0bfb5e804ed13bef6b0 languageName: node linkType: hard @@ -20418,6 +21131,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 + languageName: node + linkType: hard + "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -20509,6 +21231,13 @@ __metadata: languageName: node linkType: hard +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: 10/e37653df3e495daa7ea7790cb161b810b00075bba2e4d6c93fb06a709e747e3ae9da11a120d0489833203926511b39e038a2affbd9d279cfb7a2f3fcccd30b5d + languageName: node + linkType: hard + "tailwindcss@npm:4.1.1": version: 4.1.1 resolution: "tailwindcss@npm:4.1.1" @@ -20901,7 +21630,7 @@ __metadata: languageName: node linkType: hard -"tus-js-client@npm:^4.1.0, tus-js-client@npm:^4.2.3": +"tus-js-client@npm:4.3.1, tus-js-client@npm:^4.2.3": version: 4.3.1 resolution: "tus-js-client@npm:4.3.1" dependencies: @@ -20923,13 +21652,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^2.12.2": - version: 2.19.0 - resolution: "type-fest@npm:2.19.0" - checksum: 10/7bf9e8fdf34f92c8bb364c0af14ca875fac7e0183f2985498b77be129dc1b3b1ad0a6b3281580f19e48c6105c037fb966ad9934520c69c6434d17fd0af4eed78 - languageName: node - linkType: hard - "type-fest@npm:^4.26.1": version: 4.41.0 resolution: "type-fest@npm:4.41.0" @@ -20937,6 +21659,15 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^5.4.1": + version: 5.6.0 + resolution: "type-fest@npm:5.6.0" + dependencies: + tagged-tag: "npm:^1.0.0" + checksum: 10/2cc7a510f46a538af7a365ed50cee10e51a69bd353ca66c2a432e172b90ff12efff9ba59c7ba493d6361d07fd298c84945b9e4481ab63f85a29860c0b0430233 + languageName: node + linkType: hard + "type-is@npm:^1.6.18, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -21409,10 +22140,10 @@ __metadata: languageName: node linkType: hard -"validator@npm:^13.15.22": - version: 13.15.23 - resolution: "validator@npm:13.15.23" - checksum: 10/03e4a37c04c4e8337b0c91e529bdb6376de6b52ef683616e2e909276be73903e6054203d274ed35e88e3498ec68764125b194338dd2ee893818d3008fbad1ba7 +"validator@npm:13.15.35": + version: 13.15.35 + resolution: "validator@npm:13.15.35" + checksum: 10/62f25728064d5dedaabb10a53647cbb4f9aa762a2a53e16642469d4839ad235e467e9f18d0992c492ec1d35e1d5034956fdc680953fc7d8f764cc6d4c83cf2ae languageName: node linkType: hard @@ -21794,25 +22525,25 @@ __metadata: languageName: node linkType: hard -"webdav@npm:^5.8.0": - version: 5.8.0 - resolution: "webdav@npm:5.8.0" +"webdav@npm:5.10.0": + version: 5.10.0 + resolution: "webdav@npm:5.10.0" dependencies: "@buttercup/fetch": "npm:^0.2.1" base-64: "npm:^1.0.0" byte-length: "npm:^1.0.2" - entities: "npm:^6.0.0" - fast-xml-parser: "npm:^4.5.1" + entities: "npm:^6.0.1" + fast-xml-parser: "npm:^5.7.2" hot-patcher: "npm:^2.0.1" layerr: "npm:^3.0.0" md5: "npm:^2.3.0" - minimatch: "npm:^9.0.5" + minimatch: "npm:^9.0.9" nested-property: "npm:^4.0.0" node-fetch: "npm:^3.3.2" path-posix: "npm:^1.0.0" url-join: "npm:^5.0.0" url-parse: "npm:^1.5.10" - checksum: 10/af33b5c62d810eb0cee4b3e96c335823cbe9366a51ec7c98f734a8fde6c0caf5e2ced96b524e44d554d94358cfafad79a808f59de3c110d640b71b0d2b36e1bd + checksum: 10/ca68ad41b3c35fb41b7598bba9f9a2d9d8c5cd64f1add18fef4dc9dfc045e464955a7e646668ecc179d4a7b7e1133d609b00039d3a91acf59a9263b6534a0967 languageName: node linkType: hard @@ -22187,9 +22918,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.17.1, ws@npm:~8.17.1": - version: 8.17.1 - resolution: "ws@npm:8.17.1" +"ws@npm:8.20.1": + version: 8.20.1 + resolution: "ws@npm:8.20.1" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -22198,7 +22929,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + checksum: 10/8c4d2b06dc65381b6bfab1f2e584275dabd30a99a5ce058b4dc76f3d03fad1921cef3a21d8f53127d30a808cfd1864aa2fe6890a5d43359f682457315baec873 languageName: node linkType: hard @@ -22232,6 +22963,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:~8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10/4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + "xml-name-validator@npm:^5.0.0": version: 5.0.0 resolution: "xml-name-validator@npm:5.0.0" @@ -22239,6 +22985,13 @@ __metadata: languageName: node linkType: hard +"xml-naming@npm:^0.1.0": + version: 0.1.0 + resolution: "xml-naming@npm:0.1.0" + checksum: 10/45abd94ba64a508bda3f4d0b70e49811a3c3542596252c213caf47c858bbe9bba365ebba8eeff68e2a876e22a1bf6855d90cd2019b2f28012cebb167a4df2293 + languageName: node + linkType: hard + "xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" @@ -22362,10 +23115,10 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.24.0": - version: 3.25.76 - resolution: "zod@npm:3.25.76" - checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995 +"zod@npm:4.4.3": + version: 4.4.3 + resolution: "zod@npm:4.4.3" + checksum: 10/804b9a42aa8f35f2b3c5a8dff906291cb749115f83ee2afe3576d70b5b5c53c965365c7f4967690647a9c54af9838ff232a85ff9577a0a36c44b68bc6cdefe36 languageName: node linkType: hard From 9143d41bc27060c1d4381bc6f60a4d975f2ec859 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 21 May 2026 09:56:42 +0530 Subject: [PATCH 23/33] @uppy/companion: upgrade dev deps (#6300) all the dev deps upgraded excepts for these : - `@types/cors: 2.8.6` - `@types/jsonwebtoken: 8.3.7` - `@types/morgan: 1.7.37` - `@types/node: ^20.19.0` - `nock: ^13.1.3` upgrading these to their latest major either breaks the test suite or requires us to do code changes on our end. #6297 --------- Co-authored-by: Mikael Finstad --- packages/@uppy/companion/package.json | 44 +- yarn.lock | 930 +++++++++++++++++++++++--- 2 files changed, 846 insertions(+), 128 deletions(-) diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 4774eed9e..ec2e23396 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -78,33 +78,33 @@ "zod": "4.4.3" }, "devDependencies": { - "@types/common-tags": "^1.8.4", - "@types/compression": "1.7.0", - "@types/content-disposition": "^0.5.9", - "@types/cookie-parser": "1.4.2", + "@types/common-tags": "1.8.4", + "@types/compression": "1.8.1", + "@types/content-disposition": "0.5.9", + "@types/cookie-parser": "1.4.10", "@types/cors": "2.8.6", - "@types/eslint": "^8.2.0", - "@types/express-session": "1.17.3", - "@types/http-proxy": "^1", + "@types/eslint": "9.6.1", + "@types/express-session": "1.19.0", + "@types/http-proxy": "1.17.17", "@types/jsonwebtoken": "8.3.7", - "@types/lodash": "4.14.191", - "@types/mime-types": "^2.1.4", + "@types/lodash": "4.17.24", + "@types/mime-types": "3.0.1", "@types/morgan": "1.7.37", - "@types/ms": "0.7.31", + "@types/ms": "2.1.0", "@types/node": "^20.19.0", - "@types/node-schedule": "^2.1.8", - "@types/request": "2.48.8", - "@types/serialize-javascript": "^5.0.4", - "@types/supertest": "^6.0.3", - "@types/validator": "^13.15.10", - "@types/webpack": "^5.28.0", - "@types/ws": "8.5.3", - "execa": "^9.6.0", - "http-proxy": "^1.18.1", + "@types/node-schedule": "2.1.8", + "@types/request": "2.48.13", + "@types/serialize-javascript": "5.0.4", + "@types/supertest": "7.2.0", + "@types/validator": "13.15.10", + "@types/webpack": "5.28.5", + "@types/ws": "8.18.1", + "execa": "9.6.1", + "http-proxy": "1.18.1", "nock": "^13.1.3", - "supertest": "6.2.4", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "supertest": "7.2.2", + "typescript": "6.0.3", + "vitest": "4.1.6" }, "files": [ "dist/", diff --git a/yarn.lock b/yarn.lock index 5bae0ea9d..ed9ffa303 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3454,6 +3454,16 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/core@npm:1.10.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.1" + tslib: "npm:^2.4.0" + checksum: 10/d32f386084e64deaf2609aabb8295d1ad5af6144d0f46d2060b76cc53f1f3b486df54bec9b0f33c37d85a3822e1193ebcd4e3deb4a5f0e4cd650aa2ffc631715 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.3, @emnapi/core@npm:^1.4.5": version: 1.5.0 resolution: "@emnapi/core@npm:1.5.0" @@ -3464,6 +3474,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/runtime@npm:1.10.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/d21083d07fa0c2da171c142e78ef986b66b07d45b06accc0bcaf49fcc61bb4dbc10e1c1760813070165b9f49b054376a931045347f21c0f42ff1eb2d2040faac + languageName: node + linkType: hard + "@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.5, @emnapi/runtime@npm:^1.7.0": version: 1.8.1 resolution: "@emnapi/runtime@npm:1.8.1" @@ -3482,6 +3501,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/wasi-threads@npm:1.2.1": + version: 1.2.1 + resolution: "@emnapi/wasi-threads@npm:1.2.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/57cd4292be81c05d26aa886d68a9e4c449ff666e8503fed6463dfc6b64a4e4213f03c152d53296b7cda32840271e38cd33347332070658f01befeb9bf4e59f36 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/aix-ppc64@npm:0.25.4" @@ -4592,6 +4620,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10/5d9d207b462c11e322d71911e55e21a4e2772f71ffe8d6f1221b8eb5ae6774458c1d242f897fb0814e8714ca9a6b498abfa74dfe4f434493342902b1a48b33a5 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": version: 0.3.29 resolution: "@jridgewell/trace-mapping@npm:0.3.29" @@ -5006,6 +5041,18 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^1.1.4": + version: 1.1.4 + resolution: "@napi-rs/wasm-runtime@npm:1.1.4" + dependencies: + "@tybys/wasm-util": "npm:^0.10.1" + peerDependencies: + "@emnapi/core": ^1.7.1 + "@emnapi/runtime": ^1.7.1 + checksum: 10/1db3dc7eeb981306b09360487bd8ce4dfa5588d273bd8ea9f07dccca1b4ade57b675414180fc9bb66966c6c50b17208b0263194993e2f7f92cc7af28bda4d1af + languageName: node + linkType: hard + "@next/env@npm:16.1.5": version: 16.1.5 resolution: "@next/env@npm:16.1.5" @@ -5080,6 +5127,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:^1.1.5": + version: 1.8.0 + resolution: "@noble/hashes@npm:1.8.0" + checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e + languageName: node + linkType: hard + "@nodable/entities@npm:2.1.0, @nodable/entities@npm:^2.1.0": version: 2.1.0 resolution: "@nodable/entities@npm:2.1.0" @@ -5354,6 +5408,22 @@ __metadata: languageName: node linkType: hard +"@oxc-project/types@npm:=0.130.0": + version: 0.130.0 + resolution: "@oxc-project/types@npm:0.130.0" + checksum: 10/5f12923f32a3a9fdc8f26a275d10233a3d482e708d2035298a62b72aaa3857d26b5f16b2bea32896789d26bf61798fb22730f8e1cb37725a1951ad324526344f + languageName: node + linkType: hard + +"@paralleldrive/cuid2@npm:^2.2.2": + version: 2.3.1 + resolution: "@paralleldrive/cuid2@npm:2.3.1" + dependencies: + "@noble/hashes": "npm:^1.1.5" + checksum: 10/08687b891dfdad44f13a2c69232e95ca27efffc8b376587c2b89114b100a505808e7af5fbb51c3103053c637a6604f5987afa3ee8b4e1ba4c38742ebd47b4a84 + languageName: node + linkType: hard + "@parcel/watcher-android-arm64@npm:2.5.1": version: 2.5.1 resolution: "@parcel/watcher-android-arm64@npm:2.5.1" @@ -5618,6 +5688,115 @@ __metadata: languageName: node linkType: hard +"@rolldown/binding-android-arm64@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-android-arm64@npm:1.0.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-darwin-arm64@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-darwin-arm64@npm:1.0.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-darwin-x64@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-darwin-x64@npm:1.0.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/binding-freebsd-x64@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-freebsd-x64@npm:1.0.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-gnu@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-musl@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-linux-ppc64-gnu@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.0.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-s390x-gnu@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.0.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-gnu@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-musl@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-openharmony-arm64@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.1" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-wasm32-wasi@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.1" + dependencies: + "@emnapi/core": "npm:1.10.0" + "@emnapi/runtime": "npm:1.10.0" + "@napi-rs/wasm-runtime": "npm:^1.1.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@rolldown/binding-win32-arm64-msvc@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-win32-x64-msvc@npm:1.0.1": + version: 1.0.1 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rolldown/pluginutils@npm:1.0.0-beta.19": version: 1.0.0-beta.19 resolution: "@rolldown/pluginutils@npm:1.0.0-beta.19" @@ -5632,6 +5811,13 @@ __metadata: languageName: node linkType: hard +"@rolldown/pluginutils@npm:^1.0.0": + version: 1.0.1 + resolution: "@rolldown/pluginutils@npm:1.0.1" + checksum: 10/4e95cf9ce23d75e5aa03ea0249cd86f7d1e21f83fbf6f8520e4edd8a251ba1b82c4ba9bc13cd24b6c4661daec6225b06e6d35c64c604e731b230b2a49af47d05 + languageName: node + linkType: hard + "@rollup/plugin-json@npm:^6.1.0": version: 6.1.0 resolution: "@rollup/plugin-json@npm:6.1.0" @@ -6733,7 +6919,7 @@ __metadata: languageName: node linkType: hard -"@standard-schema/spec@npm:^1.0.0": +"@standard-schema/spec@npm:^1.0.0, @standard-schema/spec@npm:^1.1.0": version: 1.1.0 resolution: "@standard-schema/spec@npm:1.1.0" checksum: 10/a209615c9e8b2ea535d7db0a5f6aa0f962fd4ab73ee86a46c100fb78116964af1f55a27c1794d4801e534a196794223daa25ff5135021e03c7828aa3d95e1763 @@ -7523,6 +7709,15 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.10.1": + version: 0.10.2 + resolution: "@tybys/wasm-util@npm:0.10.2" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/d12f1dafe12d7a573c406b35ffef0038042b9cc9fbcc74d657267eb635499b956276afc05eebdbd81bea582e1c4c921421a1dd7243a93daaa8c8216b19395c23 + languageName: node + linkType: hard + "@tybys/wasm-util@npm:^0.9.0": version: 0.9.0 resolution: "@tybys/wasm-util@npm:0.9.0" @@ -7615,19 +7810,20 @@ __metadata: languageName: node linkType: hard -"@types/common-tags@npm:^1.8.4": +"@types/common-tags@npm:1.8.4": version: 1.8.4 resolution: "@types/common-tags@npm:1.8.4" checksum: 10/40c95a2f6388beb1cdeed3c9986ac0d6a3a551fce706e3e364a00ded48ab624b06b1ac8b94679bb2da9653e5eb3e450bad26873f5189993a5d8e8bdace74cbb2 languageName: node linkType: hard -"@types/compression@npm:1.7.0": - version: 1.7.0 - resolution: "@types/compression@npm:1.7.0" +"@types/compression@npm:1.8.1": + version: 1.8.1 + resolution: "@types/compression@npm:1.8.1" dependencies: "@types/express": "npm:*" - checksum: 10/c0bd0637f6f5d6a6897fcd3550e3ded2a3d7bb6655ec66d9193e2e9bea041d36d9b25a6548820f721e41292283994600a948c447d10a0ff673dd633bef178770 + "@types/node": "npm:*" + checksum: 10/cd746c830a5c981568d36989c3c43a55caf1872b54e3f9891b82fba04501de11882091df3ece11fbede2de01179c99d08639a08831e06c3966873f928407c01a languageName: node linkType: hard @@ -7650,19 +7846,19 @@ __metadata: languageName: node linkType: hard -"@types/content-disposition@npm:^0.5.9": +"@types/content-disposition@npm:0.5.9": version: 0.5.9 resolution: "@types/content-disposition@npm:0.5.9" checksum: 10/d895703c0027ca6c4c0c1ede363909dbb590deec3b206a84b88a49c8b2840bcbd31b4ddeb2e1e6caa1af00801cc79c5b69a5c75a8152f2959810b10fe75a4e1f languageName: node linkType: hard -"@types/cookie-parser@npm:1.4.2": - version: 1.4.2 - resolution: "@types/cookie-parser@npm:1.4.2" - dependencies: - "@types/express": "npm:*" - checksum: 10/110ab558beb59f772ca43aa7257a3595536e71e08891810f7db88cc2e58b3c2b552c970e3e0806d787642923ff1d5b7717650257febcdfc632c8b5d6e2d301a0 +"@types/cookie-parser@npm:1.4.10": + version: 1.4.10 + resolution: "@types/cookie-parser@npm:1.4.10" + peerDependencies: + "@types/express": "*" + checksum: 10/1f37b5a4115dbfd4b7bbea2d874fbf9495eca8c3e8c87fa7e38c50f9fff66222377c911cfdc7a1ea08855e822919c5534ebbcc4bf25b596bc6f7270e403483d9 languageName: node linkType: hard @@ -7729,7 +7925,7 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:*, @types/eslint@npm:^8.2.0": +"@types/eslint@npm:*": version: 8.56.10 resolution: "@types/eslint@npm:8.56.10" dependencies: @@ -7739,6 +7935,16 @@ __metadata: languageName: node linkType: hard +"@types/eslint@npm:9.6.1": + version: 9.6.1 + resolution: "@types/eslint@npm:9.6.1" + dependencies: + "@types/estree": "npm:*" + "@types/json-schema": "npm:*" + checksum: 10/719fcd255760168a43d0e306ef87548e1e15bffe361d5f4022b0f266575637acc0ecb85604ac97879ee8ae83c6a6d0613b0ed31d0209ddf22a0fe6d608fc56fe + languageName: node + linkType: hard + "@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5, @types/estree@npm:^1.0.6": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" @@ -7784,12 +7990,12 @@ __metadata: languageName: node linkType: hard -"@types/express-session@npm:1.17.3": - version: 1.17.3 - resolution: "@types/express-session@npm:1.17.3" +"@types/express-session@npm:1.19.0": + version: 1.19.0 + resolution: "@types/express-session@npm:1.19.0" dependencies: "@types/express": "npm:*" - checksum: 10/59d4821a0f362e3f9798a8a9cde6072277a11726172d08849df6f012957f4ca5f4d6ac30fc6942172afd42aebc094e57c82d1ecb44b84b05660126e4e5a3e165 + checksum: 10/cc2d693a3a40a1c5d0739acec811b5a5d1e6be3fcb7513d920e6d0f604e7f8a6ac54509d604c6d32bde6a2ca57aa84d5dee067433a5ac9859ab47b7f2a855010 languageName: node linkType: hard @@ -7851,7 +8057,16 @@ __metadata: languageName: node linkType: hard -"@types/http-proxy@npm:^1, @types/http-proxy@npm:^1.17.15, @types/http-proxy@npm:^1.17.8": +"@types/http-proxy@npm:1.17.17": + version: 1.17.17 + resolution: "@types/http-proxy@npm:1.17.17" + dependencies: + "@types/node": "npm:*" + checksum: 10/893e46e12be576baa471cf2fc13a4f0e413eaf30a5850de8fdbea3040e138ad4171234c59b986cf7137ff20a1582b254bf0c44cfd715d5ed772e1ab94dd75cd1 + languageName: node + linkType: hard + +"@types/http-proxy@npm:^1.17.15, @types/http-proxy@npm:^1.17.8": version: 1.17.16 resolution: "@types/http-proxy@npm:1.17.16" dependencies: @@ -7883,10 +8098,10 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:4.14.191": - version: 4.14.191 - resolution: "@types/lodash@npm:4.14.191" - checksum: 10/ab8cd8eeb941f0fb89248cd5d520b942b841e936e4fcb093370f76d137a8b6f6be0de7f38fc259d56d3cc45b1b50ed69d15c9b94922545166e3ef1f0218be2f2 +"@types/lodash@npm:4.17.24": + version: 4.17.24 + resolution: "@types/lodash@npm:4.17.24" + checksum: 10/0f2082565f60f9787eefc046edc38458054512be5a8b3584ef0bad5fd9e85d0ab55ec5a1fbfae1ed6ba015cf1f9e837d5fb4da1f99fc60b8f74b2a46146fb00f languageName: node linkType: hard @@ -7904,10 +8119,10 @@ __metadata: languageName: node linkType: hard -"@types/mime-types@npm:^2.1.4": - version: 2.1.4 - resolution: "@types/mime-types@npm:2.1.4" - checksum: 10/f8c521c54ee0c0b9f90a65356a80b1413ed27ccdc94f5c7ebb3de5d63cedb559cd2610ea55b4100805c7349606a920d96e54f2d16b2f0afa6b7cd5253967ccc9 +"@types/mime-types@npm:3.0.1": + version: 3.0.1 + resolution: "@types/mime-types@npm:3.0.1" + checksum: 10/96534e23b2180e5396a1e6a44f51ec59e349bd43daed4b5cb4548493126e9641cdc65f8292477e80c5e6063cf625330dae8edaf31357553b60baa23c32a8bafd languageName: node linkType: hard @@ -7927,10 +8142,10 @@ __metadata: languageName: node linkType: hard -"@types/ms@npm:0.7.31": - version: 0.7.31 - resolution: "@types/ms@npm:0.7.31" - checksum: 10/6647b295fb2a5b8347c35efabaaed1777221f094be9941d387b4bf11df0eeacb3f8a4e495b8b66ce0e4c00593bc53ab5fc25f01ebb274cd989a834ae578099de +"@types/ms@npm:2.1.0": + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 10/532d2ebb91937ccc4a89389715e5b47d4c66e708d15942fe6cc25add6dc37b2be058230a327dd50f43f89b8b6d5d52b74685a9e8f70516edfc9bdd6be910eff4 languageName: node linkType: hard @@ -7943,7 +8158,7 @@ __metadata: languageName: node linkType: hard -"@types/node-schedule@npm:^2.1.8": +"@types/node-schedule@npm:2.1.8": version: 2.1.8 resolution: "@types/node-schedule@npm:2.1.8" dependencies: @@ -8026,15 +8241,15 @@ __metadata: languageName: node linkType: hard -"@types/request@npm:2.48.8": - version: 2.48.8 - resolution: "@types/request@npm:2.48.8" +"@types/request@npm:2.48.13": + version: 2.48.13 + resolution: "@types/request@npm:2.48.13" dependencies: "@types/caseless": "npm:*" "@types/node": "npm:*" "@types/tough-cookie": "npm:*" - form-data: "npm:^2.5.0" - checksum: 10/e260c665227b498aac9e8adef6d18f8c84a81f3ef71f3c00af160bbcd7d4a9b0e85e29bb861bb1756df64de48caf63b13264c13dacefa6cdd0356c75a5089ba9 + form-data: "npm:^2.5.5" + checksum: 10/174abc42adfc0c45f6a675095b72be344e907afd74fcfe33dea4fbd7489d54bc5aae781e5064436a8079ea74458a1fdefeb62c5260a19a08c7b536529fac61c1 languageName: node linkType: hard @@ -8055,7 +8270,7 @@ __metadata: languageName: node linkType: hard -"@types/serialize-javascript@npm:^5.0.4": +"@types/serialize-javascript@npm:5.0.4": version: 5.0.4 resolution: "@types/serialize-javascript@npm:5.0.4" checksum: 10/c342a4d151736c1ba4913e6d9b00537bcf62401a06e3489dcf96b7d51a4ab147efcf3fe20ca9491b1349ee7e55c6d69606682e1630f2e076e2828eaee3764f94 @@ -8120,13 +8335,13 @@ __metadata: languageName: node linkType: hard -"@types/supertest@npm:^6.0.3": - version: 6.0.3 - resolution: "@types/supertest@npm:6.0.3" +"@types/supertest@npm:7.2.0": + version: 7.2.0 + resolution: "@types/supertest@npm:7.2.0" dependencies: "@types/methods": "npm:^1.1.4" "@types/superagent": "npm:^8.1.0" - checksum: 10/6ec05eb591c97bc856b0e78c12f5bec10545f3a749688f34232d189797a506d971bc95931718eb57b378d8513f6d2d12462383e6d68455fa72df35c19de6e89e + checksum: 10/5a322e29b81033e90ac50ab315d49559b21809ee39b5681ab7386819463e30d68e29c63c946023a1c353e7f13fb3f20d64dcb89d3d8a0fff569450501aff786c languageName: node linkType: hard @@ -8144,14 +8359,14 @@ __metadata: languageName: node linkType: hard -"@types/validator@npm:^13.15.10": +"@types/validator@npm:13.15.10": version: 13.15.10 resolution: "@types/validator@npm:13.15.10" checksum: 10/63117a776ced4d066d7fb63130d90ba487d38209dd45c25641ca1a6f5040e8394cc9a855750b919b72a923c5ffb51f8474f213b10b5aaa27d9db108bef07ad10 languageName: node linkType: hard -"@types/webpack@npm:^5.28.0": +"@types/webpack@npm:5.28.5": version: 5.28.5 resolution: "@types/webpack@npm:5.28.5" dependencies: @@ -8162,12 +8377,12 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:8.5.3": - version: 8.5.3 - resolution: "@types/ws@npm:8.5.3" +"@types/ws@npm:8.18.1": + version: 8.18.1 + resolution: "@types/ws@npm:8.18.1" dependencies: "@types/node": "npm:*" - checksum: 10/08aac698ce6480b532d8311f790a8744ae489ccdd98f374cfe4b8245855439825c64b031abcbba4f30fb280da6cc2b02a4e261e16341d058ffaeecaa24ba2bd3 + checksum: 10/1ce05e3174dcacf28dae0e9b854ef1c9a12da44c7ed73617ab6897c5cbe4fccbb155a20be5508ae9a7dde2f83bd80f5cf3baa386b934fc4b40889ec963e94f3a languageName: node linkType: hard @@ -8297,27 +8512,27 @@ __metadata: "@aws-sdk/lib-storage": "npm:3.1047.0" "@aws-sdk/s3-presigned-post": "npm:3.1047.0" "@aws-sdk/s3-request-presigner": "npm:3.1047.0" - "@types/common-tags": "npm:^1.8.4" - "@types/compression": "npm:1.7.0" - "@types/content-disposition": "npm:^0.5.9" - "@types/cookie-parser": "npm:1.4.2" + "@types/common-tags": "npm:1.8.4" + "@types/compression": "npm:1.8.1" + "@types/content-disposition": "npm:0.5.9" + "@types/cookie-parser": "npm:1.4.10" "@types/cors": "npm:2.8.6" - "@types/eslint": "npm:^8.2.0" - "@types/express-session": "npm:1.17.3" - "@types/http-proxy": "npm:^1" + "@types/eslint": "npm:9.6.1" + "@types/express-session": "npm:1.19.0" + "@types/http-proxy": "npm:1.17.17" "@types/jsonwebtoken": "npm:8.3.7" - "@types/lodash": "npm:4.14.191" - "@types/mime-types": "npm:^2.1.4" + "@types/lodash": "npm:4.17.24" + "@types/mime-types": "npm:3.0.1" "@types/morgan": "npm:1.7.37" - "@types/ms": "npm:0.7.31" + "@types/ms": "npm:2.1.0" "@types/node": "npm:^20.19.0" - "@types/node-schedule": "npm:^2.1.8" - "@types/request": "npm:2.48.8" - "@types/serialize-javascript": "npm:^5.0.4" - "@types/supertest": "npm:^6.0.3" - "@types/validator": "npm:^13.15.10" - "@types/webpack": "npm:^5.28.0" - "@types/ws": "npm:8.5.3" + "@types/node-schedule": "npm:2.1.8" + "@types/request": "npm:2.48.13" + "@types/serialize-javascript": "npm:5.0.4" + "@types/supertest": "npm:7.2.0" + "@types/validator": "npm:13.15.10" + "@types/webpack": "npm:5.28.5" + "@types/ws": "npm:8.18.1" body-parser: "npm:2.2.2" common-tags: "npm:1.8.2" connect-redis: "npm:7.1.1" @@ -8326,7 +8541,7 @@ __metadata: cors: "npm:2.8.6" escape-goat: "npm:4.0.0" escape-string-regexp: "npm:5.0.0" - execa: "npm:^9.6.0" + execa: "npm:9.6.1" express: "npm:^5.2.1" express-interceptor: "npm:1.2.0" express-prom-bundle: "npm:^8.0.0" @@ -8336,7 +8551,7 @@ __metadata: got: "npm:^13.0.0" grant: "npm:^5.4.24" helmet: "npm:8.1.0" - http-proxy: "npm:^1.18.1" + http-proxy: "npm:1.18.1" ioredis: "npm:5.10.1" ipaddr.js: "npm:2.4.0" jsonwebtoken: "npm:9.0.3" @@ -8352,12 +8567,12 @@ __metadata: prom-client: "npm:15.1.3" serialize-error: "npm:13.0.1" serialize-javascript: "npm:7.0.5" - supertest: "npm:6.2.4" + supertest: "npm:7.2.2" supports-color: "npm:10.2.2" tus-js-client: "npm:4.3.1" - typescript: "npm:^5.8.3" + typescript: "npm:6.0.3" validator: "npm:13.15.35" - vitest: "npm:^3.2.4" + vitest: "npm:4.1.6" webdav: "npm:5.10.0" ws: "npm:8.20.1" zod: "npm:4.4.3" @@ -9107,6 +9322,20 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/expect@npm:4.1.6" + dependencies: + "@standard-schema/spec": "npm:^1.1.0" + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:4.1.6" + "@vitest/utils": "npm:4.1.6" + chai: "npm:^6.2.2" + tinyrainbow: "npm:^3.1.0" + checksum: 10/20de26292c543f7f5076b59fd50a5fa89217755402de89b62e5d8c104c90441413b87b5c1d310a682a310418c76c0d4bd309dd1faf13b1b2dec79dc3bb90fef0 + languageName: node + linkType: hard + "@vitest/mocker@npm:3.2.4": version: 3.2.4 resolution: "@vitest/mocker@npm:3.2.4" @@ -9126,6 +9355,25 @@ __metadata: languageName: node linkType: hard +"@vitest/mocker@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/mocker@npm:4.1.6" + dependencies: + "@vitest/spy": "npm:4.1.6" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.21" + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10/d0669d0b1a8822ec3bc83b5261ead6b05a7e5d8c2077d1f8b9eb0c8507967e54347f16027894be28ca26cf8993e544b8269230a3b78c4eb50c8feb780cb4c688 + languageName: node + linkType: hard + "@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": version: 3.2.4 resolution: "@vitest/pretty-format@npm:3.2.4" @@ -9135,6 +9383,15 @@ __metadata: languageName: node linkType: hard +"@vitest/pretty-format@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/pretty-format@npm:4.1.6" + dependencies: + tinyrainbow: "npm:^3.1.0" + checksum: 10/28dc121181fdf619e4a9ea4a3279a63974e54567fc59f82462d3b11d4b72d893cd7966f8a7c1a9365c62eae6dee4c6fb08353074486f708aee50b80462d0bd37 + languageName: node + linkType: hard + "@vitest/runner@npm:3.2.4": version: 3.2.4 resolution: "@vitest/runner@npm:3.2.4" @@ -9146,6 +9403,16 @@ __metadata: languageName: node linkType: hard +"@vitest/runner@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/runner@npm:4.1.6" + dependencies: + "@vitest/utils": "npm:4.1.6" + pathe: "npm:^2.0.3" + checksum: 10/0e175bb61b10ca6cb79a0734a45b3d8b1570806078d53b4f2aa7dbfabd10307c9566460ee8f263a34ac909e8481da614551eee28eaff834fbecd86b4902b845b + languageName: node + linkType: hard + "@vitest/snapshot@npm:3.2.4": version: 3.2.4 resolution: "@vitest/snapshot@npm:3.2.4" @@ -9157,6 +9424,18 @@ __metadata: languageName: node linkType: hard +"@vitest/snapshot@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/snapshot@npm:4.1.6" + dependencies: + "@vitest/pretty-format": "npm:4.1.6" + "@vitest/utils": "npm:4.1.6" + magic-string: "npm:^0.30.21" + pathe: "npm:^2.0.3" + checksum: 10/167b96971ae6e31a8a7c42063abf3d48590908bdea8ae24d9e5035cd08690e47e15a12ab96cc017e5ddd6324a994b8096c901c8e87ac6e5e617910a2814717fd + languageName: node + linkType: hard + "@vitest/spy@npm:3.2.4": version: 3.2.4 resolution: "@vitest/spy@npm:3.2.4" @@ -9166,6 +9445,13 @@ __metadata: languageName: node linkType: hard +"@vitest/spy@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/spy@npm:4.1.6" + checksum: 10/6c1bddbf1eaae42af96d66e31f8c14837203707552f60e7a0f512dc2513d285e3de1fdcf057a79a5588fd20ee382ce5a53c1a69430b2a79eb623fd3517d54878 + languageName: node + linkType: hard + "@vitest/utils@npm:3.2.4": version: 3.2.4 resolution: "@vitest/utils@npm:3.2.4" @@ -9177,6 +9463,17 @@ __metadata: languageName: node linkType: hard +"@vitest/utils@npm:4.1.6": + version: 4.1.6 + resolution: "@vitest/utils@npm:4.1.6" + dependencies: + "@vitest/pretty-format": "npm:4.1.6" + convert-source-map: "npm:^2.0.0" + tinyrainbow: "npm:^3.1.0" + checksum: 10/a81506e9f167389e771503ba5bee91a61cd4f09ac386867815b65c12c9c236051fab6450d686c69b41e3fd028461d0195ee4c4ae47fd22ead649716ddb7777b3 + languageName: node + linkType: hard + "@vue/compiler-core@npm:3.5.14": version: 3.5.14 resolution: "@vue/compiler-core@npm:3.5.14" @@ -10455,6 +10752,13 @@ __metadata: languageName: node linkType: hard +"chai@npm:^6.2.2": + version: 6.2.2 + resolution: "chai@npm:6.2.2" + checksum: 10/13cda42cc40aa46da04a41cf7e5c61df6b6ae0b4e8a8c8b40e04d6947e4d7951377ea8c14f9fa7fe5aaa9e8bd9ba414f11288dc958d4cee6f5221b9436f2778f + languageName: node + linkType: hard + "chalk@npm:^2.4.1": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -10817,7 +11121,7 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.3.0": +"component-emitter@npm:^1.3.1": version: 1.3.1 resolution: "component-emitter@npm:1.3.1" checksum: 10/94550aa462c7bd5a61c1bc480e28554aa306066930152d1b1844a0dd3845d4e5db7e261ddec62ae184913b3e59b55a2ad84093b9d3596a8f17c341514d6c483d @@ -12120,6 +12424,13 @@ __metadata: languageName: node linkType: hard +"es-module-lexer@npm:^2.0.0": + version: 2.1.0 + resolution: "es-module-lexer@npm:2.1.0" + checksum: 10/554c4374e78a812a1fa3673871ce7d42236438c414ea80c2ec35521cd9bb26d1d9155287529057d07431fd91df50d6a26d9bee5afd755fb7f6f7c81905a03956 + languageName: node + linkType: hard + "es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" @@ -12902,9 +13213,9 @@ __metadata: languageName: unknown linkType: soft -"execa@npm:^9.6.0": - version: 9.6.0 - resolution: "execa@npm:9.6.0" +"execa@npm:9.6.1": + version: 9.6.1 + resolution: "execa@npm:9.6.1" dependencies: "@sindresorhus/merge-streams": "npm:^4.0.0" cross-spawn: "npm:^7.0.6" @@ -12918,7 +13229,7 @@ __metadata: signal-exit: "npm:^4.1.0" strip-final-newline: "npm:^4.0.0" yoctocolors: "npm:^2.1.1" - checksum: 10/53443be93d847ff5b52d31ed3714f77aab764fb6c1d72dc7019214ab1cb1a69888e2158ba846426a8ea51443c110fe7a86de61ffb9ee5687b00120fbd739b8a4 + checksum: 10/d0f7a2185152379f8772f6d780b188f2728a95b9a68d1a897f58805d7ba6bd55eaa5e128cb66a274251a6b5e4d9388332b1417bd7d46c25e020e4e55725cf79e languageName: node linkType: hard @@ -12943,6 +13254,13 @@ __metadata: languageName: node linkType: hard +"expect-type@npm:^1.3.0": + version: 1.3.0 + resolution: "expect-type@npm:1.3.0" + checksum: 10/a5fada3d0c621649261f886e7d93e6bf80ce26d8a86e5d517e38301b8baec8450ab2cb94ba6e7a0a6bf2fc9ee55f54e1b06938ef1efa52ddcfeffbfa01acbbcc + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -13390,7 +13708,7 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^2.5.0": +"form-data@npm:^2.5.5": version: 2.5.5 resolution: "form-data@npm:2.5.5" dependencies: @@ -13417,6 +13735,19 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.5": + version: 4.0.5 + resolution: "form-data@npm:4.0.5" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + es-set-tostringtag: "npm:^2.1.0" + hasown: "npm:^2.0.2" + mime-types: "npm:^2.1.12" + checksum: 10/52ecd6e927c8c4e215e68a7ad5e0f7c1031397439672fd9741654b4a94722c4182e74cc815b225dcb5be3f4180f36428f67c6dd39eaa98af0dcfdd26c00c19cd + languageName: node + linkType: hard + "formdata-node@npm:^6.0.3": version: 6.0.3 resolution: "formdata-node@npm:6.0.3" @@ -13433,18 +13764,6 @@ __metadata: languageName: node linkType: hard -"formidable@npm:^2.1.2": - version: 2.1.2 - resolution: "formidable@npm:2.1.2" - dependencies: - dezalgo: "npm:^1.0.4" - hexoid: "npm:^1.0.0" - once: "npm:^1.4.0" - qs: "npm:^6.11.0" - checksum: 10/d385180e0461f65e6f7b70452859fe1c32aa97a290c2ca33f00cdc33145ef44fa68bbc9b93af2c3af73ae726e42c3477c6619c49f3c34b49934e9481275b7b4c - languageName: node - linkType: hard - "formidable@npm:^3.2.4": version: 3.5.1 resolution: "formidable@npm:3.5.1" @@ -13456,6 +13775,17 @@ __metadata: languageName: node linkType: hard +"formidable@npm:^3.5.4": + version: 3.5.4 + resolution: "formidable@npm:3.5.4" + dependencies: + "@paralleldrive/cuid2": "npm:^2.2.2" + dezalgo: "npm:^1.0.4" + once: "npm:^1.4.0" + checksum: 10/4645e6ce3d8bbefd3dd873dcd6211362da3bf8a04c8426d7f454c238be0142975f02e5bdbc792fdbd2be493fdcf5442fe01d9a246bd8c3fd8e779738290cc630 + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -14257,7 +14587,7 @@ __metadata: languageName: node linkType: hard -"http-proxy@npm:^1.18.1": +"http-proxy@npm:1.18.1, http-proxy@npm:^1.18.1": version: 1.18.1 resolution: "http-proxy@npm:1.18.1" dependencies: @@ -15625,6 +15955,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-android-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-android-arm64@npm:1.32.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "lightningcss-darwin-arm64@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-darwin-arm64@npm:1.29.2" @@ -15639,6 +15976,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-darwin-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-arm64@npm:1.32.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "lightningcss-darwin-x64@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-darwin-x64@npm:1.29.2" @@ -15653,6 +15997,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-darwin-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-x64@npm:1.32.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "lightningcss-freebsd-x64@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-freebsd-x64@npm:1.29.2" @@ -15667,6 +16018,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-freebsd-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-freebsd-x64@npm:1.32.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "lightningcss-linux-arm-gnueabihf@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-linux-arm-gnueabihf@npm:1.29.2" @@ -15681,6 +16039,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-linux-arm-gnueabihf@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.32.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "lightningcss-linux-arm64-gnu@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-linux-arm64-gnu@npm:1.29.2" @@ -15695,6 +16060,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-linux-arm64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "lightningcss-linux-arm64-musl@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-linux-arm64-musl@npm:1.29.2" @@ -15709,6 +16081,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-linux-arm64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "lightningcss-linux-x64-gnu@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-linux-x64-gnu@npm:1.29.2" @@ -15723,6 +16102,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-linux-x64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "lightningcss-linux-x64-musl@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-linux-x64-musl@npm:1.29.2" @@ -15737,6 +16123,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-linux-x64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-musl@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "lightningcss-win32-arm64-msvc@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-win32-arm64-msvc@npm:1.29.2" @@ -15751,6 +16144,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-win32-arm64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-arm64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "lightningcss-win32-x64-msvc@npm:1.29.2": version: 1.29.2 resolution: "lightningcss-win32-x64-msvc@npm:1.29.2" @@ -15765,6 +16165,13 @@ __metadata: languageName: node linkType: hard +"lightningcss-win32-x64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "lightningcss@npm:1.29.2": version: 1.29.2 resolution: "lightningcss@npm:1.29.2" @@ -15845,6 +16252,49 @@ __metadata: languageName: node linkType: hard +"lightningcss@npm:^1.32.0": + version: 1.32.0 + resolution: "lightningcss@npm:1.32.0" + dependencies: + detect-libc: "npm:^2.0.3" + lightningcss-android-arm64: "npm:1.32.0" + lightningcss-darwin-arm64: "npm:1.32.0" + lightningcss-darwin-x64: "npm:1.32.0" + lightningcss-freebsd-x64: "npm:1.32.0" + lightningcss-linux-arm-gnueabihf: "npm:1.32.0" + lightningcss-linux-arm64-gnu: "npm:1.32.0" + lightningcss-linux-arm64-musl: "npm:1.32.0" + lightningcss-linux-x64-gnu: "npm:1.32.0" + lightningcss-linux-x64-musl: "npm:1.32.0" + lightningcss-win32-arm64-msvc: "npm:1.32.0" + lightningcss-win32-x64-msvc: "npm:1.32.0" + dependenciesMeta: + lightningcss-android-arm64: + optional: true + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-arm64-msvc: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: 10/098e61007f0d0ec8b5c50884e33b543b551d1ff21bc7b062434b6638fd0b8596858f823b60dfc2a4aa756f3cb120ad79f2b7f4a55b1bda2c0269ab8cf476f114 + languageName: node + linkType: hard + "lilconfig@npm:^3.1.1, lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" @@ -16266,6 +16716,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.21": + version: 0.30.21 + resolution: "magic-string@npm:0.30.21" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10/57d5691f41ed40d962d8bd300148114f53db67fadbff336207db10a99f2bdf4a1be9cac3a68ee85dba575912ee1d4402e4396408196ec2d3afd043b076156221 + languageName: node + linkType: hard + "make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" @@ -17707,6 +18166,13 @@ __metadata: languageName: node linkType: hard +"obug@npm:^2.1.1": + version: 2.1.1 + resolution: "obug@npm:2.1.1" + checksum: 10/bdcf9213361786688019345f3452b95a1dc73710e4b403c82a1994b98bad6abc31b26cb72a482128c5fd53ea9daf6fbb7d0e0e7b2b7e9c8be6d779deeccee07f + languageName: node + linkType: hard + "on-finished@npm:2.4.1, on-finished@npm:^2.3.0, on-finished@npm:^2.4.1, on-finished@npm:~2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -18280,6 +18746,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.4": + version: 4.0.4 + resolution: "picomatch@npm:4.0.4" + checksum: 10/f6ef80a3590827ce20378ae110ac78209cc4f74d39236370f1780f957b7ee41c12acde0e4651b90f39983506fd2f5e449994716f516db2e9752924aff8de93ce + languageName: node + linkType: hard + "pidtree@npm:^0.3.0": version: 0.3.1 resolution: "pidtree@npm:0.3.1" @@ -18888,6 +19361,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.5.14": + version: 8.5.14 + resolution: "postcss@npm:8.5.14" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10/2e3f4dea69692918fe9df5402beb0e54df84499995a094f2fbf63d1a9e38bc1b7a42854df47f09e02593213e01a5eb0627b1d1bd6d1b0ea90767b2e072f7167c + languageName: node + linkType: hard + "preact@npm:^10.26.10": version: 10.28.2 resolution: "preact@npm:10.28.2" @@ -19093,7 +19577,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.6": +"qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.6": version: 6.15.1 resolution: "qs@npm:6.15.1" dependencies: @@ -19655,6 +20139,64 @@ __metadata: languageName: node linkType: hard +"rolldown@npm:1.0.1": + version: 1.0.1 + resolution: "rolldown@npm:1.0.1" + dependencies: + "@oxc-project/types": "npm:=0.130.0" + "@rolldown/binding-android-arm64": "npm:1.0.1" + "@rolldown/binding-darwin-arm64": "npm:1.0.1" + "@rolldown/binding-darwin-x64": "npm:1.0.1" + "@rolldown/binding-freebsd-x64": "npm:1.0.1" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.1" + "@rolldown/binding-linux-arm64-gnu": "npm:1.0.1" + "@rolldown/binding-linux-arm64-musl": "npm:1.0.1" + "@rolldown/binding-linux-ppc64-gnu": "npm:1.0.1" + "@rolldown/binding-linux-s390x-gnu": "npm:1.0.1" + "@rolldown/binding-linux-x64-gnu": "npm:1.0.1" + "@rolldown/binding-linux-x64-musl": "npm:1.0.1" + "@rolldown/binding-openharmony-arm64": "npm:1.0.1" + "@rolldown/binding-wasm32-wasi": "npm:1.0.1" + "@rolldown/binding-win32-arm64-msvc": "npm:1.0.1" + "@rolldown/binding-win32-x64-msvc": "npm:1.0.1" + "@rolldown/pluginutils": "npm:^1.0.0" + dependenciesMeta: + "@rolldown/binding-android-arm64": + optional: true + "@rolldown/binding-darwin-arm64": + optional: true + "@rolldown/binding-darwin-x64": + optional: true + "@rolldown/binding-freebsd-x64": + optional: true + "@rolldown/binding-linux-arm-gnueabihf": + optional: true + "@rolldown/binding-linux-arm64-gnu": + optional: true + "@rolldown/binding-linux-arm64-musl": + optional: true + "@rolldown/binding-linux-ppc64-gnu": + optional: true + "@rolldown/binding-linux-s390x-gnu": + optional: true + "@rolldown/binding-linux-x64-gnu": + optional: true + "@rolldown/binding-linux-x64-musl": + optional: true + "@rolldown/binding-openharmony-arm64": + optional: true + "@rolldown/binding-wasm32-wasi": + optional: true + "@rolldown/binding-win32-arm64-msvc": + optional: true + "@rolldown/binding-win32-x64-msvc": + optional: true + bin: + rolldown: bin/cli.mjs + checksum: 10/00bef9a0454fe5e1a682ae186b0b61f9093fe9c9fa778320e6187dc9c0c7cf38b079e2c229ba8b1898a0a205f579f7df808976614387ca47a434fe4bfd874774 + languageName: node + linkType: hard + "rollup@npm:4.34.8": version: 4.34.8 resolution: "rollup@npm:4.34.8" @@ -20051,7 +20593,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -20840,6 +21382,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^4.0.0-rc.1": + version: 4.1.0 + resolution: "std-env@npm:4.1.0" + checksum: 10/008146cdb834010383138d356e0dd3e3b0ac127a8229f711b8c518bb22940813cc0dcd654fc76b17f0b18179f56089f8b8e52bd6a7ffa0041a966581e7a44dbe + languageName: node + linkType: hard + "stream-browserify@npm:3.0.0": version: 3.0.0 resolution: "stream-browserify@npm:3.0.0" @@ -21078,31 +21627,31 @@ __metadata: languageName: node linkType: hard -"superagent@npm:^8.0.0": - version: 8.1.2 - resolution: "superagent@npm:8.1.2" +"superagent@npm:^10.3.0": + version: 10.3.0 + resolution: "superagent@npm:10.3.0" dependencies: - component-emitter: "npm:^1.3.0" + component-emitter: "npm:^1.3.1" cookiejar: "npm:^2.1.4" - debug: "npm:^4.3.4" + debug: "npm:^4.3.7" fast-safe-stringify: "npm:^2.1.1" - form-data: "npm:^4.0.0" - formidable: "npm:^2.1.2" + form-data: "npm:^4.0.5" + formidable: "npm:^3.5.4" methods: "npm:^1.1.2" mime: "npm:2.6.0" - qs: "npm:^6.11.0" - semver: "npm:^7.3.8" - checksum: 10/33d0072e051baf91c7d68131c70682a0650dd1bd0b8dfb6f88e5bdfcb02e18cc2b42a66e44b32fd405ac6bcf5fd57c6e267bf80e2a8ce57a18166a9d3a78f57d + qs: "npm:^6.14.1" + checksum: 10/e62b13281403ef9a1f716465cf5d83c12dbb418afa8197d8ca3cc35c8dd1825a81bd5c627512ae289684f6b7c48fc9d76ce321c28de6142f69bbe905e866427f languageName: node linkType: hard -"supertest@npm:6.2.4": - version: 6.2.4 - resolution: "supertest@npm:6.2.4" +"supertest@npm:7.2.2": + version: 7.2.2 + resolution: "supertest@npm:7.2.2" dependencies: + cookie-signature: "npm:^1.2.2" methods: "npm:^1.1.2" - superagent: "npm:^8.0.0" - checksum: 10/5b184f9cb932ed962783516073245e4dc713760f4b410c05e54b7aa5a7e6e3940bfce40af1be601bb1a4d498489c58be44ca43a2c9f67e430c8355b5496f20f5 + superagent: "npm:^10.3.0" + checksum: 10/41b29e005b7f0fec8e062df1e43037d5a29b40c1172331d1b448e8b39ed3cc020d2aac342aad6d6e75c1e07b2f08c32bff6472cd726ab4fc9b3f10969937979d languageName: node linkType: hard @@ -21382,6 +21931,13 @@ __metadata: languageName: node linkType: hard +"tinyexec@npm:^1.0.2": + version: 1.1.2 + resolution: "tinyexec@npm:1.1.2" + checksum: 10/2bbe37f9001c6f5723ab39eb8dc1e88f77e830d7cf2e8f34bb75019eb505fcfe3b061b4799c502ff31fa63aa1a9adc649add5ff1e17b7fbd8c16e1afb75d0b9e + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -21392,6 +21948,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.16": + version: 0.2.16 + resolution: "tinyglobby@npm:0.2.16" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10/5c2c41b572ada38449e7c86a5fe034f204a1dbba577225a761a14f29f48dc3f2fc0d81a6c56fcc67c5a742cc3aa9fb5e2ca18dbf22b610b0bc0e549b34d5a0f8 + languageName: node + linkType: hard + "tinypool@npm:^1.1.1": version: 1.1.1 resolution: "tinypool@npm:1.1.1" @@ -21406,6 +21972,13 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^3.1.0": + version: 3.1.0 + resolution: "tinyrainbow@npm:3.1.0" + checksum: 10/4c2c01dde1e5bb9a74973daaae141d4d733d246280b2f9a7f6a9e7dd8e940d48b2580a6086125278777897bc44635d6ccec5f9f563c2179dd2129f4542d0ec05 + languageName: node + linkType: hard + "tinyspy@npm:^4.0.3": version: 4.0.3 resolution: "tinyspy@npm:4.0.3" @@ -21755,6 +22328,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:6.0.3": + version: 6.0.3 + resolution: "typescript@npm:6.0.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/0ef2357a4cffd916b52b683a021cdab0f81eea4e9aa35f2d254581c9a5106da02224e3392e1b0ed42b7a48f80c966e5f52b8e1a27941fa0523c1705a9c2e0330 + languageName: node + linkType: hard + "typescript@npm:^5, typescript@npm:^5.0.0, typescript@npm:^5.1.6, typescript@npm:^5.7.3, typescript@npm:^5.8.3": version: 5.9.2 resolution: "typescript@npm:5.9.2" @@ -21785,6 +22368,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A6.0.3#optional!builtin": + version: 6.0.3 + resolution: "typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=5786d5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/22b67a18dafedf9b1468b64ca20d9aa02ea61d449b65413d8aa6552aeb63f52ef369e86beb25b6b4c91a803d9726ee5c196f391a9b64201263263410a4223ee6 + languageName: node + linkType: hard + "typescript@patch:typescript@npm%3A^5#optional!builtin, typescript@patch:typescript@npm%3A^5.0.0#optional!builtin, typescript@patch:typescript@npm%3A^5.1.6#optional!builtin, typescript@patch:typescript@npm%3A^5.7.3#optional!builtin, typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": version: 5.9.2 resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" @@ -22276,6 +22869,63 @@ __metadata: languageName: node linkType: hard +"vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.0.13 + resolution: "vite@npm:8.0.13" + dependencies: + fsevents: "npm:~2.3.3" + lightningcss: "npm:^1.32.0" + picomatch: "npm:^4.0.4" + postcss: "npm:^8.5.14" + rolldown: "npm:1.0.1" + tinyglobby: "npm:^0.2.16" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + "@vitejs/devtools": ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: ">=1.21.0" + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + "@vitejs/devtools": + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10/92e7bbb8e207b9de6f6b0b7bbb3e7fac32dab419811a86c84f04cb57c2a0a17e7d0fbcb747ca96082588d0ff7fef623f2dec9a4170128c8282798072ce343755 + languageName: node + linkType: hard + "vite@npm:^6.2.5, vite@npm:^6.3.6": version: 6.3.6 resolution: "vite@npm:6.3.6" @@ -22386,6 +23036,74 @@ __metadata: languageName: node linkType: hard +"vitest@npm:4.1.6": + version: 4.1.6 + resolution: "vitest@npm:4.1.6" + dependencies: + "@vitest/expect": "npm:4.1.6" + "@vitest/mocker": "npm:4.1.6" + "@vitest/pretty-format": "npm:4.1.6" + "@vitest/runner": "npm:4.1.6" + "@vitest/snapshot": "npm:4.1.6" + "@vitest/spy": "npm:4.1.6" + "@vitest/utils": "npm:4.1.6" + es-module-lexer: "npm:^2.0.0" + expect-type: "npm:^1.3.0" + magic-string: "npm:^0.30.21" + obug: "npm:^2.1.1" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.3" + std-env: "npm:^4.0.0-rc.1" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^1.0.2" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.1.0" + vite: "npm:^6.0.0 || ^7.0.0 || ^8.0.0" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.1.6 + "@vitest/browser-preview": 4.1.6 + "@vitest/browser-webdriverio": 4.1.6 + "@vitest/coverage-istanbul": 4.1.6 + "@vitest/coverage-v8": 4.1.6 + "@vitest/ui": 4.1.6 + happy-dom: "*" + jsdom: "*" + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@opentelemetry/api": + optional: true + "@types/node": + optional: true + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": + optional: true + "@vitest/coverage-istanbul": + optional: true + "@vitest/coverage-v8": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vite: + optional: false + bin: + vitest: vitest.mjs + checksum: 10/3816121537930455e5338b5b3305179fa6c68d6cbba50e5d8ca8dcb2c0410887ed38aca61e0d2da9f673af1cc1f20278eef941fc4756644e6f8f96366822b8e6 + languageName: node + linkType: hard + "vitest@npm:^3.2.4": version: 3.2.4 resolution: "vitest@npm:3.2.4" From 5519b844099b850ca0804592ac3306ebe1a9b349 Mon Sep 17 00:00:00 2001 From: Prakash Date: Thu, 21 May 2026 09:58:03 +0530 Subject: [PATCH 24/33] @uppy: upgrade biome and more improvements (#6244) - This PR upgrades `biome` from `2.0.5` -> `2.1.2` and adds two new rules - [noUnusedImports](https://biomejs.dev/linter/rules/no-unused-private-class-members) ( we already had suppressions for this rule in code, but the rule itself was never enabled in the config ) - [noUnusedPrivateClassMembers](https://biomejs.dev/linter/rules/no-unused-private-class-members/) - remove stale suppressions. - remove stale code. --------- Co-authored-by: Mikael Finstad --- biome.json | 80 +++++---- examples/aws-companion/index.html | 2 +- examples/aws-nodejs/public/index.html | 7 +- .../public/withCustomEndpoints.html | 7 +- examples/aws-php/index.html | 2 +- examples/cdn/index.html | 6 +- examples/companion-custom-provider/index.html | 2 +- .../companion-digitalocean-spaces/index.html | 2 +- examples/companion/client/index.html | 4 +- examples/react/src/App.tsx | 2 +- .../src/components/CustomDropzone.svelte | 8 +- .../src/components/ImageEditor.svelte | 23 +-- .../src/components/MediaCapture.svelte | 11 +- .../src/components/RemoteSource.svelte | 1 + .../components/test/props-reactivity.svelte | 4 +- examples/transloadit/index.html | 4 +- examples/transloadit/server.js | 8 +- examples/vue/src/Dropzone.vue | 8 +- examples/vue/src/ImageEditor.vue | 23 +-- examples/vue/src/MediaCapture.vue | 10 +- examples/xhr-bundle/index.html | 2 +- examples/xhr-node/index.html | 2 +- examples/xhr-php/index.html | 2 +- examples/xhr-python/index.html | 2 +- package.json | 2 +- packages/@uppy/audio/src/Audio.tsx | 4 +- .../aws-s3/src/HTTPCommunicationQueue.ts | 6 +- .../@uppy/aws-s3/src/MultipartUploader.ts | 1 + .../src/scripts/with-load-balancer.ts | 4 +- .../@uppy/companion/src/server/Uploader.ts | 6 +- .../src/server/provider/facebook/adapter.ts | 2 +- .../@uppy/companion/src/types/express.d.ts | 4 +- packages/@uppy/companion/src/types/shims.d.ts | 2 +- .../@uppy/companion/test/credentials.test.ts | 2 +- .../@uppy/companion/test/providers.test.ts | 29 ++-- packages/@uppy/companion/test/url.test.ts | 31 ++-- packages/@uppy/compressor/src/index.ts | 1 - packages/@uppy/core/src/Restricter.ts | 4 +- packages/@uppy/core/src/Uppy.test.ts | 163 +++++++++--------- packages/@uppy/core/src/Uppy.ts | 7 +- packages/@uppy/core/src/loggers.ts | 2 +- packages/@uppy/dashboard/src/Dashboard.tsx | 14 +- .../dashboard/src/components/AddFiles.tsx | 22 +-- .../src/components/AddFilesPanel.tsx | 1 - .../dashboard/src/components/EditorPanel.tsx | 1 - .../src/components/FileCard/index.tsx | 1 - .../dashboard/src/components/FileList.tsx | 1 - .../src/components/PickerPanelContent.tsx | 1 - .../src/components/StatusBar/Components.tsx | 16 +- packages/@uppy/dashboard/src/index.test.ts | 3 - .../dashboard/src/utils/createSuperFocus.ts | 1 - .../@uppy/dashboard/src/utils/trapFocus.ts | 1 - packages/@uppy/form/src/index.ts | 2 +- packages/@uppy/golden-retriever/src/index.ts | 1 - packages/@uppy/locales/src/ar_SA.ts | 4 +- packages/@uppy/locales/src/bg_BG.ts | 4 +- packages/@uppy/locales/src/ca_ES.ts | 4 +- packages/@uppy/locales/src/cs_CZ.ts | 4 +- packages/@uppy/locales/src/da_DK.ts | 4 +- packages/@uppy/locales/src/de_DE.ts | 4 +- packages/@uppy/locales/src/el_GR.ts | 4 +- packages/@uppy/locales/src/en_US.ts | 4 +- packages/@uppy/locales/src/es_ES.ts | 4 +- packages/@uppy/locales/src/es_MX.ts | 4 +- packages/@uppy/locales/src/fa_IR.ts | 4 +- packages/@uppy/locales/src/fi_FI.ts | 4 +- packages/@uppy/locales/src/fr_FR.ts | 4 +- packages/@uppy/locales/src/gl_ES.ts | 4 +- packages/@uppy/locales/src/he_IL.ts | 4 +- packages/@uppy/locales/src/hi_IN.ts | 4 +- packages/@uppy/locales/src/hr_HR.ts | 4 +- packages/@uppy/locales/src/hu_HU.ts | 4 +- packages/@uppy/locales/src/id_ID.ts | 4 +- packages/@uppy/locales/src/is_IS.ts | 4 +- packages/@uppy/locales/src/it_IT.ts | 4 +- packages/@uppy/locales/src/ja_JP.ts | 4 +- packages/@uppy/locales/src/ko_KR.ts | 4 +- packages/@uppy/locales/src/ms_MY.ts | 4 +- packages/@uppy/locales/src/nb_NO.ts | 4 +- packages/@uppy/locales/src/nl_NL.ts | 4 +- packages/@uppy/locales/src/pl_PL.ts | 4 +- packages/@uppy/locales/src/pt_BR.ts | 4 +- packages/@uppy/locales/src/pt_PT.ts | 4 +- packages/@uppy/locales/src/ro_RO.ts | 4 +- packages/@uppy/locales/src/ru_RU.ts | 4 +- packages/@uppy/locales/src/sk_SK.ts | 4 +- packages/@uppy/locales/src/sr_RS_Cyrillic.ts | 4 +- packages/@uppy/locales/src/sr_RS_Latin.ts | 4 +- packages/@uppy/locales/src/sv_SE.ts | 4 +- packages/@uppy/locales/src/th_TH.ts | 4 +- packages/@uppy/locales/src/tr_TR.ts | 4 +- packages/@uppy/locales/src/uk_UA.ts | 4 +- packages/@uppy/locales/src/uz_UZ.ts | 4 +- packages/@uppy/locales/src/vi_VN.ts | 4 +- packages/@uppy/locales/src/zh_CN.ts | 4 +- packages/@uppy/locales/src/zh_TW.ts | 4 +- packages/@uppy/locales/template.ts | 4 +- packages/@uppy/status-bar/src/Components.tsx | 16 +- .../@uppy/thumbnail-generator/src/index.ts | 2 +- packages/@uppy/transloadit/src/Assembly.ts | 5 +- .../@uppy/transloadit/src/AssemblyWatcher.ts | 1 + packages/@uppy/transloadit/src/index.ts | 11 +- packages/@uppy/tus/src/index.ts | 2 - packages/@uppy/utils/src/Translator.ts | 5 +- packages/@uppy/webcam/src/Webcam.test.ts | 14 +- packages/@uppy/webcam/src/Webcam.tsx | 6 +- .../webcam/src/supportsMediaRecorder.test.ts | 8 +- packages/@uppy/xhr-upload/src/index.ts | 4 +- private/dev/dragdrop.html | 2 +- private/dev/index.html | 2 +- yarn.lock | 74 ++++---- 111 files changed, 432 insertions(+), 449 deletions(-) diff --git a/biome.json b/biome.json index c8f42a2ec..13f580c8c 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.0.5/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -14,10 +14,11 @@ "bin/**", "e2e/**", "private/**", - "!packages/**/{dist,lib}/**", + "!packages/**/{dist,lib}", "!node_modules", "!.svelte-kit", - "!packages/@uppy/components/src/input.css" + "!packages/@uppy/components/src/input.css", + "!examples/angular/**/*.html" ] }, "formatter": { @@ -25,20 +26,11 @@ "indentStyle": "space", "formatWithErrors": true }, + "html": { + "experimentalFullSupportEnabled": true + }, "linter": { "enabled": true, - "includes": [ - "packages/**", - "examples/**", - "scripts/**", - "private/**", - "!packages/**/{dist,lib}/**", - "!node_modules", - "!.svelte-kit", - "!packages/@uppy/components/src/input.css", - "!**/*.vue", - "!**/*.svelte" - ], "rules": { "recommended": true, "suspicious": { @@ -48,37 +40,26 @@ "useExhaustiveDependencies": "error", "useHookAtTopLevel": "error", "noUnusedFunctionParameters": "off", + "noUnusedImports": "error", + "noUnusedPrivateClassMembers": "error", "noUnusedVariables": { "level": "error", "options": { "ignoreRestSiblings": true } - } + }, + "noNestedComponentDefinitions": "error", + "noReactPropAssignments": "error" }, "style": { "noNonNullAssertion": "off" }, "a11y": { - "noSvgWithoutTitle": "off" - }, - "nursery": { - "noNestedComponentDefinitions": "error", - "noReactPropAssign": "error" + "noSvgWithoutTitle": "off", + "useSemanticElements": "off" } } }, - "overrides": [ - { - "includes": ["packages/@uppy/companion/**"], - "linter": { - "rules": { - "complexity": { - "useLiteralKeys": "off" - } - } - } - } - ], "javascript": { "formatter": { "quoteStyle": "single", @@ -92,5 +73,36 @@ "organizeImports": "on" } } - } + }, + "overrides": [ + { + "includes": ["packages/@uppy/companion/**"], + "linter": { + "rules": { + "complexity": { + "useLiteralKeys": "off" + } + } + } + }, + { + "includes": ["**/*.vue", "**/*.svelte", "packages/@uppy/vue/**/*.ts"], + "linter": { + "rules": { + "correctness": { + "useHookAtTopLevel": "off", + "useExhaustiveDependencies": "off" + } + } + } + }, + { + "includes": ["examples/nextjs/**/*.css"], + "css": { + "parser": { + "tailwindDirectives": true + } + } + } + ] } diff --git a/examples/aws-companion/index.html b/examples/aws-companion/index.html index 0b86787b7..01eacb7a8 100644 --- a/examples/aws-companion/index.html +++ b/examples/aws-companion/index.html @@ -1,5 +1,5 @@ - + diff --git a/examples/aws-nodejs/public/index.html b/examples/aws-nodejs/public/index.html index 881a07567..cd7d79f60 100644 --- a/examples/aws-nodejs/public/index.html +++ b/examples/aws-nodejs/public/index.html @@ -1,5 +1,5 @@ - + Uppy – AWS upload example @@ -24,7 +24,8 @@
          - + - +
          diff --git a/examples/transloadit/index.html b/examples/transloadit/index.html index a3919ae1f..a9e0b9c1f 100644 --- a/examples/transloadit/index.html +++ b/examples/transloadit/index.html @@ -1,5 +1,5 @@ - + @@ -140,7 +140,7 @@ This API is a one-shot upload UI using a modal overlay. Call the function and receive a listen to an event with upload results ✌️

          - +

          uppy.upload()

          An <input type=file> backed by uppy.upload():

          diff --git a/examples/transloadit/server.js b/examples/transloadit/server.js index 765301bd5..c71994b0e 100755 --- a/examples/transloadit/server.js +++ b/examples/transloadit/server.js @@ -36,7 +36,7 @@ function Footer() { } function FormFields(fields) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Field([name, value]) { if (name === 'transloadit') return '' let isValueJSON = false @@ -76,7 +76,7 @@ function FormFields(fields) { } function UploadsList(uploads) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Upload(upload) { return `
        • ${e(upload.name)}
        • ` } @@ -89,12 +89,12 @@ function UploadsList(uploads) { } function ResultsList(results) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Result(result) { return `
        • ${e(result.name)} View
        • ` } - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function ResultsSection(stepName) { return `

          ${e(stepName)}

          diff --git a/examples/vue/src/Dropzone.vue b/examples/vue/src/Dropzone.vue index c36d0a9a9..4bb75fd80 100644 --- a/examples/vue/src/Dropzone.vue +++ b/examples/vue/src/Dropzone.vue @@ -7,7 +7,7 @@ >
          - - - -
          +
          - - - - -
          - - - -
          - - - - - -