Skip to content

Commit a212f26

Browse files
Merge pull request #380 from mailgun/fix-node-native-form-data-issue
Node.js builtin FormData issue
2 parents 42768e5 + f00dd57 commit a212f26

File tree

4 files changed

+178
-37
lines changed

4 files changed

+178
-37
lines changed

dist/Classes/common/FormDataBuilder.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ declare class FormDataBuilder {
44
private FormDataConstructor;
55
constructor(FormDataConstructor: InputFormData);
66
createFormData(data: any): NodeFormData | FormData;
7-
private isNodeFormData;
7+
private isFormDataPackage;
88
private getAttachmentOptions;
99
private addMimeDataToFD;
1010
private addFilesToFD;

dist/mailgun.node.js

Lines changed: 61 additions & 12 deletions
Large diffs are not rendered by default.

dist/mailgun.web.js

Lines changed: 61 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/Classes/common/FormDataBuilder.ts

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as NodeFormData from 'form-data';
2-
import { InputFormData } from '../../Types/Common';
2+
import { APIErrorOptions, InputFormData } from '../../Types/Common';
3+
import APIError from './Error';
34

45
class FormDataBuilder {
56
private FormDataConstructor: InputFormData;
@@ -31,8 +32,8 @@ class FormDataBuilder {
3132
return formData;
3233
}
3334

34-
private isNodeFormData(formDataInstance: NodeFormData | FormData)
35-
: formDataInstance is NodeFormData {
35+
private isFormDataPackage(formDataInstance: NodeFormData | FormData)
36+
: boolean {
3637
return (<NodeFormData>formDataInstance).getHeaders !== undefined;
3738
}
3839

@@ -63,14 +64,37 @@ class FormDataBuilder {
6364
data: Buffer | Blob | string,
6465
formDataInstance: NodeFormData | FormData
6566
): void {
66-
if (Buffer.isBuffer(data) || typeof data === 'string') {
67+
if (typeof data === 'string') { // if string only two parameters should be used.
68+
formDataInstance.append(key, data as string);
69+
return;
70+
}
71+
72+
if (this.isFormDataPackage(formDataInstance)) { // form-data package is used
6773
const nodeFormData = formDataInstance as NodeFormData;
68-
const preparedData = typeof data === 'string' ? Buffer.from(data) : data;
69-
nodeFormData.append(key, preparedData, { filename: 'MimeMessage' });
70-
} else {
71-
const browserFormData = formDataInstance as FormData;
72-
browserFormData.append(key, data, 'MimeMessage');
74+
nodeFormData.append(key, data, { filename: 'MimeMessage' });
75+
return;
76+
}
77+
78+
if (typeof Blob !== undefined) { // either node > 18 or browser
79+
const browserFormData = formDataInstance as FormData; // Browser compliant FormData
80+
if (data instanceof Blob) {
81+
browserFormData.append(key, data, 'MimeMessage');
82+
return;
83+
}
84+
if (typeof Buffer !== 'undefined') { // node environment
85+
if (Buffer.isBuffer(data)) {
86+
const blobInstance = new Blob([data]);
87+
browserFormData.append(key, blobInstance, 'MimeMessage');
88+
return;
89+
}
90+
}
7391
}
92+
93+
throw new APIError({
94+
status: 400,
95+
statusText: `Unknown data type for ${key} property`,
96+
body: 'The mime data should have type of Buffer, String or Blob'
97+
} as APIErrorOptions);
7498
}
7599

76100
private addFilesToFD(
@@ -88,11 +112,30 @@ class FormDataBuilder {
88112
const objData = isStreamData ? obj : obj.data;
89113
// getAttachmentOptions should be called with obj parameter to prevent loosing filename
90114
const options = this.getAttachmentOptions(obj);
91-
if (this.isNodeFormData(formData)) {
92-
formData.append(key, objData, options);
115+
if (typeof objData === 'string') {
116+
formData.append(key, objData as string);
117+
return;
118+
}
119+
120+
if (this.isFormDataPackage(formData)) {
121+
const fd = formData as NodeFormData;
122+
fd.append(key, objData, options);
93123
return;
94124
}
95-
formData.append(key, objData, options.filename);
125+
126+
if (typeof Blob !== undefined) { // either node > 18 or browser
127+
const browserFormData = formDataInstance as FormData; // Browser compliant FormData
128+
if (objData instanceof Blob) {
129+
browserFormData.append(key, objData, options.filename);
130+
return;
131+
}
132+
if (typeof Buffer !== 'undefined') { // node environment
133+
if (Buffer.isBuffer(objData)) {
134+
const blobInstance = new Blob([objData]);
135+
browserFormData.append(key, blobInstance, options.filename);
136+
}
137+
}
138+
}
96139
};
97140

98141
if (Array.isArray(value)) {

0 commit comments

Comments
 (0)