@se-studio/contentful-rest-api 0.1.0 → 1.0.0-alpha-20251110080939
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 +239 -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;
|
|
52
|
+
}
|
|
53
|
+
if (isContentfulError(error)) {
|
|
54
|
+
return error.statusCode !== void 0 && (error.statusCode >= 500 || error.statusCode === 429);
|
|
57
55
|
}
|
|
58
|
-
return
|
|
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",
|
|
@@ -269,6 +226,14 @@ function convertAssetToVisual(asset, options) {
|
|
|
269
226
|
return void 0;
|
|
270
227
|
}
|
|
271
228
|
function convertAssetToImage(file, fields, sys, options) {
|
|
229
|
+
const { contentType } = file;
|
|
230
|
+
if (contentType === "image/svg+xml") {
|
|
231
|
+
return convertAssetToSvgImage(file, fields, sys, options);
|
|
232
|
+
} else {
|
|
233
|
+
return convertAssetToPicture(file, fields, sys, options);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function convertAssetToPicture(file, fields, sys, options) {
|
|
272
237
|
const { id } = sys;
|
|
273
238
|
const { title, description } = fields;
|
|
274
239
|
const { contentType, details, url } = file;
|
|
@@ -287,6 +252,25 @@ function convertAssetToImage(file, fields, sys, options) {
|
|
|
287
252
|
description: makeContentfulDescription(description, id)
|
|
288
253
|
};
|
|
289
254
|
}
|
|
255
|
+
function convertAssetToSvgImage(file, fields, sys, options) {
|
|
256
|
+
const { id } = sys;
|
|
257
|
+
const { title, description } = fields;
|
|
258
|
+
const { contentType, details, url } = file;
|
|
259
|
+
const { size, image } = details;
|
|
260
|
+
const { width, height } = image || {};
|
|
261
|
+
return {
|
|
262
|
+
...options,
|
|
263
|
+
id,
|
|
264
|
+
type: "Svg image",
|
|
265
|
+
svgSrc: `https:${url}`,
|
|
266
|
+
mimeType: contentType,
|
|
267
|
+
size,
|
|
268
|
+
width: width || 0,
|
|
269
|
+
height: height || 0,
|
|
270
|
+
name: makeContentfulTitle(title, id),
|
|
271
|
+
description: makeContentfulDescription(description, id)
|
|
272
|
+
};
|
|
273
|
+
}
|
|
290
274
|
function convertAssetToVideoDetails(file, sys) {
|
|
291
275
|
const { id } = sys;
|
|
292
276
|
const { details, url, contentType, fileName } = file;
|
|
@@ -299,7 +283,7 @@ function convertAssetToVideoDetails(file, sys) {
|
|
|
299
283
|
fileName
|
|
300
284
|
};
|
|
301
285
|
}
|
|
302
|
-
function convertAssetToVideo(file, fields, sys, options) {
|
|
286
|
+
function convertAssetToVideo(file, fields, sys, context, options) {
|
|
303
287
|
const { id } = sys;
|
|
304
288
|
const { title, description } = fields;
|
|
305
289
|
const { details } = file;
|
|
@@ -311,6 +295,7 @@ function convertAssetToVideo(file, fields, sys, options) {
|
|
|
311
295
|
id,
|
|
312
296
|
type: "Local video",
|
|
313
297
|
preview: videoDetails,
|
|
298
|
+
videoPrefix: context.videoPrefix,
|
|
314
299
|
width: width || 0,
|
|
315
300
|
height: height || 0,
|
|
316
301
|
name: makeContentfulTitle(title, id),
|
|
@@ -416,32 +401,6 @@ function lookupMediaEntry(context, link) {
|
|
|
416
401
|
return void 0;
|
|
417
402
|
}
|
|
418
403
|
|
|
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
404
|
// src/converters/resolver.ts
|
|
446
405
|
function resolveHelper(context, entry, getResolver) {
|
|
447
406
|
const id = entry.sys.id;
|
|
@@ -456,6 +415,9 @@ function resolveHelper(context, entry, getResolver) {
|
|
|
456
415
|
`No resolver found for link type ${possibleEntry.type} (${JSON.stringify(possibleEntry)}) [${JSON.stringify(entry)}]`
|
|
457
416
|
);
|
|
458
417
|
}
|
|
418
|
+
if (typeof resolver !== "function") {
|
|
419
|
+
console.log("Resolver type", possibleEntry.type, typeof resolver, resolver);
|
|
420
|
+
}
|
|
459
421
|
const resolved = resolver(
|
|
460
422
|
context,
|
|
461
423
|
possibleEntry.entry
|
|
@@ -472,6 +434,15 @@ function resolveLink(context, entry) {
|
|
|
472
434
|
(type) => context.linkResolver.get(type)
|
|
473
435
|
);
|
|
474
436
|
}
|
|
437
|
+
function resolveLinks(context, entries) {
|
|
438
|
+
return entries?.map((entry) => resolveLink(context, entry)) || [];
|
|
439
|
+
}
|
|
440
|
+
function resolveContent(context, entry) {
|
|
441
|
+
return resolveHelper(context, entry, (type) => {
|
|
442
|
+
const resolver = context.contentResolver.get(type);
|
|
443
|
+
return resolver;
|
|
444
|
+
});
|
|
445
|
+
}
|
|
475
446
|
function resolveNavigationItem(context, entry) {
|
|
476
447
|
return resolveHelper(
|
|
477
448
|
context,
|
|
@@ -480,15 +451,14 @@ function resolveNavigationItem(context, entry) {
|
|
|
480
451
|
);
|
|
481
452
|
}
|
|
482
453
|
function resolveCollectionContent(context, entry) {
|
|
483
|
-
return resolveHelper(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return
|
|
454
|
+
return resolveHelper(
|
|
455
|
+
context,
|
|
456
|
+
entry,
|
|
457
|
+
(type) => {
|
|
458
|
+
const resolver = context.contentResolver.get(type);
|
|
459
|
+
return resolver;
|
|
489
460
|
}
|
|
490
|
-
|
|
491
|
-
});
|
|
461
|
+
);
|
|
492
462
|
}
|
|
493
463
|
function resolvePageContent(context, entry) {
|
|
494
464
|
const id = entry.sys.id;
|
|
@@ -497,9 +467,6 @@ function resolvePageContent(context, entry) {
|
|
|
497
467
|
throw new Error(`Cannot find included entry for content with id ${id}`);
|
|
498
468
|
}
|
|
499
469
|
const { type } = possibleEntry;
|
|
500
|
-
if (type === "component" || type === "collection") {
|
|
501
|
-
return resolveCollectionContent(context, entry);
|
|
502
|
-
}
|
|
503
470
|
if (type === "media") {
|
|
504
471
|
const visual = convertMediaEntryToVisual(
|
|
505
472
|
context,
|
|
@@ -520,8 +487,8 @@ function resolvePageContent(context, entry) {
|
|
|
520
487
|
}
|
|
521
488
|
return visual;
|
|
522
489
|
}
|
|
523
|
-
if (type
|
|
524
|
-
return
|
|
490
|
+
if (context.contentResolver.has(type)) {
|
|
491
|
+
return resolveContent(context, entry);
|
|
525
492
|
}
|
|
526
493
|
if (context.linkResolver.has(type)) {
|
|
527
494
|
return resolveLink(context, entry);
|
|
@@ -631,9 +598,8 @@ function baseCollectionConverter(context, entry) {
|
|
|
631
598
|
additionalCopy: additionalCopyField,
|
|
632
599
|
// Field name change
|
|
633
600
|
collectionType,
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
showHeading: _showHeading,
|
|
601
|
+
showHeading,
|
|
602
|
+
heading,
|
|
637
603
|
// Already handled elsewhere
|
|
638
604
|
cmsLabel,
|
|
639
605
|
...simpleFields
|
|
@@ -648,7 +614,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
648
614
|
lookupMediaEntry(context, mobileVisualField),
|
|
649
615
|
visualCustomSize
|
|
650
616
|
);
|
|
651
|
-
|
|
617
|
+
const collection = {
|
|
652
618
|
type: "Collection",
|
|
653
619
|
id: sys.id,
|
|
654
620
|
name: cmsLabel,
|
|
@@ -656,6 +622,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
656
622
|
collectionType,
|
|
657
623
|
...DEFAULT_POSITION_FIELDS,
|
|
658
624
|
...simpleFields,
|
|
625
|
+
heading: showHeading ? heading : void 0,
|
|
659
626
|
body: resolveRichTextDocument(context, bodyField),
|
|
660
627
|
additionalCopy: resolveRichTextDocument(context, additionalCopyField),
|
|
661
628
|
icon: lookupAsset(context, iconField),
|
|
@@ -664,6 +631,7 @@ function baseCollectionConverter(context, entry) {
|
|
|
664
631
|
links: linksField?.map((link) => resolveLink(context, link)),
|
|
665
632
|
contents: contentsField?.map((content) => resolveCollectionContent(context, content))
|
|
666
633
|
};
|
|
634
|
+
return collection;
|
|
667
635
|
}
|
|
668
636
|
|
|
669
637
|
// src/converters/component.ts
|
|
@@ -682,9 +650,8 @@ function baseComponentConverter(context, entry) {
|
|
|
682
650
|
additionalCopy: additionalCopyField,
|
|
683
651
|
// Field name change
|
|
684
652
|
componentType,
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
showHeading: _showHeading,
|
|
653
|
+
showHeading,
|
|
654
|
+
heading,
|
|
688
655
|
otherMedia: _otherMedia,
|
|
689
656
|
otherVisuals: _otherVisuals,
|
|
690
657
|
// Already handled elsewhere
|
|
@@ -701,7 +668,7 @@ function baseComponentConverter(context, entry) {
|
|
|
701
668
|
lookupMediaEntry(context, mobileVisualField),
|
|
702
669
|
visualCustomSize
|
|
703
670
|
);
|
|
704
|
-
|
|
671
|
+
const component = {
|
|
705
672
|
type: "Component",
|
|
706
673
|
id: sys.id,
|
|
707
674
|
name: cmsLabel,
|
|
@@ -709,13 +676,15 @@ function baseComponentConverter(context, entry) {
|
|
|
709
676
|
componentType,
|
|
710
677
|
...DEFAULT_POSITION_FIELDS,
|
|
711
678
|
...simpleFields,
|
|
679
|
+
heading: showHeading ? heading : void 0,
|
|
712
680
|
body: resolveRichTextDocument(context, bodyField),
|
|
713
681
|
additionalCopy: resolveRichTextDocument(context, additionalCopyField),
|
|
714
682
|
icon: lookupAsset(context, iconField),
|
|
715
683
|
backgroundVisual,
|
|
716
684
|
visual,
|
|
717
|
-
links:
|
|
685
|
+
links: resolveLinks(context, linksField)
|
|
718
686
|
};
|
|
687
|
+
return component;
|
|
719
688
|
}
|
|
720
689
|
|
|
721
690
|
// src/converters/link.ts
|
|
@@ -871,7 +840,7 @@ function basePageConverter(context, entry) {
|
|
|
871
840
|
...postContent,
|
|
872
841
|
...bottomContent
|
|
873
842
|
]);
|
|
874
|
-
|
|
843
|
+
const page = {
|
|
875
844
|
type: "Page",
|
|
876
845
|
id: sys.id,
|
|
877
846
|
isHomePage: slug === "index",
|
|
@@ -885,6 +854,7 @@ function basePageConverter(context, entry) {
|
|
|
885
854
|
menu: template?.menu,
|
|
886
855
|
footer: template?.footer
|
|
887
856
|
};
|
|
857
|
+
return page;
|
|
888
858
|
}
|
|
889
859
|
function calculatePageHref(slug) {
|
|
890
860
|
if (slug === "index") {
|
|
@@ -1000,7 +970,7 @@ function baseArticleConverter(context, entry) {
|
|
|
1000
970
|
...postContent,
|
|
1001
971
|
...bottomContent
|
|
1002
972
|
]);
|
|
1003
|
-
|
|
973
|
+
const article = {
|
|
1004
974
|
type: "Article",
|
|
1005
975
|
id: sys.id,
|
|
1006
976
|
slug,
|
|
@@ -1016,6 +986,7 @@ function baseArticleConverter(context, entry) {
|
|
|
1016
986
|
menu: template?.menu,
|
|
1017
987
|
footer: template?.footer
|
|
1018
988
|
};
|
|
989
|
+
return article;
|
|
1019
990
|
}
|
|
1020
991
|
function calculateArticleTypeHref(slug) {
|
|
1021
992
|
return `/${slug}/`;
|
|
@@ -1096,12 +1067,11 @@ function createLink(context, entry) {
|
|
|
1096
1067
|
}
|
|
1097
1068
|
function baseNavigationItemConverter(context, entry) {
|
|
1098
1069
|
const { sys, fields } = entry;
|
|
1099
|
-
const {
|
|
1070
|
+
const { navigationItems } = fields;
|
|
1100
1071
|
const link = createLink(context, entry);
|
|
1101
1072
|
const resolvedNavigationItems = navigationItems?.map((item) => resolveNavigationItem(context, item)).filter((item) => item !== void 0);
|
|
1102
1073
|
return {
|
|
1103
1074
|
id: sys.id,
|
|
1104
|
-
longText,
|
|
1105
1075
|
link,
|
|
1106
1076
|
entries: resolvedNavigationItems
|
|
1107
1077
|
};
|
|
@@ -1133,70 +1103,6 @@ function baseTagLinkConverter(context, entry) {
|
|
|
1133
1103
|
);
|
|
1134
1104
|
}
|
|
1135
1105
|
|
|
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
1106
|
// src/utils/retry.ts
|
|
1201
1107
|
var DEFAULT_RETRY_CONFIG = {
|
|
1202
1108
|
maxRetries: 3,
|
|
@@ -1296,16 +1202,13 @@ var RateLimiter = class {
|
|
|
1296
1202
|
}
|
|
1297
1203
|
};
|
|
1298
1204
|
|
|
1299
|
-
// src/utils/index.ts
|
|
1300
|
-
init_timing();
|
|
1301
|
-
|
|
1302
1205
|
// src/api.ts
|
|
1303
|
-
function convertAllAssets(response) {
|
|
1206
|
+
function convertAllAssets(response, context) {
|
|
1304
1207
|
const visuals = /* @__PURE__ */ new Map();
|
|
1305
1208
|
const assets = response.includes?.Asset;
|
|
1306
1209
|
if (assets && assets.length > 0) {
|
|
1307
1210
|
for (const asset of assets) {
|
|
1308
|
-
const visual = convertAssetToVisual(asset);
|
|
1211
|
+
const visual = convertAssetToVisual(context, asset);
|
|
1309
1212
|
if (visual) {
|
|
1310
1213
|
visuals.set(visual.id, visual);
|
|
1311
1214
|
}
|
|
@@ -1330,43 +1233,30 @@ function convertAllIncludes(response) {
|
|
|
1330
1233
|
return includes;
|
|
1331
1234
|
}
|
|
1332
1235
|
async function contentfulPageRest(context, config, slug, options) {
|
|
1333
|
-
const totalTimer = new Timer(`contentfulPageRest(${slug})`);
|
|
1334
1236
|
const client = getContentfulClient(config, options?.preview);
|
|
1335
1237
|
const fetchFn = async () => {
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1238
|
+
const response = await client.getEntries(
|
|
1239
|
+
{
|
|
1240
|
+
content_type: "page",
|
|
1241
|
+
"fields.slug": slug,
|
|
1242
|
+
include: 10,
|
|
1243
|
+
locale: options?.locale,
|
|
1244
|
+
limit: 1
|
|
1245
|
+
},
|
|
1246
|
+
options
|
|
1247
|
+
);
|
|
1345
1248
|
const pageEntry = response.items[0];
|
|
1346
1249
|
if (!pageEntry || !pageEntry.fields) {
|
|
1347
|
-
totalTimer.endAndLog();
|
|
1348
1250
|
return null;
|
|
1349
1251
|
}
|
|
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");
|
|
1252
|
+
const assets = convertAllAssets(response, context);
|
|
1355
1253
|
const includes = convertAllIncludes(response);
|
|
1356
|
-
const includesTiming = includesTimer.end();
|
|
1357
|
-
includesTiming.metadata = { count: includes.size };
|
|
1358
1254
|
const fullContext = {
|
|
1359
1255
|
...context,
|
|
1360
1256
|
includes,
|
|
1361
1257
|
assets
|
|
1362
1258
|
};
|
|
1363
|
-
const conversionTimer = new Timer("Page conversion");
|
|
1364
1259
|
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
1260
|
return converted;
|
|
1371
1261
|
};
|
|
1372
1262
|
if (options?.retry) {
|
|
@@ -1378,43 +1268,49 @@ function createBaseConverterContext() {
|
|
|
1378
1268
|
const linkResolver = /* @__PURE__ */ new Map();
|
|
1379
1269
|
linkResolver.set("page", basePageLinkConverter);
|
|
1380
1270
|
linkResolver.set("article", baseArticleLinkConverter);
|
|
1381
|
-
linkResolver.set(
|
|
1382
|
-
"articleType",
|
|
1383
|
-
baseArticleTypeLinkConverter
|
|
1384
|
-
);
|
|
1271
|
+
linkResolver.set("articleType", baseArticleTypeLinkConverter);
|
|
1385
1272
|
linkResolver.set("tag", baseTagLinkConverter);
|
|
1386
1273
|
linkResolver.set("person", basePersonLinkConverter);
|
|
1387
|
-
linkResolver.set(
|
|
1388
|
-
"pageVariant",
|
|
1389
|
-
basePageVariantLinkConverter
|
|
1390
|
-
);
|
|
1274
|
+
linkResolver.set("pageVariant", basePageVariantLinkConverter);
|
|
1391
1275
|
linkResolver.set("link", baseLinkConverter);
|
|
1276
|
+
const contentResolver = /* @__PURE__ */ new Map();
|
|
1277
|
+
contentResolver.set("collection", baseCollectionConverter);
|
|
1278
|
+
contentResolver.set("component", baseComponentConverter);
|
|
1279
|
+
contentResolver.set(
|
|
1280
|
+
"externalComponent",
|
|
1281
|
+
baseComponentConverter
|
|
1282
|
+
);
|
|
1392
1283
|
return {
|
|
1393
1284
|
pageResolver: basePageConverter,
|
|
1394
1285
|
navigationItemResolver: baseNavigationItemConverter,
|
|
1395
1286
|
articleResolver: baseArticleConverter,
|
|
1396
1287
|
componentResolver: baseComponentConverter,
|
|
1397
1288
|
collectionResolver: baseCollectionConverter,
|
|
1398
|
-
linkResolver
|
|
1289
|
+
linkResolver,
|
|
1290
|
+
contentResolver,
|
|
1291
|
+
videoPrefix: ""
|
|
1399
1292
|
};
|
|
1400
1293
|
}
|
|
1401
1294
|
async function contentfulArticleRest(context, config, slug, articleTypeSlug, options) {
|
|
1402
1295
|
const client = getContentfulClient(config, options?.preview);
|
|
1403
1296
|
const fetchFn = async () => {
|
|
1404
|
-
const response = await client.getEntries(
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1297
|
+
const response = await client.getEntries(
|
|
1298
|
+
{
|
|
1299
|
+
content_type: "article",
|
|
1300
|
+
"fields.slug": slug,
|
|
1301
|
+
"fields.articleType.sys.contentType.sys.id": "articleType",
|
|
1302
|
+
"fields.articleType.fields.slug": articleTypeSlug,
|
|
1303
|
+
include: 10,
|
|
1304
|
+
locale: options?.locale,
|
|
1305
|
+
limit: 1
|
|
1306
|
+
},
|
|
1307
|
+
options
|
|
1308
|
+
);
|
|
1413
1309
|
const articleEntry = response.items[0];
|
|
1414
1310
|
if (!articleEntry || !articleEntry.fields) {
|
|
1415
1311
|
return null;
|
|
1416
1312
|
}
|
|
1417
|
-
const assets = convertAllAssets(response);
|
|
1313
|
+
const assets = convertAllAssets(response, context);
|
|
1418
1314
|
const includes = convertAllIncludes(response);
|
|
1419
1315
|
const fullContext = {
|
|
1420
1316
|
...context,
|
|
@@ -1430,6 +1326,6 @@ async function contentfulArticleRest(context, config, slug, articleTypeSlug, opt
|
|
|
1430
1326
|
return await fetchFn();
|
|
1431
1327
|
}
|
|
1432
1328
|
|
|
1433
|
-
export { AuthenticationError, ContentfulError, EntryNotFoundError, RateLimitError, RateLimiter,
|
|
1329
|
+
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
1330
|
//# sourceMappingURL=index.js.map
|
|
1435
1331
|
//# sourceMappingURL=index.js.map
|