Skip to content

Commit

Permalink
feat: merge 3.x (#767)
Browse files Browse the repository at this point in the history
* 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 <dashrushikesh1121@gmail.com>
Co-authored-by: Jimmy Wärting <jimmy@warting.se>
  • Loading branch information
3 people authored Oct 30, 2021
1 parent 1c30ec6 commit 70517da
Show file tree
Hide file tree
Showing 57 changed files with 2,163 additions and 2,451 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

### Unreleased 3.1.1

* feat: handle top level json array, string and number

### Unreleased 3.1

* feat: add firstValues, readBooleans helpers

### Unreleased 3.0

* feat: remove options.multiples ([730](https://github.com/node-formidable/formidable/pull/730))
* use modern URLSearchParams https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams internally
* files and fields values are always arrays
* fields with [] in the name do not receive special treatment
* remove unused qs and querystring dependency
* feat: Use ES modules ([727](https://github.com/node-formidable/formidable/pull/727))
* options.enabledPlugins must contain the plugin themselves instead of the plugins names


### Unreleased (`canary` & `dev` dist-tags)

* feat: add options.filter ([#716](https://github.com/node-formidable/formidable/pull/716))
Expand Down
106 changes: 67 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,11 @@ already be included. Check the examples below and the [examples/](https://github
```sh
# v2
npm install formidable
npm install formidable@latest
npm install formidable@v2

## 3.x
npm install formidable@3.x
```


# or v3
npm install formidable@v3
Expand All @@ -98,13 +101,13 @@ Parse an incoming file upload, with the
[Node.js's built-in `http` module](https://nodejs.org/api/http.html).
```js
const http = require('http');
const formidable = require('formidable');
import http from 'http';
import formidable from 'formidable';
const server = http.createServer((req, res) => {
if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
// parse a file upload
const form = formidable({ multiples: true });
const form = formidable({});
form.parse(req, (err, fields, files) => {
if (err) {
Expand Down Expand Up @@ -146,8 +149,8 @@ Or try the
[examples/with-express.js](https://github.com/node-formidable/formidable/blob/master/examples/with-express.js)

```js
const express = require('express');
const formidable = require('formidable');
import express from 'express';
import formidable from 'formidable';

const app = express();

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

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

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

```js
const Koa = require('koa');
const formidable = require('formidable');
import Koa from 'Koa';
import formidable from 'formidable';

const app = new Koa();

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

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

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

```js
const formidable = require('formidable');
const form = formidable(options);

// or
const { formidable } = require('formidable');
import formidable from 'formidable';
const form = formidable(options);

// or
const { IncomingForm } = require('formidable');
const form = new IncomingForm(options);

// or
const { Formidable } = require('formidable');
const form = new Formidable(options);
```

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

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

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

where part can be decomposed as

```js
const { originalFilename, mimetype} = part;
```

_**Note:** If this size of combined fields, or size of some file is exceeded, an
`'error'` event is fired._

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

```js
const formidable = require('formidable');

const form = formidable({ multiples: true, uploadDir: __dirname });
const form = formidable({ uploadDir: __dirname });

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

```js
const formidable = require('formidable');

const form = formidable({ keepExtensions: true });

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

```js
const { Formidable } = require('formidable');

const form = new Formidable({
import formidable, {octetstream, querystring, json} from "formidable";
const form = formidable({
hashAlgorithm: 'sha1',
enabledPlugins: ['octetstream', 'querystring', 'json'],
enabledPlugins: [octetstream, querystring, json],
});
```

Expand Down Expand Up @@ -631,7 +618,7 @@ requests.
#### `'progress'`

Emitted after each incoming chunk of data that has been parsed. Can be used to
roll your own progress bar.
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 =`

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


### Helpers

#### firstValues

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)

```js
import { firstValues } from 'formidable/src/helpers/firstValues.js';

// ...
form.parse(request, async (error, fieldsMultiple, files) => {
if (error) {
//...
}
const exceptions = ['thisshouldbeanarray'];
const fieldsSingle = firstValues(form, fieldsMultiple, exceptions);
// ...
```
#### readBooleans
Html form input type="checkbox" only send the value "on" if checked,
convert it to booleans for each input that is expected to be sent as a checkbox, only use after firstValues or similar was called.
```js
import { firstValues } from 'formidable/src/helpers/firstValues.js';
import { readBooleans } from 'formidable/src/helpers/readBooleans.js';

// ...
form.parse(request, async (error, fieldsMultiple, files) => {
if (error) {
//...
}
const fieldsSingle = firstValues(form, fieldsMultiple);

const expectedBooleans = ['checkbox1', 'wantsNewsLetter', 'hasACar'];
const fieldsWithBooleans = readBooleans(fieldsSingle, expectedBooleans);
// ...
```
## Changelog
[./CHANGELOG.md](./CHANGELOG.md)
Expand Down
42 changes: 42 additions & 0 deletions examples/express-middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import express from 'express';
import formidable from '../src/index.js';

const app = express();

// middlewares that populates req.fields and req.body
const formMiddleWare = (req, res, next) => {
const form = formidable({});

form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
req.fields = fields;
req.files = files;
next();
});
};

app.get('/', (req, res) => {
res.send(`
<h2>With <code>"express"</code> npm package</h2>
<form action="/api/upload" enctype="multipart/form-data" method="post">
<div>Text field title: <input type="text" name="title" /></div>
<div>File: <input type="file" name="someExpressFiles" multiple="multiple"></div>
<input type="submit" value="Upload">
</form>
`);
});

// use middleware
app.post('/api/upload', formMiddleWare, (req, res, next) => {
res.json({
fields: req.fields,
files: req.files,
});
});

app.listen(3000, () => {
console.log('Server listening on http://localhost:3000 ...');
});
7 changes: 3 additions & 4 deletions examples/json.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';
import http from 'http';
import util from 'util';
import formidable from '../src/index.js';

const http = require('http');
const util = require('util');
const { formidable } = require('../src/index');

const PORT = 3000;
const server = http.createServer((req, res) => {
Expand Down
7 changes: 3 additions & 4 deletions examples/log-file-content-to-console.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';
import http from 'http';
import { Writable } from 'stream';
import formidable from '../src/index.js';

const http = require('http');
const { Writable } = require('stream');
const formidable = require('../src/index');

const server = http.createServer((req, res) => {
if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
Expand Down
3 changes: 1 addition & 2 deletions examples/multipart-parser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';
import { MultipartParser } from '../src/index.js';

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

// hand crafted multipart
const boundary = '--abcxyz';
Expand Down
9 changes: 4 additions & 5 deletions examples/multiples.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';
import http from 'http';
import os from 'os';
import formidable from '../src/index.js';

const os = require('os');
const http = require('http');
const { Formidable } = require('../src/index');

const server = http.createServer((req, res) => {
if (req.url === '/') {
Expand All @@ -28,7 +27,7 @@ const server = http.createServer((req, res) => {
</form>
`);
} else if (req.url === '/upload') {
const form = new Formidable({ multiples: true, uploadDir: os.tmpdir() });
const form = formidable({ uploadDir: os.tmpdir() });

form.parse(req, (err, fields, files) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
Expand Down
10 changes: 4 additions & 6 deletions examples/store-files-on-s3.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// To test this example you have to install aws-sdk nodejs package and create a bucket named "demo-bucket"

'use strict';
import http from 'http';
import { PassThrough } from 'stream';
import AWS from 'aws-sdk';
import formidable from '../src/index.js';

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

const s3Client = new AWS.S3({
credentials: {
Expand Down
12 changes: 5 additions & 7 deletions examples/upload-multiple-files.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict';
import http from 'http';
import util from 'util';
import os from 'os';
import formidable from '../src/index.js';

const os = require('os');
const http = require('http');
const util = require('util');

const { Formidable } = require('../src/index');

const server = http.createServer((req, res) => {
if (req.url === '/') {
Expand All @@ -17,7 +15,7 @@ const server = http.createServer((req, res) => {
</form>
`);
} else if (req.url === '/upload') {
const form = new Formidable({ multiples: true, uploadDir: os.tmpdir() });
const form = formidable({ uploadDir: os.tmpdir() });
const files = [];
const fields = [];

Expand Down
10 changes: 4 additions & 6 deletions examples/urlencoded-no-enctype.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';
import http from 'http';
import util from 'util';
import formidable from '../src/index.js';

const http = require('http');
const util = require('util');

const { Formidable } = require('../src/index');

const server = http.createServer((req, res) => {
if (req.url === '/') {
Expand All @@ -16,7 +14,7 @@ const server = http.createServer((req, res) => {
</form>
`);
} else if (req.url === '/post') {
const form = new Formidable();
const form = formidable();
const fields = [];

form
Expand Down
Loading

0 comments on commit 70517da

Please sign in to comment.