diff --git a/examples/reactrouter/server.ts b/examples/reactrouter/server.ts index 80ee0542c..616e15d33 100644 --- a/examples/reactrouter/server.ts +++ b/examples/reactrouter/server.ts @@ -41,7 +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/*', (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 +49,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/packages/@uppy/companion/src/companion.ts b/packages/@uppy/companion/src/companion.ts index fb98e6782..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 })) } 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') + }) + }) })