n8n-nodes-nvk-browser 1.0.21 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -731,7 +731,6 @@ async function executeGetNetworkResponse(i, browserManager, returnData) {
731
731
  }
732
732
  }
733
733
  async function executeBrowserHttpRequest(i, browserManager, returnData) {
734
- const items = this.getInputData();
735
734
  const profileId = this.getNodeParameter('profileId', i);
736
735
  const method = this.getNodeParameter('method', i) || 'GET';
737
736
  const url = this.getNodeParameter('url', i);
@@ -784,10 +783,11 @@ async function executeBrowserHttpRequest(i, browserManager, returnData) {
784
783
  let body;
785
784
  let contentType;
786
785
  let useFormData = false;
786
+ let bodyContentType;
787
787
  if (method === 'POST') {
788
788
  const sendBody = this.getNodeParameter('sendBody', i);
789
789
  if (sendBody) {
790
- const bodyContentType = this.getNodeParameter('bodyContentType', i);
790
+ bodyContentType = this.getNodeParameter('bodyContentType', i);
791
791
  if (bodyContentType === 'json') {
792
792
  const jsonBody = this.getNodeParameter('jsonBody', i);
793
793
  body = jsonBody;
@@ -799,26 +799,37 @@ async function executeBrowserHttpRequest(i, browserManager, returnData) {
799
799
  contentType = 'text/plain';
800
800
  }
801
801
  else if (bodyContentType === 'binary') {
802
- // Handle n8n Binary File
802
+ // Handle n8n Binary File - similar to n8n HTTP Request
803
803
  const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
804
- const item = items[i];
805
- if (!item.binary || !item.binary[binaryPropertyName]) {
806
- throw new Error(`Binary data not found for property "${binaryPropertyName}"`);
804
+ const itemBinaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
805
+ let uploadData;
806
+ let contentLength;
807
+ if (itemBinaryData.id) {
808
+ // Binary data is stored as stream/file
809
+ const binaryStream = await this.helpers.getBinaryStream(itemBinaryData.id);
810
+ const chunks = [];
811
+ for await (const chunk of binaryStream) {
812
+ chunks.push(chunk);
813
+ }
814
+ uploadData = Buffer.concat(chunks);
815
+ contentLength = uploadData.length;
816
+ }
817
+ else {
818
+ // Binary data is in memory
819
+ uploadData = Buffer.from(itemBinaryData.data, 'base64');
820
+ contentLength = uploadData.length;
807
821
  }
808
- const binaryData = item.binary[binaryPropertyName];
809
- const binaryBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
810
822
  // Convert binary to base64 for transfer to browser context
811
- const base64Data = binaryBuffer.toString('base64');
812
- const mimeType = binaryData.mimeType || 'application/octet-stream';
813
- const fileName = binaryData.fileName || 'file';
814
- // We'll send this to browser context to create FormData
823
+ const base64Data = uploadData.toString('base64');
824
+ const mimeType = itemBinaryData.mimeType || 'application/octet-stream';
825
+ // Send binary data directly (not as FormData)
815
826
  body = JSON.stringify({
816
827
  type: 'binary',
817
828
  data: base64Data,
818
829
  mimeType,
819
- fileName,
830
+ contentLength,
820
831
  });
821
- useFormData = true;
832
+ contentType = mimeType;
822
833
  }
823
834
  else if (bodyContentType === 'formData') {
824
835
  const formDataParam = this.getNodeParameter('formData', i);
@@ -830,21 +841,31 @@ async function executeBrowserHttpRequest(i, browserManager, returnData) {
830
841
  for (const param of formDataParam.parameter) {
831
842
  if (param.name) {
832
843
  if (param.parameterType === 'binary') {
844
+ // Handle binary file in form data - similar to n8n HTTP Request
833
845
  const binaryPropertyName = param.binaryPropertyName || 'data';
834
- const item = items[i];
835
- if (!item.binary || !item.binary[binaryPropertyName]) {
836
- throw new Error(`Binary data not found for property "${binaryPropertyName}"`);
846
+ const itemBinaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
847
+ let uploadData;
848
+ if (itemBinaryData.id) {
849
+ // Binary data is stored as stream/file
850
+ const binaryStream = await this.helpers.getBinaryStream(itemBinaryData.id);
851
+ const chunks = [];
852
+ for await (const chunk of binaryStream) {
853
+ chunks.push(chunk);
854
+ }
855
+ uploadData = Buffer.concat(chunks);
856
+ }
857
+ else {
858
+ // Binary data is in memory
859
+ uploadData = Buffer.from(itemBinaryData.data, 'base64');
837
860
  }
838
- const binaryData = item.binary[binaryPropertyName];
839
- const binaryBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
840
- const base64Data = binaryBuffer.toString('base64');
861
+ const base64Data = uploadData.toString('base64');
841
862
  formDataItems.push({
842
863
  name: param.name,
843
864
  type: 'binary',
844
865
  binaryData: {
845
866
  data: base64Data,
846
- mimeType: binaryData.mimeType || 'application/octet-stream',
847
- fileName: binaryData.fileName || 'file',
867
+ mimeType: itemBinaryData.mimeType || 'application/octet-stream',
868
+ fileName: itemBinaryData.fileName || 'file',
848
869
  },
849
870
  });
850
871
  }
@@ -878,8 +899,16 @@ async function executeBrowserHttpRequest(i, browserManager, returnData) {
878
899
  }
879
900
  }
880
901
  }
881
- // Don't set Content-Type header if using FormData (browser will set it automatically with boundary)
882
- if (contentType && !useFormData) {
902
+ // Set Content-Type header
903
+ // For binary body, set content-type and content-length
904
+ if (bodyContentType === 'binary' && typeof body === 'string') {
905
+ const bodyData = JSON.parse(body);
906
+ if (bodyData.type === 'binary') {
907
+ browserHeaders['Content-Type'] = bodyData.mimeType || 'application/octet-stream';
908
+ browserHeaders['Content-Length'] = String(bodyData.contentLength || 0);
909
+ }
910
+ }
911
+ else if (contentType && !useFormData) {
883
912
  browserHeaders['Content-Type'] = contentType;
884
913
  }
885
914
  const response = await page.evaluate(async (requestData) => {
@@ -888,55 +917,62 @@ async function executeBrowserHttpRequest(i, browserManager, returnData) {
888
917
  headers: requestData.headers,
889
918
  };
890
919
  if (requestData.body) {
891
- if (requestData.useFormData && typeof requestData.body === 'object') {
892
- const formData = new FormData();
893
- if (requestData.body.type === 'binary' && requestData.body.data) {
894
- // Single binary file
895
- const binaryData = requestData.body.data;
896
- const mimeType = requestData.body.mimeType || 'application/octet-stream';
897
- const fileName = requestData.body.fileName || 'file';
898
- // Convert base64 to blob
899
- const binaryString = atob(binaryData);
900
- const bytes = new Uint8Array(binaryString.length);
901
- for (let i = 0; i < binaryString.length; i++) {
902
- bytes[i] = binaryString.charCodeAt(i);
920
+ if (typeof requestData.body === 'string') {
921
+ try {
922
+ const bodyObj = JSON.parse(requestData.body);
923
+ if (bodyObj.type === 'binary' && bodyObj.data) {
924
+ // Binary body - send directly as ArrayBuffer
925
+ const binaryData = bodyObj.data;
926
+ // Convert base64 to ArrayBuffer
927
+ const binaryString = atob(binaryData);
928
+ const bytes = new Uint8Array(binaryString.length);
929
+ for (let i = 0; i < binaryString.length; i++) {
930
+ bytes[i] = binaryString.charCodeAt(i);
931
+ }
932
+ fetchOptions.body = bytes.buffer;
933
+ // Content-Type and Content-Length are already set in headers
903
934
  }
904
- const blob = new Blob([bytes], { type: mimeType });
905
- const file = new File([blob], fileName, { type: mimeType });
906
- formData.append('file', file);
907
- fetchOptions.body = formData;
908
- }
909
- else if (requestData.body.type === 'formData') {
910
- // FormData with mixed text and binary
911
- const items = requestData.body.items || [];
912
- for (const item of items) {
913
- if (item.type === 'binary' && item.binaryData && item.binaryData.data) {
914
- const binaryData = item.binaryData.data;
915
- const mimeType = item.binaryData.mimeType || 'application/octet-stream';
916
- const fileName = item.binaryData.fileName || 'file';
917
- // Convert base64 to blob
918
- const binaryString = atob(binaryData);
919
- const bytes = new Uint8Array(binaryString.length);
920
- for (let i = 0; i < binaryString.length; i++) {
921
- bytes[i] = binaryString.charCodeAt(i);
935
+ else if (bodyObj.type === 'formData' && requestData.useFormData) {
936
+ // FormData with mixed text and binary
937
+ const formData = new FormData();
938
+ const items = bodyObj.items || [];
939
+ for (const item of items) {
940
+ if (item.type === 'binary' && item.binaryData && item.binaryData.data) {
941
+ const binaryData = item.binaryData.data;
942
+ const mimeType = item.binaryData.mimeType || 'application/octet-stream';
943
+ const fileName = item.binaryData.fileName || 'file';
944
+ // Convert base64 to blob
945
+ const binaryString = atob(binaryData);
946
+ const bytes = new Uint8Array(binaryString.length);
947
+ for (let i = 0; i < binaryString.length; i++) {
948
+ bytes[i] = binaryString.charCodeAt(i);
949
+ }
950
+ const blob = new Blob([bytes], { type: mimeType });
951
+ const file = new File([blob], fileName, { type: mimeType });
952
+ formData.append(item.name, file);
953
+ }
954
+ else {
955
+ formData.append(item.name, item.value || '');
922
956
  }
923
- const blob = new Blob([bytes], { type: mimeType });
924
- const file = new File([blob], fileName, { type: mimeType });
925
- formData.append(item.name, file);
926
957
  }
927
- else {
928
- formData.append(item.name, item.value || '');
958
+ fetchOptions.body = formData;
959
+ // Remove Content-Type header when using FormData (browser will set it with boundary)
960
+ if (fetchOptions.headers && typeof fetchOptions.headers === 'object' && !Array.isArray(fetchOptions.headers)) {
961
+ delete fetchOptions.headers['Content-Type'];
929
962
  }
930
963
  }
931
- fetchOptions.body = formData;
964
+ else {
965
+ // Regular string body
966
+ fetchOptions.body = typeof requestData.body === 'string' ? requestData.body : String(requestData.body);
967
+ }
932
968
  }
933
- // Remove Content-Type header when using FormData (browser will set it with boundary)
934
- if (fetchOptions.headers && typeof fetchOptions.headers === 'object' && !Array.isArray(fetchOptions.headers)) {
935
- delete fetchOptions.headers['Content-Type'];
969
+ catch {
970
+ // Not JSON, treat as regular string
971
+ fetchOptions.body = typeof requestData.body === 'string' ? requestData.body : String(requestData.body);
936
972
  }
937
973
  }
938
974
  else {
939
- fetchOptions.body = requestData.body;
975
+ fetchOptions.body = typeof requestData.body === 'string' ? requestData.body : String(requestData.body);
940
976
  }
941
977
  }
942
978
  const response = await fetch(requestData.url, fetchOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-nvk-browser",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "n8n nodes for managing Chrome browser profiles and page interactions with Puppeteer automation",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",