@teamimagine/n8n-nodes-imagineart 0.1.0

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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/credentials/ImagineArtOAuth2Api.credentials.d.ts +9 -0
  4. package/dist/credentials/ImagineArtOAuth2Api.credentials.js +68 -0
  5. package/dist/credentials/ImagineArtOAuth2Api.credentials.js.map +1 -0
  6. package/dist/credentials/logo-lg.dark.svg +31 -0
  7. package/dist/credentials/logo-lg.svg +31 -0
  8. package/dist/nodes/ImagineArt/ImagineArt.node.d.ts +12 -0
  9. package/dist/nodes/ImagineArt/ImagineArt.node.js +31 -0
  10. package/dist/nodes/ImagineArt/ImagineArt.node.js.map +1 -0
  11. package/dist/nodes/ImagineArt/logo-lg.dark.svg +31 -0
  12. package/dist/nodes/ImagineArt/logo-lg.svg +31 -0
  13. package/dist/nodes/ImagineArt/methods/loadOptions.d.ts +12 -0
  14. package/dist/nodes/ImagineArt/methods/loadOptions.js +69 -0
  15. package/dist/nodes/ImagineArt/methods/loadOptions.js.map +1 -0
  16. package/dist/nodes/ImagineArt/shared.d.ts +12 -0
  17. package/dist/nodes/ImagineArt/shared.js +1778 -0
  18. package/dist/nodes/ImagineArt/shared.js.map +1 -0
  19. package/dist/nodes/ImagineArt/transport/adStudio.d.ts +33 -0
  20. package/dist/nodes/ImagineArt/transport/adStudio.js +150 -0
  21. package/dist/nodes/ImagineArt/transport/adStudio.js.map +1 -0
  22. package/dist/nodes/ImagineArt/transport/constants.d.ts +6 -0
  23. package/dist/nodes/ImagineArt/transport/constants.js +9 -0
  24. package/dist/nodes/ImagineArt/transport/constants.js.map +1 -0
  25. package/dist/nodes/ImagineArt/transport/imageModels.d.ts +20 -0
  26. package/dist/nodes/ImagineArt/transport/imageModels.js +91 -0
  27. package/dist/nodes/ImagineArt/transport/imageModels.js.map +1 -0
  28. package/dist/nodes/ImagineArt/transport/prompts.d.ts +17 -0
  29. package/dist/nodes/ImagineArt/transport/prompts.js +216 -0
  30. package/dist/nodes/ImagineArt/transport/prompts.js.map +1 -0
  31. package/dist/nodes/ImagineArt/transport/request.d.ts +39 -0
  32. package/dist/nodes/ImagineArt/transport/request.js +74 -0
  33. package/dist/nodes/ImagineArt/transport/request.js.map +1 -0
  34. package/dist/nodes/ImagineArt/transport/status.d.ts +18 -0
  35. package/dist/nodes/ImagineArt/transport/status.js +40 -0
  36. package/dist/nodes/ImagineArt/transport/status.js.map +1 -0
  37. package/dist/nodes/ImagineArt/transport/videoModels.d.ts +29 -0
  38. package/dist/nodes/ImagineArt/transport/videoModels.js +95 -0
  39. package/dist/nodes/ImagineArt/transport/videoModels.js.map +1 -0
  40. package/dist/package.json +65 -0
  41. package/package.json +65 -0
