Binary Data
File, Blob, and ReadableStream<Uint8Array> are supported by the RPC Serializer and OpenAPI Serializer. Use them to handle binary data in your procedures.
WARNING
To better support Blob, File, and ReadableStream<Uint8Array> at the root level in cross-origin scenarios, extend your CORS allowlist to allow clients to send and receive the Content-Disposition and Standard-Server headers. Learn more in the Standard Server documentation. If you use the CORS Plugin, include them in allowHeaders and exposeHeaders:
const cors = new CORSHandlerPlugin({
allowHeaders: ['Content-Disposition', 'Standard-Server'],
exposeHeaders: ['Content-Disposition', 'Standard-Server'],
})File and Blob
Procedures can accept File and Blob as input and return them directly or inside nested structures.
WARNING
File and Blob are usually buffered in memory by default. For large files, we recommend extending the body parser for better performance and reliability.
const example = os
.input(z.file())
.output(z.object({ anyFieldName: z.instanceof(File) }))
.handler(async ({ input }) => {
const file = input
console.log(file.name)
return {
anyFieldName: new File(['Hello World'], 'hello.txt', { type: 'text/plain' }),
}
})ReadableStream<Uint8Array>
Procedures can return ReadableStream<Uint8Array> to stream binary responses. The example below uses the Response Headers Plugin to set the appropriate Content-Type header.
const example = base
.output(z.instanceof(ReadableStream))
.handler(async ({ context }) => {
context.resHeaders?.set('Content-Type', 'text/plain')
const stream = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(new TextEncoder().encode('Hello World'))
controller.close()
}
})
return stream
})
