n8n-nodes-supermachine 0.2.0 → 0.3.2

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.
@@ -23,6 +23,7 @@ class Supermachine {
23
23
  noDataExpression: true,
24
24
  options: [
25
25
  { name: 'Account', value: 'account' },
26
+ { name: 'Character', value: 'character' },
26
27
  { name: 'Folder', value: 'folder' },
27
28
  { name: 'Image', value: 'image' },
28
29
  { name: 'Tools', value: 'tools' },
@@ -31,6 +32,8 @@ class Supermachine {
31
32
  },
32
33
  ...descriptions_1.getAccountOperations,
33
34
  ...descriptions_1.getAccountFields,
35
+ ...descriptions_1.getCharacterOperations,
36
+ ...descriptions_1.getCharacterFields,
34
37
  ...descriptions_1.getFolderOperations,
35
38
  ...descriptions_1.getFolderFields,
36
39
  ...descriptions_1.getImageOperations,
@@ -249,9 +252,6 @@ class Supermachine {
249
252
  }];
250
253
  }
251
254
  },
252
- // ═══════════════════════════════════════════════════════════
253
- // Load Folders
254
- // ═══════════════════════════════════════════════════════════
255
255
  async getFolders() {
256
256
  const credentials = await this.getCredentials('supermachineApi');
257
257
  const apiKey = credentials.apiKey;
@@ -358,21 +358,64 @@ class Supermachine {
358
358
  returnData.push({ json: jsonData });
359
359
  }
360
360
  // ══════════════════════════════════════════════════════
361
+ // CHARACTER OPERATIONS
362
+ // ══════════════════════════════════════════════════════
363
+ else if (resource === 'character') {
364
+ if (operation === 'listCharacters') {
365
+ const filters = this.getNodeParameter('filters', i, {});
366
+ const qs = {};
367
+ if (!this.getNodeParameter('returnAll', i, false)) {
368
+ qs.limit = this.getNodeParameter('limit', i, 20);
369
+ }
370
+ if (filters.categoryId) {
371
+ qs.categoryId = filters.categoryId;
372
+ }
373
+ if (filters.modelId) {
374
+ const modelTitle = filters.modelId;
375
+ const modelsResponse = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', { method: 'GET', url: 'https://dev.supermachine.art/v1/models', json: true });
376
+ const models = modelsResponse.items;
377
+ const model = models.find((m) => m.title === modelTitle);
378
+ if (model) {
379
+ qs.modelId = model.id;
380
+ }
381
+ }
382
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
383
+ method: 'GET',
384
+ url: 'https://dev.supermachine.art/v1/characters',
385
+ json: true,
386
+ qs,
387
+ });
388
+ returnData.push({ json: responseData });
389
+ }
390
+ else if (operation === 'listCategories') {
391
+ const qs = {};
392
+ if (!this.getNodeParameter('returnAll', i, false)) {
393
+ qs.limit = this.getNodeParameter('limit', i, 20);
394
+ }
395
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
396
+ method: 'GET',
397
+ url: 'https://dev.supermachine.art/v1/characters/categories',
398
+ json: true,
399
+ qs,
400
+ });
401
+ returnData.push({ json: responseData });
402
+ }
403
+ }
404
+ // ══════════════════════════════════════════════════════
361
405
  // FOLDER OPERATIONS
362
406
  // ══════════════════════════════════════════════════════
363
407
  else if (resource === 'folder') {
364
408
  if (operation === 'listFolders') {
365
- const requestOptions = {
409
+ const qs = {};
410
+ if (!this.getNodeParameter('returnAll', i, false)) {
411
+ qs.limit = this.getNodeParameter('limit', i, 20);
412
+ }
413
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
366
414
  method: 'GET',
367
415
  url: 'https://dev.supermachine.art/v1/folders',
368
416
  json: true,
369
- };
370
- if (!this.getNodeParameter('returnAll', i, false)) {
371
- requestOptions.qs = {
372
- limit: this.getNodeParameter('limit', i, 20),
373
- };
374
- }
375
- const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', requestOptions);
417
+ qs,
418
+ });
376
419
  returnData.push({ json: responseData });
377
420
  }
