-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
15a2a26
commit 974a1c9
Showing
4 changed files
with
193 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use strict' | ||
|
||
const { randomUUID } = require('node:crypto') | ||
const { Readable } = require('node:stream') | ||
|
||
let textEncoder | ||
|
||
function isFormDataLike (payload) { | ||
return ( | ||
payload && | ||
typeof payload === 'object' && | ||
typeof payload.append === 'function' && | ||
typeof payload.delete === 'function' && | ||
typeof payload.get === 'function' && | ||
typeof payload.getAll === 'function' && | ||
typeof payload.has === 'function' && | ||
typeof payload.set === 'function' && | ||
payload[Symbol.toStringTag] === 'FormData' | ||
) | ||
} | ||
|
||
/* | ||
partial code extraction and refactoring of `undici`. | ||
MIT License. https://github.com/nodejs/undici/blob/043d8f1a89f606b1db259fc71f4c9bc8eb2aa1e6/lib/web/fetch/LICENSE | ||
Reference https://github.com/nodejs/undici/blob/043d8f1a89f606b1db259fc71f4c9bc8eb2aa1e6/lib/web/fetch/body.js#L102-L168 | ||
*/ | ||
function formDataToStream (formdata) { | ||
// lazy creation of TextEncoder | ||
textEncoder = textEncoder ?? new TextEncoder() | ||
|
||
// we expect the function argument must be FormData | ||
const boundary = `----formdata-${randomUUID()}` | ||
const prefix = `--${boundary}\r\nContent-Disposition: form-data` | ||
|
||
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ | ||
const escape = (str) => | ||
str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') | ||
const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') | ||
|
||
const linebreak = new Uint8Array([13, 10]) // '\r\n' | ||
|
||
async function * asyncIterator () { | ||
for (const [name, value] of formdata) { | ||
if (typeof value === 'string') { | ||
// header | ||
yield textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"\r\n\r\n`) | ||
// body | ||
yield textEncoder.encode(`${normalizeLinefeeds(value)}\r\n`) | ||
} else { | ||
let header = `${prefix}; name="${escape(normalizeLinefeeds(name))}"` | ||
value.name && (header += `; filename="${escape(value.name)}"`) | ||
header += `\r\nContent-Type: ${value.type || 'application/octet-stream'}\r\n\r\n` | ||
// header | ||
yield textEncoder.encode(header) | ||
// body | ||
/* istanbul ignore else */ | ||
if (value.stream) { | ||
yield * value.stream() | ||
} else { | ||
// shouldn't be here since Blob / File should provide .stream | ||
// and FormData always convert to USVString | ||
/* istanbul ignore next */ | ||
yield value | ||
} | ||
yield linebreak | ||
} | ||
} | ||
// end | ||
yield textEncoder.encode(`--${boundary}--`) | ||
} | ||
|
||
const stream = Readable.from(asyncIterator()) | ||
|
||
return { | ||
stream, | ||
contentType: `multipart/form-data; boundary=${boundary}` | ||
} | ||
} | ||
|
||
module.exports.isFormDataLike = isFormDataLike | ||
module.exports.formDataToStream = formDataToStream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters