import fastify from 'fastify' import fastifyMultipart from '..' import { Multipart, MultipartFields, MultipartFile } from '..' import * as util from 'util' import { pipeline, Readable } from 'stream' import * as fs from 'fs' import { expectError, expectType } from 'tsd' import { FastifyErrorConstructor } from "fastify-error" import { BusboyConfig, BusboyFileStream } from "@fastify/busboy"; const pump = util.promisify(pipeline) const runServer = async () => { const app = fastify() app.register(fastifyMultipart, { addToBody: true, sharedSchemaId: 'sharedId', throwFileSizeLimit: false, // stream should be of type streams.Readable // body should be of type fastifyMulipart.Record onFile: (fieldName: string, stream: any, filename: string, encoding: string, mimetype: string, body: Record) => { console.log(fieldName, stream, filename, encoding, mimetype, body) }, limits: { fieldNameSize: 200, fieldSize: 200, fields: 200, fileSize: 200, files: 2, headerPairs: 200 } }) app.register(fastifyMultipart, { attachFieldsToBody: true, onFile: (part: MultipartFile) => { console.log(part) } }) app.get('/path', (request) => { const isMultiPart = request.isMultipart() request.multipart((field, file, filename, encoding, mimetype) => { console.log(field, file, filename, encoding, mimetype, isMultiPart) }, (err) => { throw err }, { limits: { fileSize: 10000 } }) }) // usage app.post('/', async (req, reply) => { const data = await req.file() expectType(data.file) expectType(data.file.truncated) expectType(data.fields) expectType(data.fieldname) expectType(data.filename) expectType(data.encoding) expectType(data.mimetype) await pump(data.file, fs.createWriteStream(data.filename)) reply.send() }) // Multiple fields including scalar values app.post<{Body: {file: Multipart, foo: Multipart}}>('/upload/stringvalue', async (req, reply) => { expectError(req.body.foo.file); expectType(req.body.foo.value); expectType(req.body.file.file) expectError(req.body.file.value); reply.send(); }) app.post<{Body: {file: Multipart, num: Multipart}}>('/upload/stringvalue', async (req, reply) => { expectType(req.body.num.value); reply.send(); // file is a file expectType(req.body.file.file) expectError(req.body.file.value); }) // busboy app.post('/', async function (req, reply) { const options: Partial = { limits: { fileSize: 1000 } }; const data = await req.file(options) await pump(data.file, fs.createWriteStream(data.filename)) reply.send() }) // handle multiple file streams app.post('/', async (req, reply) => { const parts = req.files() for await (const part of parts) { await pump(part.file, fs.createWriteStream(part.filename)) } reply.send() }) // handle multiple file streams and fields app.post('/upload/raw/any', async function (req, reply) { const parts = req.parts() for await (const part of parts) { if (part.file) { await pump(part.file, fs.createWriteStream(part.filename)) } else { console.log(part) } } reply.send() }) // accumulate whole file in memory app.post('/upload/raw/any', async function (req, reply) { const data = await req.file() const buffer = await data.toBuffer() // upload to S3 reply.send() }) // upload files to disk and work with temporary file paths app.post('/upload/files', async function (req, reply) { // stores files to tmp dir and return files const files = await req.saveRequestFiles() files[0].filepath files[0].fieldname files[0].filename files[0].encoding files[0].mimetype files[0].fields // other parsed parts reply.send() }) // upload files to disk with busboy options app.post('/upload/files', async function (req, reply) { const options: Partial = { limits: { fileSize: 1000 } }; await req.saveRequestFiles(options) reply.send() }) // access all errors app.post('/upload/files', async function (req, reply) { const { FilesLimitError } = app.multipartErrors expectType(app.multipartErrors.FieldsLimitError); expectType(app.multipartErrors.FilesLimitError); expectType(app.multipartErrors.InvalidMultipartContentTypeError); expectType(app.multipartErrors.PartsLimitError); expectType(app.multipartErrors.PrototypeViolationError); expectType(app.multipartErrors.RequestFileTooLargeError); // test instanceof Error const a = new FilesLimitError(); if (a instanceof FilesLimitError) { console.log("FilesLimitError occurred."); } reply.send(); }) await app.ready() } runServer().then( console.log.bind(console, 'Success'), console.error.bind(console, 'Error') )