Skip to content

Commit

Permalink
fix(form-data): fix ssr error due to window object access (#373)
Browse files Browse the repository at this point in the history
* fix(form-data): override import from package root

* fix(httpsnippet): linting errors
  • Loading branch information
vaibhavrajsingh2001 authored Oct 16, 2024
1 parent 8a1bc90 commit 66b587b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/httpsnippet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { map as eventStreamMap } from 'event-stream';
import FormData from 'form-data';
import FormData from 'form-data/lib/form_data';
import { Param, PostDataCommon, Request as NpmHarRequest } from 'har-format';
import { validateRequest } from 'har-validator-compiled';
import { stringify as queryStringify } from 'querystring';
Expand All @@ -13,6 +13,13 @@ import { ClientId, TargetId, targets } from './targets/targets';
export { availableTargets, extname } from './helpers/utils';
export { addTarget, addTargetClient } from './targets/targets';

// We're implementing the logic for which FormData object to use, ourselves.
// This allows us to use the native FormData object in the browser and the `form-data` module in Node,
// instead of relying on the package entrypoint to handle that.
const resolveFormData =
// @ts-expect-error — we're only using window.FormData if it exists
typeof window !== 'undefined' && window.FormData ? window.FormData : FormData;

const DEBUG_MODE = false;

const debug = {
Expand Down Expand Up @@ -174,7 +181,7 @@ export class HTTPSnippet {
request.postData.mimeType = 'multipart/form-data';

if (request.postData?.params) {
const form = new FormData();
const form = new resolveFormData();

// The `form-data` module returns one of two things: a native FormData object, or its own polyfill
// Since the polyfill does not support the full API of the native FormData object, when this library is running in a browser environment it'll fail on two things:
Expand All @@ -186,15 +193,13 @@ export class HTTPSnippet {
// Since the native FormData object is iterable, we easily detect what version of `form-data` we're working with here to allow `multipart/form-data` requests to be compiled under both browser and Node environments.
//
// This hack is pretty awful but it's the only way we can use this library in the browser as if we code this against just the native FormData object, we can't polyfill that back into Node because Blob and File objects, which something like `formdata-polyfill` requires, don't exist there.
// @ts-expect-error TODO
const isNativeFormData = typeof form[Symbol.iterator] === 'function';

// TODO: THIS ABSOLUTELY MUST BE REMOVED.
// IT BREAKS SOME USE-CASES FOR MULTIPART FORMS THAT DEPEND ON BEING ABLE TO SET THE BOUNDARY.
// easter egg
const boundary = '---011000010111000001101001'; // this is binary for "api". yep.
if (!isNativeFormData) {
// @ts-expect-error THIS IS WRONG. VERY WRONG.
form._boundary = boundary;
}

Expand All @@ -205,16 +210,13 @@ export class HTTPSnippet {

if (isNativeFormData) {
if (isBlob(value)) {
// @ts-expect-error TODO
form.append(name, value, filename);
} else {
form.append(name, value);
}
} else {
form.append(name, value, {
// @ts-expect-error TODO
filename,
// @ts-expect-error TODO
contentType: param.contentType || null,
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/types/form-data.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'form-data/lib/form_data' {
import FormData from 'form-data';
export default FormData;
}

0 comments on commit 66b587b

Please sign in to comment.