@se-studio/contentful-rest-api 0.1.0 → 0.1.1
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 +34 -2
- package/dist/index.d.ts +211 -186
- package/dist/index.js +212 -343
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,193 +1,144 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
// src/utils/errors.ts
|
|
2
|
+
var ContentfulError = class _ContentfulError extends Error {
|
|
3
|
+
constructor(message, statusCode, details) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.statusCode = statusCode;
|
|
6
|
+
this.details = details;
|
|
7
|
+
this.name = "ContentfulError";
|
|
8
|
+
Object.setPrototypeOf(this, _ContentfulError.prototype);
|
|
9
|
+
}
|
|
7
10
|
};
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
var RateLimitError = class _RateLimitError extends ContentfulError {
|
|
12
|
+
constructor(message, retryAfter, details) {
|
|
13
|
+
super(message, 429, details);
|
|
14
|
+
this.retryAfter = retryAfter;
|
|
15
|
+
this.name = "RateLimitError";
|
|
16
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
17
|
+
}
|
|
11
18
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
20
|
-
function formatTimingResult(result, indent = "") {
|
|
21
|
-
const lines = [];
|
|
22
|
-
let output = `${result.label}: ${result.duration}ms`;
|
|
23
|
-
if (result.metadata) {
|
|
24
|
-
const metadataStr = Object.entries(result.metadata).map(([k, v]) => `${k}: ${v}`).join(", ");
|
|
25
|
-
output += ` (${metadataStr})`;
|
|
19
|
+
var EntryNotFoundError = class _EntryNotFoundError extends ContentfulError {
|
|
20
|
+
constructor(entryId, contentType) {
|
|
21
|
+
super(`Entry not found: ${entryId}${contentType ? ` (${contentType})` : ""}`, 404);
|
|
22
|
+
this.entryId = entryId;
|
|
23
|
+
this.contentType = contentType;
|
|
24
|
+
this.name = "EntryNotFoundError";
|
|
25
|
+
Object.setPrototypeOf(this, _EntryNotFoundError.prototype);
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (Math.abs(mem.rssMB) > 0.01) {
|
|
34
|
-
parts.push(`rss: ${mem.rssMB >= 0 ? "+" : ""}${mem.rssMB}MB`);
|
|
35
|
-
}
|
|
36
|
-
if (Math.abs(mem.externalMB) > 0.01) {
|
|
37
|
-
parts.push(`ext: ${mem.externalMB >= 0 ? "+" : ""}${mem.externalMB}MB`);
|
|
38
|
-
}
|
|
39
|
-
if (parts.length > 0) {
|
|
40
|
-
output += ` [${parts.join(", ")}]`;
|
|
41
|
-
}
|
|
27
|
+
};
|
|
28
|
+
var AuthenticationError = class _AuthenticationError extends ContentfulError {
|
|
29
|
+
constructor(message = "Authentication failed") {
|
|
30
|
+
super(message, 401);
|
|
31
|
+
this.name = "AuthenticationError";
|
|
32
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
42
33
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
34
|
+
};
|
|
35
|
+
var ValidationError = class _ValidationError extends ContentfulError {
|
|
36
|
+
constructor(message, validationErrors) {
|
|
37
|
+
super(message, 400, validationErrors);
|
|
38
|
+
this.validationErrors = validationErrors;
|
|
39
|
+
this.name = "ValidationError";
|
|
40
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
function isContentfulError(error) {
|
|
44
|
+
return error instanceof ContentfulError;
|
|
45
|
+
}
|
|
46
|
+
function isRateLimitError(error) {
|
|
47
|
+
return error instanceof RateLimitError;
|
|
48
|
+
}
|
|
49
|
+
function isRetryableError(error) {
|
|
50
|
+
if (isRateLimitError(error)) {
|
|
51
|
+
return true;
|
|
57
52
|
}
|
|
58
|
-
|
|
53
|
+
if (isContentfulError(error)) {
|
|
54
|
+
return error.statusCode !== void 0 && (error.statusCode >= 500 || error.statusCode === 429);
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
59
57
|
}
|
|
60
|
-
function
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
function getRetryAfter(error) {
|
|
59
|
+
if (isRateLimitError(error)) {
|
|
60
|
+
return error.retryAfter;
|
|
61
|
+
}
|
|
62
|
+
return void 0;
|
|
64
63
|
}
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
|
|
65
|
+
// src/client.ts
|
|
66
|
+
function buildQueryString(query) {
|
|
67
|
+
const params = new URLSearchParams();
|
|
68
|
+
Object.entries(query).forEach(([key, value]) => {
|
|
69
|
+
if (value !== void 0 && value !== null) {
|
|
70
|
+
params.append(key, String(value));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return params.toString();
|
|
67
74
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
result.memoryDelta = {
|
|
116
|
-
heapUsedMB: Number(
|
|
117
|
-
((memoryEnd.heapUsed - this.memoryStart.heapUsed) / 1024 / 1024).toFixed(2)
|
|
118
|
-
),
|
|
119
|
-
heapTotalMB: Number(
|
|
120
|
-
((memoryEnd.heapTotal - this.memoryStart.heapTotal) / 1024 / 1024).toFixed(2)
|
|
121
|
-
),
|
|
122
|
-
rssMB: Number(((memoryEnd.rss - this.memoryStart.rss) / 1024 / 1024).toFixed(2)),
|
|
123
|
-
externalMB: Number(
|
|
124
|
-
((memoryEnd.external - this.memoryStart.external) / 1024 / 1024).toFixed(2)
|
|
125
|
-
)
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* End timer and log the result
|
|
132
|
-
*/
|
|
133
|
-
endAndLog() {
|
|
134
|
-
const result = this.end();
|
|
135
|
-
if (shouldLog) {
|
|
136
|
-
logTimingResult(result);
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Execute a function and time it
|
|
142
|
-
*/
|
|
143
|
-
static async time(label, fn, metadata) {
|
|
144
|
-
const timer = new _Timer(label);
|
|
145
|
-
if (metadata) {
|
|
146
|
-
for (const [key, value] of Object.entries(metadata)) {
|
|
147
|
-
timer.addMetadata(key, value);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
const result = await fn();
|
|
151
|
-
const timing = timer.end();
|
|
152
|
-
return { result, timing };
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Execute a synchronous function and time it
|
|
156
|
-
*/
|
|
157
|
-
static timeSync(label, fn, metadata) {
|
|
158
|
-
const timer = new _Timer(label);
|
|
159
|
-
if (metadata) {
|
|
160
|
-
for (const [key, value] of Object.entries(metadata)) {
|
|
161
|
-
timer.addMetadata(key, value);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const result = fn();
|
|
165
|
-
const timing = timer.end();
|
|
166
|
-
return { result, timing };
|
|
75
|
+
async function parseErrorResponse(response) {
|
|
76
|
+
const statusCode = response.status;
|
|
77
|
+
let errorData;
|
|
78
|
+
try {
|
|
79
|
+
errorData = await response.json();
|
|
80
|
+
} catch {
|
|
81
|
+
errorData = { message: response.statusText };
|
|
82
|
+
}
|
|
83
|
+
const message = errorData?.message || `Contentful API error: ${statusCode}`;
|
|
84
|
+
switch (statusCode) {
|
|
85
|
+
case 401:
|
|
86
|
+
return new AuthenticationError(message);
|
|
87
|
+
case 404:
|
|
88
|
+
return new EntryNotFoundError(
|
|
89
|
+
errorData?.sys?.id || "unknown",
|
|
90
|
+
errorData?.sys?.contentType?.sys?.id
|
|
91
|
+
);
|
|
92
|
+
case 429: {
|
|
93
|
+
const retryAfterHeader = response.headers.get("X-Contentful-RateLimit-Reset") || response.headers.get("Retry-After");
|
|
94
|
+
const retryAfter = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : void 0;
|
|
95
|
+
return new RateLimitError(message, retryAfter, errorData);
|
|
96
|
+
}
|
|
97
|
+
case 400:
|
|
98
|
+
return new ValidationError(message, errorData);
|
|
99
|
+
default:
|
|
100
|
+
return new ContentfulError(message, statusCode, errorData);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
var ContentfulFetchClient = class {
|
|
104
|
+
baseUrl;
|
|
105
|
+
accessToken;
|
|
106
|
+
constructor(config, preview = false) {
|
|
107
|
+
const host = config.host || (preview ? "preview.contentful.com" : "cdn.contentful.com");
|
|
108
|
+
const environment = config.environment || "master";
|
|
109
|
+
this.baseUrl = `https://${host}/spaces/${config.spaceId}/environments/${environment}`;
|
|
110
|
+
this.accessToken = config.accessToken;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Fetches entries from Contentful
|
|
114
|
+
*/
|
|
115
|
+
async getEntries(query, options) {
|
|
116
|
+
const queryString = buildQueryString(query);
|
|
117
|
+
const url = `${this.baseUrl}/entries?${queryString}`;
|
|
118
|
+
const fetchOptions = {
|
|
119
|
+
headers: {
|
|
120
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
121
|
+
"Content-Type": "application/json"
|
|
167
122
|
}
|
|
168
123
|
};
|
|
124
|
+
if (options?.next) {
|
|
125
|
+
fetchOptions.next = options.next;
|
|
126
|
+
}
|
|
127
|
+
const response = await fetch(url, fetchOptions);
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
throw await parseErrorResponse(response);
|
|
130
|
+
}
|
|
131
|
+
return response.json();
|
|
169
132
|
}
|
|
170
|
-
}
|
|
133
|
+
};
|
|
171
134
|
function createContentfulClient(config) {
|
|
172
|
-
return
|
|
173
|
-
space: config.spaceId,
|
|
174
|
-
accessToken: config.accessToken,
|
|
175
|
-
environment: config.environment || "master",
|
|
176
|
-
host: config.host,
|
|
177
|
-
...config.options
|
|
178
|
-
});
|
|
135
|
+
return new ContentfulFetchClient(config, false);
|
|
179
136
|
}
|
|
180
137
|
function createContentfulPreviewClient(config) {
|
|
181
|
-
return
|
|
182
|
-
space: config.spaceId,
|
|
183
|
-
accessToken: config.accessToken,
|
|
184
|
-
environment: config.environment || "master",
|
|
185
|
-
host: "preview.contentful.com",
|
|
186
|
-
...config.options
|
|
187
|
-
});
|
|
138
|
+
return new ContentfulFetchClient(config, true);
|
|
188
139
|
}
|
|
189
140
|
function getContentfulClient(config, preview = false) {
|
|
190
|
-
return
|
|
141
|
+
return preview ? createContentfulPreviewClient(config) : createContentfulClient(config);
|
|
191
142
|
}
|
|
192
143
|
|
|
193
144
|
// src/converters/helpers.ts
|
|
@@ -212,7 +163,7 @@ function createInternalLink(id, fields, context, href, additionalProps) {
|
|
|
212
163
|
return {
|
|
213
164
|
type: "Internal link",
|
|
214
165
|
id,
|
|
215
|
-
name: cmsLabel,
|
|
166
|
+
name: cmsLabel ?? "",
|
|
216
167
|
useName: true,
|
|
217
168
|
text: makeContentfulTitle(title, id),
|
|
218
169
|
visual: lookupAsset(context, featuredImage),
|
|
@@ -242,7 +193,7 @@ function addPositionMetadata(items) {
|
|
|
242
193
|
}
|
|
243
194
|
|
|
244
195
|
// src/converters/asset.ts
|
|
245
|
-
function convertAssetToVisual(asset, options) {
|
|
196
|
+
function convertAssetToVisual(context, asset, options) {
|
|
246
197
|
if (!asset) return void 0;
|
|
247
198
|
const { fields, sys } = asset;
|
|
248
199
|
if (!fields) return void 0;
|
|
@@ -259,7 +210,13 @@ function convertAssetToVisual(asset, options) {
|
|
|
259
210
|
};
|
|
260
211
|
}
|
|
261
212
|
if (contentType?.startsWith("video/")) {
|
|
262
|
-
const video = convertAssetToVideo(
|
|
213
|
+
const video = convertAssetToVideo(
|
|
214
|
+
file,
|
|
215
|
+
fields,
|
|
216
|
+
sys,
|
|
217
|
+
context,
|
|
218
|
+
options
|
|
219
|
+
);
|
|
263
220
|
return {
|
|
264
221
|
id,
|
|
265
222
|
type: "Visual",
|
|
@@ -299,7 +256,7 @@ function convertAssetToVideoDetails(file, sys) {
|
|
|
299
256
|
fileName
|
|
300
257
|
};
|
|
301
258
|
}
|
|
302
|
-
function convertAssetToVideo(file, fields, sys, options) {
|
|
259
|
+
function convertAssetToVideo(file, fields, sys, context, options) {
|
|
303
260
|
const { id } = sys;
|
|
304
261
|
const { title, description } = fields;
|
|
305
262
|
const { details } = file;
|
|
@@ -311,6 +268,7 @@ function convertAssetToVideo(file, fields, sys, options) {
|
|
|
311
268
|
id,
|
|
312
269
|
type: "Local video",
|
|
313
270
|
preview: videoDetails,
|
|
271
|
+
videoPrefix: context.videoPrefix,
|
|
314
272
|
width: width || 0,
|
|
315
273
|
height: height || 0,
|
|
316
274
|
name: makeContentfulTitle(title, id),
|
|
@@ -416,32 +374,6 @@ function lookupMediaEntry(context, link) {
|
|
|
416
374
|
return void 0;
|
|
417
375
|
}
|
|
418
376
|
|
|
419
|
-
// src/converters/externalComponent.ts
|
|
420
|
-
function baseExternalComponentConverter(_context, entry) {
|
|
421
|
-
const { sys, fields } = entry;
|
|
422
|
-
const {
|
|
423
|
-
externalComponentType,
|
|
424
|
-
cmsLabel,
|
|
425
|
-
data,
|
|
426
|
-
heading: _heading,
|
|
427
|
-
// Exclude: not in target interface
|
|
428
|
-
...simpleFields
|
|
429
|
-
// backgroundColour, textColour
|
|
430
|
-
} = fields;
|
|
431
|
-
return {
|
|
432
|
-
type: "External component",
|
|
433
|
-
id: sys.id,
|
|
434
|
-
name: cmsLabel ?? `External component ${sys.id}`,
|
|
435
|
-
cmsLabel: cmsLabel ?? null,
|
|
436
|
-
externalType: externalComponentType,
|
|
437
|
-
data: data ?? null,
|
|
438
|
-
...DEFAULT_POSITION_FIELDS,
|
|
439
|
-
...simpleFields,
|
|
440
|
-
backgroundOverlayOpacity: null,
|
|
441
|
-
backgroundVisual: void 0
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
|
|
445
377
|
// src/converters/resolver.ts
|
|
446
378
|
function resolveHelper(context, entry, getResolver) {
|
|
447
379
|
const id = entry.sys.id;
|
|
@@ -456,6 +388,9 @@ function resolveHelper(context, entry, getResolver) {
|
|
|
456
388
|
`No resolver found for link type ${possibleEntry.type} (${JSON.stringify(possibleEntry)}) [${JSON.stringify(entry)}]`
|
|
457
389
|
);
|
|
458
390
|
}
|
|
391
|
+
if (typeof resolver !== "function") {
|
|
392
|
+
console.log("Resolver type", possibleEntry.type, typeof resolver, resolver);
|
|
393
|
+
}
|
|
459
394
|
const resolved = resolver(
|
|
460
395
|
context,
|
|
461
396
|
possibleEntry.entry
|
|
@@ -472,6 +407,15 @@ function resolveLink(context, entry) {
|
|
|
472
407
|
(type) => context.linkResolver.get(type)
|
|
473
408
|
);
|
|
474
409
|
}
|
|
410
|
+
function resolveLinks(context, entries) {
|
|
411
|
+
return entries?.map((entry) => resolveLink(context, entry)) || [];
|
|
412
|
+
}
|
|
413
|
+
function resolveContent(context, entry) {
|
|
414
|
+
return resolveHelper(context, entry, (type) => {
|
|
415
|
+
const resolver = context.contentResolver.get(type);
|
|
416
|
+
return resolver;
|
|
417
|
+
});
|
|
418
|
+
}
|
|
475
419
|
function resolveNavigationItem(context, entry) {
|
|
476
420
|
return resolveHelper(
|
|
477
421
|
context,
|
|
@@ -480,15 +424,14 @@ function resolveNavigationItem(context, entry) {
|
|
|
480
424
|
);
|
|
481
425
|
}
|
|
482
426
|
function resolveCollectionContent(context, entry) {
|
|
483
|
-
return resolveHelper(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return
|
|
427
|
+
return resolveHelper(
|
|
428
|
+
context,
|
|
429
|
+
entry,
|
|
430
|
+
(type) => {
|
|
431
|
+
const resolver = context.contentResolver.get(type);
|
|
432
|
+
return resolver;
|
|
489
433
|
}
|
|
490
|
-
|
|
491
|
-
});
|
|
434
|
+
);
|
|
492
435
|
}
|
|
493
436
|
function resolvePageContent(context, entry) {
|
|
494
437
|
const id = entry.sys.id;
|
|
@@ -497,9 +440,6 @@ function resolvePageContent(context, entry) {
|
|
|
497
440
|
throw new Error(`Cannot find included entry for content with id ${id}`);
|
|
498
441
|
}
|
|
499
442
|
const { type } = possibleEntry;
|
|
500
|
-
if (type === "component" || type === "collection") {
|
|
501
|
-
return resolveCollectionContent(context, entry);
|
|
502
|
-
}
|
|
503
443
|
if (type === "media") {
|
|
504
444
|
const visual = convertMediaEntryToVisual(
|
|
505
445
|
context,
|
|
@@ -520,8 +460,8 @@ function resolvePageContent(context, entry) {
|
|
|
520
460
|
}
|
|
521
461
|
return visual;
|
|
522
462
|
}
|
|
523
|
-
if (type
|
|
524
|
-
return
|
|
463
|
+
if (context.contentResolver.has(type)) {
|
|
464
|
+
return resolveContent(context, entry);
|
|
525
465
|
}
|
|
526
466
|
if (context.linkResolver.has(type)) {
|
|
527
467
|
return resolveLink(context, entry);
|
|
@@ -631,9 +571,8 @@ function baseCollectionConverter(context, entry) {
|
|
|
631
571
|
additionalCopy: additionalCopyField,
|
|
632
572
|
// Field name change
|
|
633
573
|
collectionType,
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
showHeading: _showHeading,
|
|
574
|
+
showHeading,
|
|
575
|
+
heading,
|
|
637
576
|
// Already handled elsewhere
|
|
638
577
|
cmsLabel,
|
|
639
578
|
...simpleFields
|
|
@@ -648,7 +587,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
648
587
|
lookupMediaEntry(context, mobileVisualField),
|
|
649
588
|
visualCustomSize
|
|
650
589
|
);
|
|
651
|
-
|
|
590
|
+
const collection = {
|
|
652
591
|
type: "Collection",
|
|
653
592
|
id: sys.id,
|
|
654
593
|
name: cmsLabel,
|
|
@@ -656,6 +595,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
656
595
|
collectionType,
|
|
657
596
|
...DEFAULT_POSITION_FIELDS,
|
|
658
597
|
...simpleFields,
|
|
598
|
+
heading: showHeading ? heading : void 0,
|
|
659
599
|
body: resolveRichTextDocument(context, bodyField),
|
|
660
600
|
additionalCopy: resolveRichTextDocument(context, additionalCopyField),
|
|
661
601
|
icon: lookupAsset(context, iconField),
|
|
@@ -664,6 +604,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
664
604
|
links: linksField?.map((link) => resolveLink(context, link)),
|
|
665
605
|
contents: contentsField?.map((content) => resolveCollectionContent(context, content))
|
|
666
606
|
};
|
|
607
|
+
return collection;
|
|
667
608
|
}
|
|
668
609
|
|
|
669
610
|
// src/converters/component.ts
|
|
@@ -682,9 +623,8 @@ function baseComponentConverter(context, entry) {
|
|
|
682
623
|
additionalCopy: additionalCopyField,
|
|
683
624
|
// Field name change
|
|
684
625
|
componentType,
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
showHeading: _showHeading,
|
|
626
|
+
showHeading,
|
|
627
|
+
heading,
|
|
688
628
|
otherMedia: _otherMedia,
|
|
689
629
|
otherVisuals: _otherVisuals,
|
|
690
630
|
// Already handled elsewhere
|
|
@@ -701,7 +641,7 @@ function baseComponentConverter(context, entry) {
|
|
|
701
641
|
lookupMediaEntry(context, mobileVisualField),
|
|
702
642
|
visualCustomSize
|
|
703
643
|
);
|
|
704
|
-
|
|
644
|
+
const component = {
|
|
705
645
|
type: "Component",
|
|
706
646
|
id: sys.id,
|
|
707
647
|
name: cmsLabel,
|
|
@@ -709,13 +649,15 @@ function baseComponentConverter(context, entry) {
|
|
|
709
649
|
componentType,
|
|
710
650
|
...DEFAULT_POSITION_FIELDS,
|
|
711
651
|
...simpleFields,
|
|
652
|
+
heading: showHeading ? heading : void 0,
|
|
712
653
|
body: resolveRichTextDocument(context, bodyField),
|
|
713
654
|
additionalCopy: resolveRichTextDocument(context, additionalCopyField),
|
|
714
655
|
icon: lookupAsset(context, iconField),
|
|
715
656
|
backgroundVisual,
|
|
716
657
|
visual,
|
|
717
|
-
links:
|
|
658
|
+
links: resolveLinks(context, linksField)
|
|
718
659
|
};
|
|
660
|
+
return component;
|
|
719
661
|
}
|
|
720
662
|
|
|
721
663
|
// src/converters/link.ts
|
|
@@ -871,7 +813,7 @@ function basePageConverter(context, entry) {
|
|
|
871
813
|
...postContent,
|
|
872
814
|
...bottomContent
|
|
873
815
|
]);
|
|
874
|
-
|
|
816
|
+
const page = {
|
|
875
817
|
type: "Page",
|
|
876
818
|
id: sys.id,
|
|
877
819
|
isHomePage: slug === "index",
|
|
@@ -885,6 +827,7 @@ function basePageConverter(context, entry) {
|
|
|
885
827
|
menu: template?.menu,
|
|
886
828
|
footer: template?.footer
|
|
887
829
|
};
|
|
830
|
+
return page;
|
|
888
831
|
}
|
|
889
832
|
function calculatePageHref(slug) {
|
|
890
833
|
if (slug === "index") {
|
|
@@ -1000,7 +943,7 @@ function baseArticleConverter(context, entry) {
|
|
|
1000
943
|
...postContent,
|
|
1001
944
|
...bottomContent
|
|
1002
945
|
]);
|
|
1003
|
-
|
|
946
|
+
const article = {
|
|
1004
947
|
type: "Article",
|
|
1005
948
|
id: sys.id,
|
|
1006
949
|
slug,
|
|
@@ -1016,6 +959,7 @@ function baseArticleConverter(context, entry) {
|
|
|
1016
959
|
menu: template?.menu,
|
|
1017
960
|
footer: template?.footer
|
|
1018
961
|
};
|
|
962
|
+
return article;
|
|
1019
963
|
}
|
|
1020
964
|
function calculateArticleTypeHref(slug) {
|
|
1021
965
|
return `/${slug}/`;
|
|
@@ -1096,12 +1040,11 @@ function createLink(context, entry) {
|
|
|
1096
1040
|
}
|
|
1097
1041
|
function baseNavigationItemConverter(context, entry) {
|
|
1098
1042
|
const { sys, fields } = entry;
|
|
1099
|
-
const {
|
|
1043
|
+
const { navigationItems } = fields;
|
|
1100
1044
|
const link = createLink(context, entry);
|
|
1101
1045
|
const resolvedNavigationItems = navigationItems?.map((item) => resolveNavigationItem(context, item)).filter((item) => item !== void 0);
|
|
1102
1046
|
return {
|
|
1103
1047
|
id: sys.id,
|
|
1104
|
-
longText,
|
|
1105
1048
|
link,
|
|
1106
1049
|
entries: resolvedNavigationItems
|
|
1107
1050
|
};
|
|
@@ -1133,70 +1076,6 @@ function baseTagLinkConverter(context, entry) {
|
|
|
1133
1076
|
);
|
|
1134
1077
|
}
|
|
1135
1078
|
|
|
1136
|
-
// src/utils/errors.ts
|
|
1137
|
-
var ContentfulError = class _ContentfulError extends Error {
|
|
1138
|
-
constructor(message, statusCode, details) {
|
|
1139
|
-
super(message);
|
|
1140
|
-
this.statusCode = statusCode;
|
|
1141
|
-
this.details = details;
|
|
1142
|
-
this.name = "ContentfulError";
|
|
1143
|
-
Object.setPrototypeOf(this, _ContentfulError.prototype);
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
var RateLimitError = class _RateLimitError extends ContentfulError {
|
|
1147
|
-
constructor(message, retryAfter, details) {
|
|
1148
|
-
super(message, 429, details);
|
|
1149
|
-
this.retryAfter = retryAfter;
|
|
1150
|
-
this.name = "RateLimitError";
|
|
1151
|
-
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
1152
|
-
}
|
|
1153
|
-
};
|
|
1154
|
-
var EntryNotFoundError = class _EntryNotFoundError extends ContentfulError {
|
|
1155
|
-
constructor(entryId, contentType) {
|
|
1156
|
-
super(`Entry not found: ${entryId}${contentType ? ` (${contentType})` : ""}`, 404);
|
|
1157
|
-
this.entryId = entryId;
|
|
1158
|
-
this.contentType = contentType;
|
|
1159
|
-
this.name = "EntryNotFoundError";
|
|
1160
|
-
Object.setPrototypeOf(this, _EntryNotFoundError.prototype);
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1163
|
-
var AuthenticationError = class _AuthenticationError extends ContentfulError {
|
|
1164
|
-
constructor(message = "Authentication failed") {
|
|
1165
|
-
super(message, 401);
|
|
1166
|
-
this.name = "AuthenticationError";
|
|
1167
|
-
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
1168
|
-
}
|
|
1169
|
-
};
|
|
1170
|
-
var ValidationError = class _ValidationError extends ContentfulError {
|
|
1171
|
-
constructor(message, validationErrors) {
|
|
1172
|
-
super(message, 400, validationErrors);
|
|
1173
|
-
this.validationErrors = validationErrors;
|
|
1174
|
-
this.name = "ValidationError";
|
|
1175
|
-
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
1176
|
-
}
|
|
1177
|
-
};
|
|
1178
|
-
function isContentfulError(error) {
|
|
1179
|
-
return error instanceof ContentfulError;
|
|
1180
|
-
}
|
|
1181
|
-
function isRateLimitError(error) {
|
|
1182
|
-
return error instanceof RateLimitError;
|
|
1183
|
-
}
|
|
1184
|
-
function isRetryableError(error) {
|
|
1185
|
-
if (isRateLimitError(error)) {
|
|
1186
|
-
return true;
|
|
1187
|
-
}
|
|
1188
|
-
if (isContentfulError(error)) {
|
|
1189
|
-
return error.statusCode !== void 0 && (error.statusCode >= 500 || error.statusCode === 429);
|
|
1190
|
-
}
|
|
1191
|
-
return false;
|
|
1192
|
-
}
|
|
1193
|
-
function getRetryAfter(error) {
|
|
1194
|
-
if (isRateLimitError(error)) {
|
|
1195
|
-
return error.retryAfter;
|
|
1196
|
-
}
|
|
1197
|
-
return void 0;
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
1079
|
// src/utils/retry.ts
|
|
1201
1080
|
var DEFAULT_RETRY_CONFIG = {
|
|
1202
1081
|
maxRetries: 3,
|
|
@@ -1296,16 +1175,13 @@ var RateLimiter = class {
|
|
|
1296
1175
|
}
|
|
1297
1176
|
};
|
|
1298
1177
|
|
|
1299
|
-
// src/utils/index.ts
|
|
1300
|
-
init_timing();
|
|
1301
|
-
|
|
1302
1178
|
// src/api.ts
|
|
1303
|
-
function convertAllAssets(response) {
|
|
1179
|
+
function convertAllAssets(response, context) {
|
|
1304
1180
|
const visuals = /* @__PURE__ */ new Map();
|
|
1305
1181
|
const assets = response.includes?.Asset;
|
|
1306
1182
|
if (assets && assets.length > 0) {
|
|
1307
1183
|
for (const asset of assets) {
|
|
1308
|
-
const visual = convertAssetToVisual(asset);
|
|
1184
|
+
const visual = convertAssetToVisual(context, asset);
|
|
1309
1185
|
if (visual) {
|
|
1310
1186
|
visuals.set(visual.id, visual);
|
|
1311
1187
|
}
|
|
@@ -1330,43 +1206,30 @@ function convertAllIncludes(response) {
|
|
|
1330
1206
|
return includes;
|
|
1331
1207
|
}
|
|
1332
1208
|
async function contentfulPageRest(context, config, slug, options) {
|
|
1333
|
-
const totalTimer = new Timer(`contentfulPageRest(${slug})`);
|
|
1334
1209
|
const client = getContentfulClient(config, options?.preview);
|
|
1335
1210
|
const fetchFn = async () => {
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1211
|
+
const response = await client.getEntries(
|
|
1212
|
+
{
|
|
1213
|
+
content_type: "page",
|
|
1214
|
+
"fields.slug": slug,
|
|
1215
|
+
include: 10,
|
|
1216
|
+
locale: options?.locale,
|
|
1217
|
+
limit: 1
|
|
1218
|
+
},
|
|
1219
|
+
options
|
|
1220
|
+
);
|
|
1345
1221
|
const pageEntry = response.items[0];
|
|
1346
1222
|
if (!pageEntry || !pageEntry.fields) {
|
|
1347
|
-
totalTimer.endAndLog();
|
|
1348
1223
|
return null;
|
|
1349
1224
|
}
|
|
1350
|
-
const
|
|
1351
|
-
const assets = convertAllAssets(response);
|
|
1352
|
-
const assetTiming = assetTimer.end();
|
|
1353
|
-
assetTiming.metadata = { count: assets.size };
|
|
1354
|
-
const includesTimer = new Timer("Includes indexing");
|
|
1225
|
+
const assets = convertAllAssets(response, context);
|
|
1355
1226
|
const includes = convertAllIncludes(response);
|
|
1356
|
-
const includesTiming = includesTimer.end();
|
|
1357
|
-
includesTiming.metadata = { count: includes.size };
|
|
1358
1227
|
const fullContext = {
|
|
1359
1228
|
...context,
|
|
1360
1229
|
includes,
|
|
1361
1230
|
assets
|
|
1362
1231
|
};
|
|
1363
|
-
const conversionTimer = new Timer("Page conversion");
|
|
1364
1232
|
const converted = fullContext.pageResolver(fullContext, pageEntry);
|
|
1365
|
-
const conversionTiming = conversionTimer.end();
|
|
1366
|
-
const totalTiming = totalTimer.end();
|
|
1367
|
-
totalTiming.children = [apiFetchTiming, assetTiming, includesTiming, conversionTiming];
|
|
1368
|
-
const { logTimingResult: logTimingResult2 } = await Promise.resolve().then(() => (init_timing(), timing_exports));
|
|
1369
|
-
logTimingResult2(totalTiming);
|
|
1370
1233
|
return converted;
|
|
1371
1234
|
};
|
|
1372
1235
|
if (options?.retry) {
|
|
@@ -1378,43 +1241,49 @@ function createBaseConverterContext() {
|
|
|
1378
1241
|
const linkResolver = /* @__PURE__ */ new Map();
|
|
1379
1242
|
linkResolver.set("page", basePageLinkConverter);
|
|
1380
1243
|
linkResolver.set("article", baseArticleLinkConverter);
|
|
1381
|
-
linkResolver.set(
|
|
1382
|
-
"articleType",
|
|
1383
|
-
baseArticleTypeLinkConverter
|
|
1384
|
-
);
|
|
1244
|
+
linkResolver.set("articleType", baseArticleTypeLinkConverter);
|
|
1385
1245
|
linkResolver.set("tag", baseTagLinkConverter);
|
|
1386
1246
|
linkResolver.set("person", basePersonLinkConverter);
|
|
1387
|
-
linkResolver.set(
|
|
1388
|
-
"pageVariant",
|
|
1389
|
-
basePageVariantLinkConverter
|
|
1390
|
-
);
|
|
1247
|
+
linkResolver.set("pageVariant", basePageVariantLinkConverter);
|
|
1391
1248
|
linkResolver.set("link", baseLinkConverter);
|
|
1249
|
+
const contentResolver = /* @__PURE__ */ new Map();
|
|
1250
|
+
contentResolver.set("collection", baseCollectionConverter);
|
|
1251
|
+
contentResolver.set("component", baseComponentConverter);
|
|
1252
|
+
contentResolver.set(
|
|
1253
|
+
"externalComponent",
|
|
1254
|
+
baseComponentConverter
|
|
1255
|
+
);
|
|
1392
1256
|
return {
|
|
1393
1257
|
pageResolver: basePageConverter,
|
|
1394
1258
|
navigationItemResolver: baseNavigationItemConverter,
|
|
1395
1259
|
articleResolver: baseArticleConverter,
|
|
1396
1260
|
componentResolver: baseComponentConverter,
|
|
1397
1261
|
collectionResolver: baseCollectionConverter,
|
|
1398
|
-
linkResolver
|
|
1262
|
+
linkResolver,
|
|
1263
|
+
contentResolver,
|
|
1264
|
+
videoPrefix: ""
|
|
1399
1265
|
};
|
|
1400
1266
|
}
|
|
1401
1267
|
async function contentfulArticleRest(context, config, slug, articleTypeSlug, options) {
|
|
1402
1268
|
const client = getContentfulClient(config, options?.preview);
|
|
1403
1269
|
const fetchFn = async () => {
|
|
1404
|
-
const response = await client.getEntries(
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1270
|
+
const response = await client.getEntries(
|
|
1271
|
+
{
|
|
1272
|
+
content_type: "article",
|
|
1273
|
+
"fields.slug": slug,
|
|
1274
|
+
"fields.articleType.sys.contentType.sys.id": "articleType",
|
|
1275
|
+
"fields.articleType.fields.slug": articleTypeSlug,
|
|
1276
|
+
include: 10,
|
|
1277
|
+
locale: options?.locale,
|
|
1278
|
+
limit: 1
|
|
1279
|
+
},
|
|
1280
|
+
options
|
|
1281
|
+
);
|
|
1413
1282
|
const articleEntry = response.items[0];
|
|
1414
1283
|
if (!articleEntry || !articleEntry.fields) {
|
|
1415
1284
|
return null;
|
|
1416
1285
|
}
|
|
1417
|
-
const assets = convertAllAssets(response);
|
|
1286
|
+
const assets = convertAllAssets(response, context);
|
|
1418
1287
|
const includes = convertAllIncludes(response);
|
|
1419
1288
|
const fullContext = {
|
|
1420
1289
|
...context,
|
|
@@ -1430,6 +1299,6 @@ async function contentfulArticleRest(context, config, slug, articleTypeSlug, opt
|
|
|
1430
1299
|
return await fetchFn();
|
|
1431
1300
|
}
|
|
1432
1301
|
|
|
1433
|
-
export { AuthenticationError, ContentfulError, EntryNotFoundError, RateLimitError, RateLimiter,
|
|
1302
|
+
export { AuthenticationError, ContentfulError, EntryNotFoundError, RateLimitError, RateLimiter, ValidationError, basePageConverter, calculateBackoffDelay, contentfulArticleRest, contentfulPageRest, createBaseConverterContext, createContentfulClient, createContentfulPreviewClient, createResponsiveVisual, getContentfulClient, getRetryAfter, isContentfulError, isRateLimitError, isRetryableError, lookupAsset, resolveLink, resolveLinks, resolveRichTextDocument, withRetry };
|
|
1434
1303
|
//# sourceMappingURL=index.js.map
|
|
1435
1304
|
//# sourceMappingURL=index.js.map
|