@@ -0,0 +1,1778 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OPERATION_DROPDOWNS = exports.RESOURCE_DROPDOWN = exports.LOAD_OPTIONS = exports.SHARED_FIELDS = void 0;
4
+ exports.operationDropdownFor = operationDropdownFor;
5
+ exports.executeImagineArt = executeImagineArt;
6
+ const n8n_workflow_1 = require("n8n-workflow");
7
+ const constants_1 = require("./transport/constants");
8
+ const imageModels_1 = require("./transport/imageModels");
9
+ const videoModels_1 = require("./transport/videoModels");
10
+ const request_1 = require("./transport/request");
11
+ const status_1 = require("./transport/status");
12
+ const prompts_1 = require("./transport/prompts");
13
+ const adStudio_1 = require("./transport/adStudio");
14
+ const loadOptions_1 = require("./methods/loadOptions");
15
+ const CREDENTIAL = 'imagineArtOAuth2Api';
16
+ async function postMultipart(ctx, vag, endpoint, fields) {
17
+ const { body, contentType } = (0, request_1.buildMultipartBody)(fields);
18
+ return ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
19
+ method: 'POST',
20
+ url: `${vag}${endpoint}`,
21
+ body,
22
+ headers: { 'content-type': contentType },
23
+ timeout: 60000,
24
+ });
25
+ }
26
+ async function submitMultipart(ctx, vag, endpoint, fields) {
27
+ var _a;
28
+ const res = (await postMultipart(ctx, vag, endpoint, fields));
29
+ const id = (_a = res === null || res === void 0 ? void 0 : res[0]) === null || _a === void 0 ? void 0 : _a.id;
30
+ if (!id) {
31
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'ImagineArt did not return a generation id.');
32
+ }
33
+ return id;
34
+ }
35
+ async function uploadUserFile(ctx, vag, orgId, file) {
36
+ var _a, _b;
37
+ const fields = { ref_service: '0', title: 'User Upload' };
38
+ if (orgId)
39
+ fields.org_id = orgId;
40
+ const { body, contentType } = (0, request_1.buildMultipartWithFile)(fields, 'file', file);
41
+ const res = (await ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
42
+ method: 'POST',
43
+ url: `${vag}/assets/upload`,
44
+ body,
45
+ headers: { 'content-type': contentType },
46
+ timeout: 60000,
47
+ }));
48
+ const url = (_b = (_a = res === null || res === void 0 ? void 0 : res.url) === null || _a === void 0 ? void 0 : _a.processed) === null || _b === void 0 ? void 0 : _b[0];
49
+ if (!url) {
50
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'ImagineArt upload did not return a URL.');
51
+ }
52
+ return url;
53
+ }
54
+ async function uploadMarketImage(ctx, vag, orgId, file) {
55
+ var _a, _b, _c;
56
+ const fields = {
57
+ ref_service: '4',
58
+ title: 'Ad Studio Upload',
59
+ bytedance_upload: 'true',
60
+ };
61
+ if (orgId)
62
+ fields.org_id = orgId;
63
+ const { body, contentType } = (0, request_1.buildMultipartWithFile)(fields, 'file', file);
64
+ const res = (await ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
65
+ method: 'POST',
66
+ url: `${vag}/assets/upload`,
67
+ body,
68
+ headers: { 'content-type': contentType },
69
+ timeout: 60000,
70
+ }));
71
+ const url = (_b = (_a = res === null || res === void 0 ? void 0 : res.url) === null || _a === void 0 ? void 0 : _a.processed) === null || _b === void 0 ? void 0 : _b[0];
72
+ if (!url) {
73
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'ImagineArt upload did not return a URL.');
74
+ }
75
+ return { url, bytedanceId: (_c = res === null || res === void 0 ? void 0 : res.bytedance_id) !== null && _c !== void 0 ? _c : null };
76
+ }
77
+ async function listMarketCatalog(ctx, vag, endpoint, ownership, mapper) {
78
+ if (ownership === 'all') {
79
+ const [sys, usr] = await Promise.all([
80
+ getJson(ctx, `${vag}${endpoint}?type=system`),
81
+ getJson(ctx, `${vag}${endpoint}?type=user`),
82
+ ]);
83
+ return [...mapper(sys), ...mapper(usr)];
84
+ }
85
+ const body = await getJson(ctx, `${vag}${endpoint}?type=${encodeURIComponent(ownership)}`);
86
+ return mapper(body);
87
+ }
88
+ async function fetchAssetStatus(ctx, vag, id) {
89
+ return (0, status_1.parseStatusResponse)(await ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
90
+ method: 'GET',
91
+ url: `${vag}/assets/${encodeURIComponent(id)}/status`,
92
+ json: true,
93
+ }));
94
+ }
95
+ async function getJson(ctx, url) {
96
+ return ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
97
+ method: 'GET',
98
+ url,
99
+ json: true,
100
+ });
101
+ }
102
+ async function downloadBinary(ctx, url, filename) {
103
+ const downloaded = (await ctx.helpers.httpRequestWithAuthentication.call(ctx, CREDENTIAL, {
104
+ method: 'GET',
105
+ url,
106
+ encoding: 'arraybuffer',
107
+ }));
108
+ return ctx.helpers.prepareBinaryData(Buffer.from(downloaded), filename);
109
+ }
110
+ exports.SHARED_FIELDS = [
111
+ {
112
+ displayName: 'Organization Name or ID',
113
+ name: 'organization',
114
+ type: 'options',
115
+ description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
116
+ typeOptions: { loadOptionsMethod: 'getOrganizations' },
117
+ default: '',
118
+ required: true,
119
+ displayOptions: { hide: { operation: ['getResult'] } },
120
+ },
121
+ {
122
+ displayName: 'Input Binary Field',
123
+ name: 'uploadBinaryProperty',
124
+ type: 'string',
125
+ default: 'data',
126
+ required: true,
127
+ hint: 'The name of the input binary field holding the file to upload',
128
+ displayOptions: { show: { resource: ['asset', 'adStudio'], operation: ['upload', 'uploadImage'] } },
129
+ },
130
+ {
131
+ displayName: 'Folder Name or ID',
132
+ name: 'folderId',
133
+ type: 'options',
134
+ description: 'The workspace folder to use. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
135
+ typeOptions: {
136
+ loadOptionsMethod: 'getFolders',
137
+ loadOptionsDependsOn: ['organization'],
138
+ },
139
+ default: '',
140
+ displayOptions: {
141
+ show: {
142
+ resource: ['image', 'video', 'audio', 'adStudio'],
143
+ operation: ['generate', 'listProjects', 'createProject', 'generateAd'],
144
+ },
145
+ },
146
+ },
147
+ {
148
+ displayName: 'Ownership',
149
+ name: 'adOwnership',
150
+ type: 'options',
151
+ options: (0, adStudio_1.adOwnershipOptions)(),
152
+ default: 'all',
153
+ description: 'Which catalog to list: system defaults, your saved items, or both',
154
+ displayOptions: { show: { resource: ['adStudio'], operation: ['listProducts', 'listAvatars'] } },
155
+ },
156
+ {
157
+ displayName: 'Template Kind',
158
+ name: 'adTemplateKind',
159
+ type: 'options',
160
+ options: (0, adStudio_1.adTemplateKindOptions)(),
161
+ default: 'format',
162
+ displayOptions: { show: { resource: ['adStudio'], operation: ['listTemplates'] } },
163
+ },
164
+ {
165
+ displayName: 'Project Name',
166
+ name: 'adProjectName',
167
+ type: 'string',
168
+ default: '',
169
+ required: true,
170
+ placeholder: 'Spring Campaign',
171
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProject'] } },
172
+ },
173
+ {
174
+ displayName: 'Create From',
175
+ name: 'adProductSource',
176
+ type: 'options',
177
+ options: [
178
+ { name: 'Product URL (Scrape)', value: 'url' },
179
+ { name: 'Uploaded Photos (Manual)', value: 'manual' },
180
+ ],
181
+ default: 'url',
182
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProduct'] } },
183
+ },
184
+ {
185
+ displayName: 'Product URL',
186
+ name: 'adProductUrl',
187
+ type: 'string',
188
+ default: '',
189
+ required: true,
190
+ placeholder: 'https://store.example.com/product/123',
191
+ description: 'A product page to scrape. Creation is async — poll Get Product Status until it is finished.',
192
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProduct'], adProductSource: ['url'] } },
193
+ },
194
+ {
195
+ displayName: 'Product Name',
196
+ name: 'adProductName',
197
+ type: 'string',
198
+ default: '',
199
+ required: true,
200
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProduct'], adProductSource: ['manual'] } },
201
+ },
202
+ {
203
+ displayName: 'Product Description',
204
+ name: 'adProductDescription',
205
+ type: 'string',
206
+ default: '',
207
+ required: true,
208
+ typeOptions: { rows: 2 },
209
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProduct'], adProductSource: ['manual'] } },
210
+ },
211
+ {
212
+ displayName: 'Photos',
213
+ name: 'adProductPhotos',
214
+ type: 'fixedCollection',
215
+ typeOptions: { multipleValues: true },
216
+ placeholder: 'Add Photo',
217
+ default: {},
218
+ description: 'Photos from Upload Image (URL + reference ID)',
219
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createProduct'], adProductSource: ['manual'] } },
220
+ options: [
221
+ {
222
+ name: 'photo',
223
+ displayName: 'Photo',
224
+ values: [
225
+ { displayName: 'URL', name: 'url', type: 'string', default: '' },
226
+ { displayName: 'Reference ID', name: 'bytedanceId', type: 'string', default: '' },
227
+ ],
228
+ },
229
+ ],
230
+ },
231
+ {
232
+ displayName: 'Product ID',
233
+ name: 'adProductId',
234
+ type: 'string',
235
+ default: '',
236
+ required: true,
237
+ displayOptions: { show: { resource: ['adStudio'], operation: ['productStatus'] } },
238
+ },
239
+ {
240
+ displayName: 'Avatar Name',
241
+ name: 'adAvatarName',
242
+ type: 'string',
243
+ default: '',
244
+ required: true,
245
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createAvatar'] } },
246
+ },
247
+ {
248
+ displayName: 'Gender',
249
+ name: 'adAvatarGender',
250
+ type: 'options',
251
+ options: (0, adStudio_1.adGenderOptions)(),
252
+ default: 'neutral',
253
+ required: true,
254
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createAvatar'] } },
255
+ },
256
+ {
257
+ displayName: 'Avatar Description',
258
+ name: 'adAvatarDescription',
259
+ type: 'string',
260
+ default: '',
261
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createAvatar'] } },
262
+ },
263
+ {
264
+ displayName: 'Photos',
265
+ name: 'adAvatarPhotos',
266
+ type: 'fixedCollection',
267
+ typeOptions: { multipleValues: true },
268
+ placeholder: 'Add Photo',
269
+ default: {},
270
+ description: 'Photos from Upload Image (URL)',
271
+ displayOptions: { show: { resource: ['adStudio'], operation: ['createAvatar'] } },
272
+ options: [
273
+ {
274
+ name: 'photo',
275
+ displayName: 'Photo',
276
+ values: [{ displayName: 'URL', name: 'url', type: 'string', default: '' }],
277
+ },
278
+ ],
279
+ },
280
+ {
281
+ displayName: 'Project Name or ID',
282
+ name: 'marketProjectId',
283
+ type: 'options',
284
+ description: 'The marketing project to attach this ad to (loads after a folder is picked). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
285
+ typeOptions: { loadOptionsMethod: 'getMarketProjects', loadOptionsDependsOn: ['folderId'] },
286
+ default: '',
287
+ required: true,
288
+ displayOptions: { show: { resource: ['adStudio'], operation: ['generateAd'] } },
289
+ },
290
+ {
291
+ displayName: 'Reference Images',
292
+ name: 'adImages',
293
+ type: 'fixedCollection',
294
+ typeOptions: { multipleValues: true },
295
+ placeholder: 'Add Image',
296
+ default: {},
297
+ description: 'Product/avatar reference images (URL + reference ID) that drive the ad',
298
+ displayOptions: { show: { resource: ['adStudio'], operation: ['generateAd'] } },
299
+ options: [
300
+ {
301
+ name: 'image',
302
+ displayName: 'Image',
303
+ values: [
304
+ { displayName: 'URL', name: 'url', type: 'string', default: '' },
305
+ { displayName: 'Reference ID', name: 'id', type: 'string', default: '' },
306
+ ],
307
+ },
308
+ ],
309
+ },
310
+ {
311
+ displayName: 'Aspect Ratio',
312
+ name: 'adAspectRatio',
313
+ type: 'options',
314
+ options: (0, adStudio_1.adAspectRatioOptions)(),
315
+ default: '9:16',
316
+ displayOptions: { show: { resource: ['adStudio'], operation: ['generateAd'] } },
317
+ },
318
+ {
319
+ displayName: 'Duration (Seconds)',
320
+ name: 'adDuration',
321
+ type: 'string',
322
+ default: '4',
323
+ displayOptions: { show: { resource: ['adStudio'], operation: ['generateAd'] } },
324
+ },
325
+ {
326
+ displayName: 'Resolution',
327
+ name: 'adResolution',
328
+ type: 'options',
329
+ options: (0, adStudio_1.adResolutionOptions)(),
330
+ default: '480p',
331
+ displayOptions: { show: { resource: ['adStudio'], operation: ['generateAd'] } },
332
+ },
333
+ {
334
+ displayName: 'Prompt',
335
+ name: 'prompt',
336
+ type: 'string',
337
+ default: '',
338
+ required: true,
339
+ typeOptions: { rows: 3 },
340
+ placeholder: 'A red fox in falling snow, cinematic lighting',
341
+ displayOptions: {
342
+ show: {
343
+ resource: ['image', 'video', 'audio', 'adStudio'],
344
+ operation: ['generate', 'generateAd'],
345
+ },
346
+ },
347
+ },
348
+ {
349
+ displayName: 'Image URL',
350
+ name: 'imageUrl',
351
+ type: 'string',
352
+ default: '',
353
+ required: true,
354
+ placeholder: 'https://example.com/photo.jpg',
355
+ description: 'Public URL of the image to process',
356
+ displayOptions: { show: { resource: ['image'], operation: ['enhance', 'removeBackground'] } },
357
+ },
358
+ {
359
+ displayName: 'Model',
360
+ name: 'model',
361
+ type: 'options',
362
+ options: (0, imageModels_1.imageModelOptions)(),
363
+ default: 'nano-banana-pro',
364
+ displayOptions: { show: { resource: ['image'], operation: ['generate'] } },
365
+ },
366
+ {
367
+ displayName: 'Aspect Ratio',
368
+ name: 'aspectRatio',
369
+ type: 'options',
370
+ options: (0, imageModels_1.aspectRatioOptions)(),
371
+ default: '1:1',
372
+ displayOptions: { show: { resource: ['image'], operation: ['generate'] } },
373
+ },
374
+ {
375
+ displayName: 'Brand Name',
376
+ name: 'logoBrandName',
377
+ type: 'string',
378
+ default: '',
379
+ required: true,
380
+ displayOptions: { show: { resource: ['image'], operation: ['logo'] } },
381
+ },
382
+ {
383
+ displayName: 'Logo Style',
384
+ name: 'logoStyle',
385
+ type: 'string',
386
+ default: '',
387
+ placeholder: 'modern wordmark with icon, minimal',
388
+ description: 'Include "horizontal" or "wide" for a 16:9 layout; otherwise 1:1',
389
+ displayOptions: { show: { resource: ['image'], operation: ['logo'] } },
390
+ },
391
+ {
392
+ displayName: 'Industry',
393
+ name: 'logoIndustry',
394
+ type: 'string',
395
+ default: '',
396
+ placeholder: 'technology',
397
+ displayOptions: { show: { resource: ['image'], operation: ['logo'] } },
398
+ },
399
+ {
400
+ displayName: 'Color Scheme',
401
+ name: 'logoPalette',
402
+ type: 'string',
403
+ default: '',
404
+ placeholder: 'brand blue and white',
405
+ displayOptions: { show: { resource: ['image'], operation: ['logo'] } },
406
+ },
407
+ {
408
+ displayName: 'Background',
409
+ name: 'logoBackground',
410
+ type: 'options',
411
+ options: [
412
+ { name: 'Black', value: 'black' },
413
+ { name: 'Transparent', value: 'transparent' },
414
+ { name: 'White', value: 'white' },
415
+ ],
416
+ default: 'white',
417
+ displayOptions: { show: { resource: ['image'], operation: ['logo'] } },
418
+ },
419
+ {
420
+ displayName: 'Brief',
421
+ name: 'igBrief',
422
+ type: 'string',
423
+ default: '',
424
+ required: true,
425
+ typeOptions: { rows: 2 },
426
+ displayOptions: { show: { resource: ['image'], operation: ['instagramPost'] } },
427
+ },
428
+ {
429
+ displayName: 'Brand Style',
430
+ name: 'igBrandStyle',
431
+ type: 'string',
432
+ default: '',
433
+ placeholder: 'modern, vibrant, clean typography, lifestyle photography aesthetic',
434
+ displayOptions: { show: { resource: ['image'], operation: ['instagramPost'] } },
435
+ },
436
+ {
437
+ displayName: 'Format',
438
+ name: 'igFormat',
439
+ type: 'options',
440
+ options: [
441
+ { name: '1:1 (Square)', value: '1:1' },
442
+ { name: '4:5 (Portrait)', value: '4:5' },
443
+ { name: '9:16 (Story)', value: '9:16' },
444
+ ],
445
+ default: '4:5',
446
+ displayOptions: { show: { resource: ['image'], operation: ['instagramPost'] } },
447
+ },
448
+ {
449
+ displayName: 'Room Type',
450
+ name: 'interiorRoomType',
451
+ type: 'string',
452
+ default: '',
453
+ required: true,
454
+ placeholder: 'living room',
455
+ displayOptions: { show: { resource: ['image'], operation: ['interiorDesign'] } },
456
+ },
457
+ {
458
+ displayName: 'Design Style',
459
+ name: 'interiorStyle',
460
+ type: 'string',
461
+ default: '',
462
+ placeholder: 'modern minimalist',
463
+ displayOptions: { show: { resource: ['image'], operation: ['interiorDesign'] } },
464
+ },
465
+ {
466
+ displayName: 'Color Palette',
467
+ name: 'interiorPalette',
468
+ type: 'string',
469
+ default: '',
470
+ placeholder: 'neutral tones with wood accents',
471
+ displayOptions: { show: { resource: ['image'], operation: ['interiorDesign'] } },
472
+ },
473
+ {
474
+ displayName: 'Specific Elements',
475
+ name: 'interiorElements',
476
+ type: 'string',
477
+ default: '',
478
+ displayOptions: { show: { resource: ['image'], operation: ['interiorDesign'] } },
479
+ },
480
+ {
481
+ displayName: 'Room Photo URL',
482
+ name: 'interiorRoomPhoto',
483
+ type: 'string',
484
+ default: '',
485
+ description: 'Optional reference photo — redesigns the existing room (img2img)',
486
+ displayOptions: { show: { resource: ['image'], operation: ['interiorDesign'] } },
487
+ },
488
+ {
489
+ displayName: 'Title',
490
+ name: 'ytTitle',
491
+ type: 'string',
492
+ default: '',
493
+ required: true,
494
+ displayOptions: { show: { resource: ['image'], operation: ['youtubeThumbnail'] } },
495
+ },
496
+ {
497
+ displayName: 'Channel Style',
498
+ name: 'ytChannelStyle',
499
+ type: 'string',
500
+ default: '',
501
+ placeholder: 'bold, high contrast, bright colors',
502
+ displayOptions: { show: { resource: ['image'], operation: ['youtubeThumbnail'] } },
503
+ },
504
+ {
505
+ displayName: 'Subject Description',
506
+ name: 'ytSubject',
507
+ type: 'string',
508
+ default: '',
509
+ displayOptions: { show: { resource: ['image'], operation: ['youtubeThumbnail'] } },
510
+ },
511
+ {
512
+ displayName: 'Product Image URL',
513
+ name: 'giantProductImage',
514
+ type: 'string',
515
+ default: '',
516
+ required: true,
517
+ placeholder: 'https://example.com/product.jpg',
518
+ displayOptions: { show: { resource: ['image'], operation: ['giantProduct'] } },
519
+ },
520
+ {
521
+ displayName: 'Person Description',
522
+ name: 'giantPerson',
523
+ type: 'string',
524
+ default: '',
525
+ placeholder: 'a stylishly dressed man',
526
+ displayOptions: { show: { resource: ['image'], operation: ['giantProduct'] } },
527
+ },
528
+ {
529
+ displayName: 'Product Name',
530
+ name: 'ugcProductName',
531
+ type: 'string',
532
+ default: '',
533
+ required: true,
534
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
535
+ },
536
+ {
537
+ displayName: 'Product Image URL',
538
+ name: 'ugcProductImageUrl',
539
+ type: 'string',
540
+ default: '',
541
+ required: true,
542
+ placeholder: 'https://example.com/product.jpg',
543
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
544
+ },
545
+ {
546
+ displayName: 'Product Type',
547
+ name: 'ugcProductType',
548
+ type: 'string',
549
+ default: '',
550
+ placeholder: 'wearable / accessory',
551
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
552
+ },
553
+ {
554
+ displayName: 'Model Description',
555
+ name: 'ugcModelDescription',
556
+ type: 'string',
557
+ default: '',
558
+ placeholder: 'woman, 25-30 years old, natural look, diverse',
559
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
560
+ },
561
+ {
562
+ displayName: 'Setting',
563
+ name: 'ugcSetting',
564
+ type: 'string',
565
+ default: '',
566
+ placeholder: 'casual lifestyle, natural lighting',
567
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
568
+ },
569
+ {
570
+ displayName: 'Platform',
571
+ name: 'ugcPlatform',
572
+ type: 'options',
573
+ options: [
574
+ { name: 'Amazon', value: 'amazon' },
575
+ { name: 'Instagram', value: 'instagram' },
576
+ { name: 'Pinterest', value: 'pinterest' },
577
+ { name: 'TikTok', value: 'tiktok' },
578
+ ],
579
+ default: 'instagram',
580
+ displayOptions: { show: { resource: ['image'], operation: ['ugcTryon'] } },
581
+ },
582
+ {
583
+ displayName: 'Location or Subject',
584
+ name: 'droneSubject',
585
+ type: 'string',
586
+ default: '',
587
+ required: true,
588
+ displayOptions: { show: { resource: ['video'], operation: ['droneVideo'] } },
589
+ },
590
+ {
591
+ displayName: 'Shot Type',
592
+ name: 'droneShotType',
593
+ type: 'options',
594
+ options: [
595
+ { name: 'Flyover', value: 'flyover' },
596
+ { name: 'Orbit', value: 'orbit' },
597
+ { name: 'Reveal', value: 'reveal' },
598
+ { name: 'Top Down', value: 'top-down' },
599
+ ],
600
+ default: 'reveal',
601
+ displayOptions: { show: { resource: ['video'], operation: ['droneVideo'] } },
602
+ },
603
+ {
604
+ displayName: 'Style',
605
+ name: 'droneStyle',
606
+ type: 'string',
607
+ default: '',
608
+ placeholder: 'golden hour, cinematic, 4K, ultra-detailed',
609
+ displayOptions: { show: { resource: ['video'], operation: ['droneVideo'] } },
610
+ },
611
+ {
612
+ displayName: 'Reference Image URL',
613
+ name: 'droneReferenceImage',
614
+ type: 'string',
615
+ default: '',
616
+ description: 'Optional first frame — runs image-to-video when set',
617
+ displayOptions: { show: { resource: ['video'], operation: ['droneVideo'] } },
618
+ },
619
+ {
620
+ displayName: 'Model',
621
+ name: 'droneModel',
622
+ type: 'options',
623
+ options: (0, videoModels_1.videoModelOptions)(),
624
+ default: 'veo-3.1',
625
+ displayOptions: { show: { resource: ['video'], operation: ['droneVideo'] } },
626
+ },
627
+ {
628
+ displayName: 'Product Image URL',
629
+ name: 'paProductImageUrl',
630
+ type: 'string',
631
+ default: '',
632
+ required: true,
633
+ placeholder: 'https://example.com/product.jpg',
634
+ displayOptions: { show: { resource: ['video'], operation: ['productAd'] } },
635
+ },
636
+ {
637
+ displayName: 'Brand Brief',
638
+ name: 'paBrandBrief',
639
+ type: 'string',
640
+ default: '',
641
+ required: true,
642
+ typeOptions: { rows: 2 },
643
+ displayOptions: { show: { resource: ['video'], operation: ['productAd'] } },
644
+ },
645
+ {
646
+ displayName: 'Mood',
647
+ name: 'paMood',
648
+ type: 'string',
649
+ default: '',
650
+ placeholder: 'luxury / playful / minimal / tech',
651
+ displayOptions: { show: { resource: ['video'], operation: ['productAd'] } },
652
+ },
653
+ {
654
+ displayName: 'Resolution',
655
+ name: 'paResolution',
656
+ type: 'options',
657
+ options: [
658
+ { name: '1080p', value: '1080p' },
659
+ { name: '4k', value: '4k' },
660
+ { name: '720p', value: '720p' },
661
+ ],
662
+ default: '1080p',
663
+ displayOptions: { show: { resource: ['video'], operation: ['productAd'] } },
664
+ },
665
+ {
666
+ displayName: 'Model',
667
+ name: 'paModel',
668
+ type: 'options',
669
+ options: (0, videoModels_1.videoModelOptions)(),
670
+ default: 'veo-3.1',
671
+ displayOptions: { show: { resource: ['video'], operation: ['productAd'] } },
672
+ },
673
+ {
674
+ displayName: 'Person Image URL',
675
+ name: 'cookingPersonImage',
676
+ type: 'string',
677
+ default: '',
678
+ required: true,
679
+ placeholder: 'https://example.com/person.jpg',
680
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
681
+ },
682
+ {
683
+ displayName: 'Dish',
684
+ name: 'cookingDish',
685
+ type: 'string',
686
+ default: '',
687
+ placeholder: 'fresh pasta',
688
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
689
+ },
690
+ {
691
+ displayName: 'Kitchen Style',
692
+ name: 'cookingKitchenStyle',
693
+ type: 'string',
694
+ default: '',
695
+ placeholder: 'Italian rustic-modern',
696
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
697
+ },
698
+ {
699
+ displayName: 'Outfit',
700
+ name: 'cookingOutfit',
701
+ type: 'string',
702
+ default: '',
703
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
704
+ },
705
+ {
706
+ displayName: 'Duration (Seconds)',
707
+ name: 'cookingDurationSeconds',
708
+ type: 'number',
709
+ default: 15,
710
+ typeOptions: { minValue: 1 },
711
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
712
+ },
713
+ {
714
+ displayName: 'Resolution',
715
+ name: 'cookingResolution',
716
+ type: 'options',
717
+ options: [
718
+ { name: '1080p', value: '1080p' },
719
+ { name: '480p', value: '480p' },
720
+ { name: '720p', value: '720p' },
721
+ ],
722
+ default: '720p',
723
+ displayOptions: { show: { resource: ['video'], operation: ['cookingVideo'] } },
724
+ },
725
+ {
726
+ displayName: 'Jewelry Description',
727
+ name: 'jewelryDescription',
728
+ type: 'string',
729
+ default: '',
730
+ placeholder: 'a delicate rose gold ring with a lotus design and a sparkling diamond',
731
+ displayOptions: { show: { resource: ['video'], operation: ['jewelryVideo'] } },
732
+ },
733
+ {
734
+ displayName: 'Surface Description',
735
+ name: 'jewelrySurface',
736
+ type: 'string',
737
+ default: '',
738
+ placeholder: 'a beige surface',
739
+ displayOptions: { show: { resource: ['video'], operation: ['jewelryVideo'] } },
740
+ },
741
+ {
742
+ displayName: 'Duration (Seconds)',
743
+ name: 'jewelryDuration',
744
+ type: 'number',
745
+ default: 5,
746
+ typeOptions: { minValue: 1 },
747
+ displayOptions: { show: { resource: ['video'], operation: ['jewelryVideo'] } },
748
+ },
749
+ {
750
+ displayName: 'Resolution',
751
+ name: 'jewelryResolution',
752
+ type: 'options',
753
+ options: [
754
+ { name: '1080p', value: '1080p' },
755
+ { name: '4k', value: '4k' },
756
+ { name: '720p', value: '720p' },
757
+ ],
758
+ default: '1080p',
759
+ displayOptions: { show: { resource: ['video'], operation: ['jewelryVideo'] } },
760
+ },
761
+ {
762
+ displayName: 'Model',
763
+ name: 'jewelryModel',
764
+ type: 'options',
765
+ options: (0, videoModels_1.videoModelOptions)(),
766
+ default: 'kling-2.6-pro',
767
+ displayOptions: { show: { resource: ['video'], operation: ['jewelryVideo'] } },
768
+ },
769
+ {
770
+ displayName: 'Logo Image URL',
771
+ name: 'logo3dImageUrl',
772
+ type: 'string',
773
+ default: '',
774
+ required: true,
775
+ placeholder: 'https://example.com/logo.png',
776
+ description: 'A flat 2D logo to convert to 3D and animate',
777
+ displayOptions: { show: { resource: ['video'], operation: ['logo3d'] } },
778
+ },
779
+ {
780
+ displayName: 'Material Style',
781
+ name: 'logo3dMaterial',
782
+ type: 'string',
783
+ default: '',
784
+ placeholder: 'glossy glass and chrome',
785
+ displayOptions: { show: { resource: ['video'], operation: ['logo3d'] } },
786
+ },
787
+ {
788
+ displayName: 'Duration (Seconds)',
789
+ name: 'logo3dDuration',
790
+ type: 'number',
791
+ default: 6,
792
+ typeOptions: { minValue: 1 },
793
+ displayOptions: { show: { resource: ['video'], operation: ['logo3d'] } },
794
+ },
795
+ {
796
+ displayName: 'Resolution',
797
+ name: 'logo3dResolution',
798
+ type: 'options',
799
+ options: [
800
+ { name: '1080p', value: '1080p' },
801
+ { name: '4k', value: '4k' },
802
+ { name: '720p', value: '720p' },
803
+ ],
804
+ default: '1080p',
805
+ displayOptions: { show: { resource: ['video'], operation: ['logo3d'] } },
806
+ },
807
+ {
808
+ displayName: 'Model',
809
+ name: 'logo3dModel',
810
+ type: 'options',
811
+ options: (0, videoModels_1.videoModelOptions)(),
812
+ default: 'veo-3.1-fast',
813
+ displayOptions: { show: { resource: ['video'], operation: ['logo3d'] } },
814
+ },
815
+ {
816
+ displayName: 'Model',
817
+ name: 'videoModel',
818
+ type: 'options',
819
+ options: (0, videoModels_1.videoModelOptions)(),
820
+ default: 'ltx-2.3',
821
+ displayOptions: { show: { resource: ['video'], operation: ['generate'] } },
822
+ },
823
+ {
824
+ displayName: 'Aspect Ratio',
825
+ name: 'videoAspectRatio',
826
+ type: 'options',
827
+ options: (0, videoModels_1.videoAspectRatioOptions)(),
828
+ default: '16:9',
829
+ displayOptions: { show: { resource: ['video'], operation: ['generate'] } },
830
+ },
831
+ {
832
+ displayName: 'Duration',
833
+ name: 'duration',
834
+ type: 'options',
835
+ options: (0, videoModels_1.videoDurationOptions)(),
836
+ default: '6',
837
+ displayOptions: { show: { resource: ['video'], operation: ['generate'] } },
838
+ },
839
+ {
840
+ displayName: 'Duration (Seconds)',
841
+ name: 'musicDuration',
842
+ type: 'number',
843
+ default: 10,
844
+ typeOptions: { minValue: 1 },
845
+ displayOptions: { show: { resource: ['audio'], operation: ['generate'] } },
846
+ },
847
+ {
848
+ displayName: 'Variation',
849
+ name: 'musicVariation',
850
+ type: 'string',
851
+ default: 'music',
852
+ description: 'Music variation preset',
853
+ displayOptions: { show: { resource: ['audio'], operation: ['generate'] } },
854
+ },
855
+ {
856
+ displayName: 'Asset ID',
857
+ name: 'assetId',
858
+ type: 'string',
859
+ default: '',
860
+ required: true,
861
+ description: 'The asset ID returned by a Generate action (`assetId`)',
862
+ displayOptions: { show: { operation: ['getResult'] } },
863
+ },
864
+ ];
865
+ exports.LOAD_OPTIONS = { getOrganizations: loadOptions_1.getOrganizations, getFolders: loadOptions_1.getFolders, getMarketProjects: loadOptions_1.getMarketProjects };
866
+ const OPERATIONS = {
867
+ image: {
868
+ default: 'generate',
869
+ options: [
870
+ {
871
+ name: 'Enhance',
872
+ value: 'enhance',
873
+ action: 'Enhance an image',
874
+ description: 'Upscale and enhance an existing image',
875
+ },
876
+ {
877
+ name: 'Generate',
878
+ value: 'generate',
879
+ action: 'Generate an image',
880
+ description: 'Generate an image from a text prompt',
881
+ },
882
+ {
883
+ name: 'Generate Giant Product Showcase',
884
+ value: 'giantProduct',
885
+ action: 'Generate a giant product showcase',
886
+ description: 'Enlarge a product to building scale beside a person (needs a product image)',
887
+ },
888
+ {
889
+ name: 'Generate Instagram Post',
890
+ value: 'instagramPost',
891
+ action: 'Generate an instagram post image',
892
+ description: 'Generate a scroll-stopping Instagram hero image from a brief',
893
+ },
894
+ {
895
+ name: 'Generate Interior Design',
896
+ value: 'interiorDesign',
897
+ action: 'Generate an interior design render',
898
+ description: 'Render a room design, optionally from a reference photo',
899
+ },
900
+ {
901
+ name: 'Generate Logo',
902
+ value: 'logo',
903
+ action: 'Generate a logo',
904
+ description: 'Generate a clean vector-style brand logo',
905
+ },
906
+ {
907
+ name: 'Generate UGC Try-On',
908
+ value: 'ugcTryon',
909
+ action: 'Generate a ugc try on image',
910
+ description: 'Create a UGC lifestyle try-on photo (needs a product image)',
911
+ },
912
+ {
913
+ name: 'Generate YouTube Thumbnail',
914
+ value: 'youtubeThumbnail',
915
+ action: 'Generate a you tube thumbnail',
916
+ description: 'Generate a high click-through 16:9 thumbnail image',
917
+ },
918
+ {
919
+ name: 'Get Result',
920
+ value: 'getResult',
921
+ action: 'Get an image result',
922
+ description: 'Fetch a submitted image generation and download it once ready',
923
+ },
924
+ {
925
+ name: 'Remove Background',
926
+ value: 'removeBackground',
927
+ action: 'Remove an image background',
928
+ description: 'Remove the background from an existing image',
929
+ },
930
+ ],
931
+ },
932
+ video: {
933
+ default: 'generate',
934
+ options: [
935
+ {
936
+ name: 'Generate',
937
+ value: 'generate',
938
+ action: 'Generate a video',
939
+ description: 'Submit a text-to-video generation (returns an asset ID to poll)',
940
+ },
941
+ {
942
+ name: 'Generate 3D Logo Animation',
943
+ value: 'logo3d',
944
+ action: 'Generate a 3d logo animation',
945
+ description: 'Turn a flat 2D logo into an animated 3D reveal (returns an asset ID to poll)',
946
+ },
947
+ {
948
+ name: 'Generate Cooking Video',
949
+ value: 'cookingVideo',
950
+ action: 'Generate a cooking video',
951
+ description: 'Turn a person photo into a cooking tutorial video (returns an asset ID to poll)',
952
+ },
953
+ {
954
+ name: 'Generate Drone Video',
955
+ value: 'droneVideo',
956
+ action: 'Generate a drone video',
957
+ description: 'Submit a cinematic aerial drone video (returns an asset ID to poll)',
958
+ },
959
+ {
960
+ name: 'Generate Jewelry Video',
961
+ value: 'jewelryVideo',
962
+ action: 'Generate a jewelry video',
963
+ description: 'Generate a luxury jewelry ad video from a text description (returns an asset ID to poll)',
964
+ },
965
+ {
966
+ name: 'Generate Product Ad',
967
+ value: 'productAd',
968
+ action: 'Generate a product ad video',
969
+ description: 'Submit a cinematic product ad from a product image (returns an asset ID to poll)',
970
+ },
971
+ {
972
+ name: 'Get Result',
973
+ value: 'getResult',
974
+ action: 'Get a video result',
975
+ description: 'Check a submitted video and return it once it is ready',
976
+ },
977
+ ],
978
+ },
979
+ audio: {
980
+ default: 'generate',
981
+ options: [
982
+ {
983
+ name: 'Generate',
984
+ value: 'generate',
985
+ action: 'Generate music',
986
+ description: 'Generate music from a text prompt',
987
+ },
988
+ {
989
+ name: 'Get Result',
990
+ value: 'getResult',
991
+ action: 'Get a music result',
992
+ description: 'Fetch a submitted music generation and download it once ready',
993
+ },
994
+ ],
995
+ },
996
+ asset: {
997
+ default: 'listGenerations',
998
+ options: [
999
+ {
1000
+ name: 'List Generations',
1001
+ value: 'listGenerations',
1002
+ action: 'List generated assets',
1003
+ description: 'List finished image and video generations',
1004
+ },
1005
+ {
1006
+ name: 'List Uploaded Assets',
1007
+ value: 'listUploadedAssets',
1008
+ action: 'List uploaded assets',
1009
+ description: 'List assets you have uploaded',
1010
+ },
1011
+ {
1012
+ name: 'Upload',
1013
+ value: 'upload',
1014
+ action: 'Upload a file',
1015
+ description: 'Upload a binary file and get its asset URL',
1016
+ },
1017
+ ],
1018
+ },
1019
+ account: {
1020
+ default: 'getBalance',
1021
+ options: [
1022
+ {
1023
+ name: 'Get Balance',
1024
+ value: 'getBalance',
1025
+ action: 'Get the credit balance',
1026
+ description: 'Get the credit balance for the organization',
1027
+ },
1028
+ ],
1029
+ },
1030
+ adStudio: {
1031
+ default: 'generateAd',
1032
+ options: [
1033
+ {
1034
+ name: 'Create Avatar',
1035
+ value: 'createAvatar',
1036
+ action: 'Create an ad avatar',
1037
+ description: 'Create a marketing avatar from uploaded photos',
1038
+ },
1039
+ {
1040
+ name: 'Create Product',
1041
+ value: 'createProduct',
1042
+ action: 'Create an ad product',
1043
+ description: 'Create a marketing product from a URL or uploaded photos',
1044
+ },
1045
+ {
1046
+ name: 'Create Project',
1047
+ value: 'createProject',
1048
+ action: 'Create a marketing project',
1049
+ description: 'Create a marketing project (campaign) in a folder',
1050
+ },
1051
+ {
1052
+ name: 'Generate Ad',
1053
+ value: 'generateAd',
1054
+ action: 'Generate an ad video',
1055
+ description: 'Generate an ad video from a prompt and product/avatar references',
1056
+ },
1057
+ {
1058
+ name: 'Get Product Status',
1059
+ value: 'productStatus',
1060
+ action: 'Get product status',
1061
+ description: 'Poll a from-URL product until it finishes scraping',
1062
+ },
1063
+ {
1064
+ name: 'Get Result',
1065
+ value: 'getResult',
1066
+ action: 'Get an ad result',
1067
+ description: 'Fetch a submitted ad generation and download it once ready',
1068
+ },
1069
+ {
1070
+ name: 'List Avatars',
1071
+ value: 'listAvatars',
1072
+ action: 'List ad avatars',
1073
+ description: 'List marketing avatars (system and/or saved)',
1074
+ },
1075
+ {
1076
+ name: 'List Products',
1077
+ value: 'listProducts',
1078
+ action: 'List ad products',
1079
+ description: 'List marketing products (system and/or saved)',
1080
+ },
1081
+ {
1082
+ name: 'List Projects',
1083
+ value: 'listProjects',
1084
+ action: 'List marketing projects',
1085
+ description: 'List marketing projects in a folder',
1086
+ },
1087
+ {
1088
+ name: 'List Templates',
1089
+ value: 'listTemplates',
1090
+ action: 'List ad templates',
1091
+ description: 'List ad templates (formats, backgrounds, or hooks)',
1092
+ },
1093
+ {
1094
+ name: 'Upload Image',
1095
+ value: 'uploadImage',
1096
+ action: 'Upload an ad image',
1097
+ description: 'Upload a product/avatar photo and get its URL and reference ID',
1098
+ },
1099
+ ],
1100
+ },
1101
+ };
1102
+ exports.RESOURCE_DROPDOWN = {
1103
+ displayName: 'Resource',
1104
+ name: 'resource',
1105
+ type: 'options',
1106
+ noDataExpression: true,
1107
+ options: [
1108
+ { name: 'Account', value: 'account' },
1109
+ { name: 'Ad Studio', value: 'adStudio' },
1110
+ { name: 'Asset', value: 'asset' },
1111
+ { name: 'Audio', value: 'audio' },
1112
+ { name: 'Image', value: 'image' },
1113
+ { name: 'Video', value: 'video' },
1114
+ ],
1115
+ default: 'image',
1116
+ };
1117
+ function operationDropdownFor(resource) {
1118
+ const spec = OPERATIONS[resource];
1119
+ return {
1120
+ displayName: 'Operation',
1121
+ name: 'operation',
1122
+ type: 'options',
1123
+ noDataExpression: true,
1124
+ displayOptions: { show: { resource: [resource] } },
1125
+ options: spec.options,
1126
+ default: spec.default,
1127
+ };
1128
+ }
1129
+ exports.OPERATION_DROPDOWNS = Object.keys(OPERATIONS).map(operationDropdownFor);
1130
+ async function executeImagineArt() {
1131
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
1132
+ const items = this.getInputData();
1133
+ const returnData = [];
1134
+ const { vag } = constants_1.BASE_URLS;
1135
+ for (let i = 0; i < items.length; i++) {
1136
+ try {
1137
+ const resource = this.getNodeParameter('resource', i);
1138
+ const operation = this.getNodeParameter('operation', i);
1139
+ if (resource === 'image' && operation === 'generate') {
1140
+ const orgId = this.getNodeParameter('organization', i);
1141
+ const prompt = this.getNodeParameter('prompt', i);
1142
+ const { config, aspectRatio, model } = (0, imageModels_1.resolveImageModel)(this.getNodeParameter('model', i), this.getNodeParameter('aspectRatio', i));
1143
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1144
+ prompt,
1145
+ styleId: config.styleId,
1146
+ variation: config.variation,
1147
+ aspectRatio,
1148
+ orgId,
1149
+ folderId: this.getNodeParameter('folderId', i, ''),
1150
+ }));
1151
+ returnData.push({
1152
+ json: {
1153
+ assetId: id,
1154
+ status: 'queued',
1155
+ done: false,
1156
+ resource: 'image',
1157
+ model,
1158
+ aspectRatio,
1159
+ filename: 'imagineart.png',
1160
+ },
1161
+ pairedItem: { item: i },
1162
+ });
1163
+ }
1164
+ else if (resource === 'image' && operation === 'enhance') {
1165
+ const orgId = this.getNodeParameter('organization', i);
1166
+ const imageUrl = this.getNodeParameter('imageUrl', i);
1167
+ const id = await submitMultipart(this, vag, '/image/enhance/upload', {
1168
+ image_url: imageUrl,
1169
+ style_id: '40201',
1170
+ org_id: orgId,
1171
+ });
1172
+ returnData.push({
1173
+ json: {
1174
+ assetId: id,
1175
+ status: 'queued',
1176
+ done: false,
1177
+ resource: 'image',
1178
+ filename: 'imagineart-enhanced.png',
1179
+ },
1180
+ pairedItem: { item: i },
1181
+ });
1182
+ }
1183
+ else if (resource === 'image' && operation === 'removeBackground') {
1184
+ const orgId = this.getNodeParameter('organization', i);
1185
+ const imageUrl = this.getNodeParameter('imageUrl', i);
1186
+ const id = await submitMultipart(this, vag, '/image/background/remover/upload', {
1187
+ image_url: imageUrl,
1188
+ org_id: orgId,
1189
+ });
1190
+ returnData.push({
1191
+ json: {
1192
+ assetId: id,
1193
+ status: 'queued',
1194
+ done: false,
1195
+ resource: 'image',
1196
+ filename: 'imagineart-no-bg.png',
1197
+ },
1198
+ pairedItem: { item: i },
1199
+ });
1200
+ }
1201
+ else if (resource === 'image' && operation === 'logo') {
1202
+ const orgId = this.getNodeParameter('organization', i);
1203
+ const style = this.getNodeParameter('logoStyle', i);
1204
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('ideogram-v4', (0, prompts_1.resolveLogoAspect)(style));
1205
+ const prompt = (0, prompts_1.buildLogoPrompt)(this.getNodeParameter('logoBrandName', i), style, this.getNodeParameter('logoIndustry', i), this.getNodeParameter('logoPalette', i), this.getNodeParameter('logoBackground', i));
1206
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({ prompt, styleId: config.styleId, variation: 'txt2img', aspectRatio, orgId }));
1207
+ returnData.push({
1208
+ json: {
1209
+ assetId: id,
1210
+ status: 'queued',
1211
+ done: false,
1212
+ resource: 'image',
1213
+ filename: 'imagineart-logo.png',
1214
+ },
1215
+ pairedItem: { item: i },
1216
+ });
1217
+ }
1218
+ else if (resource === 'image' && operation === 'instagramPost') {
1219
+ const orgId = this.getNodeParameter('organization', i);
1220
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('nano-banana-pro', (0, prompts_1.resolveInstagramFormat)(this.getNodeParameter('igFormat', i)));
1221
+ const prompt = (0, prompts_1.buildInstagramPrompt)(this.getNodeParameter('igBrief', i), this.getNodeParameter('igBrandStyle', i));
1222
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({ prompt, styleId: config.styleId, variation: 'txt2img', aspectRatio, orgId }));
1223
+ returnData.push({
1224
+ json: {
1225
+ assetId: id,
1226
+ status: 'queued',
1227
+ done: false,
1228
+ resource: 'image',
1229
+ filename: 'imagineart-instagram.png',
1230
+ },
1231
+ pairedItem: { item: i },
1232
+ });
1233
+ }
1234
+ else if (resource === 'image' && operation === 'interiorDesign') {
1235
+ const orgId = this.getNodeParameter('organization', i);
1236
+ const roomPhoto = this.getNodeParameter('interiorRoomPhoto', i).trim();
1237
+ const hasPhoto = roomPhoto !== '';
1238
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('nano-banana-pro', '16:9');
1239
+ const prompt = (0, prompts_1.buildInteriorPrompt)(this.getNodeParameter('interiorRoomType', i), this.getNodeParameter('interiorStyle', i), this.getNodeParameter('interiorPalette', i), this.getNodeParameter('interiorElements', i), hasPhoto);
1240
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1241
+ prompt,
1242
+ styleId: config.styleId,
1243
+ variation: hasPhoto ? 'img2img' : 'txt2img',
1244
+ aspectRatio,
1245
+ orgId,
1246
+ imageUrl: hasPhoto ? roomPhoto : undefined,
1247
+ }));
1248
+ returnData.push({
1249
+ json: {
1250
+ assetId: id,
1251
+ status: 'queued',
1252
+ done: false,
1253
+ resource: 'image',
1254
+ filename: 'imagineart-interior.png',
1255
+ },
1256
+ pairedItem: { item: i },
1257
+ });
1258
+ }
1259
+ else if (resource === 'image' && operation === 'youtubeThumbnail') {
1260
+ const orgId = this.getNodeParameter('organization', i);
1261
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('nano-banana-pro', '16:9');
1262
+ const prompt = (0, prompts_1.buildYouTubeThumbnailPrompt)(this.getNodeParameter('ytTitle', i), this.getNodeParameter('ytChannelStyle', i), this.getNodeParameter('ytSubject', i));
1263
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({ prompt, styleId: config.styleId, variation: 'txt2img', aspectRatio, orgId }));
1264
+ returnData.push({
1265
+ json: {
1266
+ assetId: id,
1267
+ status: 'queued',
1268
+ done: false,
1269
+ resource: 'image',
1270
+ filename: 'imagineart-thumbnail.png',
1271
+ },
1272
+ pairedItem: { item: i },
1273
+ });
1274
+ }
1275
+ else if (resource === 'image' && operation === 'giantProduct') {
1276
+ const orgId = this.getNodeParameter('organization', i);
1277
+ const productImage = this.getNodeParameter('giantProductImage', i).trim();
1278
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('nano-banana-pro', '3:4');
1279
+ const prompt = (0, prompts_1.buildGiantProductPrompt)(this.getNodeParameter('giantPerson', i));
1280
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1281
+ prompt,
1282
+ styleId: config.styleId,
1283
+ variation: 'img2img',
1284
+ aspectRatio,
1285
+ orgId,
1286
+ imageUrl: productImage,
1287
+ }));
1288
+ returnData.push({
1289
+ json: {
1290
+ assetId: id,
1291
+ status: 'queued',
1292
+ done: false,
1293
+ resource: 'image',
1294
+ filename: 'imagineart-showcase.png',
1295
+ },
1296
+ pairedItem: { item: i },
1297
+ });
1298
+ }
1299
+ else if (resource === 'image' && operation === 'ugcTryon') {
1300
+ const orgId = this.getNodeParameter('organization', i);
1301
+ const productImageUrl = this.getNodeParameter('ugcProductImageUrl', i).trim();
1302
+ const { config, aspectRatio } = (0, imageModels_1.resolveImageModel)('nano-banana-pro', (0, prompts_1.resolveUGCAspect)(this.getNodeParameter('ugcPlatform', i)));
1303
+ const prompt = (0, prompts_1.buildUGCPrompt)(this.getNodeParameter('ugcProductName', i), this.getNodeParameter('ugcProductType', i), this.getNodeParameter('ugcModelDescription', i), this.getNodeParameter('ugcSetting', i));
1304
+ const id = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1305
+ prompt,
1306
+ styleId: config.styleId,
1307
+ variation: 'img2img',
1308
+ aspectRatio,
1309
+ orgId,
1310
+ imageUrl: productImageUrl,
1311
+ }));
1312
+ returnData.push({
1313
+ json: {
1314
+ assetId: id,
1315
+ status: 'queued',
1316
+ done: false,
1317
+ resource: 'image',
1318
+ filename: 'imagineart-ugc.png',
1319
+ },
1320
+ pairedItem: { item: i },
1321
+ });
1322
+ }
1323
+ else if (resource === 'video' && operation === 'droneVideo') {
1324
+ const orgId = this.getNodeParameter('organization', i);
1325
+ const referenceImage = this.getNodeParameter('droneReferenceImage', i).trim();
1326
+ const { config, aspectRatio, duration, model } = (0, videoModels_1.resolveVideoModel)(this.getNodeParameter('droneModel', i), '16:9', '6');
1327
+ const prompt = (0, prompts_1.buildDronePrompt)(this.getNodeParameter('droneSubject', i), this.getNodeParameter('droneShotType', i), this.getNodeParameter('droneStyle', i));
1328
+ const id = await submitMultipart(this, vag, '/video/upload', (0, request_1.buildVideoForm)({
1329
+ prompt,
1330
+ styleId: config.styleId,
1331
+ variation: referenceImage ? 'image_to_video' : 'text_to_video',
1332
+ aspectRatio,
1333
+ duration,
1334
+ orgId,
1335
+ resolution: (0, videoModels_1.resolveVideoResolution)(config, ''),
1336
+ imageUrl: referenceImage || undefined,
1337
+ }));
1338
+ returnData.push({
1339
+ json: { assetId: id, status: 'queued', done: false, resource: 'video', model, aspectRatio, duration, filename: 'imagineart.mp4' },
1340
+ pairedItem: { item: i },
1341
+ });
1342
+ }
1343
+ else if (resource === 'video' && operation === 'productAd') {
1344
+ const orgId = this.getNodeParameter('organization', i);
1345
+ const productImageUrl = this.getNodeParameter('paProductImageUrl', i).trim();
1346
+ const { config, aspectRatio, duration, model } = (0, videoModels_1.resolveVideoModel)(this.getNodeParameter('paModel', i), '16:9', '6');
1347
+ const prompt = (0, prompts_1.buildProductAdPrompt)(this.getNodeParameter('paBrandBrief', i), this.getNodeParameter('paMood', i));
1348
+ const id = await submitMultipart(this, vag, '/video/upload', (0, request_1.buildVideoForm)({
1349
+ prompt,
1350
+ styleId: config.styleId,
1351
+ variation: 'image_to_video',
1352
+ aspectRatio,
1353
+ duration,
1354
+ orgId,
1355
+ resolution: (0, videoModels_1.resolveVideoResolution)(config, this.getNodeParameter('paResolution', i)),
1356
+ imageUrl: productImageUrl,
1357
+ }));
1358
+ returnData.push({
1359
+ json: { assetId: id, status: 'queued', done: false, resource: 'video', model, aspectRatio, duration, filename: 'imagineart.mp4' },
1360
+ pairedItem: { item: i },
1361
+ });
1362
+ }
1363
+ else if (resource === 'video' && operation === 'cookingVideo') {
1364
+ const orgId = this.getNodeParameter('organization', i);
1365
+ const personImage = this.getNodeParameter('cookingPersonImage', i).trim();
1366
+ const dish = this.getNodeParameter('cookingDish', i);
1367
+ const kitchen = this.getNodeParameter('cookingKitchenStyle', i);
1368
+ const outfit = this.getNodeParameter('cookingOutfit', i);
1369
+ const durationSeconds = String(this.getNodeParameter('cookingDurationSeconds', i));
1370
+ const sheetImg = (0, imageModels_1.resolveImageModel)('gpt-image-2', '16:9');
1371
+ const sheetId = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1372
+ prompt: (0, prompts_1.buildCookingSheetPrompt)(dish, kitchen, outfit, durationSeconds),
1373
+ styleId: sheetImg.config.styleId,
1374
+ variation: 'img2img',
1375
+ aspectRatio: sheetImg.aspectRatio,
1376
+ orgId,
1377
+ imageUrl: personImage,
1378
+ }));
1379
+ const vid = (0, videoModels_1.resolveVideoModel)('seedance-2.0-fast', '16:9', durationSeconds);
1380
+ const videoFields = (0, request_1.buildVideoForm)({
1381
+ prompt: (0, prompts_1.buildCookingVideoPrompt)(dish, kitchen, outfit, durationSeconds),
1382
+ styleId: vid.config.styleId,
1383
+ variation: 'image_to_video',
1384
+ aspectRatio: vid.aspectRatio,
1385
+ duration: vid.duration,
1386
+ orgId,
1387
+ resolution: (0, videoModels_1.resolveVideoResolution)(vid.config, this.getNodeParameter('cookingResolution', i)),
1388
+ });
1389
+ returnData.push({
1390
+ json: {
1391
+ assetId: sheetId,
1392
+ status: 'queued',
1393
+ done: false,
1394
+ resource: 'video',
1395
+ stage: 'image',
1396
+ pendingVideo: { endpoint: '/video/upload', fields: videoFields, filename: 'imagineart-cooking.mp4' },
1397
+ },
1398
+ pairedItem: { item: i },
1399
+ });
1400
+ }
1401
+ else if (resource === 'video' && operation === 'jewelryVideo') {
1402
+ const orgId = this.getNodeParameter('organization', i);
1403
+ const desc = this.getNodeParameter('jewelryDescription', i);
1404
+ const surface = this.getNodeParameter('jewelrySurface', i);
1405
+ const stillImg = (0, imageModels_1.resolveImageModel)('nano-banana-2', '1:1');
1406
+ const stillId = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1407
+ prompt: (0, prompts_1.buildJewelryImagePrompt)(desc, surface),
1408
+ styleId: stillImg.config.styleId,
1409
+ variation: 'txt2img',
1410
+ aspectRatio: stillImg.aspectRatio,
1411
+ orgId,
1412
+ }));
1413
+ const vid = (0, videoModels_1.resolveVideoModel)(this.getNodeParameter('jewelryModel', i), '1:1', String(this.getNodeParameter('jewelryDuration', i)));
1414
+ const videoFields = (0, request_1.buildVideoForm)({
1415
+ prompt: (0, prompts_1.buildJewelryVideoPrompt)(desc, surface),
1416
+ styleId: vid.config.styleId,
1417
+ variation: 'image_to_video',
1418
+ aspectRatio: vid.aspectRatio,
1419
+ duration: vid.duration,
1420
+ orgId,
1421
+ resolution: (0, videoModels_1.resolveVideoResolution)(vid.config, this.getNodeParameter('jewelryResolution', i)),
1422
+ });
1423
+ returnData.push({
1424
+ json: {
1425
+ assetId: stillId,
1426
+ status: 'queued',
1427
+ done: false,
1428
+ resource: 'video',
1429
+ stage: 'image',
1430
+ pendingVideo: { endpoint: '/video/upload', fields: videoFields, filename: 'imagineart-jewelry.mp4' },
1431
+ },
1432
+ pairedItem: { item: i },
1433
+ });
1434
+ }
1435
+ else if (resource === 'video' && operation === 'logo3d') {
1436
+ const orgId = this.getNodeParameter('organization', i);
1437
+ const logoUrl = this.getNodeParameter('logo3dImageUrl', i).trim();
1438
+ const material = this.getNodeParameter('logo3dMaterial', i);
1439
+ const stillImg = (0, imageModels_1.resolveImageModel)('nano-banana-2', '1:1');
1440
+ const stillId = await submitMultipart(this, vag, '/image/generations/upload', (0, request_1.buildImageForm)({
1441
+ prompt: (0, prompts_1.buildLogo3DImagePrompt)(material),
1442
+ styleId: stillImg.config.styleId,
1443
+ variation: 'img2img',
1444
+ aspectRatio: stillImg.aspectRatio,
1445
+ orgId,
1446
+ imageUrl: logoUrl,
1447
+ }));
1448
+ const vid = (0, videoModels_1.resolveVideoModel)(this.getNodeParameter('logo3dModel', i), '16:9', String(this.getNodeParameter('logo3dDuration', i)));
1449
+ const videoFields = (0, request_1.buildVideoForm)({
1450
+ prompt: (0, prompts_1.buildLogoAnimationPrompt)(material),
1451
+ styleId: vid.config.styleId,
1452
+ variation: 'image_to_video',
1453
+ aspectRatio: vid.aspectRatio,
1454
+ duration: vid.duration,
1455
+ orgId,
1456
+ resolution: (0, videoModels_1.resolveVideoResolution)(vid.config, this.getNodeParameter('logo3dResolution', i)),
1457
+ });
1458
+ returnData.push({
1459
+ json: {
1460
+ assetId: stillId,
1461
+ status: 'queued',
1462
+ done: false,
1463
+ resource: 'video',
1464
+ stage: 'image',
1465
+ pendingVideo: { endpoint: '/video/upload', fields: videoFields, filename: 'imagineart-logo3d.mp4' },
1466
+ },
1467
+ pairedItem: { item: i },
1468
+ });
1469
+ }
1470
+ else if (resource === 'video' && operation === 'generate') {
1471
+ const orgId = this.getNodeParameter('organization', i);
1472
+ const prompt = this.getNodeParameter('prompt', i);
1473
+ const { config, aspectRatio, duration, model } = (0, videoModels_1.resolveVideoModel)(this.getNodeParameter('videoModel', i), this.getNodeParameter('videoAspectRatio', i), this.getNodeParameter('duration', i));
1474
+ const id = await submitMultipart(this, vag, '/video/upload', (0, request_1.buildVideoForm)({
1475
+ prompt,
1476
+ styleId: config.styleId,
1477
+ variation: config.variation,
1478
+ aspectRatio,
1479
+ duration,
1480
+ orgId,
1481
+ resolution: (0, videoModels_1.resolveVideoResolution)(config, ''),
1482
+ folderId: this.getNodeParameter('folderId', i, ''),
1483
+ }));
1484
+ returnData.push({
1485
+ json: {
1486
+ assetId: id,
1487
+ status: 'queued',
1488
+ done: false,
1489
+ resource: 'video',
1490
+ model,
1491
+ aspectRatio,
1492
+ duration,
1493
+ filename: 'imagineart.mp4',
1494
+ },
1495
+ pairedItem: { item: i },
1496
+ });
1497
+ }
1498
+ else if (operation === 'getResult') {
1499
+ const assetId = this.getNodeParameter('assetId', i);
1500
+ const inputJson = ((_b = (_a = items[i]) === null || _a === void 0 ? void 0 : _a.json) !== null && _b !== void 0 ? _b : {});
1501
+ const status = await fetchAssetStatus(this, vag, assetId);
1502
+ const url = (0, status_1.firstGenerationUrl)(status);
1503
+ if (!url) {
1504
+ const carry = {};
1505
+ if (inputJson.filename)
1506
+ carry.filename = inputJson.filename;
1507
+ if (inputJson.pendingVideo)
1508
+ carry.pendingVideo = inputJson.pendingVideo;
1509
+ returnData.push({
1510
+ json: {
1511
+ assetId,
1512
+ status: (_d = (_c = status.assets[0]) === null || _c === void 0 ? void 0 : _c.status) !== null && _d !== void 0 ? _d : status.status,
1513
+ done: false,
1514
+ failed: status.assets.some((a) => (0, status_1.isFailureStatus)(a.status)),
1515
+ ...carry,
1516
+ },
1517
+ pairedItem: { item: i },
1518
+ });
1519
+ }
1520
+ else if (inputJson.pendingVideo) {
1521
+ const pending = inputJson.pendingVideo;
1522
+ const videoId = await submitMultipart(this, vag, pending.endpoint, {
1523
+ ...pending.fields,
1524
+ image_url: url,
1525
+ });
1526
+ returnData.push({
1527
+ json: { assetId: videoId, status: 'queued', done: false, filename: (_e = pending.filename) !== null && _e !== void 0 ? _e : 'imagineart.mp4' },
1528
+ pairedItem: { item: i },
1529
+ });
1530
+ }
1531
+ else {
1532
+ const filename = inputJson.filename || 'imagineart-result';
1533
+ const binary = await downloadBinary(this, url, filename);
1534
+ returnData.push({
1535
+ json: { assetId, url, done: true },
1536
+ binary: { data: binary },
1537
+ pairedItem: { item: i },
1538
+ });
1539
+ }
1540
+ }
1541
+ else if (resource === 'audio' && operation === 'generate') {
1542
+ const orgId = this.getNodeParameter('organization', i);
1543
+ const prompt = this.getNodeParameter('prompt', i);
1544
+ const duration = this.getNodeParameter('musicDuration', i);
1545
+ const variation = this.getNodeParameter('musicVariation', i);
1546
+ const id = await submitMultipart(this, vag, '/audio/music/upload', (0, request_1.buildMusicForm)({
1547
+ prompt,
1548
+ duration: String(duration),
1549
+ variation,
1550
+ orgId,
1551
+ folderId: this.getNodeParameter('folderId', i, ''),
1552
+ }));
1553
+ returnData.push({
1554
+ json: {
1555
+ assetId: id,
1556
+ status: 'queued',
1557
+ done: false,
1558
+ resource: 'audio',
1559
+ filename: 'imagineart.mp3',
1560
+ },
1561
+ pairedItem: { item: i },
1562
+ });
1563
+ }
1564
+ else if (resource === 'asset' && operation === 'listGenerations') {
1565
+ const orgId = this.getNodeParameter('organization', i);
1566
+ const query = `status=finished&service=image&service=video&limit=50&offset=0&org_id=${encodeURIComponent(orgId)}`;
1567
+ const res = (0, status_1.parseStatusResponse)(await getJson(this, `${vag}/assets/status?${query}`));
1568
+ for (const a of res.assets) {
1569
+ returnData.push({
1570
+ json: {
1571
+ status: a.status,
1572
+ url: (_h = (_g = (_f = a.url) === null || _f === void 0 ? void 0 : _f.generation) === null || _g === void 0 ? void 0 : _g[0]) !== null && _h !== void 0 ? _h : null,
1573
+ thumbnailUrl: (_l = (_k = (_j = a.url) === null || _j === void 0 ? void 0 : _j.thumbnail) === null || _k === void 0 ? void 0 : _k[0]) !== null && _l !== void 0 ? _l : null,
1574
+ metadata: (_m = a.asset_metadata) !== null && _m !== void 0 ? _m : {},
1575
+ },
1576
+ pairedItem: { item: i },
1577
+ });
1578
+ }
1579
+ }
1580
+ else if (resource === 'asset' && operation === 'listUploadedAssets') {
1581
+ const orgId = this.getNodeParameter('organization', i);
1582
+ const query = `service=user&refService=image,video&limit=50&offset=0&org_id=${encodeURIComponent(orgId)}`;
1583
+ const res = (0, status_1.parseStatusResponse)(await getJson(this, `${vag}/assets/status?${query}`));
1584
+ for (const a of res.assets) {
1585
+ returnData.push({
1586
+ json: {
1587
+ status: a.status,
1588
+ url: (_t = (_q = (_p = (_o = a.url) === null || _o === void 0 ? void 0 : _o.processed) === null || _p === void 0 ? void 0 : _p[0]) !== null && _q !== void 0 ? _q : (_s = (_r = a.url) === null || _r === void 0 ? void 0 : _r.generation) === null || _s === void 0 ? void 0 : _s[0]) !== null && _t !== void 0 ? _t : null,
1589
+ thumbnailUrl: (_w = (_v = (_u = a.url) === null || _u === void 0 ? void 0 : _u.thumbnail) === null || _v === void 0 ? void 0 : _v[0]) !== null && _w !== void 0 ? _w : null,
1590
+ metadata: (_x = a.asset_metadata) !== null && _x !== void 0 ? _x : {},
1591
+ },
1592
+ pairedItem: { item: i },
1593
+ });
1594
+ }
1595
+ }
1596
+ else if (resource === 'asset' && operation === 'upload') {
1597
+ const orgId = this.getNodeParameter('organization', i);
1598
+ const prop = this.getNodeParameter('uploadBinaryProperty', i);
1599
+ const binaryData = this.helpers.assertBinaryData(i, prop);
1600
+ const buffer = await this.helpers.getBinaryDataBuffer(i, prop);
1601
+ const url = await uploadUserFile(this, vag, orgId, {
1602
+ buffer,
1603
+ filename: (_y = binaryData.fileName) !== null && _y !== void 0 ? _y : 'upload',
1604
+ mimeType: (_z = binaryData.mimeType) !== null && _z !== void 0 ? _z : 'application/octet-stream',
1605
+ });
1606
+ returnData.push({
1607
+ json: {
1608
+ url,
1609
+ fileName: (_0 = binaryData.fileName) !== null && _0 !== void 0 ? _0 : null,
1610
+ mimeType: (_1 = binaryData.mimeType) !== null && _1 !== void 0 ? _1 : null,
1611
+ },
1612
+ pairedItem: { item: i },
1613
+ });
1614
+ }
1615
+ else if (resource === 'adStudio' && operation === 'listProducts') {
1616
+ const ownership = this.getNodeParameter('adOwnership', i);
1617
+ const rows = await listMarketCatalog(this, vag, '/market/product', ownership, adStudio_1.mapProductRows);
1618
+ for (const row of rows) {
1619
+ returnData.push({ json: row, pairedItem: { item: i } });
1620
+ }
1621
+ }
1622
+ else if (resource === 'adStudio' && operation === 'listAvatars') {
1623
+ const ownership = this.getNodeParameter('adOwnership', i);
1624
+ const rows = await listMarketCatalog(this, vag, '/market/avatar', ownership, adStudio_1.mapAvatarRows);
1625
+ for (const row of rows) {
1626
+ returnData.push({ json: row, pairedItem: { item: i } });
1627
+ }
1628
+ }
1629
+ else if (resource === 'adStudio' && operation === 'listTemplates') {
1630
+ const kind = this.getNodeParameter('adTemplateKind', i);
1631
+ const body = await getJson(this, `${vag}/market/template?type=${encodeURIComponent(kind)}`);
1632
+ for (const row of (0, adStudio_1.mapTemplateRows)(body)) {
1633
+ returnData.push({ json: row, pairedItem: { item: i } });
1634
+ }
1635
+ }
1636
+ else if (resource === 'adStudio' && operation === 'listProjects') {
1637
+ const folderId = this.getNodeParameter('folderId', i, '').trim();
1638
+ if (!folderId) {
1639
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A folder is required to list marketing projects.', { itemIndex: i });
1640
+ }
1641
+ const body = await getJson(this, `${vag}/marketing-mode/projects?folder_id=${encodeURIComponent(folderId)}`);
1642
+ for (const row of (0, adStudio_1.mapProjectRows)(body)) {
1643
+ returnData.push({ json: row, pairedItem: { item: i } });
1644
+ }
1645
+ }
1646
+ else if (resource === 'adStudio' && operation === 'createProject') {
1647
+ const name = this.getNodeParameter('adProjectName', i).trim();
1648
+ const folderId = this.getNodeParameter('folderId', i, '').trim();
1649
+ if (!folderId) {
1650
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A folder is required to create a marketing project.', { itemIndex: i });
1651
+ }
1652
+ const body = (await postMultipart(this, vag, '/marketing-mode/projects', {
1653
+ name,
1654
+ folder_id: folderId,
1655
+ }));
1656
+ if (!(body === null || body === void 0 ? void 0 : body.uuid)) {
1657
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'ImagineArt did not return a project id.', {
1658
+ itemIndex: i,
1659
+ });
1660
+ }
1661
+ returnData.push({
1662
+ json: { marketProjectId: body.uuid, name: (_2 = body.name) !== null && _2 !== void 0 ? _2 : name },
1663
+ pairedItem: { item: i },
1664
+ });
1665
+ }
1666
+ else if (resource === 'adStudio' && operation === 'uploadImage') {
1667
+ const orgId = this.getNodeParameter('organization', i);
1668
+ const prop = this.getNodeParameter('uploadBinaryProperty', i);
1669
+ const binaryData = this.helpers.assertBinaryData(i, prop);
1670
+ const buffer = await this.helpers.getBinaryDataBuffer(i, prop);
1671
+ const uploaded = await uploadMarketImage(this, vag, orgId, {
1672
+ buffer,
1673
+ filename: (_3 = binaryData.fileName) !== null && _3 !== void 0 ? _3 : 'upload',
1674
+ mimeType: (_4 = binaryData.mimeType) !== null && _4 !== void 0 ? _4 : 'application/octet-stream',
1675
+ });
1676
+ returnData.push({ json: uploaded, pairedItem: { item: i } });
1677
+ }
1678
+ else if (resource === 'adStudio' && operation === 'createProduct') {
1679
+ const source = this.getNodeParameter('adProductSource', i);
1680
+ let body;
1681
+ if (source === 'url') {
1682
+ const productUrl = this.getNodeParameter('adProductUrl', i).trim();
1683
+ body = (await postMultipart(this, vag, '/market/product/from-url', {
1684
+ url: productUrl,
1685
+ }));
1686
+ }
1687
+ else {
1688
+ const name = this.getNodeParameter('adProductName', i).trim();
1689
+ const description = this.getNodeParameter('adProductDescription', i).trim();
1690
+ const photos = (0, adStudio_1.collectPhotos)(this.getNodeParameter('adProductPhotos.photo', i, []), ['url', 'bytedanceId']);
1691
+ if (photos.length === 0) {
1692
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one uploaded photo is required for a manual product.', { itemIndex: i });
1693
+ }
1694
+ body = (await postMultipart(this, vag, '/market/product/manual', {
1695
+ name,
1696
+ description,
1697
+ photos: JSON.stringify(photos),
1698
+ }));
1699
+ }
1700
+ returnData.push({
1701
+ json: { id: (_5 = body === null || body === void 0 ? void 0 : body.id) !== null && _5 !== void 0 ? _5 : null, status: (_6 = body === null || body === void 0 ? void 0 : body.status) !== null && _6 !== void 0 ? _6 : null },
1702
+ pairedItem: { item: i },
1703
+ });
1704
+ }
1705
+ else if (resource === 'adStudio' && operation === 'productStatus') {
1706
+ const id = this.getNodeParameter('adProductId', i).trim();
1707
+ const body = (await getJson(this, `${vag}/market/product/${encodeURIComponent(id)}`));
1708
+ returnData.push({
1709
+ json: { id: (_7 = body === null || body === void 0 ? void 0 : body.id) !== null && _7 !== void 0 ? _7 : id, status: (_8 = body === null || body === void 0 ? void 0 : body.status) !== null && _8 !== void 0 ? _8 : null },
1710
+ pairedItem: { item: i },
1711
+ });
1712
+ }
1713
+ else if (resource === 'adStudio' && operation === 'createAvatar') {
1714
+ const name = this.getNodeParameter('adAvatarName', i).trim();
1715
+ const gender = this.getNodeParameter('adAvatarGender', i);
1716
+ const description = this.getNodeParameter('adAvatarDescription', i, '').trim();
1717
+ const photos = (0, adStudio_1.collectPhotos)(this.getNodeParameter('adAvatarPhotos.photo', i, []), ['url']);
1718
+ if (photos.length === 0) {
1719
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one uploaded photo is required for an avatar.', { itemIndex: i });
1720
+ }
1721
+ const fields = { name, gender, photos: JSON.stringify(photos) };
1722
+ if (description)
1723
+ fields.description = description;
1724
+ const body = (await postMultipart(this, vag, '/market/avatar', fields));
1725
+ returnData.push({ json: { id: (_9 = body === null || body === void 0 ? void 0 : body.id) !== null && _9 !== void 0 ? _9 : null }, pairedItem: { item: i } });
1726
+ }
1727
+ else if (resource === 'adStudio' && operation === 'generateAd') {
1728
+ const orgId = this.getNodeParameter('organization', i);
1729
+ const marketProjectId = this.getNodeParameter('marketProjectId', i).trim();
1730
+ const prompt = this.getNodeParameter('prompt', i);
1731
+ const folderId = this.getNodeParameter('folderId', i, '').trim();
1732
+ const images = this.getNodeParameter('adImages.image', i, [])
1733
+ .map((im) => { var _a, _b; return ({ url: ((_a = im.url) !== null && _a !== void 0 ? _a : '').trim(), id: ((_b = im.id) !== null && _b !== void 0 ? _b : '').trim() }); })
1734
+ .filter((im) => im.url !== '');
1735
+ const id = await submitMultipart(this, vag, '/video/upload', (0, adStudio_1.buildAdForm)({
1736
+ prompt,
1737
+ marketProjectId,
1738
+ orgId,
1739
+ folderId: folderId || undefined,
1740
+ images,
1741
+ aspectRatio: this.getNodeParameter('adAspectRatio', i),
1742
+ duration: this.getNodeParameter('adDuration', i),
1743
+ resolution: this.getNodeParameter('adResolution', i),
1744
+ }));
1745
+ returnData.push({
1746
+ json: {
1747
+ assetId: id,
1748
+ status: 'queued',
1749
+ done: false,
1750
+ resource: 'adStudio',
1751
+ filename: 'imagineart-ad.mp4',
1752
+ },
1753
+ pairedItem: { item: i },
1754
+ });
1755
+ }
1756
+ else if (resource === 'account' && operation === 'getBalance') {
1757
+ const orgId = this.getNodeParameter('organization', i);
1758
+ const body = (await getJson(this, `${vag}/credit?org_id=${encodeURIComponent(orgId)}`));
1759
+ returnData.push({
1760
+ json: { total: (_10 = body.total) !== null && _10 !== void 0 ? _10 : 0, tokens: (_11 = body.tokens) !== null && _11 !== void 0 ? _11 : [] },
1761
+ pairedItem: { item: i },
1762
+ });
1763
+ }
1764
+ else {
1765
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported operation: ${resource} → ${operation}`, { itemIndex: i });
1766
+ }
1767
+ }
1768
+ catch (error) {
1769
+ if (this.continueOnFail()) {
1770
+ returnData.push({ json: { error: error.message }, pairedItem: { item: i } });
1771
+ continue;
1772
+ }
1773
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error, { itemIndex: i });
1774
+ }
1775
+ }
1776
+ return [returnData];
1777
+ }
1778
+ //# sourceMappingURL=shared.js.map