n8n-nodes-binary-to-url 0.0.7 → 0.0.9

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.
@@ -1,4 +1,4 @@
1
- import type { Icon, ICredentialType, INodeProperties } from 'n8n-workflow';
1
+ import type { ICredentialType, INodeProperties, Icon } from 'n8n-workflow';
2
2
  export declare class S3Api implements ICredentialType {
3
3
  name: string;
4
4
  displayName: string;
@@ -4,43 +4,50 @@ exports.S3Api = void 0;
4
4
  class S3Api {
5
5
  constructor() {
6
6
  this.name = 's3Api';
7
- this.displayName = 'S3 API';
7
+ this.displayName = 'S3';
8
8
  this.icon = 'file:../icons/BinaryToUrl.svg';
9
9
  this.documentationUrl = 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/AccessCredentials.html';
10
10
  this.properties = [
11
11
  {
12
- displayName: 'Access Key ID',
13
- name: 'accessKeyId',
14
- type: 'string',
15
- typeOptions: { password: true },
16
- default: '',
17
- },
18
- {
19
- displayName: 'Secret Access Key',
20
- name: 'secretAccessKey',
12
+ displayName: 'S3 Endpoint',
13
+ name: 'endpoint',
21
14
  type: 'string',
22
- typeOptions: { password: true },
23
15
  default: '',
16
+ description: 'S3-compatible service endpoint (e.g., https://s3.amazonaws.com, https://minio.example.com)',
24
17
  },
25
18
  {
26
19
  displayName: 'Region',
27
20
  name: 'region',
28
21
  type: 'string',
29
22
  default: 'us-east-1',
30
- description: 'AWS region (e.g., us-east-1, eu-west-1)',
23
+ description: 'AWS region or custom region for S3-compatible service',
31
24
  },
32
25
  {
33
- displayName: 'S3 Endpoint',
34
- name: 's3Api',
26
+ displayName: 'Access Key ID',
27
+ name: 'accessKeyId',
28
+ type: 'string',
29
+ default: '',
30
+ },
31
+ {
32
+ displayName: 'Secret Access Key',
33
+ name: 'secretAccessKey',
35
34
  type: 'string',
36
35
  default: '',
37
- placeholder: 'https://s3.amazonaws.com',
38
- description: 'S3-compatible service endpoint (required for MinIO, DigitalOcean Spaces, Wasabi, etc.). Leave empty for AWS S3.',
36
+ typeOptions: {
37
+ password: true,
38
+ },
39
+ },
40
+ {
41
+ displayName: 'Force Path Style',
42
+ name: 'forcePathStyle',
43
+ type: 'boolean',
44
+ default: false,
45
+ description: 'Use path-style addressing (required for MinIO, DigitalOcean Spaces, etc.)',
39
46
  },
40
47
  ];
41
48
  this.test = {
42
49
  request: {
43
- baseURL: '={{$credentials.s3Api}}',
50
+ baseURL: '={{$credentials.endpoint}}',
44
51
  url: '=/',
45
52
  method: 'GET',
46
53
  },
@@ -17,20 +17,23 @@ async function createStorageDriver(context, bucket) {
17
17
  const creds = credentials;
18
18
  const accessKeyId = creds.accessKeyId || '';
19
19
  const secretAccessKey = creds.secretAccessKey || '';
20
- const credentialEndpoint = creds.s3Api;
20
+ const credentialEndpoint = creds.endpoint;
21
21
  const credentialRegion = creds.region;
22
- // Use credential endpoint if node parameter is empty
22
+ // Convert forcePathStyle from credential (could be string or boolean)
23
+ const credentialForcePathStyle = String(creds.forcePathStyle) === 'true';
24
+ // Use credential values if node parameters are empty
23
25
  const finalEndpoint = endpoint || credentialEndpoint;
24
- // Use credential region if node parameter is empty
25
26
  const finalRegion = region || credentialRegion || 'us-east-1';
27
+ // Use boolean OR to combine forcePathStyle from node and credential
28
+ const finalForcePathStyle = forcePathStyle || credentialForcePathStyle || false;
26
29
  if (!accessKeyId || !secretAccessKey) {
27
30
  throw new Error('Invalid credentials. Missing access key or secret key.');
28
31
  }
29
32
  // Auto-determine if path style should be forced
30
- let shouldForcePathStyle = forcePathStyle;
33
+ let shouldForcePathStyle = finalForcePathStyle;
31
34
  // Force path style by default if custom endpoint is provided
32
35
  // This is needed for MinIO, Wasabi, DigitalOcean Spaces, Alibaba OSS, Tencent COS, etc.
33
- if (finalEndpoint && finalEndpoint !== '') {
36
+ if (finalEndpoint && finalEndpoint !== '' && !finalForcePathStyle) {
34
37
  shouldForcePathStyle = true;
35
38
  }
36
39
  const config = {
@@ -254,7 +254,12 @@ class BinaryToUrl {
254
254
  exports.BinaryToUrl = BinaryToUrl;
255
255
  async function handleUpload(context, items, storage) {
256
256
  const binaryPropertyName = context.getNodeParameter('binaryPropertyName', 0);
257
- const webhookBaseUrl = buildWebhookUrl(context, 'default', 'file');
257
+ // Build webhook URL using n8n's instance base URL and workflow ID
258
+ // Format: {baseUrl}/webhook/{workflowId}/file/:fileKey
259
+ const baseUrl = context.getInstanceBaseUrl();
260
+ const workflow = context.getWorkflow();
261
+ const workflowId = workflow.id;
262
+ const webhookUrl = `${baseUrl}/webhook/${workflowId}/file/:fileKey`;
258
263
  const returnData = [];
259
264
  for (const item of items) {
260
265
  const binaryData = item.binary?.[binaryPropertyName];
@@ -272,7 +277,8 @@ async function handleUpload(context, items, storage) {
272
277
  throw new n8n_workflow_1.NodeOperationError(context.getNode(), `File size exceeds maximum limit of ${MAX_FILE_SIZE / 1024 / 1024}MB`);
273
278
  }
274
279
  const result = await storage.uploadStream(buffer, contentType);
275
- const proxyUrl = `${webhookBaseUrl}/${result.fileKey}`;
280
+ // Replace the :fileKey placeholder with the actual file key
281
+ const proxyUrl = webhookUrl.replace(':fileKey', result.fileKey);
276
282
  returnData.push({
277
283
  json: {
278
284
  fileKey: result.fileKey,
@@ -302,14 +308,6 @@ async function handleDelete(context, items, storage) {
302
308
  }
303
309
  return [returnData];
304
310
  }
305
- function buildWebhookUrl(context, webhookName, path) {
306
- const baseUrl = context.getInstanceBaseUrl();
307
- const node = context.getNode();
308
- const workflow = context.getWorkflow();
309
- const workflowId = workflow.id;
310
- const nodeName = encodeURIComponent(node.name.toLowerCase());
311
- return `${baseUrl}/webhook/${workflowId}/${nodeName}/${path}`;
312
- }
313
311
  function isValidFileKey(fileKey) {
314
312
  if (!fileKey || typeof fileKey !== 'string') {
315
313
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-binary-to-url",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "n8n community node for binary file to public URL bridge with S3 storage",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",