n8n-nodes-h2i 1.0.0 → 1.0.1

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.
@@ -11,7 +11,8 @@ class DavixH2IApi {
11
11
  type: 'string',
12
12
  default: 'https://pixlab.davix.dev',
13
13
  placeholder: 'https://pixlab.davix.dev',
14
- description: 'Your PixLab API base URL (no trailing slash). Example: https://pixlab.davix.dev',
14
+ description: 'PixLab API base URL (no trailing slash). Example: https://pixlab.davix.dev',
15
+ required: true,
15
16
  },
16
17
  {
17
18
  displayName: 'API Key',
@@ -19,6 +20,8 @@ class DavixH2IApi {
19
20
  type: 'string',
20
21
  typeOptions: { password: true },
21
22
  default: '',
23
+ required: true,
24
+ description: 'Your Davix PixLab API key.',
22
25
  },
23
26
  ];
24
27
  }
@@ -18,7 +18,7 @@ class DavixH2I {
18
18
  icon: 'file:davixH2I.svg',
19
19
  group: ['transform'],
20
20
  version: 1,
21
- subtitle: '={{$parameter["resource"]}}',
21
+ subtitle: '={{$parameter["resource"] + " • " + ($parameter["operation"] || "")}}',
22
22
  description: 'Use Davix PixLab public API endpoints (H2I, Image, PDF, Tools).',
23
23
  defaults: {
24
24
  name: 'Davix H2I',
@@ -27,6 +27,9 @@ class DavixH2I {
27
27
  outputs: ['main'],
28
28
  credentials: [{ name: 'davixH2IApi', required: true }],
29
29
  properties: [
30
+ // -------------------------
31
+ // Resource + Operation
32
+ // -------------------------
30
33
  {
31
34
  displayName: 'Resource',
32
35
  name: 'resource',
@@ -39,6 +42,48 @@ class DavixH2I {
39
42
  { name: 'Tools (Analyze Images)', value: 'tools' },
40
43
  ],
41
44
  },
45
+ // H2I operation
46
+ {
47
+ displayName: 'Operation',
48
+ name: 'operation',
49
+ type: 'options',
50
+ default: 'render',
51
+ displayOptions: { show: { resource: ['h2i'] } },
52
+ options: [{ name: 'Render HTML → Image', value: 'render' }],
53
+ },
54
+ // Image operation
55
+ {
56
+ displayName: 'Operation',
57
+ name: 'operation',
58
+ type: 'options',
59
+ default: 'transform',
60
+ displayOptions: { show: { resource: ['image'] } },
61
+ options: [{ name: 'Transform / Convert', value: 'transform' }],
62
+ },
63
+ // PDF operations
64
+ {
65
+ displayName: 'Operation',
66
+ name: 'operation',
67
+ type: 'options',
68
+ default: 'merge',
69
+ displayOptions: { show: { resource: ['pdf'] } },
70
+ options: [
71
+ { name: 'Merge', value: 'merge' },
72
+ { name: 'Split', value: 'split' },
73
+ { name: 'Compress', value: 'compress' },
74
+ { name: 'To Images', value: 'to-images' },
75
+ { name: 'Extract Images', value: 'extract-images' },
76
+ ],
77
+ },
78
+ // Tools operation
79
+ {
80
+ displayName: 'Operation',
81
+ name: 'operation',
82
+ type: 'options',
83
+ default: 'analyze',
84
+ displayOptions: { show: { resource: ['tools'] } },
85
+ options: [{ name: 'Analyze Images', value: 'analyze' }],
86
+ },
42
87
  // -------------------------
43
88
  // H2I
44
89
  // -------------------------
@@ -49,7 +94,7 @@ class DavixH2I {
49
94
  default: '',
50
95
  required: true,
51
96
  typeOptions: { rows: 6 },
52
- displayOptions: { show: { resource: ['h2i'] } },
97
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
53
98
  },
54
99
  {
55
100
  displayName: 'CSS',
@@ -57,21 +102,21 @@ class DavixH2I {
57
102
  type: 'string',
58
103
  default: '',
59
104
  typeOptions: { rows: 4 },
60
- displayOptions: { show: { resource: ['h2i'] } },
105
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
61
106
  },
62
107
  {
63
108
  displayName: 'Width',
64
109
  name: 'width',
65
110
  type: 'number',
66
111
  default: 1000,
67
- displayOptions: { show: { resource: ['h2i'] } },
112
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
68
113
  },
69
114
  {
70
115
  displayName: 'Height',
71
116
  name: 'height',
72
117
  type: 'number',
73
118
  default: 1500,
74
- displayOptions: { show: { resource: ['h2i'] } },
119
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
75
120
  },
76
121
  {
77
122
  displayName: 'Format',
@@ -82,21 +127,21 @@ class DavixH2I {
82
127
  { name: 'PNG', value: 'png' },
83
128
  { name: 'JPEG', value: 'jpeg' },
84
129
  ],
85
- displayOptions: { show: { resource: ['h2i'] } },
130
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
86
131
  },
87
132
  {
88
133
  displayName: 'Download Result as Binary',
89
134
  name: 'downloadBinary',
90
135
  type: 'boolean',
91
136
  default: false,
92
- displayOptions: { show: { resource: ['h2i'] } },
137
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'] } },
93
138
  },
94
139
  {
95
140
  displayName: 'Output Binary Property',
96
141
  name: 'outputBinaryProperty',
97
142
  type: 'string',
98
143
  default: 'data',
99
- displayOptions: { show: { resource: ['h2i'], downloadBinary: [true] } },
144
+ displayOptions: { show: { resource: ['h2i'], operation: ['render'], downloadBinary: [true] } },
100
145
  },
101
146
  // -------------------------
102
147
  // Image
@@ -108,7 +153,7 @@ class DavixH2I {
108
153
  default: 'data',
109
154
  placeholder: 'data OR image1,image2',
110
155
  description: 'Comma-separated binary property names from previous nodes (each will be sent as an `images` file).',
111
- displayOptions: { show: { resource: ['image'] } },
156
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
112
157
  },
113
158
  {
114
159
  displayName: 'Format',
@@ -124,22 +169,40 @@ class DavixH2I {
124
169
  { name: 'SVG', value: 'svg' },
125
170
  { name: 'PDF', value: 'pdf' },
126
171
  ],
127
- displayOptions: { show: { resource: ['image'] } },
172
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
173
+ },
174
+ {
175
+ displayName: 'Width',
176
+ name: 'imageWidth',
177
+ type: 'number',
178
+ default: 0,
179
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
180
+ },
181
+ {
182
+ displayName: 'Height',
183
+ name: 'imageHeight',
184
+ type: 'number',
185
+ default: 0,
186
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
187
+ },
188
+ {
189
+ displayName: 'Enlarge',
190
+ name: 'enlarge',
191
+ type: 'boolean',
192
+ default: false,
193
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
128
194
  },
129
- { displayName: 'Width', name: 'imageWidth', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
130
- { displayName: 'Height', name: 'imageHeight', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
131
- { displayName: 'Enlarge', name: 'enlarge', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'] } } },
132
- { displayName: 'Crop X', name: 'cropX', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
133
- { displayName: 'Crop Y', name: 'cropY', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
134
- { displayName: 'Crop Width', name: 'cropWidth', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
135
- { displayName: 'Crop Height', name: 'cropHeight', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
136
- { displayName: 'Rotate (degrees)', name: 'rotate', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
137
- { displayName: 'Flip Horizontal', name: 'flipH', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'] } } },
138
- { displayName: 'Flip Vertical', name: 'flipV', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'] } } },
139
- { displayName: 'Target Size (KB)', name: 'targetSizeKB', type: 'number', default: 0, displayOptions: { show: { resource: ['image'] } } },
140
- { displayName: 'Quality', name: 'quality', type: 'number', default: 82, displayOptions: { show: { resource: ['image'] } } },
141
- { displayName: 'Keep Metadata', name: 'keepMetadata', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'] } } },
142
- // PDF-only options
195
+ { displayName: 'Crop X', name: 'cropX', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
196
+ { displayName: 'Crop Y', name: 'cropY', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
197
+ { displayName: 'Crop Width', name: 'cropWidth', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
198
+ { displayName: 'Crop Height', name: 'cropHeight', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
199
+ { displayName: 'Rotate (degrees)', name: 'rotate', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
200
+ { displayName: 'Flip Horizontal', name: 'flipH', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
201
+ { displayName: 'Flip Vertical', name: 'flipV', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
202
+ { displayName: 'Target Size (KB)', name: 'targetSizeKB', type: 'number', default: 0, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
203
+ { displayName: 'Quality', name: 'quality', type: 'number', default: 82, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
204
+ { displayName: 'Keep Metadata', name: 'keepMetadata', type: 'boolean', default: false, displayOptions: { show: { resource: ['image'], operation: ['transform'] } } },
205
+ // PDF-only options for Image endpoint (format=pdf)
143
206
  {
144
207
  displayName: 'PDF Mode',
145
208
  name: 'pdfMode',
@@ -149,7 +212,7 @@ class DavixH2I {
149
212
  { name: 'Single', value: 'single' },
150
213
  { name: 'Multi', value: 'multi' },
151
214
  ],
152
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
215
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
153
216
  },
154
217
  {
155
218
  displayName: 'PDF Page Size',
@@ -161,7 +224,7 @@ class DavixH2I {
161
224
  { name: 'A4', value: 'a4' },
162
225
  { name: 'Letter', value: 'letter' },
163
226
  ],
164
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
227
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
165
228
  },
166
229
  {
167
230
  displayName: 'PDF Orientation',
@@ -172,14 +235,14 @@ class DavixH2I {
172
235
  { name: 'Portrait', value: 'portrait' },
173
236
  { name: 'Landscape', value: 'landscape' },
174
237
  ],
175
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
238
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
176
239
  },
177
240
  {
178
241
  displayName: 'PDF Margin',
179
242
  name: 'pdfMargin',
180
243
  type: 'number',
181
244
  default: 0,
182
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
245
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
183
246
  },
184
247
  {
185
248
  displayName: 'PDF Embed Format',
@@ -190,46 +253,32 @@ class DavixH2I {
190
253
  { name: 'PNG', value: 'png' },
191
254
  { name: 'JPEG', value: 'jpeg' },
192
255
  ],
193
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
256
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
194
257
  },
195
258
  {
196
259
  displayName: 'PDF JPEG Quality',
197
260
  name: 'pdfJpegQuality',
198
261
  type: 'number',
199
262
  default: 85,
200
- displayOptions: { show: { resource: ['image'], imageFormat: ['pdf'] } },
263
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageFormat: ['pdf'] } },
201
264
  },
202
265
  {
203
266
  displayName: 'Download Result(s) as Binary',
204
267
  name: 'imageDownloadBinary',
205
268
  type: 'boolean',
206
269
  default: false,
207
- displayOptions: { show: { resource: ['image'] } },
270
+ displayOptions: { show: { resource: ['image'], operation: ['transform'] } },
208
271
  },
209
272
  {
210
273
  displayName: 'Output Binary Property',
211
274
  name: 'imageOutputBinaryProperty',
212
275
  type: 'string',
213
276
  default: 'data',
214
- displayOptions: { show: { resource: ['image'], imageDownloadBinary: [true] } },
277
+ displayOptions: { show: { resource: ['image'], operation: ['transform'], imageDownloadBinary: [true] } },
215
278
  },
216
279
  // -------------------------
217
280
  // PDF
218
281
  // -------------------------
219
- {
220
- displayName: 'Action',
221
- name: 'pdfAction',
222
- type: 'options',
223
- default: 'merge',
224
- options: [
225
- { name: 'Merge', value: 'merge' },
226
- { name: 'Split', value: 'split' },
227
- { name: 'Compress', value: 'compress' },
228
- { name: 'To Images', value: 'to-images' },
229
- { name: 'Extract Images', value: 'extract-images' },
230
- ],
231
- displayOptions: { show: { resource: ['pdf'] } },
232
- },
233
282
  {
234
283
  displayName: 'Input Binary Properties',
235
284
  name: 'pdfBinaryProps',
@@ -244,7 +293,7 @@ class DavixH2I {
244
293
  name: 'sortByName',
245
294
  type: 'boolean',
246
295
  default: false,
247
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['merge'] } },
296
+ displayOptions: { show: { resource: ['pdf'], operation: ['merge'] } },
248
297
  },
249
298
  {
250
299
  displayName: 'Ranges',
@@ -252,14 +301,14 @@ class DavixH2I {
252
301
  type: 'string',
253
302
  default: '',
254
303
  placeholder: '1-3,4-5',
255
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['split'] } },
304
+ displayOptions: { show: { resource: ['pdf'], operation: ['split'] } },
256
305
  },
257
306
  {
258
307
  displayName: 'Prefix',
259
308
  name: 'prefix',
260
309
  type: 'string',
261
310
  default: 'split_',
262
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['split'] } },
311
+ displayOptions: { show: { resource: ['pdf'], operation: ['split'] } },
263
312
  },
264
313
  {
265
314
  displayName: 'Pages',
@@ -267,7 +316,7 @@ class DavixH2I {
267
316
  type: 'string',
268
317
  default: 'all',
269
318
  placeholder: 'all OR 1-3,5,7',
270
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['to-images', 'extract-images'] } },
319
+ displayOptions: { show: { resource: ['pdf'], operation: ['to-images', 'extract-images'] } },
271
320
  },
272
321
  {
273
322
  displayName: 'To Format',
@@ -279,14 +328,14 @@ class DavixH2I {
279
328
  { name: 'JPEG', value: 'jpeg' },
280
329
  { name: 'WebP', value: 'webp' },
281
330
  ],
282
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['to-images'] } },
331
+ displayOptions: { show: { resource: ['pdf'], operation: ['to-images'] } },
283
332
  },
284
- { displayName: 'Width', name: 'pdfWidth', type: 'number', default: 0, displayOptions: { show: { resource: ['pdf'], pdfAction: ['to-images'] } } },
285
- { displayName: 'Height', name: 'pdfHeight', type: 'number', default: 0, displayOptions: { show: { resource: ['pdf'], pdfAction: ['to-images'] } } },
286
- { displayName: 'DPI', name: 'dpi', type: 'number', default: 150, displayOptions: { show: { resource: ['pdf'], pdfAction: ['to-images'] } } },
333
+ { displayName: 'Width', name: 'pdfWidth', type: 'number', default: 0, displayOptions: { show: { resource: ['pdf'], operation: ['to-images'] } } },
334
+ { displayName: 'Height', name: 'pdfHeight', type: 'number', default: 0, displayOptions: { show: { resource: ['pdf'], operation: ['to-images'] } } },
335
+ { displayName: 'DPI', name: 'dpi', type: 'number', default: 150, displayOptions: { show: { resource: ['pdf'], operation: ['to-images'] } } },
287
336
  {
288
337
  displayName: 'Extract Image Format',
289
- name: 'imageFormat',
338
+ name: 'extractImageFormat',
290
339
  type: 'options',
291
340
  default: 'png',
292
341
  options: [
@@ -294,7 +343,7 @@ class DavixH2I {
294
343
  { name: 'JPEG', value: 'jpeg' },
295
344
  { name: 'WebP', value: 'webp' },
296
345
  ],
297
- displayOptions: { show: { resource: ['pdf'], pdfAction: ['extract-images'] } },
346
+ displayOptions: { show: { resource: ['pdf'], operation: ['extract-images'] } },
298
347
  },
299
348
  {
300
349
  displayName: 'Download Result(s) as Binary',
@@ -320,7 +369,7 @@ class DavixH2I {
320
369
  default: 'data',
321
370
  placeholder: 'data OR img1,img2',
322
371
  description: 'Comma-separated binary property names (each will be sent as an `images` file).',
323
- displayOptions: { show: { resource: ['tools'] } },
372
+ displayOptions: { show: { resource: ['tools'], operation: ['analyze'] } },
324
373
  },
325
374
  {
326
375
  displayName: 'Tools',
@@ -334,10 +383,22 @@ class DavixH2I {
334
383
  { name: 'Orientation', value: 'orientation' },
335
384
  { name: 'Hash', value: 'hash' },
336
385
  ],
337
- displayOptions: { show: { resource: ['tools'] } },
386
+ displayOptions: { show: { resource: ['tools'], operation: ['analyze'] } },
387
+ },
388
+ {
389
+ displayName: 'Include Raw EXIF',
390
+ name: 'includeRawExif',
391
+ type: 'boolean',
392
+ default: false,
393
+ displayOptions: { show: { resource: ['tools'], operation: ['analyze'] } },
394
+ },
395
+ {
396
+ displayName: 'Palette Size',
397
+ name: 'paletteSize',
398
+ type: 'number',
399
+ default: 5,
400
+ displayOptions: { show: { resource: ['tools'], operation: ['analyze'] } },
338
401
  },
339
- { displayName: 'Include Raw EXIF', name: 'includeRawExif', type: 'boolean', default: false, displayOptions: { show: { resource: ['tools'] } } },
340
- { displayName: 'Palette Size', name: 'paletteSize', type: 'number', default: 5, displayOptions: { show: { resource: ['tools'] } } },
341
402
  {
342
403
  displayName: 'Hash Type',
343
404
  name: 'hashType',
@@ -348,7 +409,7 @@ class DavixH2I {
348
409
  { name: 'MD5', value: 'md5' },
349
410
  { name: 'SHA1', value: 'sha1' },
350
411
  ],
351
- displayOptions: { show: { resource: ['tools'] } },
412
+ displayOptions: { show: { resource: ['tools'], operation: ['analyze'] } },
352
413
  },
353
414
  ],
354
415
  };
@@ -357,8 +418,11 @@ class DavixH2I {
357
418
  const out = [];
358
419
  for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
359
420
  const resource = this.getNodeParameter('resource', itemIndex);
421
+ const operation = this.getNodeParameter('operation', itemIndex);
360
422
  // ---- H2I (JSON)
361
423
  if (resource === 'h2i') {
424
+ if (operation !== 'render')
425
+ throw new Error(`Unsupported H2I operation: ${operation}`);
362
426
  const body = {
363
427
  html: this.getNodeParameter('html', itemIndex),
364
428
  css: this.getNodeParameter('css', itemIndex),
@@ -375,7 +439,7 @@ class DavixH2I {
375
439
  const downloadBinary = this.getNodeParameter('downloadBinary', itemIndex);
376
440
  if (downloadBinary && typeof response.url === 'string') {
377
441
  const binName = this.getNodeParameter('outputBinaryProperty', itemIndex);
378
- const dl = await GenericFunctions_1.downloadToBinary.call(this, response.url, `h2i.${body.format === 'jpeg' ? 'jpg' : 'png'}`);
442
+ const dl = await GenericFunctions_1.downloadToBinary.call(this, String(response.url), `h2i.${body.format === 'jpeg' ? 'jpg' : 'png'}`);
379
443
  const binary = await this.helpers.prepareBinaryData(dl.data, dl.fileName, dl.mimeType);
380
444
  out.push({ json: response, binary: { [binName]: binary } });
381
445
  }
@@ -386,7 +450,10 @@ class DavixH2I {
386
450
  }
387
451
  // Helper to attach multiple binaries as files
388
452
  const attachFiles = async (fieldName, propList, formData) => {
389
- const names = propList.split(',').map((s) => s.trim()).filter(Boolean);
453
+ const names = propList
454
+ .split(',')
455
+ .map((s) => s.trim())
456
+ .filter(Boolean);
390
457
  if (names.length === 0)
391
458
  throw new Error('No binary property names provided.');
392
459
  for (const name of names) {
@@ -394,7 +461,6 @@ class DavixH2I {
394
461
  const meta = items[itemIndex].binary?.[name];
395
462
  const fileName = meta?.fileName ?? `${fieldName}-${name}`;
396
463
  const mimeType = meta?.mimeType;
397
- // n8n request helper supports this shape for multipart file upload
398
464
  formData[fieldName] = formData[fieldName] || [];
399
465
  formData[fieldName].push({
400
466
  value: buffer,
@@ -407,6 +473,8 @@ class DavixH2I {
407
473
  };
408
474
  // ---- IMAGE (multipart)
409
475
  if (resource === 'image') {
476
+ if (operation !== 'transform')
477
+ throw new Error(`Unsupported Image operation: ${operation}`);
410
478
  const imageBinaryProps = this.getNodeParameter('imageBinaryProps', itemIndex);
411
479
  const format = this.getNodeParameter('imageFormat', itemIndex);
412
480
  const formData = {};
@@ -457,11 +525,9 @@ class DavixH2I {
457
525
  const downloadBinary = this.getNodeParameter('imageDownloadBinary', itemIndex);
458
526
  if (downloadBinary) {
459
527
  const binName = this.getNodeParameter('imageOutputBinaryProperty', itemIndex);
460
- // PixLab returns either url or results[] with urls (depending on implementation),
461
- // so we support both.
462
528
  const urls = [];
463
529
  if (typeof response.url === 'string')
464
- urls.push(response.url);
530
+ urls.push(String(response.url));
465
531
  if (Array.isArray(response.results)) {
466
532
  for (const r of response.results) {
467
533
  if (r?.url)
@@ -486,7 +552,7 @@ class DavixH2I {
486
552
  }
487
553
  // ---- PDF (multipart)
488
554
  if (resource === 'pdf') {
489
- const action = this.getNodeParameter('pdfAction', itemIndex);
555
+ const action = operation;
490
556
  const pdfBinaryProps = this.getNodeParameter('pdfBinaryProps', itemIndex);
491
557
  const formData = {};
492
558
  await attachFiles('files', pdfBinaryProps, formData);
@@ -511,7 +577,7 @@ class DavixH2I {
511
577
  }
512
578
  if (action === 'extract-images') {
513
579
  formData.pages = this.getNodeParameter('pages', itemIndex);
514
- formData.imageFormat = this.getNodeParameter('imageFormat', itemIndex);
580
+ formData.imageFormat = this.getNodeParameter('extractImageFormat', itemIndex);
515
581
  }
516
582
  const response = await GenericFunctions_1.davixRequest.call(this, {
517
583
  method: 'POST',
@@ -524,7 +590,7 @@ class DavixH2I {
524
590
  const binName = this.getNodeParameter('pdfOutputBinaryProperty', itemIndex);
525
591
  const urls = [];
526
592
  if (typeof response.url === 'string')
527
- urls.push(response.url);
593
+ urls.push(String(response.url));
528
594
  if (Array.isArray(response.results)) {
529
595
  for (const r of response.results) {
530
596
  if (r?.url)
@@ -548,6 +614,8 @@ class DavixH2I {
548
614
  }
549
615
  // ---- TOOLS (multipart)
550
616
  if (resource === 'tools') {
617
+ if (operation !== 'analyze')
618
+ throw new Error(`Unsupported Tools operation: ${operation}`);
551
619
  const toolsBinaryProps = this.getNodeParameter('toolsBinaryProps', itemIndex);
552
620
  const formData = {};
553
621
  await attachFiles('images', toolsBinaryProps, formData);
@@ -5,6 +5,11 @@ exports.downloadToBinary = downloadToBinary;
5
5
  function stripTrailingSlash(url) {
6
6
  return url.endsWith('/') ? url.slice(0, -1) : url;
7
7
  }
8
+ function ensureLeadingSlash(path) {
9
+ if (!path)
10
+ return '/';
11
+ return path.startsWith('/') ? path : `/${path}`;
12
+ }
8
13
  async function davixRequest(options) {
9
14
  const creds = await this.getCredentials('davixH2IApi');
10
15
  const baseUrl = stripTrailingSlash(String(creds.baseUrl || ''));
@@ -15,7 +20,7 @@ async function davixRequest(options) {
15
20
  throw new Error('Missing API Key in credentials.');
16
21
  const requestOptions = {
17
22
  ...options,
18
- url: `${baseUrl}${options.url}`,
23
+ url: `${baseUrl}${ensureLeadingSlash(String(options.url || ''))}`,
19
24
  headers: {
20
25
  ...(options.headers || {}),
21
26
  // PixLab accepts x-api-key
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-h2i",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Davix H2I (PixLab) community node for n8n: H2I, Image, PDF, Tools endpoints",
5
5
  "license": "MIT",
6
6
  "keywords": [