@shushed/helpers 0.0.204 → 0.0.205-fix-erp-729-20251209153116
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/dist/cjs/src-public/airtable.js +0 -1
- package/dist/cjs/src-public/bcOrder.js +77 -42
- package/dist/cjs/src-public/centra.js +45 -38
- package/dist/cjs/src-public/dato.js +244 -10
- package/dist/types/src-public/airtable.d.ts +0 -1
- package/dist/types/src-public/centra.d.ts +7 -5
- package/dist/types/src-public/dato.d.ts +27 -1
- package/package.json +1 -1
|
@@ -62,7 +62,6 @@ class AirtableHelper extends runtime_1.default {
|
|
|
62
62
|
fieldsToMergeOn: (options.fieldsToMergeOn ?? [this.primaryKeyFieldName]).map(x => this.dictionary[x] || x),
|
|
63
63
|
},
|
|
64
64
|
returnFieldsByFieldId: true,
|
|
65
|
-
typecast: options.typecast || false,
|
|
66
65
|
records: currentBatch.map(x => {
|
|
67
66
|
const recordId = x.$recordId;
|
|
68
67
|
const fieldsWithoutRecordId = { ...x };
|
|
@@ -400,18 +400,15 @@ function transformMasterOrder(payload) {
|
|
|
400
400
|
const desc = String(line?.description || '').trim().toLowerCase();
|
|
401
401
|
return desc === 'delivery';
|
|
402
402
|
};
|
|
403
|
-
let invoicesNetMinor = 0;
|
|
404
403
|
let invoicesGrossMinor = 0;
|
|
405
404
|
(payload.invoices || []).forEach((inv) => {
|
|
406
405
|
(inv.invoice_lines || []).forEach((line) => {
|
|
407
406
|
if (!isDeliveryItem(line)) {
|
|
408
|
-
invoicesNetMinor += toMinorUnits(Number(line?.amount || line?.amount_excl_vat || 0));
|
|
409
407
|
invoicesGrossMinor += toMinorUnits(Number(line?.amount_including_vat || line?.amount_incl_vat || 0));
|
|
410
408
|
}
|
|
411
409
|
});
|
|
412
410
|
});
|
|
413
411
|
if (invoicesGrossMinor === 0 && (payload.invoices || []).length > 0) {
|
|
414
|
-
invoicesNetMinor = toMinorUnits((payload.invoices || []).reduce((acc, inv) => acc + (inv.amount_excl_vat || 0), 0));
|
|
415
412
|
invoicesGrossMinor = toMinorUnits((payload.invoices || []).reduce((acc, inv) => acc + (inv.amount_incl_vat || 0), 0));
|
|
416
413
|
}
|
|
417
414
|
if (invoicesGrossMinor === 0 && invoicedLineNos.size > 0 && sale0?.sale_lines) {
|
|
@@ -423,10 +420,8 @@ function transformMasterOrder(payload) {
|
|
|
423
420
|
const lineNo = Number(l?.line_no || -1);
|
|
424
421
|
return invoicedLineNos.has(lineNo);
|
|
425
422
|
});
|
|
426
|
-
invoicesNetMinor = toMinorUnits(invoicedSaleLines.reduce((acc, l) => acc + (Number(l?.amount || 0)), 0));
|
|
427
423
|
invoicesGrossMinor = toMinorUnits(invoicedSaleLines.reduce((acc, l) => acc + (Number(l?.amount_including_vat || 0)), 0));
|
|
428
424
|
}
|
|
429
|
-
let nonInvSalesNetMinor = 0;
|
|
430
425
|
let nonInvSalesGrossMinor = 0;
|
|
431
426
|
if (sale0?.sale_lines && sale0.sale_lines.length > 0) {
|
|
432
427
|
const allSaleLines = (sale0.sale_lines || []).filter((l) => {
|
|
@@ -436,26 +431,20 @@ function transformMasterOrder(payload) {
|
|
|
436
431
|
return false;
|
|
437
432
|
return true;
|
|
438
433
|
});
|
|
439
|
-
const totalSaleNetMinor = toMinorUnits(allSaleLines.reduce((acc, l) => acc + (Number(l?.amount || 0)), 0));
|
|
440
434
|
const totalSaleGrossMinor = toMinorUnits(allSaleLines.reduce((acc, l) => acc + (Number(l?.amount_including_vat || 0)), 0));
|
|
441
435
|
if (invoicesGrossMinor > 0) {
|
|
442
|
-
nonInvSalesNetMinor = Math.max(0, totalSaleNetMinor - invoicesNetMinor);
|
|
443
436
|
nonInvSalesGrossMinor = Math.max(0, totalSaleGrossMinor - invoicesGrossMinor);
|
|
444
437
|
}
|
|
445
438
|
else {
|
|
446
|
-
nonInvSalesNetMinor = totalSaleNetMinor;
|
|
447
439
|
nonInvSalesGrossMinor = totalSaleGrossMinor;
|
|
448
440
|
}
|
|
449
441
|
}
|
|
450
442
|
else if (sale0 && (sale0.amount_excl_vat || sale0.amount_incl_vat)) {
|
|
451
|
-
const saleNetMinor = toMinorUnits(sale0.amount_excl_vat || 0);
|
|
452
443
|
const saleGrossMinor = toMinorUnits(sale0.amount_incl_vat || 0);
|
|
453
444
|
if (invoicesGrossMinor > 0) {
|
|
454
|
-
nonInvSalesNetMinor = Math.max(0, saleNetMinor - invoicesNetMinor);
|
|
455
445
|
nonInvSalesGrossMinor = Math.max(0, saleGrossMinor - invoicesGrossMinor);
|
|
456
446
|
}
|
|
457
447
|
else {
|
|
458
|
-
nonInvSalesNetMinor = saleNetMinor;
|
|
459
448
|
nonInvSalesGrossMinor = saleGrossMinor;
|
|
460
449
|
}
|
|
461
450
|
}
|
|
@@ -468,32 +457,30 @@ function transformMasterOrder(payload) {
|
|
|
468
457
|
const lineNo = Number(l?.line_no || -1);
|
|
469
458
|
return !invoicedLineNos.has(lineNo);
|
|
470
459
|
});
|
|
471
|
-
nonInvSalesNetMinor = toMinorUnits(nonInvoicedSales.reduce((acc, l) => acc + (Number(l?.amount || 0)), 0));
|
|
472
460
|
nonInvSalesGrossMinor = toMinorUnits(nonInvoicedSales.reduce((acc, l) => acc + (Number(l?.amount_including_vat || 0)), 0));
|
|
473
461
|
}
|
|
474
|
-
const returnsNetMinor = toMinorUnits((payload.credit_memos || []).reduce((acc, cm) => acc + (cm.amount_excl_vat || 0), 0));
|
|
475
|
-
const returnsGrossMinor = toMinorUnits((payload.credit_memos || []).reduce((acc, cm) => acc + (cm.amount_incl_vat || 0), 0));
|
|
476
|
-
const totalNetMinor = invoicesNetMinor + nonInvSalesNetMinor;
|
|
477
462
|
const totalGrossMinor = invoicesGrossMinor + nonInvSalesGrossMinor;
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
amount_gross: moneyFromMinor(returnsGrossMinor),
|
|
489
|
-
discount_amount_net: money(0),
|
|
490
|
-
discount_amount_gross: money(0),
|
|
491
|
-
discount_amount_percent: 0,
|
|
463
|
+
const invoicesNetMinorWithDelivery = toMinorUnits((payload.invoices || []).reduce((acc, inv) => acc + (inv.amount_excl_vat || 0), 0));
|
|
464
|
+
const invoicesGrossMinorWithDelivery = toMinorUnits((payload.invoices || []).reduce((acc, inv) => acc + (inv.amount_incl_vat || 0), 0));
|
|
465
|
+
let nonInvSalesNetMinorWithDelivery = 0;
|
|
466
|
+
let nonInvSalesGrossMinorWithDelivery = 0;
|
|
467
|
+
if (sale0 && (sale0.amount_excl_vat || sale0.amount_incl_vat)) {
|
|
468
|
+
const saleNetMinor = toMinorUnits(sale0.amount_excl_vat || 0);
|
|
469
|
+
const saleGrossMinor = toMinorUnits(sale0.amount_incl_vat || 0);
|
|
470
|
+
if (invoicesGrossMinorWithDelivery > 0) {
|
|
471
|
+
nonInvSalesNetMinorWithDelivery = Math.max(0, saleNetMinor - invoicesNetMinorWithDelivery);
|
|
472
|
+
nonInvSalesGrossMinorWithDelivery = Math.max(0, saleGrossMinor - invoicesGrossMinorWithDelivery);
|
|
492
473
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
474
|
+
else {
|
|
475
|
+
nonInvSalesNetMinorWithDelivery = saleNetMinor;
|
|
476
|
+
nonInvSalesGrossMinorWithDelivery = saleGrossMinor;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const totalNetMinorWithDelivery = invoicesNetMinorWithDelivery + nonInvSalesNetMinorWithDelivery;
|
|
480
|
+
const totalGrossMinorWithDelivery = invoicesGrossMinorWithDelivery + nonInvSalesGrossMinorWithDelivery;
|
|
481
|
+
const total = {
|
|
482
|
+
amount_net: moneyFromMinor(totalNetMinorWithDelivery),
|
|
483
|
+
amount_gross: moneyFromMinor(totalGrossMinorWithDelivery),
|
|
497
484
|
discount_amount_net: money(0),
|
|
498
485
|
discount_amount_gross: money(0),
|
|
499
486
|
discount_amount_percent: 0,
|
|
@@ -603,7 +590,7 @@ function transformMasterOrder(payload) {
|
|
|
603
590
|
const merchReturnGrossFromCreditMemos = (payload.credit_memos || []).reduce((acc, cm) => {
|
|
604
591
|
const lines = cm?.credit_memo_lines || [];
|
|
605
592
|
let hasQualifying = false;
|
|
606
|
-
const
|
|
593
|
+
const sumGross = lines.reduce((s, l) => {
|
|
607
594
|
const itemNo = String(l?.item_no || l?.no || "");
|
|
608
595
|
const desc = String(l?.description || "");
|
|
609
596
|
const looksProduct = itemNo.includes('-') || desc.includes(' - ');
|
|
@@ -616,24 +603,36 @@ function transformMasterOrder(payload) {
|
|
|
616
603
|
}
|
|
617
604
|
return s;
|
|
618
605
|
}, 0);
|
|
606
|
+
const sumNet = lines.reduce((s, l) => {
|
|
607
|
+
const itemNo = String(l?.item_no || l?.no || "");
|
|
608
|
+
const desc = String(l?.description || "");
|
|
609
|
+
const looksProduct = itemNo.includes('-') || desc.includes(' - ');
|
|
610
|
+
const typeStr = String(l?.type || "").toLowerCase();
|
|
611
|
+
const isItemish = typeStr.includes('item') || looksProduct;
|
|
612
|
+
const isRefund = itemNo.toUpperCase() === 'REFUND';
|
|
613
|
+
if ((l?.quantity || 0) > 0 && isItemish && !isRefund && !isDeliveryItem(l)) {
|
|
614
|
+
return s + (l?.amount || l?.amount_excl_vat || 0);
|
|
615
|
+
}
|
|
616
|
+
return s;
|
|
617
|
+
}, 0);
|
|
619
618
|
if (!hasQualifying)
|
|
620
619
|
return acc;
|
|
621
620
|
if (cm?.amount_incl_vat != null && cm.amount_incl_vat > 0) {
|
|
622
|
-
return acc + cm.amount_incl_vat;
|
|
621
|
+
return { gross: acc.gross + cm.amount_incl_vat, net: acc.net + (cm.amount_excl_vat || 0) };
|
|
623
622
|
}
|
|
624
|
-
return acc +
|
|
625
|
-
}, 0);
|
|
623
|
+
return { gross: acc.gross + sumGross, net: acc.net + sumNet };
|
|
624
|
+
}, { gross: 0, net: 0 });
|
|
626
625
|
const merchReturnGrossFromReturnSales = (payload.sales || []).reduce((acc, sale) => {
|
|
627
626
|
const docTypeRaw = String(sale?.document_type || sale?.documentType || "");
|
|
628
627
|
const isReturnOrder = docTypeRaw.toLowerCase().includes('return');
|
|
629
628
|
if (!isReturnOrder)
|
|
630
629
|
return acc;
|
|
631
630
|
if (sale?.amount_incl_vat != null && sale.amount_incl_vat > 0) {
|
|
632
|
-
return acc + sale.amount_incl_vat;
|
|
631
|
+
return { gross: acc.gross + sale.amount_incl_vat, net: acc.net + (sale.amount_excl_vat || sale.amount || 0) };
|
|
633
632
|
}
|
|
634
633
|
const lines = sale?.sale_lines || [];
|
|
635
634
|
let hasQualifying = false;
|
|
636
|
-
const
|
|
635
|
+
const sumGross = lines.reduce((s, l) => {
|
|
637
636
|
const itemNo = String(l?.item_no || l?.no || "");
|
|
638
637
|
const desc = String(l?.description || "");
|
|
639
638
|
const looksProduct = itemNo.includes('-') || desc.includes(' - ');
|
|
@@ -646,10 +645,46 @@ function transformMasterOrder(payload) {
|
|
|
646
645
|
}
|
|
647
646
|
return s;
|
|
648
647
|
}, 0);
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
648
|
+
const sumNet = lines.reduce((s, l) => {
|
|
649
|
+
const itemNo = String(l?.item_no || l?.no || "");
|
|
650
|
+
const desc = String(l?.description || "");
|
|
651
|
+
const looksProduct = itemNo.includes('-') || desc.includes(' - ');
|
|
652
|
+
const typeStr = String(l?.type || "").toLowerCase();
|
|
653
|
+
const isItemish = typeStr.includes('item') || looksProduct;
|
|
654
|
+
const isRefund = itemNo.toUpperCase() === 'REFUND';
|
|
655
|
+
if ((l?.quantity || 0) > 0 && isItemish && !isRefund && !isDeliveryItem(l)) {
|
|
656
|
+
return s + (l?.amount || l?.amount_excl_vat || 0);
|
|
657
|
+
}
|
|
658
|
+
return s;
|
|
659
|
+
}, 0);
|
|
660
|
+
if (sumGross > 0) {
|
|
661
|
+
return { gross: acc.gross + sumGross, net: acc.net + sumNet };
|
|
662
|
+
}
|
|
663
|
+
if (hasQualifying) {
|
|
664
|
+
return { gross: acc.gross + (sale?.amount_incl_vat || sale?.amount_including_vat || 0), net: acc.net + (sale?.amount_excl_vat || sale?.amount || 0) };
|
|
665
|
+
}
|
|
666
|
+
return acc;
|
|
667
|
+
}, { gross: 0, net: 0 });
|
|
668
|
+
const merchReturnGross = merchReturnGrossFromCreditMemos.gross + merchReturnGrossFromReturnSales.gross;
|
|
652
669
|
const hasMerchReturn = merchReturnGross > 0;
|
|
670
|
+
const returnsNetMinor = toMinorUnits((payload.credit_memos || []).reduce((acc, cm) => acc + (cm.amount_excl_vat || 0), 0));
|
|
671
|
+
const returnsGrossMinor = toMinorUnits((payload.credit_memos || []).reduce((acc, cm) => acc + (cm.amount_incl_vat || 0), 0));
|
|
672
|
+
const return_total = (returnsGrossMinor > 0)
|
|
673
|
+
? {
|
|
674
|
+
amount_net: moneyFromMinor(returnsNetMinor),
|
|
675
|
+
amount_gross: moneyFromMinor(returnsGrossMinor),
|
|
676
|
+
discount_amount_net: money(0),
|
|
677
|
+
discount_amount_gross: money(0),
|
|
678
|
+
discount_amount_percent: 0,
|
|
679
|
+
}
|
|
680
|
+
: undefined;
|
|
681
|
+
const net_total = {
|
|
682
|
+
amount_net: moneyFromMinor(Math.max(0, totalNetMinorWithDelivery - returnsNetMinor)),
|
|
683
|
+
amount_gross: moneyFromMinor(Math.max(0, totalGrossMinorWithDelivery - returnsGrossMinor)),
|
|
684
|
+
discount_amount_net: money(0),
|
|
685
|
+
discount_amount_gross: money(0),
|
|
686
|
+
discount_amount_percent: 0,
|
|
687
|
+
};
|
|
653
688
|
const totalOrderGrossMinor = totalGrossMinor;
|
|
654
689
|
const sourceLineMap = new Map();
|
|
655
690
|
sourceLines.forEach((line) => {
|
|
@@ -73,14 +73,6 @@ class CentraHelper extends env_1.default {
|
|
|
73
73
|
errors.push(...userErrors.map((x) => ({ message: x.message, path: x.path })));
|
|
74
74
|
return { errors, limitExceeded: response.status === 429 };
|
|
75
75
|
}
|
|
76
|
-
if (resp.data && typeof resp.data === 'object') {
|
|
77
|
-
for (const key in resp.data) {
|
|
78
|
-
if (resp.data[key] && typeof resp.data[key] === 'object' && 'userErrors' in resp.data[key] && Array.isArray(resp.data[key].userErrors) && resp.data[key].userErrors.length > 0) {
|
|
79
|
-
errors.push(...resp.data[key].userErrors.map((x) => ({ message: x.message, path: x.path })));
|
|
80
|
-
return { errors, limitExceeded: response.status === 429 };
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
76
|
}
|
|
85
77
|
if (response.status === 429) {
|
|
86
78
|
resp.limitExceeded = true;
|
|
@@ -331,7 +323,7 @@ class CentraHelper extends env_1.default {
|
|
|
331
323
|
} while (hasNextPage);
|
|
332
324
|
return result;
|
|
333
325
|
}
|
|
334
|
-
async fetchCentraMarkets() {
|
|
326
|
+
async fetchCentraMarkets(externalIds) {
|
|
335
327
|
const result = [];
|
|
336
328
|
const limit = 200;
|
|
337
329
|
let page = 0;
|
|
@@ -341,15 +333,15 @@ class CentraHelper extends env_1.default {
|
|
|
341
333
|
method: 'POST',
|
|
342
334
|
body: JSON.stringify({
|
|
343
335
|
query: `
|
|
344
|
-
query GetMarkets($limit: Int, $page: Int) {
|
|
345
|
-
markets(limit: $limit, page: $page) {
|
|
336
|
+
query GetMarkets($limit: Int, $page: Int${externalIds ? `, $externalIds: MarketsFilter` : ''}) {
|
|
337
|
+
markets(${externalIds ? `where: $externalIds, ` : ''}limit: $limit, page: $page) {
|
|
346
338
|
id
|
|
347
339
|
externalId
|
|
348
340
|
name
|
|
349
341
|
}
|
|
350
342
|
}
|
|
351
343
|
`,
|
|
352
|
-
variables: { page: page, limit: limit }
|
|
344
|
+
variables: { page: page, limit: limit, externalIds: { externalId: externalIds } }
|
|
353
345
|
})
|
|
354
346
|
});
|
|
355
347
|
if (CentraHelper.isCentraErrors(data)) {
|
|
@@ -479,7 +471,7 @@ class CentraHelper extends env_1.default {
|
|
|
479
471
|
nextCursor = null;
|
|
480
472
|
}
|
|
481
473
|
if (data && data.data?.productConnection?.edges?.length) {
|
|
482
|
-
for (let i =
|
|
474
|
+
for (let i = data.data.productConnection.edges.length; i < styleIds.length; i++) {
|
|
483
475
|
const { node } = data.data.productConnection.edges[i];
|
|
484
476
|
result[node.externalId] = node;
|
|
485
477
|
}
|
|
@@ -505,15 +497,16 @@ class CentraHelper extends env_1.default {
|
|
|
505
497
|
edges {
|
|
506
498
|
node {
|
|
507
499
|
id
|
|
500
|
+
externalId
|
|
508
501
|
status
|
|
509
|
-
|
|
502
|
+
url
|
|
510
503
|
metaTitle
|
|
511
504
|
metaDescription
|
|
512
505
|
name
|
|
513
506
|
categories {
|
|
514
507
|
id
|
|
515
508
|
name
|
|
516
|
-
|
|
509
|
+
url
|
|
517
510
|
isTopCategory
|
|
518
511
|
}
|
|
519
512
|
markets {
|
|
@@ -525,7 +518,7 @@ class CentraHelper extends env_1.default {
|
|
|
525
518
|
externalId
|
|
526
519
|
status
|
|
527
520
|
}
|
|
528
|
-
|
|
521
|
+
productVariant {
|
|
529
522
|
id
|
|
530
523
|
externalId
|
|
531
524
|
status
|
|
@@ -572,8 +565,8 @@ class CentraHelper extends env_1.default {
|
|
|
572
565
|
for (let i = 0; i < edges.length; i++) {
|
|
573
566
|
const { node } = edges[i];
|
|
574
567
|
if (inputIdType === 'variant') {
|
|
575
|
-
result[+node.
|
|
576
|
-
result[+node.
|
|
568
|
+
result[+node.productVariant[0].id] = [];
|
|
569
|
+
result[+node.productVariant[0].id].push(node);
|
|
577
570
|
}
|
|
578
571
|
else {
|
|
579
572
|
result[+node.product.id] = [];
|
|
@@ -797,45 +790,59 @@ class CentraHelper extends env_1.default {
|
|
|
797
790
|
}
|
|
798
791
|
return Object.assign({}, pricelistInCache, pricelistToSet);
|
|
799
792
|
}
|
|
800
|
-
async getCentraMarkets(alwaysFetch = false) {
|
|
793
|
+
async getCentraMarkets(externalIds, alwaysFetch = false) {
|
|
794
|
+
if (externalIds && !externalIds.length) {
|
|
795
|
+
return {};
|
|
796
|
+
}
|
|
801
797
|
let marketInCache = {};
|
|
802
|
-
let
|
|
798
|
+
let dedupedExternalIds = [];
|
|
803
799
|
let marketsToFetch = null;
|
|
804
800
|
if (!alwaysFetch) {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
801
|
+
if (!externalIds) {
|
|
802
|
+
externalIds = (await this.get(this.getCacheKeyForMarkets(), 'env', {
|
|
803
|
+
isEphemeral: true,
|
|
804
|
+
encrypted: false,
|
|
805
|
+
}).then(x => x ? JSON.parse(x) : null));
|
|
806
|
+
}
|
|
807
|
+
if (externalIds) {
|
|
808
|
+
dedupedExternalIds = externalIds.filter((x, index, self) => self.indexOf(x) === index);
|
|
809
|
+
marketInCache = Object.fromEntries(Object.entries(await this.get(dedupedExternalIds.map(x => this.getCacheKeyForMarket(x)), 'env', {
|
|
812
810
|
isEphemeral: true,
|
|
813
811
|
encrypted: false,
|
|
814
812
|
})).map(([key, value]) => [key, value ? JSON.parse(value || 'null') : undefined]).filter(([_, value]) => value));
|
|
815
|
-
marketsToFetch =
|
|
813
|
+
marketsToFetch = dedupedExternalIds.filter(x => !marketInCache[x]);
|
|
816
814
|
}
|
|
817
815
|
}
|
|
818
816
|
const marketToSet = {};
|
|
819
817
|
if (!marketsToFetch || marketsToFetch.length) {
|
|
820
|
-
const markets = await this.fetchCentraMarkets();
|
|
818
|
+
const markets = await this.fetchCentraMarkets(marketsToFetch);
|
|
821
819
|
if (CentraHelper.isCentraErrors(markets)) {
|
|
822
|
-
|
|
820
|
+
if (marketsToFetch) {
|
|
821
|
+
for (const marketExternalId of marketsToFetch) {
|
|
822
|
+
marketToSet[marketExternalId] = new Error(`Failed to fetch market ${marketExternalId}: ${markets.errors.map((x) => x.message).join(', ')}`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
return new Error(`Failed to fetch markets: ${markets.errors.map((x) => x.message).join(', ')}`);
|
|
827
|
+
}
|
|
823
828
|
}
|
|
824
829
|
else {
|
|
825
830
|
for (const market of markets) {
|
|
826
|
-
marketToSet[market.
|
|
831
|
+
marketToSet[market.externalId] = market;
|
|
827
832
|
}
|
|
828
833
|
await this.set(Object.entries(marketToSet).filter(([_, value]) => !(value instanceof Error)).map(([key, value]) => ({ name: this.getCacheKeyForMarket(key), value: JSON.stringify(value) })), 'env', {
|
|
829
834
|
ephemeralMs: CACHE_EXPIRATION_MS,
|
|
830
835
|
encrypted: false,
|
|
831
836
|
});
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
837
|
+
if (!marketsToFetch) {
|
|
838
|
+
await this.set([{
|
|
839
|
+
name: this.getCacheKeyForMarkets(),
|
|
840
|
+
value: JSON.stringify(Object.keys(marketToSet)),
|
|
841
|
+
}], 'env', {
|
|
842
|
+
ephemeralMs: CACHE_EXPIRATION_MS,
|
|
843
|
+
encrypted: false,
|
|
844
|
+
});
|
|
845
|
+
}
|
|
839
846
|
}
|
|
840
847
|
}
|
|
841
848
|
return Object.assign({}, marketInCache, marketToSet);
|
|
@@ -72,6 +72,11 @@ class DatoHelper extends runtime_1.default {
|
|
|
72
72
|
return response;
|
|
73
73
|
}
|
|
74
74
|
async createAssetFromUpload(uploadId, opts, uploadCollectionId) {
|
|
75
|
+
const normalizedTags = Array.isArray(opts.tags) && opts.tags.length > 0
|
|
76
|
+
? opts.tags
|
|
77
|
+
: ["integrations"];
|
|
78
|
+
const safeTitle = opts.title && opts.title.trim().length > 0 ? opts.title : "untitled";
|
|
79
|
+
const safeAlt = opts.alt && opts.alt.trim().length > 0 ? opts.alt : safeTitle;
|
|
75
80
|
const body = {
|
|
76
81
|
data: {
|
|
77
82
|
type: 'upload',
|
|
@@ -80,13 +85,35 @@ class DatoHelper extends runtime_1.default {
|
|
|
80
85
|
author: opts.author,
|
|
81
86
|
copyright: opts.copyright,
|
|
82
87
|
notes: opts.notes || null,
|
|
88
|
+
title: safeTitle,
|
|
89
|
+
alt: safeAlt,
|
|
83
90
|
default_field_metadata: {
|
|
91
|
+
"en-GB": {
|
|
92
|
+
title: safeTitle,
|
|
93
|
+
alt: safeAlt,
|
|
94
|
+
custom_data: {
|
|
95
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
96
|
+
tags: normalizedTags,
|
|
97
|
+
}
|
|
98
|
+
},
|
|
84
99
|
en: {
|
|
85
|
-
title:
|
|
86
|
-
alt:
|
|
100
|
+
title: safeTitle,
|
|
101
|
+
alt: safeAlt,
|
|
102
|
+
custom_data: {
|
|
103
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
104
|
+
tags: normalizedTags,
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"en-US": {
|
|
108
|
+
title: safeTitle,
|
|
109
|
+
alt: safeAlt,
|
|
110
|
+
custom_data: {
|
|
111
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
112
|
+
tags: normalizedTags,
|
|
113
|
+
}
|
|
87
114
|
}
|
|
88
115
|
},
|
|
89
|
-
tags:
|
|
116
|
+
tags: normalizedTags || [],
|
|
90
117
|
},
|
|
91
118
|
},
|
|
92
119
|
};
|
|
@@ -155,8 +182,119 @@ class DatoHelper extends runtime_1.default {
|
|
|
155
182
|
this.logging.error(timeoutMsg);
|
|
156
183
|
throw new Error(timeoutMsg);
|
|
157
184
|
}
|
|
185
|
+
updateUpload = async (options) => {
|
|
186
|
+
try {
|
|
187
|
+
this.logging.log(`Starting update upload - ${JSON.stringify(options)}`);
|
|
188
|
+
if (!options.id)
|
|
189
|
+
throw new Error("updateUpload requires 'id' in options");
|
|
190
|
+
const safeTitle = options.title && options.title.trim().length > 0
|
|
191
|
+
? options.title.trim()
|
|
192
|
+
: options.filename?.trim().split(".")[0] || "untitled";
|
|
193
|
+
const safeAlt = options.alt && options.alt.trim().length > 0
|
|
194
|
+
? options.alt.trim()
|
|
195
|
+
: safeTitle;
|
|
196
|
+
const normalizedTags = Array.isArray(options.tags) && options.tags.length > 0
|
|
197
|
+
? options.tags
|
|
198
|
+
: ["integrations"];
|
|
199
|
+
const body = {
|
|
200
|
+
data: {
|
|
201
|
+
type: "upload",
|
|
202
|
+
id: options.id,
|
|
203
|
+
attributes: {
|
|
204
|
+
author: options.author,
|
|
205
|
+
copyright: options.copyright,
|
|
206
|
+
tags: normalizedTags,
|
|
207
|
+
notes: options.notes || null,
|
|
208
|
+
default_field_metadata: {
|
|
209
|
+
"en-GB": {
|
|
210
|
+
title: safeTitle,
|
|
211
|
+
alt: safeAlt,
|
|
212
|
+
custom_data: {
|
|
213
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
214
|
+
tags: normalizedTags,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
en: {
|
|
218
|
+
title: safeTitle,
|
|
219
|
+
alt: safeAlt,
|
|
220
|
+
custom_data: {
|
|
221
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
222
|
+
tags: normalizedTags,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
"en-US": {
|
|
226
|
+
title: safeTitle,
|
|
227
|
+
alt: safeAlt,
|
|
228
|
+
custom_data: {
|
|
229
|
+
source: normalizedTags[0] || "uploaded-by-integrations",
|
|
230
|
+
tags: normalizedTags,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
if (options.uploadCollectionId) {
|
|
238
|
+
body.data.relationships = {
|
|
239
|
+
upload_collection: {
|
|
240
|
+
data: {
|
|
241
|
+
type: "upload_collection",
|
|
242
|
+
id: options.uploadCollectionId,
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const response = await fetch(`${this.baseUrl}/uploads/${options.id}`, {
|
|
248
|
+
method: "PATCH",
|
|
249
|
+
headers: {
|
|
250
|
+
Authorization: `Bearer ${this.apiToken}`,
|
|
251
|
+
"X-Api-Version": "3",
|
|
252
|
+
"X-Environment": this.environment,
|
|
253
|
+
"Content-Type": "application/vnd.api+json",
|
|
254
|
+
Accept: "application/json",
|
|
255
|
+
},
|
|
256
|
+
body: JSON.stringify(body),
|
|
257
|
+
});
|
|
258
|
+
if (!response.ok) {
|
|
259
|
+
const errorText = await response.text();
|
|
260
|
+
this.logging.error(`Failed to update upload: ${response.statusText} - ${errorText}`);
|
|
261
|
+
throw new Error(`Failed to update upload: ${response.statusText} - ${errorText}`);
|
|
262
|
+
}
|
|
263
|
+
const updated = await response.json();
|
|
264
|
+
if (Array.isArray(updated.data) && updated.data[0]?.type === "api_error") {
|
|
265
|
+
const errorCode = updated.data[0].attributes?.code || "UNKNOWN_ERROR";
|
|
266
|
+
const errorMsg = `DatoCMS API error: ${errorCode}`;
|
|
267
|
+
this.logging.error(errorMsg);
|
|
268
|
+
throw new Error(errorMsg);
|
|
269
|
+
}
|
|
270
|
+
if (updated.data?.type === "job") {
|
|
271
|
+
this.logging.log(`Waiting for job completion: ${updated.data.id}`);
|
|
272
|
+
const jobPayload = await this.waitForJobCompletion(updated.data.id);
|
|
273
|
+
const assetId = jobPayload?.data?.id;
|
|
274
|
+
const assetUrl = jobPayload?.data?.attributes?.url;
|
|
275
|
+
if (!assetId || !assetUrl) {
|
|
276
|
+
throw new Error(`Job completed but payload missing expected fields: ${JSON.stringify(jobPayload)}`);
|
|
277
|
+
}
|
|
278
|
+
this.logging.log(`Job completed for upload: ${assetId}`);
|
|
279
|
+
return { success: true, assetId, upload: assetUrl };
|
|
280
|
+
}
|
|
281
|
+
if (updated.data?.type === "upload") {
|
|
282
|
+
const { id, attributes } = updated.data;
|
|
283
|
+
this.logging.log(`Upload updated successfully: ${id}`);
|
|
284
|
+
return { success: true, assetId: id, upload: attributes.url };
|
|
285
|
+
}
|
|
286
|
+
const errMsg = `Unexpected update response: ${JSON.stringify(updated)}`;
|
|
287
|
+
this.logging.error(errMsg);
|
|
288
|
+
throw new Error(errMsg);
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
const msg = err?.message ?? JSON.stringify(err);
|
|
292
|
+
this.logging.error(`[updateUpload] failed: ${msg}`);
|
|
293
|
+
throw new Error(msg);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
158
296
|
async uploadFromUrl(options) {
|
|
159
|
-
const { url, filename, uploadCollectionId } = options;
|
|
297
|
+
const { url, filename, uploadCollectionId, skipCreationIfAlreadyExists } = options;
|
|
160
298
|
this.logging.log(`Starting upload from URL: ${url}`);
|
|
161
299
|
const fileResponse = await fetch(url);
|
|
162
300
|
if (!fileResponse.ok) {
|
|
@@ -164,9 +302,43 @@ class DatoHelper extends runtime_1.default {
|
|
|
164
302
|
this.logging.error(errorMsg);
|
|
165
303
|
throw new Error(errorMsg);
|
|
166
304
|
}
|
|
167
|
-
let finalFilename = filename || path_1.default.basename(new URL(url).pathname) ||
|
|
168
|
-
|
|
169
|
-
|
|
305
|
+
let finalFilename = filename || path_1.default.basename(new URL(url).pathname) ||
|
|
306
|
+
`bs-${this.triggerId}-${Date.now()}`;
|
|
307
|
+
if (filename && !path_1.default.extname(finalFilename)) {
|
|
308
|
+
const urlObj = new URL(url);
|
|
309
|
+
const pathname = urlObj.pathname;
|
|
310
|
+
if (pathname.includes(".")) {
|
|
311
|
+
const urlExtension = path_1.default.extname(pathname);
|
|
312
|
+
if (urlExtension) {
|
|
313
|
+
finalFilename += urlExtension;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (!path_1.default.extname(finalFilename) && fileResponse.headers.has('content-type')) {
|
|
317
|
+
const ext = (0, mime_types_1.extension)(fileResponse.headers.get('content-type'));
|
|
318
|
+
if (typeof ext === "string" && ext.length > 0) {
|
|
319
|
+
finalFilename += `.${ext}`;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
else if (!filename) {
|
|
324
|
+
if (!path_1.default.extname(finalFilename) && fileResponse.headers.has('content-type')) {
|
|
325
|
+
const ext = (0, mime_types_1.extension)(fileResponse.headers.get('content-type'));
|
|
326
|
+
if (typeof ext === "string" && ext.length > 0) {
|
|
327
|
+
finalFilename += `.${ext}`;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (skipCreationIfAlreadyExists) {
|
|
332
|
+
const existing = await this.findUploadByFilename(finalFilename);
|
|
333
|
+
if (existing) {
|
|
334
|
+
this.logging.log(`Skipping upload: existing asset found for "${finalFilename}"`);
|
|
335
|
+
return {
|
|
336
|
+
success: true,
|
|
337
|
+
assetId: existing.id,
|
|
338
|
+
upload: existing.attributes.url,
|
|
339
|
+
skipped: true,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
170
342
|
}
|
|
171
343
|
const uploadRequest = await this.requestUploadParameters(finalFilename);
|
|
172
344
|
const uploadId = uploadRequest.data.id;
|
|
@@ -183,6 +355,7 @@ class DatoHelper extends runtime_1.default {
|
|
|
183
355
|
success: true,
|
|
184
356
|
upload: assetPayload.data.attributes.url,
|
|
185
357
|
assetId: assetPayload.data.id,
|
|
358
|
+
skipped: false,
|
|
186
359
|
};
|
|
187
360
|
}
|
|
188
361
|
async uploadFromFile(options) {
|
|
@@ -264,7 +437,14 @@ class DatoHelper extends runtime_1.default {
|
|
|
264
437
|
}
|
|
265
438
|
async findUploadByFilename(filename) {
|
|
266
439
|
try {
|
|
267
|
-
|
|
440
|
+
if (!filename || typeof filename !== 'string') {
|
|
441
|
+
this.logging.log(`findUploadByFilename called with invalid filename: ${String(filename)}`);
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
const normalizedTarget = filename.trim().toLowerCase().replace(/\.[^.]+$/, '');
|
|
445
|
+
const query = encodeURIComponent(normalizedTarget);
|
|
446
|
+
this.logging.log(`Searching uploads with query="${normalizedTarget}" for filename="${filename}"`);
|
|
447
|
+
const response = await fetch(`${this.baseUrl}/uploads?filter[query]=${query}&page[limit]=100`, {
|
|
268
448
|
headers: {
|
|
269
449
|
'Authorization': `Bearer ${this.apiToken}`,
|
|
270
450
|
'X-Api-Version': '3',
|
|
@@ -281,10 +461,32 @@ class DatoHelper extends runtime_1.default {
|
|
|
281
461
|
this.logging.error(`Failed to parse JSON in findUploadByFilename: ${err.message}`);
|
|
282
462
|
return null;
|
|
283
463
|
});
|
|
284
|
-
|
|
464
|
+
const uploads = data?.data || [];
|
|
465
|
+
if (!uploads.length) {
|
|
466
|
+
this.logging.log(`No uploads returned for query="${normalizedTarget}"`);
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
const targetFull = filename.trim().toLowerCase();
|
|
470
|
+
const match = uploads.find((u) => {
|
|
471
|
+
const storedFull = u?.attributes?.filename?.toLowerCase();
|
|
472
|
+
if (!storedFull)
|
|
473
|
+
return false;
|
|
474
|
+
if (storedFull === targetFull)
|
|
475
|
+
return true;
|
|
476
|
+
const storedNormalized = storedFull.replace(/\.[^.]+$/, '');
|
|
477
|
+
if (storedNormalized === normalizedTarget)
|
|
478
|
+
return true;
|
|
479
|
+
return false;
|
|
480
|
+
});
|
|
481
|
+
if (match) {
|
|
482
|
+
this.logging.log(`Found existing upload for "${filename}" -> asset_id=${match.id}, storedFilename=${match.attributes?.filename}`);
|
|
483
|
+
return match;
|
|
484
|
+
}
|
|
485
|
+
this.logging.log(`No exact filename match found among ${uploads.length} uploads for "${filename}" (query="${normalizedTarget}")`);
|
|
486
|
+
return null;
|
|
285
487
|
}
|
|
286
488
|
catch (err) {
|
|
287
|
-
this.logging.error(`Error in findUploadByFilename: ${err
|
|
489
|
+
this.logging.error(`Error in findUploadByFilename: ${err?.message ?? String(err)}`);
|
|
288
490
|
return null;
|
|
289
491
|
}
|
|
290
492
|
}
|
|
@@ -399,5 +601,37 @@ class DatoHelper extends runtime_1.default {
|
|
|
399
601
|
throw err;
|
|
400
602
|
}
|
|
401
603
|
}
|
|
604
|
+
async updateProductSwatch(productId, uploadId) {
|
|
605
|
+
try {
|
|
606
|
+
const res = await fetch(`${this.baseUrl}/items/${productId}`, {
|
|
607
|
+
method: "PATCH",
|
|
608
|
+
headers: {
|
|
609
|
+
Authorization: `Bearer ${this.apiToken}`,
|
|
610
|
+
"X-Api-Version": "3",
|
|
611
|
+
"X-Environment": this.environment,
|
|
612
|
+
"Content-Type": "application/vnd.api+json",
|
|
613
|
+
Accept: "application/json",
|
|
614
|
+
},
|
|
615
|
+
body: JSON.stringify({
|
|
616
|
+
data: {
|
|
617
|
+
type: "item",
|
|
618
|
+
id: productId,
|
|
619
|
+
attributes: {
|
|
620
|
+
swatch: { upload_id: uploadId },
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
}),
|
|
624
|
+
});
|
|
625
|
+
if (!res.ok) {
|
|
626
|
+
const errorText = await res.text();
|
|
627
|
+
throw new Error(`Failed to update product swatch: ${res.status} ${res.statusText} - ${errorText}`);
|
|
628
|
+
}
|
|
629
|
+
return await res.json();
|
|
630
|
+
}
|
|
631
|
+
catch (err) {
|
|
632
|
+
this.logging.error(`updateProductSwatch failed: ${err.message}`);
|
|
633
|
+
throw err;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
402
636
|
}
|
|
403
637
|
exports.default = DatoHelper;
|
|
@@ -44,7 +44,6 @@ declare class AirtableHelper<T extends Record<string, string>, K extends keyof T
|
|
|
44
44
|
}>, options?: {
|
|
45
45
|
fieldsToMergeOn?: Array<keyof T>;
|
|
46
46
|
primaryKeyWritable?: boolean;
|
|
47
|
-
typecast?: boolean;
|
|
48
47
|
}, callIdx?: number, collectedResult?: {
|
|
49
48
|
updatedRecords: Array<string>;
|
|
50
49
|
createdRecords: Array<string>;
|
|
@@ -19,18 +19,19 @@ export type BasicCentraProduct = {
|
|
|
19
19
|
export type BasicCentraDisplay = {
|
|
20
20
|
id: number;
|
|
21
21
|
name: string;
|
|
22
|
+
externalId: string;
|
|
22
23
|
status: string;
|
|
23
|
-
|
|
24
|
+
url: string;
|
|
24
25
|
metaTitle: string;
|
|
25
26
|
metaDescription: string;
|
|
26
27
|
categories: {
|
|
27
28
|
id: number;
|
|
28
29
|
name: string;
|
|
29
|
-
|
|
30
|
+
url: string;
|
|
30
31
|
isTopCategory: boolean;
|
|
31
32
|
}[];
|
|
32
33
|
markets: BasicCentraMarket[];
|
|
33
|
-
|
|
34
|
+
productVariant: Array<{
|
|
34
35
|
id: number;
|
|
35
36
|
externalId: string;
|
|
36
37
|
status: string;
|
|
@@ -76,6 +77,7 @@ export type BasicCentraCountry = {
|
|
|
76
77
|
export type BasicCentraMarket = {
|
|
77
78
|
id: number;
|
|
78
79
|
name: string;
|
|
80
|
+
externalId: string;
|
|
79
81
|
};
|
|
80
82
|
export type BasicCentraVariant = {
|
|
81
83
|
id: number;
|
|
@@ -156,14 +158,14 @@ export default class CentraHelper extends EnvEngine {
|
|
|
156
158
|
fetchCentraWarehouses(externalIds?: string[] | undefined | null): Promise<CentraErrors | Array<BasicCentraWarehouse>>;
|
|
157
159
|
fetchCentraCampaigns(names?: string[] | undefined | null): Promise<CentraErrors | Record<string, BasicCentraCampaign | Error>>;
|
|
158
160
|
fetchPricelists(names?: string[] | undefined | null): Promise<CentraErrors | Array<BasicPricelist>>;
|
|
159
|
-
fetchCentraMarkets(): Promise<CentraErrors | Array<BasicCentraMarket>>;
|
|
161
|
+
fetchCentraMarkets(externalIds?: string[] | undefined | null): Promise<CentraErrors | Array<BasicCentraMarket>>;
|
|
160
162
|
fetchCentraSizeCharts(externalIds?: string[] | undefined | null): Promise<CentraErrors | Array<BasicCentraSizeChart>>;
|
|
161
163
|
private fetchCentraProducts;
|
|
162
164
|
private fetchCentraDisplays;
|
|
163
165
|
private fetchCentraVariants;
|
|
164
166
|
getCentraWarehouses(externalIds?: string[] | null | undefined, alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicCentraWarehouse>>;
|
|
165
167
|
getCentraPricelists(names?: string[] | null | undefined, alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicPricelist>>;
|
|
166
|
-
getCentraMarkets(alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicCentraMarket>>;
|
|
168
|
+
getCentraMarkets(externalIds?: string[] | null | undefined, alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicCentraMarket>>;
|
|
167
169
|
getCentraCountries(iso2Codes?: string[] | null | undefined, alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicCentraCountry>>;
|
|
168
170
|
getCentraSizeCharts(externalIds?: string[] | null | undefined, alwaysFetch?: boolean): Promise<Error | Record<string, Error | BasicCentraSizeChart>>;
|
|
169
171
|
getCentraProducts(styleIds: string[]): Promise<Error | Record<string, Error | BasicCentraProduct>>;
|
|
@@ -8,6 +8,16 @@ interface UploadResult {
|
|
|
8
8
|
success: boolean;
|
|
9
9
|
upload: string;
|
|
10
10
|
assetId?: string;
|
|
11
|
+
skipped?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface UploadReturn {
|
|
14
|
+
id: string;
|
|
15
|
+
type: string;
|
|
16
|
+
attributes: {
|
|
17
|
+
url: string;
|
|
18
|
+
filename: string;
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
};
|
|
11
21
|
}
|
|
12
22
|
export default class DatoHelper extends Runtime {
|
|
13
23
|
private apiToken;
|
|
@@ -19,6 +29,21 @@ export default class DatoHelper extends Runtime {
|
|
|
19
29
|
private createAssetFromUpload;
|
|
20
30
|
private checkJobResult;
|
|
21
31
|
private waitForJobCompletion;
|
|
32
|
+
updateUpload: (options: {
|
|
33
|
+
id: string;
|
|
34
|
+
filename?: string;
|
|
35
|
+
tags: string[];
|
|
36
|
+
notes?: string;
|
|
37
|
+
title: string;
|
|
38
|
+
alt: string;
|
|
39
|
+
author: string;
|
|
40
|
+
copyright: string;
|
|
41
|
+
uploadCollectionId?: string;
|
|
42
|
+
}) => Promise<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
assetId: string;
|
|
45
|
+
upload: string;
|
|
46
|
+
}>;
|
|
22
47
|
uploadFromUrl(options: {
|
|
23
48
|
url: string;
|
|
24
49
|
copyright: string;
|
|
@@ -53,10 +78,11 @@ export default class DatoHelper extends Runtime {
|
|
|
53
78
|
quality?: number;
|
|
54
79
|
format?: 'jpg' | 'pjpg' | 'png' | 'webp' | 'avif' | 'gif' | 'jxl' | 'jp2' | 'jxr' | 'json' | 'blurhash' | (string & {});
|
|
55
80
|
}): string;
|
|
56
|
-
findUploadByFilename(filename: string): Promise<
|
|
81
|
+
findUploadByFilename(filename: string): Promise<UploadReturn | null>;
|
|
57
82
|
getItemTypeId(apiKey: string): Promise<string>;
|
|
58
83
|
getProductBySku(sku: string): Promise<any>;
|
|
59
84
|
createProduct(sku: string, productTypeId: string): Promise<any>;
|
|
60
85
|
updateProductGallery(productId: string, gallery: any[]): Promise<any>;
|
|
86
|
+
updateProductSwatch(productId: string, uploadId: string): Promise<any>;
|
|
61
87
|
}
|
|
62
88
|
export {};
|