Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Multer adds a `body` object and a `file` or `files` object to the `request` obje
Basic usage example:

```javascript
import multer from 'multer'
import express from 'express'
const multer = require('multer')
const express = require('express')

const app = express()
const upload = multer()
Expand Down Expand Up @@ -49,8 +49,8 @@ app.post('/cool-profile', cpUpload, (req, res, next) => {
In case you need to handle a text-only multipart form, you can use the `.none()` method, example:

```javascript
import multer from 'multer'
import express from 'express'
const multer = require('multer')
const express = require('express')

const app = express()
const upload = multer()
Expand Down
10 changes: 6 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import bytes from 'bytes'
const createFileFilter = require('./lib/file-filter')
const createMiddleware = require('./lib/middleware')

import createFileFilter from './lib/file-filter.js'
import createMiddleware from './lib/middleware.js'
const bytes = require('bytes')

const kLimits = Symbol('limits')

Expand Down Expand Up @@ -60,7 +60,7 @@ class Multer {
}
}

export default function multer (options = {}) {
function multer (options = {}) {
if (options === null) throw new TypeError('Expected object for argument "options", got null')
if (typeof options !== 'object') throw new TypeError(`Expected object for argument "options", got ${typeof options}`)

Expand All @@ -70,3 +70,5 @@ export default function multer (options = {}) {

return new Multer(options)
}

module.exports = multer
4 changes: 3 additions & 1 deletion lib/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const errorMessages = new Map([
['LIMIT_UNEXPECTED_FILE', 'Unexpected file field']
])

export default class MulterError extends Error {
class MulterError extends Error {
constructor (code, optionalField) {
super(errorMessages.get(code))

Expand All @@ -19,3 +19,5 @@ export default class MulterError extends Error {
Error.captureStackTrace(this, this.constructor)
}
}

module.exports = MulterError
4 changes: 3 additions & 1 deletion lib/file-appender.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function createFileAppender (strategy, req, fields) {
function createFileAppender (strategy, req, fields) {
switch (strategy) {
case 'NONE': break
case 'VALUE': req.file = null; break
Expand All @@ -22,3 +22,5 @@ export default function createFileAppender (strategy, req, fields) {
}
}
}

module.exports = createFileAppender
6 changes: 4 additions & 2 deletions lib/file-filter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MulterError from './error.js'
const MulterError = require('./error')

export default function createFileFilter (fields) {
function createFileFilter (fields) {
const filesLeft = new Map()

for (const field of fields) {
Expand All @@ -25,3 +25,5 @@ export default function createFileFilter (fields) {
filesLeft.set(file.fieldName, left - 1)
}
}

module.exports = createFileFilter
14 changes: 8 additions & 6 deletions lib/middleware.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import fs from 'node:fs'
const fs = require('node:fs')

import appendField from 'append-field'
import is from 'type-is'
const appendField = require('append-field')
const is = require('type-is')

import createFileAppender from './file-appender.js'
import readBody from './read-body.js'
const createFileAppender = require('./file-appender')
const readBody = require('./read-body')

async function handleRequest (setup, req) {
const options = setup()
Expand All @@ -26,9 +26,11 @@ async function handleRequest (setup, req) {
}
}

export default function createMiddleware (setup) {
function createMiddleware (setup) {
return function multerMiddleware (req, _, next) {
if (!is(req, ['multipart'])) return next()
handleRequest(setup, req).then(next, next)
}
}

module.exports = createMiddleware
25 changes: 13 additions & 12 deletions lib/read-body.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { extname } from 'node:path'
import { pipeline as _pipeline } from 'node:stream'
import { promisify } from 'node:util'
const { extname } = require('node:path')
const { pipeline: _pipeline } = require('node:stream')
const { promisify } = require('node:util')

import Busboy from '@fastify/busboy'
import { createWriteStream } from 'fs-temp'
import hasOwnProperty from 'has-own-property'
import _onFinished from 'on-finished'
import FileType from 'stream-file-type'
const Busboy = require('@fastify/busboy')
const { createWriteStream } = require('fs-temp')
const _onFinished = require('on-finished')
const FileType = require('stream-file-type')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I believe that this will fail on Node.js versions that cannot require ESM modules)


import MulterError from './error.js'
const MulterError = require('./error')

const onFinished = promisify(_onFinished)
const pipeline = promisify(_pipeline)
Expand All @@ -29,7 +28,7 @@ function collectFields (busboy, limits) {
if (valueTruncated) return reject(new MulterError('LIMIT_FIELD_VALUE', fieldname))

// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
if (limits && hasOwnProperty(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
if (limits && Object.hasOwn(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
return reject(new MulterError('LIMIT_FIELD_KEY'))
}

Expand All @@ -54,7 +53,7 @@ function collectFiles (busboy, limits, fileFilter) {
})

// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
if (limits && hasOwnProperty(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
if (limits && Object.hasOwn(limits, 'fieldNameSize') && fieldname.length > limits.fieldNameSize) {
return reject(new MulterError('LIMIT_FIELD_KEY'))
}

Expand Down Expand Up @@ -96,7 +95,7 @@ function collectFiles (busboy, limits, fileFilter) {
})
}

export default async function readBody (req, limits, fileFilter) {
async function readBody (req, limits, fileFilter) {
const busboy = new Busboy({ headers: req.headers, limits: limits })

const fields = collectFields(busboy, limits)
Expand Down Expand Up @@ -128,3 +127,5 @@ export default async function readBody (req, limits, fileFilter) {
throw err
}
}

module.exports = readBody
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
],
"license": "MIT",
"repository": "expressjs/multer",
"type": "module",
"exports": "./index.js",
"keywords": [
"form",
"post",
Expand All @@ -22,7 +20,7 @@
],
"dependencies": {
"@fastify/busboy": "^1.0.0",
"append-field": "^2.0.0",
"append-field": "^1.0.0",
"bytes": "^3.1.0",
"fs-temp": "^2.0.1",
"has-own-property": "^2.0.0",
Expand Down
27 changes: 14 additions & 13 deletions test/_util.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import assert from 'node:assert'
import fs from 'node:fs'
import stream from 'node:stream'
import { promisify } from 'node:util'
const path = require('path')
const assert = require('node:assert')
const fs = require('node:fs')
const stream = require('node:stream')
const { promisify } = require('node:util')

import hasha from 'hasha'
import _onFinished from 'on-finished'
const hasha = require('hasha')
const _onFinished = require('on-finished')

const onFinished = promisify(_onFinished)

Expand Down Expand Up @@ -51,15 +52,15 @@ const files = new Map([
}]
])

export function file (name) {
return fs.createReadStream(new URL(`files/${name}${files.get(name).extension}`, import.meta.url))
exports.file = function file (name) {
return fs.createReadStream(path.join(__dirname, 'files', name + files.get(name).extension))
}

export function knownFileLength (name) {
exports.knownFileLength = function knownFileLength (name) {
return files.get(name).size
}

export async function assertFile (file, fieldName, fileName) {
exports.assertFile = async function assertFile (file, fieldName, fileName) {
if (!files.has(fileName)) {
throw new Error(`No file named "${fileName}"`)
}
Expand All @@ -81,15 +82,15 @@ export async function assertFile (file, fieldName, fileName) {
assert.strictEqual(hash, expected.hash)
}

export async function assertFiles (files) {
await Promise.all(files.map((args) => assertFile(args[0], args[1], args[2])))
exports.assertFiles = async function assertFiles (files) {
await Promise.all(files.map((args) => exports.assertFile(args[0], args[1], args[2])))
}

function getLength (form) {
return promisify(form.getLength).call(form)
}

export async function submitForm (multer, form) {
exports.submitForm = async (multer, form) => {
const length = await getLength(form)
const req = new stream.PassThrough()

Expand Down
12 changes: 6 additions & 6 deletions test/aborted-requests.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-env mocha */

import assert from 'node:assert'
import { PassThrough } from 'node:stream'
import { promisify } from 'node:util'
const assert = require('node:assert')
const { PassThrough } = require('node:stream')
const { promisify } = require('node:util')

import FormData from 'form-data'
const FormData = require('form-data')

import * as util from './_util.js'
import multer from '../index.js'
const util = require('./_util')
const multer = require('../')

function getLength (form) {
return promisify(form.getLength).call(form)
Expand Down
25 changes: 12 additions & 13 deletions test/body.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/* eslint-env mocha */

import assert from 'node:assert'
import stream from 'node:stream'
import { promisify } from 'node:util'
const assert = require('node:assert')
const stream = require('node:stream')
const { promisify } = require('node:util')

import FormData from 'form-data'
import hasOwnProperty from 'has-own-property'
import recursiveNullify from 'recursive-nullify'
import testData from 'testdata-w3c-json-form'
const FormData = require('form-data')
const recursiveNullify = require('recursive-nullify')
const testData = require('testdata-w3c-json-form')

import * as util from './_util.js'
import multer from '../index.js'
const util = require('./_util')
const multer = require('../')

describe('body', () => {
let parser
Expand Down Expand Up @@ -72,8 +71,8 @@ describe('body', () => {

await promisify(parser)(req, null)

assert.strictEqual(hasOwnProperty(req, 'body'), false)
assert.strictEqual(hasOwnProperty(req, 'files'), false)
assert.strictEqual(Object.hasOwn(req, 'body'), false)
assert.strictEqual(Object.hasOwn(req, 'files'), false)
})

it('should not process non-multipart GET request', async () => {
Expand All @@ -88,8 +87,8 @@ describe('body', () => {

await promisify(parser)(req, null)

assert.strictEqual(hasOwnProperty(req, 'body'), false)
assert.strictEqual(hasOwnProperty(req, 'files'), false)
assert.strictEqual(Object.hasOwn(req, 'body'), false)
assert.strictEqual(Object.hasOwn(req, 'files'), false)
})

for (const test of testData) {
Expand Down
12 changes: 6 additions & 6 deletions test/error-handling.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-env mocha */

import assert from 'node:assert'
import stream from 'node:stream'
import { promisify } from 'node:util'
const assert = require('node:assert')
const stream = require('stream')
const { promisify } = require('node:util')

import FormData from 'form-data'
const FormData = require('form-data')

import * as util from './_util.js'
import multer from '../index.js'
const util = require('./_util')
const multer = require('../')

function withLimits (limits, fields) {
return multer({ limits: limits }).fields(fields)
Expand Down
16 changes: 8 additions & 8 deletions test/express-integration.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/* eslint-env mocha */

import assert from 'node:assert'
import { promisify } from 'node:util'
const assert = require('node:assert')
const { promisify } = require('node:util')

import express from 'express'
import FormData from 'form-data'
import getStream from 'get-stream'
import _onFinished from 'on-finished'
const express = require('express')
const FormData = require('form-data')
const getStream = require('get-stream')
const _onFinished = require('on-finished')

import * as util from './_util.js'
import multer from '../index.js'
const multer = require('../')
const util = require('./_util')

const onFinished = promisify(_onFinished)

Expand Down
8 changes: 4 additions & 4 deletions test/limits.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-env mocha */

import assert from 'node:assert'
import FormData from 'form-data'
const assert = require('node:assert')
const FormData = require('form-data')

import * as util from './_util.js'
import multer from '../index.js'
const util = require('./_util')
const multer = require('../')

describe('limits', () => {
it('should report limit errors', async () => {
Expand Down
10 changes: 5 additions & 5 deletions test/misc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-env mocha */

import assert from 'node:assert'
import { PassThrough, pipeline } from 'node:stream'
import FormData from 'form-data'
const assert = require('node:assert')
const { PassThrough, pipeline } = require('node:stream')
const FormData = require('form-data')

import * as util from './_util.js'
import multer from '../index.js'
const util = require('./_util')
const multer = require('../')

describe('Misc', () => {
it('should handle unicode filenames', async () => {
Expand Down
Loading