55 lines
2.2 KiB
JavaScript
55 lines
2.2 KiB
JavaScript
import { flattenAndStringify, stringifyRequestData } from './utils.js';
|
|
// Method for formatting HTTP body for the multipart/form-data specification
|
|
// Mostly taken from Fermata.js
|
|
// https://github.com/natevw/fermata/blob/5d9732a33d776ce925013a265935facd1626cc88/fermata.js#L315-L343
|
|
const multipartDataGenerator = (method, data, headers) => {
|
|
const segno = (Math.round(Math.random() * 1e16) + Math.round(Math.random() * 1e16)).toString();
|
|
headers['Content-Type'] = `multipart/form-data; boundary=${segno}`;
|
|
const textEncoder = new TextEncoder();
|
|
let buffer = new Uint8Array(0);
|
|
const endBuffer = textEncoder.encode('\r\n');
|
|
function push(l) {
|
|
const prevBuffer = buffer;
|
|
const newBuffer = l instanceof Uint8Array ? l : new Uint8Array(textEncoder.encode(l));
|
|
buffer = new Uint8Array(prevBuffer.length + newBuffer.length + 2);
|
|
buffer.set(prevBuffer);
|
|
buffer.set(newBuffer, prevBuffer.length);
|
|
buffer.set(endBuffer, buffer.length - 2);
|
|
}
|
|
function q(s) {
|
|
return `"${s.replace(/"|"/g, '%22').replace(/\r\n|\r|\n/g, ' ')}"`;
|
|
}
|
|
const flattenedData = flattenAndStringify(data);
|
|
for (const k in flattenedData) {
|
|
const v = flattenedData[k];
|
|
push(`--${segno}`);
|
|
if (Object.prototype.hasOwnProperty.call(v, 'data')) {
|
|
const typedEntry = v;
|
|
push(`Content-Disposition: form-data; name=${q(k)}; filename=${q(typedEntry.name || 'blob')}`);
|
|
push(`Content-Type: ${typedEntry.type || 'application/octet-stream'}`);
|
|
push('');
|
|
push(typedEntry.data);
|
|
}
|
|
else {
|
|
push(`Content-Disposition: form-data; name=${q(k)}`);
|
|
push('');
|
|
push(v);
|
|
}
|
|
}
|
|
push(`--${segno}--`);
|
|
return buffer;
|
|
};
|
|
export function multipartRequestDataProcessor(method, data, headers, callback) {
|
|
data = data || {};
|
|
if (method !== 'POST') {
|
|
return callback(null, stringifyRequestData(data));
|
|
}
|
|
this._stripe._platformFunctions
|
|
.tryBufferData(data)
|
|
.then((bufferedData) => {
|
|
const buffer = multipartDataGenerator(method, bufferedData, headers);
|
|
return callback(null, buffer);
|
|
})
|
|
.catch((err) => callback(err, null));
|
|
}
|