Socket
Socket
Sign inDemoInstall

@fastify/multipart

Package Overview
Dependencies
Maintainers
20
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fastify/multipart - npm Package Compare versions

Comparing version 8.0.0 to 8.1.0

.gitattributes

72

.eslintrc.json
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"standard"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"env": { "node": true },
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"project": "./tsconfig.eslint.json",
"createDefaultProgram": true
},
"rules": {
"no-console": "off",
"@typescript-eslint/indent": ["error", 2],
"semi": ["error", "never"],
"import/export": "off" // this errors on multiple exports (overload interfaces)
},
"overrides": [
{
"files": ["*.d.ts","*.test-d.ts"],
"rules": {
"no-use-before-define": "off",
"no-redeclare": "off",
"@typescript-eslint/no-explicit-any": "off"
}
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "standard"],
"overrides": [
{
"files": ["types/*.test-d.ts", "types/*.d.ts"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.eslint.json"]
},
{
"files": ["*.test-d.ts"],
"rules": {
"no-unused-expressions": "off",
"@typescript-eslint/no-var-requires": "off",
"no-unused-vars": "off",
"n/handle-callback-err": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-misused-promises": ["error", {
"checksVoidReturn": false
}]
},
"globals": {
"NodeJS": "readonly"
}
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"rules": {
"no-unused-expressions": "off",
"no-use-before-define": "off",
"no-redeclare": "off",
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-unused-vars": "off"
}
]
}
}
]
}

@@ -20,3 +20,2 @@ 'use strict'

const kMultipartHandler = Symbol('multipartHandler')
const getDescriptor = Object.getOwnPropertyDescriptor

@@ -33,3 +32,3 @@ const PartsLimitError = createError('FST_PARTS_LIMIT', 'reach parts limit', 413)

function setMultipart (req, payload, done) {
req.raw[kMultipart] = true
req[kMultipart] = true
done()

@@ -100,2 +99,4 @@ }

