Skip to content

Commit 70517da

Browse files
GrosSacASacRishi-121jimmywarting
authored
feat: merge 3.x (#767)
* chore: start version 3 * feat: Use ES modules (#727) * feat: Url search params and remove multiple (#730) * docs: Fixed the missing "=" in options.filter (#732) * docs: fix example * docs: specify what part actually is * docs: fix types * docs: add warning for progress event * docs: finish removing multiples in examples * docs: add example for express as middleware * docs: example handle common internet errors * feat: add corepack support * fix: corepack support * fix: fix examples comment * fix: fix example comment * feat: add firstValues, readBooleans helpers (#757) * feat: add firstValues, readBooleans helpers * feat: export types * docs: document helpers * docs: fix example * fix: #760 (#761) * fix: fix error when there is an error * tests: fix some of the tests (#763) * chore: up supertest jest and nyc * tests: convert to import , fix some tests * test: make malformed boundary as per comment ? * tests: refactor * style: fix some prettier issues (#764) * chore: publish as 3.x tag * docs: add changelog link * docs: typo Co-authored-by: Hrushikesh Das <[email protected]> Co-authored-by: Jimmy Wärting <[email protected]>
1 parent 1c30ec6 commit 70517da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2163
-2451
lines changed

CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
### Unreleased 3.1.1
4+
5+
* feat: handle top level json array, string and number
6+
7+
### Unreleased 3.1
8+
9+
* feat: add firstValues, readBooleans helpers
10+
11+
### Unreleased 3.0
12+
13+
* feat: remove options.multiples ([730](https://github.com/node-formidable/formidable/pull/730))
14+
* use modern URLSearchParams https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams internally
15+
* files and fields values are always arrays
16+
* fields with [] in the name do not receive special treatment
17+
* remove unused qs and querystring dependency
18+
* feat: Use ES modules ([727](https://github.com/node-formidable/formidable/pull/727))
19+
* options.enabledPlugins must contain the plugin themselves instead of the plugins names
20+
21+
322
### Unreleased (`canary` & `dev` dist-tags)
423

524
* feat: add options.filter ([#716](https://github.com/node-formidable/formidable/pull/716))

README.md

+67-39
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,11 @@ already be included. Check the examples below and the [examples/](https://github
7878
```sh
7979
# v2
8080
npm install formidable
81-
npm install formidable@latest
82-
npm install formidable@v2
81+
82+
## 3.x
83+
npm install [email protected]
84+
```
85+
8386

8487
# or v3
8588
npm install formidable@v3
@@ -98,13 +101,13 @@ Parse an incoming file upload, with the
98101
[Node.js's built-in `http` module](https://nodejs.org/api/http.html).
99102
100103
```js
101-
const http = require('http');
102-
const formidable = require('formidable');
104+
import http from 'http';
105+
import formidable from 'formidable';
103106
104107
const server = http.createServer((req, res) => {
105108
if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
106109
// parse a file upload
107-
const form = formidable({ multiples: true });
110+
const form = formidable({});
108111
109112
form.parse(req, (err, fields, files) => {
110113
if (err) {
@@ -146,8 +149,8 @@ Or try the
146149
[examples/with-express.js](https://github.com/node-formidable/formidable/blob/master/examples/with-express.js)
147150

148151
```js
149-
const express = require('express');
150-
const formidable = require('formidable');
152+
import express from 'express';
153+
import formidable from 'formidable';
151154

152155
const app = express();
153156

@@ -163,7 +166,7 @@ app.get('/', (req, res) => {
163166
});
164167

165168
app.post('/api/upload', (req, res, next) => {
166-
const form = formidable({ multiples: true });
169+
const form = formidable({});
167170

168171
form.parse(req, (err, fields, files) => {
169172
if (err) {
@@ -192,8 +195,8 @@ which is Node.js's Request, and **NOT** the `ctx.request` which is Koa's Request
192195
object - there is a difference._
193196

194197
```js
195-
const Koa = require('koa');
196-
const formidable = require('formidable');
198+
import Koa from 'Koa';
199+
import formidable from 'formidable';
197200

198201
const app = new Koa();
199202

@@ -203,7 +206,7 @@ app.on('error', (err) => {
203206

204207
app.use(async (ctx, next) => {
205208
if (ctx.url === '/api/upload' && ctx.method.toLowerCase() === 'post') {
206-
const form = formidable({ multiples: true });
209+
const form = formidable({});
207210

208211
// not very elegant, but that's for now if you don't want to use `koa-better-body`
209212
// or other middlewares.
@@ -292,20 +295,8 @@ _Please pass [`options`](#options) to the function/constructor, not by assigning
292295
them to the instance `form`_
293296

294297
```js
295-
const formidable = require('formidable');
296-
const form = formidable(options);
297-
298-
// or
299-
const { formidable } = require('formidable');
298+
import formidable from 'formidable';
300299
const form = formidable(options);
301-
302-
// or
303-
const { IncomingForm } = require('formidable');
304-
const form = new IncomingForm(options);
305-
306-
// or
307-
const { Formidable } = require('formidable');
308-
const form = new Formidable(options);
309300
```
310301

311302
### Options
@@ -343,11 +334,6 @@ See it's defaults in [src/Formidable.js DEFAULT_OPTIONS](./src/Formidable.js)
343334
(AWS S3, Azure blob storage, Google cloud storage) or private file storage,
344335
this is the option you're looking for. When this option is defined the default
345336
behavior of writing the file in the host machine file system is lost.
346-
- `options.multiples` **{boolean}** - default `false`; when you call the
347-
`.parse` method, the `files` argument (of the callback) will contain arrays of
348-
files for inputs which submit multiple files using the HTML5 `multiple`
349-
attribute. Also, the `fields` argument will contain arrays of values for
350-
fields that have names ending with '[]'.
351337
- `options.filename` **{function}** - default `undefined` Use it to control
352338
newFilename. Must return a string. Will be joined with options.uploadDir.
353339

@@ -357,6 +343,12 @@ See it's defaults in [src/Formidable.js DEFAULT_OPTIONS](./src/Formidable.js)
357343

358344
#### `options.filename` **{function}** function (name, ext, part, form) -> string
359345

346+
where part can be decomposed as
347+
348+
```js
349+
const { originalFilename, mimetype} = part;
350+
```
351+
360352
_**Note:** If this size of combined fields, or size of some file is exceeded, an
361353
`'error'` event is fired._
362354

@@ -390,9 +382,7 @@ Parses an incoming Node.js `request` containing form data. If `callback` is
390382
provided, all fields and files are collected and passed to the callback.
391383

392384
```js
393-
const formidable = require('formidable');
394-
395-
const form = formidable({ multiples: true, uploadDir: __dirname });
385+
const form = formidable({ uploadDir: __dirname });
396386

397387
form.parse(req, (err, fields, files) => {
398388
console.log('fields:', fields);
@@ -515,8 +505,6 @@ Formidable instance (the `form` across the README examples) and the options.
515505
**Note:** the plugin function's `this` context is also the same instance.
516506

517507
```js
518-
const formidable = require('formidable');
519-
520508
const form = formidable({ keepExtensions: true });
521509

522510
form.use((self, options) => {
@@ -541,11 +529,10 @@ which is used in [src/plugins/multipart.js](./src/plugins/multipart.js)), then
541529
you can remove it from the `options.enabledPlugins`, like so
542530

543531
```js
544-
const { Formidable } = require('formidable');
545-
546-
const form = new Formidable({
532+
import formidable, {octetstream, querystring, json} from "formidable";
533+
const form = formidable({
547534
hashAlgorithm: 'sha1',
548-
enabledPlugins: ['octetstream', 'querystring', 'json'],
535+
enabledPlugins: [octetstream, querystring, json],
549536
});
550537
```
551538

@@ -631,7 +618,7 @@ requests.
631618
#### `'progress'`
632619

633620
Emitted after each incoming chunk of data that has been parsed. Can be used to
634-
roll your own progress bar.
621+
roll your own progress bar. **Warning** Use this only for server side progress bar. On the client side better use `XMLHttpRequest` with `xhr.upload.onprogress =`
635622

636623
```js
637624
form.on('progress', (bytesReceived, bytesExpected) => {});
@@ -707,6 +694,47 @@ finished flushing to disk. This is a great place for you to send your response.
707694
form.on('end', () => {});
708695
```
709696

697+
698+
### Helpers
699+
700+
#### firstValues
701+
702+
Gets first values of fields, like pre 3.0.0 without multiples pass in a list of optional exceptions where arrays of strings is still wanted (`<select multiple>` for example)
703+
704+
```js
705+
import { firstValues } from 'formidable/src/helpers/firstValues.js';
706+
707+
// ...
708+
form.parse(request, async (error, fieldsMultiple, files) => {
709+
if (error) {
710+
//...
711+
}
712+
const exceptions = ['thisshouldbeanarray'];
713+
const fieldsSingle = firstValues(form, fieldsMultiple, exceptions);
714+
// ...
715+
```
716+
717+
#### readBooleans
718+
719+
Html form input type="checkbox" only send the value "on" if checked,
720+
convert it to booleans for each input that is expected to be sent as a checkbox, only use after firstValues or similar was called.
721+
722+
```js
723+
import { firstValues } from 'formidable/src/helpers/firstValues.js';
724+
import { readBooleans } from 'formidable/src/helpers/readBooleans.js';
725+
726+
// ...
727+
form.parse(request, async (error, fieldsMultiple, files) => {
728+
if (error) {
729+
//...
730+
}
731+
const fieldsSingle = firstValues(form, fieldsMultiple);
732+
733+
const expectedBooleans = ['checkbox1', 'wantsNewsLetter', 'hasACar'];
734+
const fieldsWithBooleans = readBooleans(fieldsSingle, expectedBooleans);
735+
// ...
736+
```
737+
710738
## Changelog
711739
712740
[./CHANGELOG.md](./CHANGELOG.md)

examples/express-middleware.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import express from 'express';
2+
import formidable from '../src/index.js';
3+
4+
const app = express();
5+
6+
// middlewares that populates req.fields and req.body
7+
const formMiddleWare = (req, res, next) => {
8+
const form = formidable({});
9+
10+
form.parse(req, (err, fields, files) => {
11+
if (err) {
12+
next(err);
13+
return;
14+
}
15+
req.fields = fields;
16+
req.files = files;
17+
next();
18+
});
19+
};
20+
21+
app.get('/', (req, res) => {
22+
res.send(`
23+
<h2>With <code>"express"</code> npm package</h2>
24+
<form action="/api/upload" enctype="multipart/form-data" method="post">
25+
<div>Text field title: <input type="text" name="title" /></div>
26+
<div>File: <input type="file" name="someExpressFiles" multiple="multiple"></div>
27+
<input type="submit" value="Upload">
28+
</form>
29+
`);
30+
});
31+
32+
// use middleware
33+
app.post('/api/upload', formMiddleWare, (req, res, next) => {
34+
res.json({
35+
fields: req.fields,
36+
files: req.files,
37+
});
38+
});
39+
40+
app.listen(3000, () => {
41+
console.log('Server listening on http://localhost:3000 ...');
42+
});

examples/json.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
'use strict';
1+
import http from 'http';
2+
import util from 'util';
3+
import formidable from '../src/index.js';
24

3-
const http = require('http');
4-
const util = require('util');
5-
const { formidable } = require('../src/index');
65

76
const PORT = 3000;
87
const server = http.createServer((req, res) => {

examples/log-file-content-to-console.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
'use strict';
1+
import http from 'http';
2+
import { Writable } from 'stream';
3+
import formidable from '../src/index.js';
24

3-
const http = require('http');
4-
const { Writable } = require('stream');
5-
const formidable = require('../src/index');
65

76
const server = http.createServer((req, res) => {
87
if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {

examples/multipart-parser.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
'use strict';
1+
import { MultipartParser } from '../src/index.js';
22

3-
const { MultipartParser } = require('../src/index');
43

54
// hand crafted multipart
65
const boundary = '--abcxyz';

examples/multiples.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
'use strict';
1+
import http from 'http';
2+
import os from 'os';
3+
import formidable from '../src/index.js';
24

3-
const os = require('os');
4-
const http = require('http');
5-
const { Formidable } = require('../src/index');
65

76
const server = http.createServer((req, res) => {
87
if (req.url === '/') {
@@ -28,7 +27,7 @@ const server = http.createServer((req, res) => {
2827
</form>
2928
`);
3029
} else if (req.url === '/upload') {
31-
const form = new Formidable({ multiples: true, uploadDir: os.tmpdir() });
30+
const form = formidable({ uploadDir: os.tmpdir() });
3231

3332
form.parse(req, (err, fields, files) => {
3433
res.writeHead(200, { 'Content-Type': 'application/json' });

examples/store-files-on-s3.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
// To test this example you have to install aws-sdk nodejs package and create a bucket named "demo-bucket"
22

3-
'use strict';
3+
import http from 'http';
4+
import { PassThrough } from 'stream';
5+
import AWS from 'aws-sdk';
6+
import formidable from '../src/index.js';
47

5-
const http = require('http');
6-
const { PassThrough } = require('stream');
7-
// eslint-disable-next-line import/no-unresolved
8-
const AWS = require('aws-sdk');
9-
const formidable = require('../src/index');
108

119
const s3Client = new AWS.S3({
1210
credentials: {

examples/upload-multiple-files.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
'use strict';
1+
import http from 'http';
2+
import util from 'util';
3+
import os from 'os';
4+
import formidable from '../src/index.js';
25

3-
const os = require('os');
4-
const http = require('http');
5-
const util = require('util');
6-
7-
const { Formidable } = require('../src/index');
86

97
const server = http.createServer((req, res) => {
108
if (req.url === '/') {
@@ -17,7 +15,7 @@ const server = http.createServer((req, res) => {
1715
</form>
1816
`);
1917
} else if (req.url === '/upload') {
20-
const form = new Formidable({ multiples: true, uploadDir: os.tmpdir() });
18+
const form = formidable({ uploadDir: os.tmpdir() });
2119
const files = [];
2220
const fields = [];
2321

examples/urlencoded-no-enctype.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
'use strict';
1+
import http from 'http';
2+
import util from 'util';
3+
import formidable from '../src/index.js';
24

3-
const http = require('http');
4-
const util = require('util');
5-
6-
const { Formidable } = require('../src/index');
75

86
const server = http.createServer((req, res) => {
97
if (req.url === '/') {
@@ -16,7 +14,7 @@ const server = http.createServer((req, res) => {
1614
</form>
1715
`);
1816
} else if (req.url === '/post') {
19-
const form = new Formidable();
17+
const form = formidable();
2018
const fields = [];
2119

2220
form

0 commit comments

Comments
 (0)