From 0d9ba36de84996b9a598bf738acafbc30eac054a Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Thu, 6 Jul 2023 15:49:24 +0300 Subject: [PATCH 1/4] fix(file-upload-form): fixed form data for node env --- src/file/generateFileUploadForm.ts | 4 +- src/file/spec/generateFileUploadForm.spec.ts | 111 +++++++++++++------ src/job-execution/SasjsJobExecutor.ts | 5 +- src/job-execution/WebJobExecutor.ts | 8 +- src/utils/getFormData.ts | 5 + src/utils/index.ts | 1 + src/utils/spec/getFormData.spec.ts | 20 ++++ 7 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 src/utils/getFormData.ts create mode 100644 src/utils/spec/getFormData.spec.ts diff --git a/src/file/generateFileUploadForm.ts b/src/file/generateFileUploadForm.ts index d88f13d..0fc695f 100644 --- a/src/file/generateFileUploadForm.ts +++ b/src/file/generateFileUploadForm.ts @@ -26,12 +26,12 @@ export const generateFileUploadForm = ( ) } - if (typeof FormData === 'undefined' && formData instanceof NodeFormData) { + if (formData instanceof NodeFormData) { formData.append(name, csv, { filename: `${name}.csv`, contentType: 'application/csv' }) - } else { + } else if (formData instanceof FormData) { const file = new Blob([csv], { type: 'application/csv' }) diff --git a/src/file/spec/generateFileUploadForm.spec.ts b/src/file/spec/generateFileUploadForm.spec.ts index fb97fb9..62db1d5 100644 --- a/src/file/spec/generateFileUploadForm.spec.ts +++ b/src/file/spec/generateFileUploadForm.spec.ts @@ -1,4 +1,6 @@ import { generateFileUploadForm } from '../generateFileUploadForm' +import * as NodeFormData from 'form-data' +import { convertToCSV } from '../../utils/convertToCsv' describe('generateFileUploadForm', () => { beforeAll(() => { @@ -11,44 +13,89 @@ describe('generateFileUploadForm', () => { ;(global as any).Blob = BlobMock }) - it('should generate file upload form from data', () => { - const formData = new FormData() - const testTable = 'sometable' - const testTableWithNullVars: { [key: string]: any } = { - [testTable]: [ - { var1: 'string', var2: 232, nullvar: 'A' }, - { var1: 'string', var2: 232, nullvar: 'B' }, - { var1: 'string', var2: 232, nullvar: '_' }, - { var1: 'string', var2: 232, nullvar: 0 }, - { var1: 'string', var2: 232, nullvar: 'z' }, - { var1: 'string', var2: 232, nullvar: null } - ], - [`$${testTable}`]: { formats: { var1: '$char12.', nullvar: 'best.' } } - } - const tableName = Object.keys(testTableWithNullVars).filter((key: string) => - Array.isArray(testTableWithNullVars[key]) - )[0] + describe('browser', () => { + it('should generate file upload form from data', () => { + const formData = new FormData() + const testTable = 'sometable' + const testTableWithNullVars: { [key: string]: any } = { + [testTable]: [ + { var1: 'string', var2: 232, nullvar: 'A' }, + { var1: 'string', var2: 232, nullvar: 'B' }, + { var1: 'string', var2: 232, nullvar: '_' }, + { var1: 'string', var2: 232, nullvar: 0 }, + { var1: 'string', var2: 232, nullvar: 'z' }, + { var1: 'string', var2: 232, nullvar: null } + ], + [`$${testTable}`]: { formats: { var1: '$char12.', nullvar: 'best.' } } + } + const tableName = Object.keys(testTableWithNullVars).filter( + (key: string) => Array.isArray(testTableWithNullVars[key]) + )[0] - jest.spyOn(formData, 'append').mockImplementation(() => {}) + jest.spyOn(formData, 'append').mockImplementation(() => {}) - generateFileUploadForm(formData, testTableWithNullVars) + generateFileUploadForm(formData, testTableWithNullVars) - expect(formData.append).toHaveBeenCalledOnce() - expect(formData.append).toHaveBeenCalledWith( - tableName, - {}, - `${tableName}.csv` - ) + expect(formData.append).toHaveBeenCalledOnce() + expect(formData.append).toHaveBeenCalledWith( + tableName, + {}, + `${tableName}.csv` + ) + }) + + it('should throw an error if too large string was provided', () => { + const formData = new FormData() + const data = { testTable: [{ var1: 'z'.repeat(32765 + 1) }] } + + expect(() => generateFileUploadForm(formData, data)).toThrow( + new Error( + 'The max length of a string value in SASjs is 32765 characters.' + ) + ) + }) }) - it('should throw an error if too large string was provided', () => { - const formData = new FormData() - const data = { testTable: [{ var1: 'z'.repeat(32765 + 1) }] } + describe('node', () => { + it('should generate file upload form from data', () => { + const formData = new NodeFormData() + const testTable = 'sometable' + const testTableWithNullVars: { [key: string]: any } = { + [testTable]: [ + { var1: 'string', var2: 232, nullvar: 'A' }, + { var1: 'string', var2: 232, nullvar: 'B' }, + { var1: 'string', var2: 232, nullvar: '_' }, + { var1: 'string', var2: 232, nullvar: 0 }, + { var1: 'string', var2: 232, nullvar: 'z' }, + { var1: 'string', var2: 232, nullvar: null } + ], + [`$${testTable}`]: { formats: { var1: '$char12.', nullvar: 'best.' } } + } + const tableName = Object.keys(testTableWithNullVars).filter( + (key: string) => Array.isArray(testTableWithNullVars[key]) + )[0] + const csv = convertToCSV(testTableWithNullVars, tableName) - expect(() => generateFileUploadForm(formData, data)).toThrow( - new Error( - 'The max length of a string value in SASjs is 32765 characters.' + jest.spyOn(formData, 'append').mockImplementation(() => {}) + + generateFileUploadForm(formData, testTableWithNullVars) + + expect(formData.append).toHaveBeenCalledOnce() + expect(formData.append).toHaveBeenCalledWith(tableName, csv, { + contentType: 'application/csv', + filename: `${tableName}.csv` + }) + }) + + it('should throw an error if too large string was provided', () => { + const formData = new NodeFormData() + const data = { testTable: [{ var1: 'z'.repeat(32765 + 1) }] } + + expect(() => generateFileUploadForm(formData, data)).toThrow( + new Error( + 'The max length of a string value in SASjs is 32765 characters.' + ) ) - ) + }) }) }) diff --git a/src/job-execution/SasjsJobExecutor.ts b/src/job-execution/SasjsJobExecutor.ts index 6b768f8..0aecbf4 100644 --- a/src/job-execution/SasjsJobExecutor.ts +++ b/src/job-execution/SasjsJobExecutor.ts @@ -10,8 +10,8 @@ import { LoginRequiredError } from '../types/errors' import { generateFileUploadForm } from '../file/generateFileUploadForm' - import { RequestClient } from '../request/RequestClient' +import { getFormData } from '../utils' import { isRelativePath, @@ -53,8 +53,7 @@ export class SasjsJobExecutor extends BaseJobExecutor { * Use the available form data object (FormData in Browser, NodeFormData in * Node) */ - let formData = - typeof FormData === 'undefined' ? new NodeFormData() : new FormData() + let formData = getFormData() if (data) { // file upload approach diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index fe52903..2fd65e5 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -16,10 +16,11 @@ import { SASViyaApiClient } from '../SASViyaApiClient' import { isRelativePath, parseSasViyaDebugResponse, - appendExtraResponseAttributes + appendExtraResponseAttributes, + parseWeboutResponse, + getFormData } from '../utils' import { BaseJobExecutor } from './JobExecutor' -import { parseWeboutResponse } from '../utils/parseWeboutResponse' export interface WaitingRequstPromise { promise: Promise | null @@ -112,8 +113,7 @@ export class WebJobExecutor extends BaseJobExecutor { * Use the available form data object (FormData in Browser, NodeFormData in * Node) */ - let formData = - typeof FormData === 'undefined' ? new NodeFormData() : new FormData() + let formData = getFormData() if (data) { const stringifiedData = JSON.stringify(data) diff --git a/src/utils/getFormData.ts b/src/utils/getFormData.ts new file mode 100644 index 0000000..8290af3 --- /dev/null +++ b/src/utils/getFormData.ts @@ -0,0 +1,5 @@ +import { isNode } from './' +import * as NodeFormData from 'form-data' + +export const getFormData = () => + isNode() ? new NodeFormData() : new FormData() diff --git a/src/utils/index.ts b/src/utils/index.ts index 4f02fc8..68def1a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -20,3 +20,4 @@ export * from './parseWeboutResponse' export * from './serialize' export * from './splitChunks' export * from './validateInput' +export * from './getFormData' diff --git a/src/utils/spec/getFormData.spec.ts b/src/utils/spec/getFormData.spec.ts new file mode 100644 index 0000000..1fd192c --- /dev/null +++ b/src/utils/spec/getFormData.spec.ts @@ -0,0 +1,20 @@ +import { getFormData } from '..' +import * as isNodeModule from '../isNode' +import * as NodeFormData from 'form-data' + +describe('getFormData', () => { + it('should return NodeFormData if environment is Node', () => { + jest.spyOn(isNodeModule, 'isNode').mockImplementation(() => true) + + expect(getFormData() instanceof NodeFormData).toEqual(true) + }) + + it('should return FormData if environment is not Node', () => { + const formDataMock = () => {} + ;(global as any).FormData = formDataMock + + jest.spyOn(isNodeModule, 'isNode').mockImplementation(() => false) + + expect(getFormData() instanceof FormData).toEqual(true) + }) +}) From 104d1b88b3cef6bfdabc5ef423c7acd6c84be03c Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Mon, 10 Jul 2023 17:07:39 +0300 Subject: [PATCH 2/4] chore(deps): bimped tough-cookie and @types/tough-cookie --- package-lock.json | 84 ++++++++++++++++++++++++++++++++++------------- package.json | 4 +-- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b2e294..dc7819d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", "https": "1.0.0", - "tough-cookie": "4.0.0" + "tough-cookie": "4.1.3" }, "devDependencies": { "@cypress/webpack-preprocessor": "5.9.1", @@ -21,7 +21,7 @@ "@types/jest": "27.4.0", "@types/mime": "2.0.3", "@types/pem": "1.9.6", - "@types/tough-cookie": "4.0.1", + "@types/tough-cookie": "4.0.2", "copyfiles": "2.4.1", "cp": "0.2.0", "cypress": "7.7.0", @@ -3440,9 +3440,9 @@ "dev": true }, "node_modules/@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" }, "node_modules/@types/yargs": { "version": "16.0.5", @@ -14110,6 +14110,11 @@ "node": ">=0.4.x" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -14457,6 +14462,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -15702,22 +15712,23 @@ } }, "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { "node": ">=6" } }, "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "engines": { "node": ">= 4.0.0" } @@ -16351,6 +16362,15 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -19536,9 +19556,9 @@ "dev": true }, "@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" }, "@types/yargs": { "version": "16.0.5", @@ -27552,6 +27572,11 @@ "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -27833,6 +27858,11 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -28799,19 +28829,20 @@ "dev": true }, "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "dependencies": { "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" } } }, @@ -29269,6 +29300,15 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", diff --git a/package.json b/package.json index 90078f5..504f0db 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@types/jest": "27.4.0", "@types/mime": "2.0.3", "@types/pem": "1.9.6", - "@types/tough-cookie": "4.0.1", + "@types/tough-cookie": "4.0.2", "copyfiles": "2.4.1", "cp": "0.2.0", "cypress": "7.7.0", @@ -82,6 +82,6 @@ "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", "https": "1.0.0", - "tough-cookie": "4.0.0" + "tough-cookie": "4.1.3" } } From 6272eeda23109f49cd54998bbd222965ac895b6a Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Mon, 10 Jul 2023 19:14:47 +0300 Subject: [PATCH 3/4] fix(form-data): fixed formData type check --- src/file/generateFileUploadForm.ts | 9 ++++++--- src/file/spec/generateFileUploadForm.spec.ts | 8 +++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/file/generateFileUploadForm.ts b/src/file/generateFileUploadForm.ts index 0fc695f..efb4792 100644 --- a/src/file/generateFileUploadForm.ts +++ b/src/file/generateFileUploadForm.ts @@ -1,5 +1,6 @@ import * as NodeFormData from 'form-data' import { convertToCSV } from '../utils/convertToCsv' +import { isNode } from '../utils' /** * One of the approaches SASjs takes to send tables-formatted JSON (see README) @@ -26,12 +27,14 @@ export const generateFileUploadForm = ( ) } - if (formData instanceof NodeFormData) { - formData.append(name, csv, { + if (isNode()) { + // environment is Node and formData is instance of NodeFormData + ;(formData as NodeFormData).append(name, csv, { filename: `${name}.csv`, contentType: 'application/csv' }) - } else if (formData instanceof FormData) { + } else { + // environment is Browser and formData is instance of FormData const file = new Blob([csv], { type: 'application/csv' }) diff --git a/src/file/spec/generateFileUploadForm.spec.ts b/src/file/spec/generateFileUploadForm.spec.ts index 62db1d5..1dc9db9 100644 --- a/src/file/spec/generateFileUploadForm.spec.ts +++ b/src/file/spec/generateFileUploadForm.spec.ts @@ -1,6 +1,7 @@ import { generateFileUploadForm } from '../generateFileUploadForm' -import * as NodeFormData from 'form-data' import { convertToCSV } from '../../utils/convertToCsv' +import * as NodeFormData from 'form-data' +import * as isNodeModule from '../../utils/isNode' describe('generateFileUploadForm', () => { beforeAll(() => { @@ -14,6 +15,10 @@ describe('generateFileUploadForm', () => { }) describe('browser', () => { + afterAll(() => { + jest.restoreAllMocks() + }) + it('should generate file upload form from data', () => { const formData = new FormData() const testTable = 'sometable' @@ -33,6 +38,7 @@ describe('generateFileUploadForm', () => { )[0] jest.spyOn(formData, 'append').mockImplementation(() => {}) + jest.spyOn(isNodeModule, 'isNode').mockImplementation(() => false) generateFileUploadForm(formData, testTableWithNullVars) From fe03faa59f1192d0450e0fde9593b920ffa2a2ff Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Tue, 11 Jul 2023 09:26:36 +0300 Subject: [PATCH 4/4] chore(file-upload-form): left comments --- src/file/generateFileUploadForm.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/file/generateFileUploadForm.ts b/src/file/generateFileUploadForm.ts index efb4792..75da2c6 100644 --- a/src/file/generateFileUploadForm.ts +++ b/src/file/generateFileUploadForm.ts @@ -27,14 +27,15 @@ export const generateFileUploadForm = ( ) } + // INFO: unfortunately it is not possible to check if formData is instance of NodeFormData or FormData because it will return true for both if (isNode()) { - // environment is Node and formData is instance of NodeFormData + // INFO: environment is Node and formData is instance of NodeFormData ;(formData as NodeFormData).append(name, csv, { filename: `${name}.csv`, contentType: 'application/csv' }) } else { - // environment is Browser and formData is instance of FormData + // INFO: environment is Browser and formData is instance of FormData const file = new Blob([csv], { type: 'application/csv' })