@uppy/xhr-upload: bring back getResponseData (#5354)

This commit is contained in:
Merlijn Vos 2024-07-18 16:22:29 +02:00 committed by GitHub
parent 415ce7c6ea
commit 7b92d9d2cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 8 deletions

View file

@ -245,6 +245,16 @@ export default {
};
```
#### `getResponseData`
An optional function to turn your non-JSON response into JSON with a `url`
property pointing to the uploaded file
(`(xhr: XMLHttpRequest) => { url: string }`).
You can also return properties other than `url` and they will end up in
`file.response.body`. If you do, make sure to set the `Body` generic on `Uppy`
to make it typesafe when using TS.
## Frequently Asked Questions
### How can I refresh auth tokens after they expire?

View file

@ -4,7 +4,7 @@ import Core from '@uppy/core'
import XHRUpload from './index.ts'
describe('XHRUpload', () => {
it('should leverage hooks from fetcher', () => {
it('should leverage hooks from fetcher', async () => {
nock('https://fake-endpoint.uppy.io')
.defaultReplyHeaders({
'access-control-allow-method': 'POST',
@ -17,12 +17,16 @@ describe('XHRUpload', () => {
.options('/')
.reply(204, {})
.post('/')
.reply(200, {})
.reply(200, 'https://fake-endpoint.uppy.io/random-id')
const core = new Core()
const core = new Core<any, { url: string }>()
const shouldRetry = vi.fn(() => true)
const onBeforeRequest = vi.fn(() => {})
const onAfterResponse = vi.fn(() => {})
// Test that we can turn a text response into a JSON response.
const getResponseData = vi.fn((xhr: XMLHttpRequest) => ({
url: xhr.responseText,
}))
core.use(XHRUpload, {
id: 'XHRUpload',
@ -30,6 +34,7 @@ describe('XHRUpload', () => {
shouldRetry,
onBeforeRequest,
onAfterResponse,
getResponseData,
})
const id = core.addFile({
type: 'image/png',
@ -45,10 +50,14 @@ describe('XHRUpload', () => {
endpoint: 'https://fake-endpoint.uppy.io',
},
})
return core.upload().then(() => {
expect(shouldRetry).toHaveBeenCalledTimes(1)
expect(onAfterResponse).toHaveBeenCalledTimes(2)
expect(onBeforeRequest).toHaveBeenCalledTimes(2)
await core.upload()
expect(shouldRetry).toHaveBeenCalledTimes(1)
expect(onAfterResponse).toHaveBeenCalledTimes(2)
expect(onBeforeRequest).toHaveBeenCalledTimes(2)
expect(core.getFile(id).response!.body).toEqual({
url: 'https://fake-endpoint.uppy.io/random-id',
})
})

View file

@ -55,6 +55,7 @@ export interface XhrUploadOpts<M extends Meta, B extends Body>
onBeforeRequest?: FetcherOptions['onBeforeRequest']
shouldRetry?: FetcherOptions['shouldRetry']
onAfterResponse?: FetcherOptions['onAfterResponse']
getResponseData?: (xhr: XMLHttpRequest) => B | Promise<B>
allowedMetaFields?: boolean | string[]
bundle?: boolean
}
@ -218,7 +219,16 @@ export default class XHRUpload<
},
})
const body = JSON.parse(res.responseText) as B
let body = await this.opts.getResponseData?.(res)
try {
body ??= JSON.parse(res.responseText) as B
} catch (cause) {
throw new Error(
'@uppy/xhr-upload expects a JSON response (with a `url` property). To parse non-JSON responses, use `getResponseData` to turn your response into JSON.',
{ cause },
)
}
const uploadURL = typeof body?.url === 'string' ? body.url : undefined
for (const file of files) {