378
421
  else if (operation === 'getFolder') {
@@ -412,7 +455,7 @@ class Supermachine {
412
455
  else if (operation === 'deleteFolder') {
413
456
  const folderId = this.getNodeParameter('folderId', i);
414
457
  const deleteMode = this.getNodeParameter('deleteMode', i);
415
- const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
458
+ await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
416
459
  method: 'DELETE',
417
460
  url: `https://dev.supermachine.art/v1/folders/${folderId}`,
418
461
  json: true,
@@ -536,12 +579,80 @@ class Supermachine {
536
579
  }
537
580
  });
538
581
  }
582
+ else if (operation === 'listImages') {
583
+ const filters = this.getNodeParameter('filters', i, {});
584
+ const qs = {};
585
+ if (!this.getNodeParameter('returnAll', i, false)) {
586
+ qs.limit = this.getNodeParameter('limit', i, 20);
587
+ }
588
+ if (filters.batchId) {
589
+ qs.batchId = filters.batchId;
590
+ }
591
+ if (filters.folderId) {
592
+ qs.folderId = filters.folderId;
593
+ }
594
+ if (filters.model) {
595
+ qs.model = filters.model;
596
+ }
597
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
598
+ method: 'GET',
599
+ url: 'https://dev.supermachine.art/v1/images',
600
+ json: true,
601
+ qs,
602
+ });
603
+ returnData.push({ json: responseData });
604
+ }
605
+ else if (operation === 'getImage') {
606
+ const imageId = this.getNodeParameter('imageId', i);
607
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
608
+ method: 'GET',
609
+ url: `https://dev.supermachine.art/v1/images/${imageId}`,
610
+ json: true,
611
+ });
612
+ returnData.push({ json: responseData });
613
+ }
614
+ else if (operation === 'moveImage') {
615
+ const imageId = this.getNodeParameter('imageId', i);
616
+ const targetFolderId = this.getNodeParameter('targetFolderId', i);
617
+ const responseData = await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
618
+ method: 'POST',
619
+ url: `https://dev.supermachine.art/v1/images/${imageId}/move`,
620
+ json: true,
621
+ body: {
622
+ folderId: targetFolderId,
623
+ },
624
+ });
625
+ returnData.push({
626
+ json: {
627
+ success: true,
628
+ imageId,
629
+ targetFolderId,
630
+ message: 'Image moved successfully',
631
+ ...responseData,
632
+ }
633
+ });
634
+ }
635
+ else if (operation === 'deleteImage') {
636
+ const imageId = this.getNodeParameter('imageId', i);
637
+ await this.helpers.requestWithAuthentication.call(this, 'supermachineApi', {
638
+ method: 'DELETE',
639
+ url: `https://dev.supermachine.art/v1/images/${imageId}`,
640
+ json: true,
641
+ });
642
+ returnData.push({
643
+ json: {
644
+ success: true,
645
+ imageId,
646
+ message: 'Image deleted successfully',
647
+ }
648
+ });
649
+ }
539
650
  }
540
651
  // ══════════════════════════════════════════════════════
541
652
  // TOOLS OPERATIONS
542
653
  // ══════════════════════════════════════════════════════
543
654
  else if (resource === 'tools') {
544
- throw new Error('⚠️ Tools operations are coming soon. These features will be available when Supermachine API provides official endpoints.');
655
+ throw new Error('⚠️ Tools operations are coming soon.');
545
656
  }
546
657
  }
547
658
  catch (error) {
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCharacterFields = exports.getCharacterOperations = void 0;
4
+ exports.getCharacterOperations = [
5
+ {
6
+ displayName: 'Operation',
7
+ name: 'operation',
8
+ type: 'options',
9
+ noDataExpression: true,
10
+ displayOptions: {
11
+ show: {
12
+ resource: ['character'],
13
+ },
14
+ },
15
+ options: [
16
+ {
17
+ name: 'List Characters',
18
+ value: 'listCharacters',
19
+ description: 'List characters, optionally filtered by category or model',
20
+ action: 'List all characters',
21
+ },
22
+ {
23
+ name: 'List Character Categories',
24
+ value: 'listCategories',
25
+ description: 'List all character categories',
26
+ action: 'List character categories',
27
+ },
28
+ ],
29
+ default: 'listCharacters',
30
+ },
31
+ ];
32
+ exports.getCharacterFields = [
33
+ // ═══════════════════════════════════════════════════════════
34
+ // LIST CHARACTERS
35
+ // ═══════════════════════════════════════════════════════════
36
+ {
37
+ displayName: 'Return All',
38
+ name: 'returnAll',
39
+ type: 'boolean',
40
+ displayOptions: {
41
+ show: {
42
+ resource: ['character'],
43
+ operation: ['listCharacters', 'listCategories'],
44
+ },
45
+ },
46
+ default: false,
47
+ description: 'Whether to return all results or only up to a given limit',
48
+ },
49
+ {
50
+ displayName: 'Limit',
51
+ name: 'limit',
52
+ type: 'number',
53
+ typeOptions: { minValue: 1, maxValue: 100 },
54
+ displayOptions: {
55
+ show: {
56
+ resource: ['character'],
57
+ operation: ['listCharacters', 'listCategories'],
58
+ returnAll: [false],
59
+ },
60
+ },
61
+ default: 20,
62
+ description: 'Max number of results to return',
63
+ },
64
+ {
65
+ displayName: 'Filters',
66
+ name: 'filters',
67
+ type: 'collection',
68
+ placeholder: 'Add Filter',
69
+ default: {},
70
+ displayOptions: {
71
+ show: {
72
+ resource: ['character'],
73
+ operation: ['listCharacters'],
74
+ },
75
+ },
76
+ options: [
77
+ {
78
+ displayName: 'Category Name or ID',
79
+ name: 'categoryId',
80
+ type: 'options',
81
+ typeOptions: {
82
+ loadOptionsMethod: 'getCharacterCategories',
83
+ },
84
+ default: '',
85
+ description: 'Filter by character category. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
86
+ },
87
+ {
88
+ displayName: 'Model Name or ID',
89
+ name: 'modelId',
90
+ type: 'options',
91
+ typeOptions: {
92
+ loadOptionsMethod: 'getModels',
93
+ },
94
+ default: '',
95
+ description: 'Filter by compatible model. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
96
+ },
97
+ ],
98
+ },
99
+ ];
@@ -19,12 +19,38 @@ exports.getImageOperations = [
19
19
  description: 'Tạo ảnh mới từ text prompt (tự động chờ hoàn tất)',
20
20
  action: 'Generate an image',
21
21
  },
22
+ {
23
+ name: 'List Images',
24
+ value: 'listImages',
25
+ description: 'List all generated images',
26
+ action: 'List all images',
27
+ },
28
+ {
29
+ name: 'Get Image',
30
+ value: 'getImage',
31
+ description: 'Get a single image by ID',
32
+ action: 'Get an image by ID',
33
+ },
34
+ {
35
+ name: 'Move Image to Folder',
36
+ value: 'moveImage',
37
+ description: 'Move an image to a specific folder',
38
+ action: 'Move image to folder',
39
+ },
40
+ {
41
+ name: 'Delete Image',
42
+ value: 'deleteImage',
43
+ description: 'Delete an image permanently',
44
+ action: 'Delete an image',
45
+ },
22
46
  ],
23
47
  default: 'generate',
24
48
  },
25
49
  ];
26
50
  exports.getImageFields = [
27
- // Model, Prompt, Width, Height fields giữ nguyên...
51
+ // ═══════════════════════════════════════════════════════════
52
+ // GENERATE OPERATION (giữ nguyên code cũ)
53
+ // ═══════════════════════════════════════════════════════════
28
54
  {
29
55
  displayName: 'Model Name or ID',
30
56
  name: 'model',
@@ -57,7 +83,7 @@ exports.getImageFields = [
57
83
  },
58
84
  default: '',
59
85
  placeholder: 'A beautiful sunset over mountains, photorealistic, 8k',
60
- description: 'Mô tả ảnh muốn tạo (bằng tiếng Anh cho kết quả tốt nhất)',
86
+ description: 'Mô tả ảnh muốn tạo',
61
87
  required: true,
62
88
  },
63
89
  {
@@ -114,7 +140,7 @@ exports.getImageFields = [
114
140
  typeOptions: { rows: 2 },
115
141
  default: '',
116
142
  placeholder: 'blurry, low quality, distorted',
117
- description: 'Những gì KHÔNG muốn xuất hiện trong ảnh',
143
+ description: 'Những gì KHÔNG muốn xuất hiện',
118
144
  },
119
145
  {
120
146
  displayName: 'Number of Results',
@@ -150,7 +176,7 @@ exports.getImageFields = [
150
176
  type: 'number',
151
177
  typeOptions: { minValue: 1, maxValue: 80 },
152
178
  default: 30,
153
- description: 'Số bước inference (20-50 recommended)',
179
+ description: 'Số bước inference',
154
180
  },
155
181
  {
156
182
  displayName: 'CFG Scale',
@@ -162,7 +188,7 @@ exports.getImageFields = [
162
188
  numberPrecision: 1,
163
189
  },
164
190
  default: 7,
165
- description: 'Độ tuân thủ prompt (7-9 recommended)',
191
+ description: 'Độ tuân thủ prompt',
166
192
  },
167
193
  {
168
194
  displayName: 'Move to Folder',
@@ -172,7 +198,7 @@ exports.getImageFields = [
172
198
  loadOptionsMethod: 'getFolders',
173
199
  },
174
200
  default: '',
175
- description: 'Move generated image to this folder. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
201
+ description: 'Move image to folder. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
176
202
  },
177
203
  {
178
204
  displayName: 'Polling Interval (seconds)',
@@ -180,7 +206,7 @@ exports.getImageFields = [
180
206
  type: 'number',
181
207
  typeOptions: { minValue: 1, maxValue: 10 },
182
208
  default: 2,
183
- description: 'Thời gian chờ giữa các lần check (giây)',
209
+ description: 'Thời gian chờ giữa các lần check',
184
210
  },
185
211
  {
186
212
  displayName: 'Max Polling Time (seconds)',
@@ -188,7 +214,7 @@ exports.getImageFields = [
188
214
  type: 'number',
189
215
  typeOptions: { minValue: 10, maxValue: 300 },
190
216
  default: 120,
191
- description: 'Thời gian tối đa chờ hoàn thành (giây)',
217
+ description: 'Thời gian tối đa chờ',
192
218
  },
193
219
  {
194
220
  displayName: 'LoRAs',
@@ -198,7 +224,7 @@ exports.getImageFields = [
198
224
  multipleValues: true,
199
225
  },
200
226
  default: {},
201
- description: 'Thêm LoRA để điều chỉnh style',
227
+ description: 'Thêm LoRA',
202
228
  options: [
203
229
  {
204
230
  name: 'loraValues',
@@ -225,7 +251,7 @@ exports.getImageFields = [
225
251
  numberPrecision: 1,
226
252
  },
227
253
  default: 1,
228
- description: 'Độ mạnh của LoRA (0-2)',
254
+ description: 'Độ mạnh LoRA (0-2)',
229
255
  },
230
256
  ],
231
257
  },
@@ -239,7 +265,7 @@ exports.getImageFields = [
239
265
  loadOptionsMethod: 'getCharacterCategories',
240
266
  },
241
267
  default: '',
242
- description: 'Chọn category để filter characters. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
268
+ description: 'Chọn category. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
243
269
  },
244
270
  {
245
271
  displayName: 'Character',
@@ -255,14 +281,14 @@ exports.getImageFields = [
255
281
  },
256
282
  },
257
283
  default: '',
258
- description: 'Chọn character. Embed code sẽ tự động thêm vào prompt. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
284
+ description: 'Chọn character. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
259
285
  },
260
286
  {
261
287
  displayName: 'Image to Image',
262
288
  name: 'img2img',
263
289
  type: 'fixedCollection',
264
290
  default: {},
265
- description: 'Dùng ảnh có sẵn làm base',
291
+ description: 'Dùng ảnh làm base',
266
292
  options: [
267
293
  {
268
294
  name: 'img2imgValues',
@@ -274,7 +300,7 @@ exports.getImageFields = [
274
300
  type: 'string',
275
301
  default: '',
276
302
  placeholder: 'https://example.com/image.png',
277
- description: 'URL của ảnh gốc',
303
+ description: 'URL ảnh gốc',
278
304
  },
279
305
  {
280
306
  displayName: 'Denoising Strength',
@@ -294,4 +320,116 @@ exports.getImageFields = [
294
320
  },
295
321
  ],
296
322
  },
323
+ // ═══════════════════════════════════════════════════════════
324
+ // LIST IMAGES
325
+ // ═══════════════════════════════════════════════════════════
326
+ {
327
+ displayName: 'Return All',
328
+ name: 'returnAll',
329
+ type: 'boolean',
330
+ displayOptions: {
331
+ show: {
332
+ resource: ['image'],
333
+ operation: ['listImages'],
334
+ },
335
+ },
336
+ default: false,
337
+ description: 'Whether to return all results or only up to a given limit',
338
+ },
339
+ {
340
+ displayName: 'Limit',
341
+ name: 'limit',
342
+ type: 'number',
343
+ typeOptions: { minValue: 1, maxValue: 100 },
344
+ displayOptions: {
345
+ show: {
346
+ resource: ['image'],
347
+ operation: ['listImages'],
348
+ returnAll: [false],
349
+ },
350
+ },
351
+ default: 20,
352
+ description: 'Max number of results to return',
353
+ },
354
+ {
355
+ displayName: 'Filters',
356
+ name: 'filters',
357
+ type: 'collection',
358
+ placeholder: 'Add Filter',
359
+ default: {},
360
+ displayOptions: {
361
+ show: {
362
+ resource: ['image'],
363
+ operation: ['listImages'],
364
+ },
365
+ },
366
+ options: [
367
+ {
368
+ displayName: 'Batch ID',
369
+ name: 'batchId',
370
+ type: 'string',
371
+ default: '',
372
+ placeholder: '1997744',
373
+ description: 'Filter by batch ID',
374
+ },
375
+ {
376
+ displayName: 'Folder Name or ID',
377
+ name: 'folderId',
378
+ type: 'options',
379
+ typeOptions: {
380
+ loadOptionsMethod: 'getFolders',
381
+ },
382
+ default: '',
383
+ description: 'Filter by folder. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
384
+ },
385
+ {
386
+ displayName: 'Model Name or ID',
387
+ name: 'model',
388
+ type: 'options',
389
+ typeOptions: {
390
+ loadOptionsMethod: 'getModels',
391
+ },
392
+ default: '',
393
+ description: 'Filter by model. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
394
+ },
395
+ ],
396
+ },
397
+ // ═══════════════════════════════════════════════════════════
398
+ // GET IMAGE
399
+ // ═══════════════════════════════════════════════════════════
400
+ {
401
+ displayName: 'Image ID',
402
+ name: 'imageId',
403
+ type: 'string',
404
+ displayOptions: {
405
+ show: {
406
+ resource: ['image'],
407
+ operation: ['getImage', 'moveImage', 'deleteImage'],
408
+ },
409
+ },
410
+ default: '',
411
+ required: true,
412
+ placeholder: '8870379',
413
+ description: 'ID của ảnh',
414
+ },
415
+ // ═══════════════════════════════════════════════════════════
416
+ // MOVE IMAGE
417
+ // ═══════════════════════════════════════════════════════════
418
+ {
419
+ displayName: 'Target Folder Name or ID',
420
+ name: 'targetFolderId',
421
+ type: 'options',
422
+ typeOptions: {
423
+ loadOptionsMethod: 'getFolders',
424
+ },
425
+ displayOptions: {
426
+ show: {
427
+ resource: ['image'],
428
+ operation: ['moveImage'],
429
+ },
430
+ },
431
+ default: '',
432
+ required: true,
433
+ description: 'Folder đích để move ảnh. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
434
+ },
297
435
  ];
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./AccountDescription"), exports);
18
+ __exportStar(require("./CharacterDescription"), exports);
18
19
  __exportStar(require("./FolderDescription"), exports);
19
20
  __exportStar(require("./ImageDescription"), exports);
20
21
  __exportStar(require("./ToolsDescription"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-supermachine",
3
- "version": "0.2.0",
3
+ "version": "0.3.2",
4
4
  "description": "n8n community node for Supermachine AI Image API — Generate images, manage models, LoRAs, and characters",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",