@shushed/helpers 0.0.204-main-20251209142954 → 0.0.204
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/dato.js +10 -244
- package/dist/types/src-public/dato.d.ts +1 -27
- package/package.json +1 -1
|
@@ -72,11 +72,6 @@ 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;
|
|
80
75
|
const body = {
|
|
81
76
|
data: {
|
|
82
77
|
type: 'upload',
|
|
@@ -85,35 +80,13 @@ class DatoHelper extends runtime_1.default {
|
|
|
85
80
|
author: opts.author,
|
|
86
81
|
copyright: opts.copyright,
|
|
87
82
|
notes: opts.notes || null,
|
|
88
|
-
title: safeTitle,
|
|
89
|
-
alt: safeAlt,
|
|
90
83
|
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
|
-
},
|
|
99
84
|
en: {
|
|
100
|
-
title:
|
|
101
|
-
alt:
|
|
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
|
-
}
|
|
85
|
+
title: opts.title,
|
|
86
|
+
alt: opts.alt,
|
|
114
87
|
}
|
|
115
88
|
},
|
|
116
|
-
tags:
|
|
89
|
+
tags: opts.tags || [],
|
|
117
90
|
},
|
|
118
91
|
},
|
|
119
92
|
};
|
|
@@ -182,119 +155,8 @@ class DatoHelper extends runtime_1.default {
|
|
|
182
155
|
this.logging.error(timeoutMsg);
|
|
183
156
|
throw new Error(timeoutMsg);
|
|
184
157
|
}
|
|
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
|
-
};
|
|
296
158
|
async uploadFromUrl(options) {
|
|
297
|
-
const { url, filename, uploadCollectionId
|
|
159
|
+
const { url, filename, uploadCollectionId } = options;
|
|
298
160
|
this.logging.log(`Starting upload from URL: ${url}`);
|
|
299
161
|
const fileResponse = await fetch(url);
|
|
300
162
|
if (!fileResponse.ok) {
|
|
@@ -302,43 +164,9 @@ class DatoHelper extends runtime_1.default {
|
|
|
302
164
|
this.logging.error(errorMsg);
|
|
303
165
|
throw new Error(errorMsg);
|
|
304
166
|
}
|
|
305
|
-
let finalFilename = filename || path_1.default.basename(new URL(url).pathname) ||
|
|
306
|
-
|
|
307
|
-
|
|
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
|
-
}
|
|
167
|
+
let finalFilename = filename || path_1.default.basename(new URL(url).pathname) || 'bs-' + this.triggerId + '-' + new Date().getTime();
|
|
168
|
+
if (!path_1.default.extname(finalFilename) && fileResponse.headers.has('content-type')) {
|
|
169
|
+
finalFilename += `.${(0, mime_types_1.extension)(fileResponse.headers.get('content-type'))}`;
|
|
342
170
|
}
|
|
343
171
|
const uploadRequest = await this.requestUploadParameters(finalFilename);
|
|
344
172
|
const uploadId = uploadRequest.data.id;
|
|
@@ -355,7 +183,6 @@ class DatoHelper extends runtime_1.default {
|
|
|
355
183
|
success: true,
|
|
356
184
|
upload: assetPayload.data.attributes.url,
|
|
357
185
|
assetId: assetPayload.data.id,
|
|
358
|
-
skipped: false,
|
|
359
186
|
};
|
|
360
187
|
}
|
|
361
188
|
async uploadFromFile(options) {
|
|
@@ -437,14 +264,7 @@ class DatoHelper extends runtime_1.default {
|
|
|
437
264
|
}
|
|
438
265
|
async findUploadByFilename(filename) {
|
|
439
266
|
try {
|
|
440
|
-
|
|
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`, {
|
|
267
|
+
const response = await fetch(`${this.baseUrl}/uploads?filter[filename]=${encodeURIComponent(filename)}`, {
|
|
448
268
|
headers: {
|
|
449
269
|
'Authorization': `Bearer ${this.apiToken}`,
|
|
450
270
|
'X-Api-Version': '3',
|
|
@@ -461,32 +281,10 @@ class DatoHelper extends runtime_1.default {
|
|
|
461
281
|
this.logging.error(`Failed to parse JSON in findUploadByFilename: ${err.message}`);
|
|
462
282
|
return null;
|
|
463
283
|
});
|
|
464
|
-
|
|
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;
|
|
284
|
+
return data?.data?.[0] || null;
|
|
487
285
|
}
|
|
488
286
|
catch (err) {
|
|
489
|
-
this.logging.error(`Error in findUploadByFilename: ${err
|
|
287
|
+
this.logging.error(`Error in findUploadByFilename: ${err.message}`);
|
|
490
288
|
return null;
|
|
491
289
|
}
|
|
492
290
|
}
|
|
@@ -601,37 +399,5 @@ class DatoHelper extends runtime_1.default {
|
|
|
601
399
|
throw err;
|
|
602
400
|
}
|
|
603
401
|
}
|
|
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
|
-
}
|
|
636
402
|
}
|
|
637
403
|
exports.default = DatoHelper;
|
|
@@ -8,16 +8,6 @@ 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
|
-
};
|
|
21
11
|
}
|
|
22
12
|
export default class DatoHelper extends Runtime {
|
|
23
13
|
private apiToken;
|
|
@@ -29,21 +19,6 @@ export default class DatoHelper extends Runtime {
|
|
|
29
19
|
private createAssetFromUpload;
|
|
30
20
|
private checkJobResult;
|
|
31
21
|
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
|
-
}>;
|
|
47
22
|
uploadFromUrl(options: {
|
|
48
23
|
url: string;
|
|
49
24
|
copyright: string;
|
|
@@ -78,11 +53,10 @@ export default class DatoHelper extends Runtime {
|
|
|
78
53
|
quality?: number;
|
|
79
54
|
format?: 'jpg' | 'pjpg' | 'png' | 'webp' | 'avif' | 'gif' | 'jxl' | 'jp2' | 'jxr' | 'json' | 'blurhash' | (string & {});
|
|
80
55
|
}): string;
|
|
81
|
-
findUploadByFilename(filename: string): Promise<
|
|
56
|
+
findUploadByFilename(filename: string): Promise<any>;
|
|
82
57
|
getItemTypeId(apiKey: string): Promise<string>;
|
|
83
58
|
getProductBySku(sku: string): Promise<any>;
|
|
84
59
|
createProduct(sku: string, productTypeId: string): Promise<any>;
|
|
85
60
|
updateProductGallery(productId: string, gallery: any[]): Promise<any>;
|
|
86
|
-
updateProductSwatch(productId: string, uploadId: string): Promise<any>;
|
|
87
61
|
}
|
|
88
62
|
export {};
|