Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Body): Added support for BodyMixin.formData() and constructing bodies with FormData #1314

Merged
merged 34 commits into from Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
73a19ff
Added support for body toFormData
jimmywarting Sep 26, 2021
9f6c298
added formData method
jimmywarting Sep 26, 2021
fe0de91
remove discouraged buffer
jimmywarting Sep 26, 2021
78f32f3
lint + fix
jimmywarting Sep 26, 2021
0f6e10d
xo fix
jimmywarting Sep 26, 2021
7b514a3
latest v
jimmywarting Sep 26, 2021
0f2f9bd
add type support
jimmywarting Sep 26, 2021
57ce9eb
use // fallsthrough instead
jimmywarting Sep 28, 2021
3a9c1bd
hoisted the throw/if conditions
jimmywarting Sep 28, 2021
560320d
update comment
jimmywarting Sep 28, 2021
7384b52
rm unused PARSER_UNINITIALIZED
jimmywarting Sep 28, 2021
58005c3
rm PART_END
jimmywarting Sep 28, 2021
d472c94
added comment/suggestion
jimmywarting Sep 28, 2021
8c869e5
throw instead of returning
jimmywarting Sep 28, 2021
b06dd35
define every function as noop
jimmywarting Sep 29, 2021
405bcc0
rm unnecessary isFormData
jimmywarting Sep 29, 2021
0881b13
remove unnecessary and invalid jsdoc
jimmywarting Sep 29, 2021
6a6b949
misc
jimmywarting Sep 29, 2021
d98efc2
re-added test for formdata-node support
jimmywarting Sep 29, 2021
1058f55
lint stuff
jimmywarting Sep 29, 2021
5a3b042
moved formdata-node to devDep
jimmywarting Sep 29, 2021
a378d7a
bump formdata for null comparison
jimmywarting Sep 30, 2021
87d1bbb
no short name for formData
jimmywarting Oct 1, 2021
2145fd8
Merge branch 'main' into feature/body-formData
jimmywarting Oct 8, 2021
b267584
lint fix
jimmywarting Oct 8, 2021
c9a1a57
bring back return
jimmywarting Oct 15, 2021
d3b3899
throw on default
jimmywarting Oct 15, 2021
bcec478
remove some code comments
jimmywarting Oct 15, 2021
d331ad8
change the first state
jimmywarting Oct 15, 2021
81dc639
better name
jimmywarting Oct 15, 2021
2882e39
remove start state
jimmywarting Oct 15, 2021
cfaeb63
shorter comments
jimmywarting Oct 16, 2021
9e59b14
Merge branch 'main' into feature/body-formData
jimmywarting Oct 28, 2021
be7530b
Merge branch 'main' into feature/body-formData
jimmywarting Nov 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions @types/index.d.ts
Expand Up @@ -95,6 +95,7 @@ export type BodyInit =
| Blob
| Buffer
| URLSearchParams
| FormData
| NodeJS.ReadableStream
| string;
declare class BodyMixin {
Expand All @@ -106,6 +107,7 @@ declare class BodyMixin {

buffer(): Promise<Buffer>;
arrayBuffer(): Promise<ArrayBuffer>;
formData(): Promise<FormData>;
blob(): Promise<Blob>;
json(): Promise<unknown>;
text(): Promise<string>;
Expand Down
10 changes: 2 additions & 8 deletions README.md
Expand Up @@ -712,6 +712,8 @@ A boolean property for if this body has been consumed. Per the specs, a consumed

#### body.arrayBuffer()

#### body.formData()

#### body.blob()

#### body.json()
Expand All @@ -724,14 +726,6 @@ A boolean property for if this body has been consumed. Per the specs, a consumed

Consume the body and return a promise that will resolve to one of these formats.

#### body.buffer()

<small>_(node-fetch extension)_</small>

- Returns: `Promise<Buffer>`

Consume the body and return a promise that will resolve to a Buffer.

<a id="class-fetcherror"></a>

### Class: FetchError
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- other: Deprecated/Discourage [form-data](https://www.npmjs.com/package/form-data) and body.buffer() (#1212)
- fix: Normalize `Body.body` into a `node:stream` (#924)
- feat: Added support for `Body.formData()`

## v3.0.0

Expand Down
6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -55,15 +55,15 @@
"coveralls": "^3.1.0",
"delay": "^5.0.0",
"form-data": "^4.0.0",
"formdata-node": "^3.5.4",
"mocha": "^8.3.2",
"p-timeout": "^5.0.0",
"tsd": "^0.14.0",
"xo": "^0.39.1"
},
"dependencies": {
"data-uri-to-buffer": "^3.0.1",
"fetch-blob": "^3.1.2"
"fetch-blob": "^3.1.2",
"formdata-polyfill": "^4.0.8"
},
"tsd": {
"cwd": "@types",
Expand Down Expand Up @@ -91,6 +91,8 @@
"unicorn/numeric-separators-style": 0,
"unicorn/explicit-length-check": 0,
"capitalized-comments": 0,
"node/no-unsupported-features/es-syntax": 0,
"no-fallthrough": 0,
jimmywarting marked this conversation as resolved.
Show resolved Hide resolved
"@typescript-eslint/member-ordering": 0
},
"overrides": [
Expand Down
29 changes: 21 additions & 8 deletions src/body.js
Expand Up @@ -9,10 +9,10 @@ import Stream, {PassThrough} from 'stream';
import {types, deprecate} from 'util';

import Blob from 'fetch-blob';
import {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';
jimmywarting marked this conversation as resolved.
Show resolved Hide resolved

import {FetchError} from './errors/fetch-error.js';
import {FetchBaseError} from './errors/base.js';
import {formDataIterator, getBoundary, getFormDataLength} from './utils/form-data.js';
import {isBlob, isURLSearchParameters, isFormData} from './utils/is.js';

const INTERNALS = Symbol('Body internals');
Expand Down Expand Up @@ -52,8 +52,8 @@ export default class Body {
// Body is stream
} else if (isFormData(body)) {
// Body is an instance of formdata-node
boundary = `nodefetchformdataboundary${getBoundary()}`;
body = Stream.Readable.from(formDataIterator(body, boundary));
body = formDataToBlob(body);
boundary = body.type.split('=')[1];
jimmywarting marked this conversation as resolved.
Show resolved Hide resolved
} else {
// None of the above
// coerce to string then buffer
Expand Down Expand Up @@ -105,6 +105,24 @@ export default class Body {
return buffer.slice(byteOffset, byteOffset + byteLength);
}

async formData() {
const ct = this.headers.get('content-type');

if (ct.startsWith('application/x-www-form-urlencoded')) {
const fd = new FormData();
jimmywarting marked this conversation as resolved.
Show resolved Hide resolved
const parameters = new URLSearchParams(await this.text());

for (const [name, value] of parameters) {
fd.append(name, value);
}

return fd;
}

const {toFormData} = await import('./utils/multipart-parser.js');
return toFormData(this.body, ct);
}

/**
* Return raw response as Blob
*
Expand Down Expand Up @@ -352,11 +370,6 @@ export const getTotalBytes = request => {
return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null;
}

// Body is a spec-compliant FormData
if (isFormData(body)) {
return getFormDataLength(request[INTERNALS].boundary);
jimmywarting marked this conversation as resolved.
Show resolved Hide resolved
}

// Body is stream
return null;
};
Expand Down
2 changes: 1 addition & 1 deletion src/response.js
Expand Up @@ -29,7 +29,7 @@ export default class Response extends Body {
const headers = new Headers(options.headers);

if (body !== null && !headers.has('Content-Type')) {
const contentType = extractContentType(body);
const contentType = extractContentType(body, this);
if (contentType) {
headers.append('Content-Type', contentType);
}
Expand Down
78 changes: 0 additions & 78 deletions src/utils/form-data.js

This file was deleted.