/* Don't modify the body if a field doesn't have a value or an attached buffer */
/* istanbul ignore else */
if (field.value !== undefined) {

@@ -145,2 +146,3 @@ body[key] = field.value

fastify.addContentTypeParser('multipart/form-data', setMultipart)
fastify.decorateRequest(kMultipart, false)
fastify.decorateRequest(kMultipartHandler, handleMultipart)

@@ -167,3 +169,3 @@

function isMultipart () {
return this.raw[kMultipart]
return this[kMultipart]
}

@@ -257,3 +259,3 @@

// don't overwrite prototypes
if (getDescriptor(Object.prototype, name)) {
if (name in Object.prototype) {
onError(new PrototypeViolationError())

@@ -304,3 +306,3 @@ return

// don't overwrite prototypes
if (getDescriptor(Object.prototype, name)) {
if (name in Object.prototype) {
// ensure that stream is consumed, any error is suppressed

@@ -463,3 +465,4 @@ sendToWormhole(file)

} catch (error) {
this.log.error(error, 'could not delete file')
/* istanbul ignore next */
this.log.error(error, 'Could not delete file')
}

@@ -473,2 +476,4 @@ }

while ((part = await parts()) != null) {
/* Only return a part if the file property exists */
/* istanbul ignore else */
if (part.file) {

@@ -475,0 +480,0 @@ return part

{
"name": "@fastify/multipart",
"version": "8.0.0",
"version": "8.1.0",
"description": "Multipart plugin for Fastify",
"main": "index.js",
"type": "commonjs",
"types": "types/index.d.ts",

@@ -11,4 +12,2 @@ "dependencies": {

"@fastify/error": "^3.0.0",
"@fastify/swagger": "^8.3.1",
"@fastify/swagger-ui": "^1.8.0",
"fastify-plugin": "^4.0.0",

@@ -20,2 +19,4 @@ "secure-json-parse": "^2.4.0",

"@fastify/pre-commit": "^2.0.2",
"@fastify/swagger": "^8.10.1",
"@fastify/swagger-ui": "^2.0.1",
"@types/node": "^20.1.0",

@@ -25,3 +26,3 @@ "@typescript-eslint/eslint-plugin": "^6.3.0",

"benchmark": "^2.1.4",
"climem": "^1.0.3",
"climem": "^2.0.0",
"concat-stream": "^2.0.0",

@@ -37,7 +38,7 @@ "eslint": "^8.20.0",

"pump": "^3.0.0",
"readable-stream": "^3.6.0",
"readable-stream": "^4.5.1",
"snazzy": "^9.0.0",
"standard": "^17.0.0",
"tap": "^16.0.0",
"tsd": "^0.29.0"
"tsd": "^0.30.0"
},

@@ -44,0 +45,0 @@ "scripts": {

@@ -291,3 +291,3 @@ # @fastify/multipart

If you enable `attachFieldsToBody: 'keyValues'` then the response body and JSON Schema validation will behave similarly to `application/json` and [`application/x-www-form-urlencoded`](https://github.com/fastify/fastify-formbody) content types. Files will be decoded using `Buffer.toString()` and attached as a body value.
When the `attachFieldsToBody` parameter is set to `'keyValues'`, JSON Schema validation on the body will behave similarly to `application/json` and [`application/x-www-form-urlencoded`](https://github.com/fastify/fastify-formbody) content types. Additionally, uploaded files will be attached to the body as `Buffer` objects.

@@ -306,5 +306,3 @@ ```js

myFile: {
type: 'string',
// validate that file contents match a UUID
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
type: 'object',
},

@@ -311,0 +309,0 @@ hello: {

@@ -107,2 +107,137 @@ 'use strict'

test('should not allow toString as field name', function (t) {
t.plan(4)
const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))
fastify.register(multipart)
fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())
try {
await req.file()
reply.code(200).send()
} catch (error) {
t.ok(error instanceof fastify.multipartErrors.PrototypeViolationError)
reply.code(500).send()
}
})
fastify.listen({ port: 0 }, async function () {
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}
const req = http.request(opts, (res) => {
t.equal(res.statusCode, 500)
res.resume()
res.on('end', () => {
t.pass('res ended successfully')
})
})
form.append('toString', 'world')
form.pipe(req)
})
})
test('should not allow hasOwnProperty as field name', function (t) {
t.plan(4)
const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))
fastify.register(multipart)
fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())
try {
await req.file()
reply.code(200).send()
} catch (error) {
t.ok(error instanceof fastify.multipartErrors.PrototypeViolationError)
reply.code(500).send()
}
})
fastify.listen({ port: 0 }, async function () {
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}
const req = http.request(opts, (res) => {
t.equal(res.statusCode, 500)
res.resume()
res.on('end', () => {
t.pass('res ended successfully')
})
})
form.append('hasOwnProperty', 'world')
form.pipe(req)
})
})
test('should not allow propertyIsEnumerable as field name', function (t) {
t.plan(4)
const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))
fastify.register(multipart)
fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())
try {
await req.file()
reply.code(200).send()
} catch (error) {
t.ok(error instanceof fastify.multipartErrors.PrototypeViolationError)
reply.code(500).send()
}
})
fastify.listen({ port: 0 }, async function () {
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}
const req = http.request(opts, (res) => {
t.equal(res.statusCode, 500)
res.resume()
res.on('end', () => {
t.pass('res ended successfully')
})
})
form.append('propertyIsEnumerable', 'world')
form.pipe(req)
})
})
test('should use default for fileSize', async function (t) {

@@ -109,0 +244,0 @@ t.plan(4)

{
"compilerOptions": {
"target": "es6",
"lib": [ "es2015", "ES2018" ],
"module": "commonjs",
"noEmit": true,
"strict": true
},
"include": [
"types/*.test-d.ts",
"types/*.d.ts"
]
}
"compilerOptions": {
"target": "es6",
"lib": ["ES2015", "ES2018"],
"module": "commonjs",
"noEmit": true,
"strict": true
},
"include": ["types/*.test-d.ts", "types/*.d.ts"]
}

@@ -17,6 +17,6 @@ import { BusboyConfig, BusboyFileStream } from '@fastify/busboy'

file: (
options?: Omit<BusboyConfig, 'headers'>
options?: Omit<BusboyConfig, 'headers'> | fastifyMultipart.FastifyMultipartBaseOptions
) => Promise<fastifyMultipart.MultipartFile | undefined>;
files: (
options?: Omit<BusboyConfig, 'headers'>
options?: Omit<BusboyConfig, 'headers'> | fastifyMultipart.FastifyMultipartBaseOptions
) => AsyncIterableIterator<fastifyMultipart.MultipartFile>;

@@ -162,2 +162,8 @@

headerPairs?: number;
/**
* For multipart forms, the max number of parts (fields + files)
* @default 1000
*/
parts?: number;
};

@@ -164,0 +170,0 @@ }

import fastify from 'fastify'
import fastifyMultipart, { MultipartValue, MultipartFields, MultipartFile } from '..'
import fastifyMultipart, { MultipartValue, MultipartFields, MultipartFile, FastifyMultipartBaseOptions } from '..'
import * as util from 'util'

@@ -17,2 +17,5 @@ import { pipeline } from 'stream'

attachFieldsToBody: true,
limits: {
parts: 500
},
onFile: (part: MultipartFile) => {

@@ -77,4 +80,13 @@ console.log(part)

app.post('/', async function (req, reply) {
const options: Partial<BusboyConfig> = { limits: { fileSize: 1000 } }
const data = await req.file(options)
const data = await req.file({
limits: { fileSize: 1000, parts: 500 },
throwFileSizeLimit: true,
sharedSchemaId: 'schemaId',
isPartAFile: (fieldName, contentType, fileName) => {
expectType<string | undefined>(fieldName)
expectType<string | undefined>(contentType)
expectType<string | undefined>(fileName)
return true
}
})
if (!data) throw new Error('missing file')

@@ -87,3 +99,13 @@ await pump(data.file, fs.createWriteStream(data.filename))

app.post('/', async (req, reply) => {
const parts = req.files()
const parts = req.files({
limits: { fileSize: 1000, parts: 500 },
throwFileSizeLimit: true,
sharedSchemaId: 'schemaId',
isPartAFile: (fieldName, contentType, fileName) => {
expectType<string | undefined>(fieldName)
expectType<string | undefined>(contentType)
expectType<string | undefined>(fileName)
return true
}
})
for await (const part of parts) {

@@ -90,0 +112,0 @@ await pump(part.file, fs.createWriteStream(part.filename))

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc