n8n-nodes-sudomock 0.8.3 → 0.9.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.
package/README.md
CHANGED
|
@@ -21,10 +21,10 @@ n8n community node for the SudoMock API. Integrate mockup rendering into your n8
|
|
|
21
21
|
### 2D Mockups
|
|
22
22
|
|
|
23
23
|
- **2D: Create Mockup**: Create a reusable 2D mockup from an image
|
|
24
|
-
- **2D: Get Mockup**: Check preparation status and get ready print areas
|
|
24
|
+
- **2D: Get Mockup**: Check preparation status and get the ready surfaces and print areas
|
|
25
25
|
- **2D: List Mockups**: List your 2D mockups
|
|
26
26
|
- **2D: Set Print Areas**: Define print areas with four-point quads
|
|
27
|
-
- **2D: Render Mockup**: Render artwork
|
|
27
|
+
- **2D: Render Mockup**: Render artwork onto a ready surface or print area for 5 credits
|
|
28
28
|
- **2D: Delete Mockup**: Delete a 2D mockup
|
|
29
29
|
|
|
30
30
|
### Rendering
|
|
@@ -120,18 +120,36 @@ Retrieve your account information, subscription details, and credit usage.
|
|
|
120
120
|
"name": "John Doe"
|
|
121
121
|
},
|
|
122
122
|
"subscription": {
|
|
123
|
-
"plan":
|
|
123
|
+
"plan": "pro-25k",
|
|
124
|
+
"tier": "pro",
|
|
124
125
|
"status": "active"
|
|
125
126
|
},
|
|
126
127
|
"usage": {
|
|
127
|
-
"credits_used_this_month":
|
|
128
|
-
"credits_limit":
|
|
129
|
-
"credits_remaining":
|
|
128
|
+
"credits_used_this_month": 6250,
|
|
129
|
+
"credits_limit": 25000,
|
|
130
|
+
"credits_remaining": 18750,
|
|
131
|
+
"prepaid_balance": 0,
|
|
132
|
+
"prepaid_balance_currency": "USD"
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
```
|
|
134
137
|
|
|
138
|
+
An account is funded either by a subscription allowance or by a prepaid balance,
|
|
139
|
+
and the two are independent. The three `credits_*` fields describe the allowance
|
|
140
|
+
only. An account paying as it goes has no allowance, so it reports all three as `0`
|
|
141
|
+
while holding a positive `prepaid_balance` and being perfectly able to pay:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
"usage": {
|
|
145
|
+
"credits_used_this_month": 0,
|
|
146
|
+
"credits_limit": 0,
|
|
147
|
+
"credits_remaining": 0,
|
|
148
|
+
"prepaid_balance": 12.5,
|
|
149
|
+
"prepaid_balance_currency": "USD"
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
135
153
|
---
|
|
136
154
|
|
|
137
155
|
### Upload PSD
|
|
@@ -342,12 +360,28 @@ Deletion confirmation
|
|
|
342
360
|
Create, prepare, render, and manage reusable mockups from product images without a PSD.
|
|
343
361
|
|
|
344
362
|
1. **2D: Create Mockup** accepts a public `source_url` or `source_base64`, plus an optional name. By default it waits and returns the ready mockup detail unchanged. Enable **Run Asynchronously** to receive a 202 job with `job_id` and `status_url`, then use **Get Job** when needed.
|
|
345
|
-
2. **2D: Get Mockup** returns `draft`, `ready`, or `failed` status. Poll this operation until the mockup is `ready`. The ready response
|
|
363
|
+
2. **2D: Get Mockup** returns `draft`, `ready`, or `failed` status. Poll this operation until the mockup is `ready`. The ready response lists every printable product in `data.surfaces` (addressed by `surface_uuid`), and every print area someone has drawn in `data.quads` (addressed by `print_area_id`).
|
|
346
364
|
3. **2D: List Mockups** returns your 2D mockups with limit, offset, and shopper-customizable filtering.
|
|
347
365
|
4. **2D: Set Print Areas** replaces saved areas with quads made from four `[x, y]` coordinate pairs. It can also send an empty list; the API remains authoritative and accepts that only when the mockup can remain renderable without saved areas.
|
|
348
|
-
5. **2D: Render Mockup** accepts the mockup UUID and one or more ready render targets. Each target
|
|
366
|
+
5. **2D: Render Mockup** accepts the mockup UUID and one or more ready render targets. Each target names exactly one address: `uuid` for a saved print area, or `surface_uuid` for a surface. Each target also includes either an artwork URL or Base64 artwork, with optional background removal (adds 25 credits per artwork), color, public adjustments, and placement. Export options support PNG, JPG, or WebP from 100 to 10000 pixels, plus quality and optional DPI. Each render costs 5 credits and returns `print_files`, where `print_files[0]` is the CDN URL.
|
|
349
367
|
6. **2D: Delete Mockup** deletes the selected 2D mockup.
|
|
350
368
|
|
|
369
|
+
A surface and a print area are separate render targets. Saving a print area on a
|
|
370
|
+
product does not close off the surface under it, so an all-over print and a chest
|
|
371
|
+
logo can both be addressed on the same product, in the same call, as two targets.
|
|
372
|
+
|
|
373
|
+
Placement is where the two kinds differ:
|
|
374
|
+
|
|
375
|
+
- A **surface** target takes **Coverage**, a percentage from 10 to 100. Leave it out
|
|
376
|
+
and the artwork covers the whole surface.
|
|
377
|
+
- A **print area** target takes either **Fit** (`contain`, `fill`, or `cover`), which
|
|
378
|
+
always sizes the artwork to the whole area, or an explicit **Width** and **Height**
|
|
379
|
+
pair when you want to choose the box yourself. Send one or the other, never both,
|
|
380
|
+
and send Width and Height together. Leaving Fit out is the same as `contain`.
|
|
381
|
+
|
|
382
|
+
Both kinds take position, offset, and rotation. Anything you do not set is not sent,
|
|
383
|
+
so the API decides it.
|
|
384
|
+
|
|
351
385
|
Create must reach `ready` through **2D: Get Mockup** before **2D: Render Mockup**.
|
|
352
386
|
|
|
353
387
|
---
|
|
@@ -539,12 +573,33 @@ See [`examples/README.md`](./examples/README.md) for detailed instructions, cust
|
|
|
539
573
|
→ Check credit usage
|
|
540
574
|
|
|
541
575
|
3. [IF Node]
|
|
542
|
-
→ If
|
|
576
|
+
→ If credits_limit > 0
|
|
577
|
+
AND credits_remaining < 5% of credits_limit
|
|
578
|
+
OR credits_limit == 0
|
|
579
|
+
AND prepaid_balance < 5
|
|
543
580
|
|
|
544
581
|
4. [Send Email/Slack]
|
|
545
|
-
→ Alert about low
|
|
582
|
+
→ Alert about low funds
|
|
546
583
|
```
|
|
547
584
|
|
|
585
|
+
Alert on whichever way the account is actually funded, because the two branches
|
|
586
|
+
measure different things and neither one alone is correct.
|
|
587
|
+
|
|
588
|
+
An account with a subscription has an allowance, so watch `credits_remaining`
|
|
589
|
+
against `credits_limit`. Use a percentage rather than a fixed number: the
|
|
590
|
+
allowance ranges from 5,000 to 100,000 depending on the plan, so a threshold
|
|
591
|
+
tuned for one plan is noise on another.
|
|
592
|
+
|
|
593
|
+
An account paying as it goes has no allowance at all. It reports
|
|
594
|
+
`credits_limit: 0` and `credits_remaining: 0` permanently, and those numbers
|
|
595
|
+
never reset, so a bare `credits_remaining < 100` fires forever on an account
|
|
596
|
+
that is fully funded. Watch `prepaid_balance` for that account instead.
|
|
597
|
+
|
|
598
|
+
Do not build a percentage or a progress bar out of `prepaid_balance`. It is an
|
|
599
|
+
amount, not a fraction, and it has no denominator to be a percentage of. For the
|
|
600
|
+
same reason, never report the pair as `0 / 0`: that reads as an empty account
|
|
601
|
+
when it means the allowance is simply not the thing paying.
|
|
602
|
+
|
|
548
603
|
## Rate Limits
|
|
549
604
|
|
|
550
605
|
### Request Rate Limits
|
|
@@ -497,7 +497,7 @@ class SudoMock {
|
|
|
497
497
|
},
|
|
498
498
|
default: {},
|
|
499
499
|
placeholder: 'Add Render Target',
|
|
500
|
-
description: 'Artwork and options for each target.
|
|
500
|
+
description: 'Artwork and options for each target. Each target names exactly one address: a saved print area UUID, or a surface UUID.',
|
|
501
501
|
options: [
|
|
502
502
|
{
|
|
503
503
|
name: 'items',
|
|
@@ -626,46 +626,30 @@ class SudoMock {
|
|
|
626
626
|
placeholder: '#FF0000',
|
|
627
627
|
description: 'Optional hex color fill or overlay',
|
|
628
628
|
},
|
|
629
|
-
{
|
|
630
|
-
displayName: 'Full-Surface UUID',
|
|
631
|
-
name: 'surfaceUuid',
|
|
632
|
-
type: 'string',
|
|
633
|
-
required: true,
|
|
634
|
-
displayOptions: {
|
|
635
|
-
show: {
|
|
636
|
-
targetType: ['fullSurface'],
|
|
637
|
-
},
|
|
638
|
-
},
|
|
639
|
-
default: '',
|
|
640
|
-
description: 'The surface_uuid returned in data.surfaces by 2D: Get Mockup',
|
|
641
|
-
},
|
|
642
629
|
{
|
|
643
630
|
displayName: 'Placement',
|
|
644
631
|
name: 'placement',
|
|
645
632
|
type: 'collection',
|
|
646
633
|
placeholder: 'Add Placement Option',
|
|
634
|
+
displayOptions: {
|
|
635
|
+
show: {
|
|
636
|
+
targetType: ['savedPrintArea'],
|
|
637
|
+
},
|
|
638
|
+
},
|
|
647
639
|
default: {},
|
|
648
|
-
description: '
|
|
640
|
+
description: 'Where the artwork sits inside the saved print area, and how it is sized. Options you do not add are not sent.',
|
|
649
641
|
options: [
|
|
650
|
-
{
|
|
651
|
-
displayName: 'Coverage',
|
|
652
|
-
name: 'coverage',
|
|
653
|
-
type: 'number',
|
|
654
|
-
typeOptions: { minValue: 10, maxValue: 100 },
|
|
655
|
-
default: 70,
|
|
656
|
-
description: 'Percentage of the print area covered by the artwork',
|
|
657
|
-
},
|
|
658
642
|
{
|
|
659
643
|
displayName: 'Fit',
|
|
660
644
|
name: 'fit',
|
|
661
645
|
type: 'options',
|
|
662
646
|
options: [
|
|
663
|
-
{ name: 'Fill', value: 'fill' },
|
|
664
647
|
{ name: 'Contain', value: 'contain' },
|
|
665
648
|
{ name: 'Cover', value: 'cover' },
|
|
649
|
+
{ name: 'Stretch', value: 'fill' },
|
|
666
650
|
],
|
|
667
651
|
default: 'contain',
|
|
668
|
-
description: 'How the artwork
|
|
652
|
+
description: 'How the artwork is sized to the whole print area. Leaving it out is the same as Contain. To place the artwork in a box of your own instead, add Width and Height and leave Fit out: sending both is rejected.',
|
|
669
653
|
},
|
|
670
654
|
{
|
|
671
655
|
displayName: 'Height',
|
|
@@ -720,7 +704,7 @@ class SudoMock {
|
|
|
720
704
|
type: 'number',
|
|
721
705
|
typeOptions: { minValue: 1, maxValue: 30000 },
|
|
722
706
|
default: 1000,
|
|
723
|
-
description: 'Artwork width in print-area pixels. Add Height alongside it
|
|
707
|
+
description: 'Artwork width in print-area pixels. Add Height alongside it. The pair sizes the artwork to a box you choose, so it takes the place of Fit rather than joining it. Width and Height are independent, so any aspect ratio is allowed.',
|
|
724
708
|
},
|
|
725
709
|
],
|
|
726
710
|
},
|
|
@@ -744,6 +728,97 @@ class SudoMock {
|
|
|
744
728
|
default: '',
|
|
745
729
|
description: 'The print_area_id returned in data.quads by 2D: Get Mockup',
|
|
746
730
|
},
|
|
731
|
+
{
|
|
732
|
+
displayName: 'Surface Placement',
|
|
733
|
+
name: 'surfacePlacement',
|
|
734
|
+
type: 'collection',
|
|
735
|
+
placeholder: 'Add Placement Option',
|
|
736
|
+
displayOptions: {
|
|
737
|
+
show: {
|
|
738
|
+
targetType: ['surface', 'fullSurface'],
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
default: {},
|
|
742
|
+
description: 'Where the artwork sits on the surface, and how much of the surface it takes up. Options you do not add are not sent.',
|
|
743
|
+
options: [
|
|
744
|
+
{
|
|
745
|
+
displayName: 'Coverage',
|
|
746
|
+
name: 'coverage',
|
|
747
|
+
type: 'number',
|
|
748
|
+
typeOptions: { minValue: 10, maxValue: 100 },
|
|
749
|
+
default: 100,
|
|
750
|
+
description: 'Percentage of the surface the artwork takes up, from 10 to 100. Leaving it out covers the whole surface. Use this or an explicit Width and Height pair, not both.',
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
displayName: 'Height',
|
|
754
|
+
name: 'height',
|
|
755
|
+
type: 'number',
|
|
756
|
+
typeOptions: { minValue: 1, maxValue: 30000 },
|
|
757
|
+
default: 0,
|
|
758
|
+
description: 'Artwork height in pixels. Send together with Width. A drawn size cannot be expressed as a percentage when its proportions differ from the surface, which is why the pair is offered here at all.',
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
displayName: 'Offset X',
|
|
762
|
+
name: 'offset_x',
|
|
763
|
+
type: 'number',
|
|
764
|
+
default: 0,
|
|
765
|
+
description: 'Horizontal artwork offset in pixels',
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
displayName: 'Offset Y',
|
|
769
|
+
name: 'offset_y',
|
|
770
|
+
type: 'number',
|
|
771
|
+
default: 0,
|
|
772
|
+
description: 'Vertical artwork offset in pixels',
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
displayName: 'Position',
|
|
776
|
+
name: 'position',
|
|
777
|
+
type: 'options',
|
|
778
|
+
options: [
|
|
779
|
+
{ name: 'Bottom Center', value: 'bottom_center' },
|
|
780
|
+
{ name: 'Bottom Left', value: 'bottom_left' },
|
|
781
|
+
{ name: 'Bottom Right', value: 'bottom_right' },
|
|
782
|
+
{ name: 'Center', value: 'center' },
|
|
783
|
+
{ name: 'Center Left', value: 'center_left' },
|
|
784
|
+
{ name: 'Center Right', value: 'center_right' },
|
|
785
|
+
{ name: 'Top Center', value: 'top_center' },
|
|
786
|
+
{ name: 'Top Left', value: 'top_left' },
|
|
787
|
+
{ name: 'Top Right', value: 'top_right' },
|
|
788
|
+
],
|
|
789
|
+
default: 'center',
|
|
790
|
+
description: 'Predefined artwork position on the surface',
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
displayName: 'Rotation',
|
|
794
|
+
name: 'rotation',
|
|
795
|
+
type: 'number',
|
|
796
|
+
default: 0,
|
|
797
|
+
description: 'Artwork rotation in degrees',
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
displayName: 'Width',
|
|
801
|
+
name: 'width',
|
|
802
|
+
type: 'number',
|
|
803
|
+
typeOptions: { minValue: 1, maxValue: 30000 },
|
|
804
|
+
default: 0,
|
|
805
|
+
description: 'Artwork width in pixels. Send together with Height, and without Coverage.',
|
|
806
|
+
},
|
|
807
|
+
],
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
displayName: 'Surface UUID',
|
|
811
|
+
name: 'surfaceUuid',
|
|
812
|
+
type: 'string',
|
|
813
|
+
required: true,
|
|
814
|
+
displayOptions: {
|
|
815
|
+
show: {
|
|
816
|
+
targetType: ['surface', 'fullSurface'],
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
default: '',
|
|
820
|
+
description: 'The surface_uuid returned in data.surfaces by 2D: Get Mockup',
|
|
821
|
+
},
|
|
747
822
|
{
|
|
748
823
|
displayName: 'Target Type',
|
|
749
824
|
name: 'targetType',
|
|
@@ -755,13 +830,13 @@ class SudoMock {
|
|
|
755
830
|
description: 'Target a saved print area returned in data.quads',
|
|
756
831
|
},
|
|
757
832
|
{
|
|
758
|
-
name: '
|
|
759
|
-
value: '
|
|
760
|
-
description: 'Target a
|
|
833
|
+
name: 'Surface',
|
|
834
|
+
value: 'surface',
|
|
835
|
+
description: 'Target a printable product returned in data.surfaces',
|
|
761
836
|
},
|
|
762
837
|
],
|
|
763
838
|
default: 'savedPrintArea',
|
|
764
|
-
description: 'Whether this artwork targets a saved area or
|
|
839
|
+
description: 'Whether this artwork targets a saved print area or the surface it sits on. A product can carry both, and they are separate targets.',
|
|
765
840
|
},
|
|
766
841
|
],
|
|
767
842
|
},
|
|
@@ -931,9 +1006,9 @@ class SudoMock {
|
|
|
931
1006
|
type: 'options',
|
|
932
1007
|
options: [
|
|
933
1008
|
{
|
|
934
|
-
name: '
|
|
1009
|
+
name: 'Stretch',
|
|
935
1010
|
value: 'fill',
|
|
936
|
-
description: '
|
|
1011
|
+
description: 'Scales the design to the bounds without keeping its proportions (default)',
|
|
937
1012
|
},
|
|
938
1013
|
{
|
|
939
1014
|
name: 'Contain',
|
|
@@ -943,7 +1018,7 @@ class SudoMock {
|
|
|
943
1018
|
{
|
|
944
1019
|
name: 'Cover',
|
|
945
1020
|
value: 'cover',
|
|
946
|
-
description: '
|
|
1021
|
+
description: 'Covers the area and crops the overflow, proportions kept',
|
|
947
1022
|
},
|
|
948
1023
|
],
|
|
949
1024
|
default: 'fill',
|
|
@@ -1325,9 +1400,9 @@ class SudoMock {
|
|
|
1325
1400
|
type: 'options',
|
|
1326
1401
|
options: [
|
|
1327
1402
|
{
|
|
1328
|
-
name: '
|
|
1403
|
+
name: 'Stretch',
|
|
1329
1404
|
value: 'fill',
|
|
1330
|
-
description: '
|
|
1405
|
+
description: 'Scales the design to the bounds without keeping its proportions',
|
|
1331
1406
|
},
|
|
1332
1407
|
{
|
|
1333
1408
|
name: 'Contain',
|
|
@@ -1337,7 +1412,7 @@ class SudoMock {
|
|
|
1337
1412
|
{
|
|
1338
1413
|
name: 'Cover',
|
|
1339
1414
|
value: 'cover',
|
|
1340
|
-
description: '
|
|
1415
|
+
description: 'Covers the area and crops the overflow, proportions kept (recommended)',
|
|
1341
1416
|
},
|
|
1342
1417
|
],
|
|
1343
1418
|
default: 'cover',
|
|
@@ -2170,14 +2245,15 @@ class SudoMock {
|
|
|
2170
2245
|
const mockupUuid = this.getNodeParameter('twoDMockupUuid', i);
|
|
2171
2246
|
const printAreasData = this.getNodeParameter('twoDRenderPrintAreas.items', i, []);
|
|
2172
2247
|
const printAreas = printAreasData.map((area) => {
|
|
2173
|
-
|
|
2174
|
-
const
|
|
2248
|
+
// 'fullSurface' is what workflows saved before the rename carry.
|
|
2249
|
+
const targetType = area.targetType === 'fullSurface' ? 'surface' : area.targetType ?? 'savedPrintArea';
|
|
2250
|
+
const targetValue = targetType === 'surface' ? area.surfaceUuid : area.uuid;
|
|
2175
2251
|
if (!targetValue) {
|
|
2176
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), targetType === '
|
|
2177
|
-
? '
|
|
2252
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), targetType === 'surface'
|
|
2253
|
+
? 'Surface UUID is required for a surface render target'
|
|
2178
2254
|
: 'Saved Print Area UUID is required for a saved print-area render target');
|
|
2179
2255
|
}
|
|
2180
|
-
const printArea = targetType === '
|
|
2256
|
+
const printArea = targetType === 'surface' ? { surface_uuid: targetValue } : { uuid: targetValue };
|
|
2181
2257
|
if (area.artworkSource === 'base64') {
|
|
2182
2258
|
printArea.base64 = area.base64;
|
|
2183
2259
|
}
|
|
@@ -2202,8 +2278,55 @@ class SudoMock {
|
|
|
2202
2278
|
blend_mode,
|
|
2203
2279
|
}).filter(([, value]) => value !== undefined));
|
|
2204
2280
|
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2281
|
+
const placement = (targetType === 'surface' ? area.surfacePlacement : area.placement);
|
|
2282
|
+
if (placement && Object.keys(placement).length > 0) {
|
|
2283
|
+
// Which options the caller WROTE, not which of them hold a value. An
|
|
2284
|
+
// explicitly written null is the caller naming the option, and the API
|
|
2285
|
+
// answers it by name; a value check waves that through and teaches the
|
|
2286
|
+
// author nothing.
|
|
2287
|
+
const named = (key) => Object.prototype.hasOwnProperty.call(placement, key);
|
|
2288
|
+
const hasWidth = named('width');
|
|
2289
|
+
const hasHeight = named('height');
|
|
2290
|
+
if (hasWidth !== hasHeight) {
|
|
2291
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Width and Height travel together. Add the missing one, or drop both.');
|
|
2292
|
+
}
|
|
2293
|
+
// `scale` was a placement control until 0.8.0, where one multiplier
|
|
2294
|
+
// was found unable to express two free axes. It was retired with no
|
|
2295
|
+
// alias and no mapping, so workflows saved before that still carry
|
|
2296
|
+
// it on disk with no control left to remove it through. Naming it
|
|
2297
|
+
// here keeps the retirement visible, which was the point, without
|
|
2298
|
+
// putting a field the API refuses on the wire.
|
|
2299
|
+
if (named('scale')) {
|
|
2300
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Scale was retired: one multiplier cannot size two independent axes. Size the artwork with a Width and Height pair instead, and remove Scale.');
|
|
2301
|
+
}
|
|
2302
|
+
if (targetType === 'savedPrintArea') {
|
|
2303
|
+
if (named('fit') && (hasWidth || hasHeight)) {
|
|
2304
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A print area takes either Fit or an explicit Width and Height pair, not both. Remove one of them.');
|
|
2305
|
+
}
|
|
2306
|
+
// A percentage on a print area is no longer a thing the API will
|
|
2307
|
+
// answer. Workflows saved before 2026-08-19 still carry
|
|
2308
|
+
// `coverage: 70` on disk and cannot edit it away through a
|
|
2309
|
+
// control that no longer exists, so it is dropped here rather
|
|
2310
|
+
// than forwarded into a 422 whose cause the author cannot see.
|
|
2311
|
+
delete placement.coverage;
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
// A surface is the whole product, so there are no bounds to fit
|
|
2315
|
+
// against and Fit belongs to a print area alone. The surface
|
|
2316
|
+
// collection never offers it, so arriving here means the target
|
|
2317
|
+
// was built by an expression rather than the panel. Refusing it
|
|
2318
|
+
// by name beats forwarding a 422 the author has no field to
|
|
2319
|
+
// trace back to.
|
|
2320
|
+
if (named('fit')) {
|
|
2321
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A surface covers the whole product, so it has no bounds to fit against. Fit belongs to a print area. Use Coverage, or a Width and Height pair.');
|
|
2322
|
+
}
|
|
2323
|
+
if (named('coverage') && (hasWidth || hasHeight)) {
|
|
2324
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A surface takes either Coverage or an explicit Width and Height pair, not both. Remove one of them.');
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
if (Object.keys(placement).length > 0) {
|
|
2328
|
+
printArea.placement = placement;
|
|
2329
|
+
}
|
|
2207
2330
|
}
|
|
2208
2331
|
return printArea;
|
|
2209
2332
|
});
|
|
@@ -95,7 +95,9 @@ class SudoMockTrigger {
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
catch (error) {
|
|
98
|
-
|
|
98
|
+
if (Number(error.statusCode) !== 404) {
|
|
99
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
|
|
100
|
+
}
|
|
99
101
|
}
|
|
100
102
|
delete data.webhookId;
|
|
101
103
|
delete data.webhookSecret;
|