@se-studio/contentful-rest-api 0.1.1 → 1.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -439,11 +439,17 @@ declare function getContentfulClient(config: ContentfulConfig, preview?: boolean
439
439
  declare function createResponsiveVisual(visual: IVisual | undefined, mobileVisual: IVisual | undefined, customSize?: number | null): IResponsiveVisual | undefined;
440
440
 
441
441
  declare function resolveLink(context: ConverterContext, entry: UnresolvedLink<'Entry'>): IInternalLink;
442
- declare function resolveLinks(context: ConverterContext, entries: UnresolvedLink<'Entry'>[] | undefined): IInternalLink[] | undefined;
442
+ declare function resolveLinks(context: ConverterContext, entries: UnresolvedLink<'Entry'>[] | undefined): readonly IInternalLink[] | undefined;
443
443
  declare function resolveRichTextDocument(context: ConverterContext, richText: Document | undefined): {
444
444
  json: Document;
445
445
  } | undefined;
446
446
 
447
+ declare function notEmpty<TValue>(value: TValue | null | undefined): value is TValue;
448
+ declare function arrayOrUndefined<T>(array?: ReadonlyArray<T>): readonly T[] | undefined;
449
+
450
+ declare function isValidDate(date: unknown): boolean;
451
+ declare function safeDate(date: unknown): Date | null;
452
+
447
453
  declare class ContentfulError extends Error {
448
454
  readonly statusCode?: number | undefined;
449
455
  readonly details?: unknown | undefined;
@@ -484,4 +490,4 @@ declare class RateLimiter {
484
490
  getAvailableTokens(): number;
485
491
  }
486
492
 
487
- export { AuthenticationError, type ContentResolverFunction, ContentfulFetchClient as ContentfulClient, type ContentfulConfig, ContentfulError, ContentfulFetchClient, type ConverterContext, type DefaultChainModifier, EntryNotFoundError, type FetchOptions, type IContentfulRichText, RateLimitError, RateLimiter, type RetryConfig, ValidationError, basePageConverter, calculateBackoffDelay, contentfulArticleRest, contentfulPageRest, createBaseConverterContext, createContentfulClient, createContentfulPreviewClient, createResponsiveVisual, getContentfulClient, getRetryAfter, isContentfulError, isRateLimitError, isRetryableError, lookupAsset, resolveLink, resolveLinks, resolveRichTextDocument, withRetry };
493
+ export { AuthenticationError, type ContentResolverFunction, ContentfulFetchClient as ContentfulClient, type ContentfulConfig, ContentfulError, ContentfulFetchClient, type ConverterContext, type DefaultChainModifier, EntryNotFoundError, type FetchOptions, type IContentfulRichText, RateLimitError, RateLimiter, type RetryConfig, ValidationError, arrayOrUndefined, basePageConverter, calculateBackoffDelay, contentfulArticleRest, contentfulPageRest, createBaseConverterContext, createContentfulClient, createContentfulPreviewClient, createResponsiveVisual, getContentfulClient, getRetryAfter, isContentfulError, isRateLimitError, isRetryableError, isValidDate, lookupAsset, notEmpty, resolveLink, resolveLinks, resolveRichTextDocument, safeDate, withRetry };
package/dist/index.js CHANGED
@@ -226,6 +226,14 @@ function convertAssetToVisual(context, asset, options) {
226
226
  return void 0;
227
227
  }
228
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) {
229
237
  const { id } = sys;
230
238
  const { title, description } = fields;
231
239
  const { contentType, details, url } = file;
@@ -244,6 +252,25 @@ function convertAssetToImage(file, fields, sys, options) {
244
252
  description: makeContentfulDescription(description, id)
245
253
  };
246
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
+ }
247
274
  function convertAssetToVideoDetails(file, sys) {
248
275
  const { id } = sys;
249
276
  const { details, url, contentType, fileName } = file;
@@ -374,6 +401,138 @@ function lookupMediaEntry(context, link) {
374
401
  return void 0;
375
402
  }
376
403
 
404
+ // src/utils/arrayUtils.ts
405
+ function notEmpty(value) {
406
+ if (value === null || value === void 0) return false;
407
+ return true;
408
+ }
409
+ function arrayOrUndefined(array) {
410
+ if (array && array.length > 0) {
411
+ return array;
412
+ }
413
+ return void 0;
414
+ }
415
+
416
+ // src/utils/dateUtils.ts
417
+ function isValidDate(date) {
418
+ if (date instanceof Date) {
419
+ return !Number.isNaN(date.getTime());
420
+ }
421
+ if (typeof date === "string" || typeof date === "number") {
422
+ const parsed = new Date(date);
423
+ return !Number.isNaN(parsed.getTime()) && parsed.getTime() > 0;
424
+ }
425
+ return false;
426
+ }
427
+ function safeDate(date) {
428
+ if (!isValidDate(date)) {
429
+ return null;
430
+ }
431
+ if (date instanceof Date) {
432
+ return date;
433
+ }
434
+ return new Date(date);
435
+ }
436
+
437
+ // src/utils/retry.ts
438
+ var DEFAULT_RETRY_CONFIG = {
439
+ maxRetries: 3,
440
+ initialDelay: 1e3,
441
+ // 1 second
442
+ maxDelay: 3e4,
443
+ // 30 seconds
444
+ backoffMultiplier: 2
445
+ };
446
+ function sleep(ms) {
447
+ return new Promise((resolve) => setTimeout(resolve, ms));
448
+ }
449
+ function calculateBackoffDelay(attempt, config, retryAfter) {
450
+ if (retryAfter !== void 0) {
451
+ return Math.min(retryAfter * 1e3, config.maxDelay);
452
+ }
453
+ const exponentialDelay = config.initialDelay * config.backoffMultiplier ** attempt;
454
+ const jitter = Math.random() * exponentialDelay;
455
+ return Math.min(exponentialDelay + jitter, config.maxDelay);
456
+ }
457
+ async function withRetry(fn, config) {
458
+ const retryConfig = {
459
+ ...DEFAULT_RETRY_CONFIG,
460
+ ...config
461
+ };
462
+ let lastError;
463
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
464
+ try {
465
+ return await fn();
466
+ } catch (error) {
467
+ lastError = error;
468
+ if (attempt === retryConfig.maxRetries) {
469
+ break;
470
+ }
471
+ if (!isRetryableError(error)) {
472
+ throw error;
473
+ }
474
+ const retryAfter = getRetryAfter(error);
475
+ const delay = calculateBackoffDelay(attempt, retryConfig, retryAfter);
476
+ if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
477
+ console.warn(
478
+ `Retry attempt ${attempt + 1}/${retryConfig.maxRetries} after ${delay}ms`,
479
+ error
480
+ );
481
+ }
482
+ await sleep(delay);
483
+ }
484
+ }
485
+ throw lastError;
486
+ }
487
+ var RateLimiter = class {
488
+ constructor(maxTokens, refillRate) {
489
+ this.maxTokens = maxTokens;
490
+ this.refillRate = refillRate;
491
+ this.tokens = maxTokens;
492
+ this.lastRefill = Date.now();
493
+ }
494
+ tokens;
495
+ lastRefill;
496
+ /**
497
+ * Refills tokens based on time elapsed
498
+ */
499
+ refill() {
500
+ const now = Date.now();
501
+ const timePassed = (now - this.lastRefill) / 1e3;
502
+ const tokensToAdd = timePassed * this.refillRate;
503
+ this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
504
+ this.lastRefill = now;
505
+ }
506
+ /**
507
+ * Attempts to consume a token
508
+ * @returns true if token was consumed, false if rate limited
509
+ */
510
+ tryConsume() {
511
+ this.refill();
512
+ if (this.tokens >= 1) {
513
+ this.tokens -= 1;
514
+ return true;
515
+ }
516
+ return false;
517
+ }
518
+ /**
519
+ * Waits until a token is available and consumes it
520
+ */
521
+ async consume() {
522
+ while (!this.tryConsume()) {
523
+ const waitTime = 1 / this.refillRate * 1e3;
524
+ await sleep(waitTime);
525
+ }
526
+ }
527
+ /**
528
+ * Gets current number of available tokens
529
+ */
530
+ getAvailableTokens() {
531
+ this.refill();
532
+ return Math.floor(this.tokens);
533
+ }
534
+ };
535
+
377
536
  // src/converters/resolver.ts
378
537
  function resolveHelper(context, entry, getResolver) {
379
538
  const id = entry.sys.id;
@@ -408,7 +567,7 @@ function resolveLink(context, entry) {
408
567
  );
409
568
  }
410
569
  function resolveLinks(context, entries) {
411
- return entries?.map((entry) => resolveLink(context, entry)) || [];
570
+ return arrayOrUndefined(entries?.map((entry) => resolveLink(context, entry)));
412
571
  }
413
572
  function resolveContent(context, entry) {
414
573
  return resolveHelper(context, entry, (type) => {
@@ -1076,105 +1235,6 @@ function baseTagLinkConverter(context, entry) {
1076
1235
  );
1077
1236
  }
1078
1237
 
1079
- // src/utils/retry.ts
1080
- var DEFAULT_RETRY_CONFIG = {
1081
- maxRetries: 3,
1082
- initialDelay: 1e3,
1083
- // 1 second
1084
- maxDelay: 3e4,
1085
- // 30 seconds
1086
- backoffMultiplier: 2
1087
- };
1088
- function sleep(ms) {
1089
- return new Promise((resolve) => setTimeout(resolve, ms));
1090
- }
1091
- function calculateBackoffDelay(attempt, config, retryAfter) {
1092
- if (retryAfter !== void 0) {
1093
- return Math.min(retryAfter * 1e3, config.maxDelay);
1094
- }
1095
- const exponentialDelay = config.initialDelay * config.backoffMultiplier ** attempt;
1096
- const jitter = Math.random() * exponentialDelay;
1097
- return Math.min(exponentialDelay + jitter, config.maxDelay);
1098
- }
1099
- async function withRetry(fn, config) {
1100
- const retryConfig = {
1101
- ...DEFAULT_RETRY_CONFIG,
1102
- ...config
1103
- };
1104
- let lastError;
1105
- for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
1106
- try {
1107
- return await fn();
1108
- } catch (error) {
1109
- lastError = error;
1110
- if (attempt === retryConfig.maxRetries) {
1111
- break;
1112
- }
1113
- if (!isRetryableError(error)) {
1114
- throw error;
1115
- }
1116
- const retryAfter = getRetryAfter(error);
1117
- const delay = calculateBackoffDelay(attempt, retryConfig, retryAfter);
1118
- if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
1119
- console.warn(
1120
- `Retry attempt ${attempt + 1}/${retryConfig.maxRetries} after ${delay}ms`,
1121
- error
1122
- );
1123
- }
1124
- await sleep(delay);
1125
- }
1126
- }
1127
- throw lastError;
1128
- }
1129
- var RateLimiter = class {
1130
- constructor(maxTokens, refillRate) {
1131
- this.maxTokens = maxTokens;
1132
- this.refillRate = refillRate;
1133
- this.tokens = maxTokens;
1134
- this.lastRefill = Date.now();
1135
- }
1136
- tokens;
1137
- lastRefill;
1138
- /**
1139
- * Refills tokens based on time elapsed
1140
- */
1141
- refill() {
1142
- const now = Date.now();
1143
- const timePassed = (now - this.lastRefill) / 1e3;
1144
- const tokensToAdd = timePassed * this.refillRate;
1145
- this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
1146
- this.lastRefill = now;
1147
- }
1148
- /**
1149
- * Attempts to consume a token
1150
- * @returns true if token was consumed, false if rate limited
1151
- */
1152
- tryConsume() {
1153
- this.refill();
1154
- if (this.tokens >= 1) {
1155
- this.tokens -= 1;
1156
- return true;
1157
- }
1158
- return false;
1159
- }
1160
- /**
1161
- * Waits until a token is available and consumes it
1162
- */
1163
- async consume() {
1164
- while (!this.tryConsume()) {
1165
- const waitTime = 1 / this.refillRate * 1e3;
1166
- await sleep(waitTime);
1167
- }
1168
- }
1169
- /**
1170
- * Gets current number of available tokens
1171
- */
1172
- getAvailableTokens() {
1173
- this.refill();
1174
- return Math.floor(this.tokens);
1175
- }
1176
- };
1177
-
1178
1238
  // src/api.ts
1179
1239
  function convertAllAssets(response, context) {
1180
1240
  const visuals = /* @__PURE__ */ new Map();
@@ -1299,6 +1359,6 @@ async function contentfulArticleRest(context, config, slug, articleTypeSlug, opt
1299
1359
  return await fetchFn();
1300
1360
  }
1301
1361
 
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 };
1362
+ export { AuthenticationError, ContentfulError, EntryNotFoundError, RateLimitError, RateLimiter, ValidationError, arrayOrUndefined, basePageConverter, calculateBackoffDelay, contentfulArticleRest, contentfulPageRest, createBaseConverterContext, createContentfulClient, createContentfulPreviewClient, createResponsiveVisual, getContentfulClient, getRetryAfter, isContentfulError, isRateLimitError, isRetryableError, isValidDate, lookupAsset, notEmpty, resolveLink, resolveLinks, resolveRichTextDocument, safeDate, withRetry };
1303
1363
  //# sourceMappingURL=index.js.map
1304
1364
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/errors.ts","../src/client.ts","../src/converters/helpers.ts","../src/converters/asset.ts","../src/converters/resolver.ts","../src/converters/collection.ts","../src/converters/component.ts","../src/converters/link.ts","../src/converters/template.ts","../src/converters/page.ts","../src/converters/person.ts","../src/converters/article.ts","../src/converters/navigationItem.ts","../src/converters/tag.ts","../src/utils/retry.ts","../src/api.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Custom error classes for Contentful API errors\n */\n\n/**\n * Base error class for all Contentful-related errors\n */\nexport class ContentfulError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = 'ContentfulError';\n Object.setPrototypeOf(this, ContentfulError.prototype);\n }\n}\n\n/**\n * Error thrown when rate limit is exceeded\n */\nexport class RateLimitError extends ContentfulError {\n constructor(\n message: string,\n public readonly retryAfter?: number,\n details?: unknown,\n ) {\n super(message, 429, details);\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * Error thrown when entry is not found\n */\nexport class EntryNotFoundError extends ContentfulError {\n constructor(\n public readonly entryId: string,\n public readonly contentType?: string,\n ) {\n super(`Entry not found: ${entryId}${contentType ? ` (${contentType})` : ''}`, 404);\n this.name = 'EntryNotFoundError';\n Object.setPrototypeOf(this, EntryNotFoundError.prototype);\n }\n}\n\n/**\n * Error thrown when authentication fails\n */\nexport class AuthenticationError extends ContentfulError {\n constructor(message = 'Authentication failed') {\n super(message, 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends ContentfulError {\n constructor(\n message: string,\n public readonly validationErrors?: unknown,\n ) {\n super(message, 400, validationErrors);\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Checks if an error is a Contentful error\n */\nexport function isContentfulError(error: unknown): error is ContentfulError {\n return error instanceof ContentfulError;\n}\n\n/**\n * Checks if an error is a rate limit error\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError;\n}\n\n/**\n * Checks if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (isRateLimitError(error)) {\n return true;\n }\n\n if (isContentfulError(error)) {\n // Retry on 5xx errors and rate limits\n return error.statusCode !== undefined && (error.statusCode >= 500 || error.statusCode === 429);\n }\n\n return false;\n}\n\n/**\n * Extracts retry-after header value from error\n */\nexport function getRetryAfter(error: unknown): number | undefined {\n if (isRateLimitError(error)) {\n return error.retryAfter;\n }\n return undefined;\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: Any ok for now! */\nimport type { ContentfulConfig, FetchOptions } from './types';\nimport {\n AuthenticationError,\n ContentfulError,\n EntryNotFoundError,\n RateLimitError,\n ValidationError,\n} from './utils/errors';\n\n/**\n * Contentful REST API response structure\n * The items array contains Entry objects when T is an EntrySkeletonType\n */\nexport interface ContentfulResponse<T = any> {\n sys: {\n type: 'Array';\n };\n total: number;\n skip: number;\n limit: number;\n items: T extends import('contentful').EntrySkeletonType\n ? Array<import('contentful').Entry<T, 'WITHOUT_LINK_RESOLUTION', string>>\n : T[];\n includes?: {\n Entry?: any[];\n Asset?: any[];\n };\n}\n\n/**\n * Query parameters for Contentful API\n */\nexport interface ContentfulQuery {\n content_type?: string;\n locale?: string;\n include?: number;\n limit?: number;\n skip?: number;\n [key: string]: any;\n}\n\n/**\n * Builds query string from query parameters\n */\nfunction buildQueryString(query: ContentfulQuery): string {\n const params = new URLSearchParams();\n\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n params.append(key, String(value));\n }\n });\n\n return params.toString();\n}\n\n/**\n * Parses error response from Contentful API\n */\nasync function parseErrorResponse(response: Response): Promise<ContentfulError> {\n const statusCode = response.status;\n let errorData: any;\n\n try {\n errorData = await response.json();\n } catch {\n errorData = { message: response.statusText };\n }\n\n const message = errorData?.message || `Contentful API error: ${statusCode}`;\n\n switch (statusCode) {\n case 401:\n return new AuthenticationError(message);\n\n case 404:\n return new EntryNotFoundError(\n errorData?.sys?.id || 'unknown',\n errorData?.sys?.contentType?.sys?.id,\n );\n\n case 429: {\n // Parse retry-after header (in seconds)\n const retryAfterHeader =\n response.headers.get('X-Contentful-RateLimit-Reset') || response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : undefined;\n return new RateLimitError(message, retryAfter, errorData);\n }\n\n case 400:\n return new ValidationError(message, errorData);\n\n default:\n return new ContentfulError(message, statusCode, errorData);\n }\n}\n\ntype NextRequestInit = RequestInit & {\n next?: {\n revalidate?: number | false;\n tags?: string[];\n };\n};\n\n/**\n * Fetch-based Contentful client that participates in Next.js caching\n */\nexport class ContentfulFetchClient {\n private readonly baseUrl: string;\n private readonly accessToken: string;\n\n constructor(config: ContentfulConfig, preview = false) {\n const host = config.host || (preview ? 'preview.contentful.com' : 'cdn.contentful.com');\n const environment = config.environment || 'master';\n\n this.baseUrl = `https://${host}/spaces/${config.spaceId}/environments/${environment}`;\n this.accessToken = config.accessToken;\n }\n\n /**\n * Fetches entries from Contentful\n */\n async getEntries<T = any>(\n query: ContentfulQuery,\n options?: FetchOptions,\n ): Promise<ContentfulResponse<T>> {\n const queryString = buildQueryString(query);\n const url = `${this.baseUrl}/entries?${queryString}`;\n\n const fetchOptions: NextRequestInit = {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n 'Content-Type': 'application/json',\n },\n };\n\n // Add Next.js cache configuration if provided\n if (options?.next) {\n fetchOptions.next = options.next;\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<ContentfulResponse<T>>;\n }\n}\n\n/**\n * Creates a Contentful Content Delivery API (CDA) client\n *\n * @param config - Configuration object for the Contentful client\n * @returns Contentful CDA client instance\n *\n * @example\n * ```ts\n * const client = createContentfulClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,\n * environment: 'master'\n * });\n * ```\n */\nexport function createContentfulClient(config: ContentfulConfig): ContentfulFetchClient {\n return new ContentfulFetchClient(config, false);\n}\n\n/**\n * Creates a Contentful Content Preview API (CPA) client\n *\n * @param config - Configuration object for the Contentful preview client\n * @returns Contentful CPA client instance\n *\n * @example\n * ```ts\n * const previewClient = createContentfulPreviewClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!,\n * environment: 'master'\n * });\n * ```\n */\nexport function createContentfulPreviewClient(config: ContentfulConfig): ContentfulFetchClient {\n return new ContentfulFetchClient(config, true);\n}\n\n/**\n * Gets the appropriate Contentful client based on preview mode\n *\n * @param config - Configuration for the Contentful client\n * @param preview - Whether to use the preview API\n * @returns Contentful client instance (CDA or CPA)\n *\n * @example\n * ```ts\n * const client = getContentfulClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: preview\n * ? process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!\n * : process.env.CONTENTFUL_ACCESS_TOKEN!,\n * }, preview);\n * ```\n */\nexport function getContentfulClient(\n config: ContentfulConfig,\n preview = false,\n): ContentfulFetchClient {\n return preview ? createContentfulPreviewClient(config) : createContentfulClient(config);\n}\n","import type { IInternalLink, IVisual } from '@se-studio/core-data-types';\nimport type { Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier, PossibleResolvedEntry } from '../api';\nimport type { BaseContent, BaseLink } from '../baseTypes/baseShared';\nimport type { baseArticleConverter } from './article';\nimport type { baseCollectionConverter } from './collection';\nimport type { baseComponentConverter } from './component';\nimport type { baseNavigationItemConverter } from './navigationItem';\nimport type { basePageConverter } from './page';\n\nexport function makeContentfulTitle(\n title: string | undefined | null,\n id: string,\n prefix = 'Title for ',\n) {\n return title ?? `${prefix}${id}`;\n}\n\nexport function makeContentfulDescription(description: string | undefined | null, id: string) {\n return description ?? `Description for ${id}`;\n}\n\nexport function lookupAsset(context: ConverterContext, asset: UnresolvedLink<'Asset'> | undefined) {\n if (!asset) return undefined;\n return context.assets.get(asset.sys.id);\n}\n\n/**\n * Default positioning fields for content items before they are processed\n */\nexport const DEFAULT_POSITION_FIELDS = {\n index: 0,\n isFirst: false,\n isLast: false,\n indexOfType: 0,\n} as const;\n\n/**\n * Creates an internal link object with common fields\n * Used by multiple converters (tag, page, article, person) to reduce duplication\n */\nexport function createInternalLink(\n id: string,\n fields: {\n cmsLabel?: string | null;\n title?: string | null;\n featuredImage?: UnresolvedLink<'Asset'>;\n backgroundColour?: string | null;\n textColour?: string | null;\n indexed?: boolean | null;\n hidden?: boolean | null;\n slug: string;\n },\n context: ConverterContext,\n href: string,\n additionalProps?: Partial<IInternalLink>,\n): IInternalLink {\n const { cmsLabel, title, featuredImage, backgroundColour, textColour, indexed, hidden, slug } =\n fields;\n\n return {\n type: 'Internal link',\n id,\n name: cmsLabel ?? '',\n useName: true,\n text: makeContentfulTitle(title, id),\n visual: lookupAsset(context, featuredImage),\n backgroundColour,\n textColour,\n indexed,\n hidden,\n slug,\n href,\n ...additionalProps,\n };\n}\n\nexport type ContentResolverFunction = (\n context: ConverterContext,\n entry: Entry<BaseContent, DefaultChainModifier, string>,\n) => unknown; // PageContent\nexport type ContentResolverMap = Map<string, ContentResolverFunction>;\nexport type LinkResolverFunction = (\n context: ConverterContext,\n entry: Entry<BaseLink, DefaultChainModifier, string>,\n) => IInternalLink;\nexport type LinkResolverMap = Map<string, LinkResolverFunction>;\n\nexport type ConverterContext = {\n videoPrefix: string;\n includes: Map<string, PossibleResolvedEntry>;\n assets: Map<string, IVisual>;\n linkResolver: LinkResolverMap;\n contentResolver: Map<\n string,\n (context: ConverterContext, entry: Entry<BaseContent, DefaultChainModifier, string>) => unknown\n >;\n navigationItemResolver: typeof baseNavigationItemConverter;\n pageResolver: typeof basePageConverter;\n articleResolver: typeof baseArticleConverter;\n componentResolver: typeof baseComponentConverter;\n collectionResolver: typeof baseCollectionConverter;\n};\n\n/**\n * Adds position metadata to an array of content items\n * Each item gets: index, isFirst, isLast, indexOfType\n *\n * @param items - Array of content items to add metadata to\n * @returns New array with position metadata added to each item\n */\nexport function addPositionMetadata<\n T extends {\n type: string;\n index?: number;\n isFirst?: boolean;\n isLast?: boolean;\n indexOfType?: number;\n },\n>(items: T[]): T[] {\n if (items.length === 0) return items;\n\n // Count items by type for indexOfType calculation\n const typeCount = new Map<string, number>();\n\n return items.map((item, index) => {\n const currentTypeIndex = typeCount.get(item.type) ?? 0;\n typeCount.set(item.type, currentTypeIndex + 1);\n\n return {\n ...item,\n index,\n isFirst: index === 0,\n isLast: index === items.length - 1,\n indexOfType: currentTypeIndex,\n };\n });\n}\n","import type {\n IAnimation,\n IImage,\n IResponsiveVisual,\n IVideo,\n IVideoDetails,\n IVisual,\n} from '@se-studio/core-data-types';\nimport type { Asset, AssetFields, AssetFile, AssetSys, Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseExternalVideoSkeleton } from '../baseTypes/baseExternalVideo';\nimport type { BaseMediaSkeleton } from '../baseTypes/baseMedia';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset, makeContentfulDescription, makeContentfulTitle } from './helpers';\n\nexport function convertAssetToVisual(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n asset?: Asset<DefaultChainModifier, string>,\n options?: Partial<IImage> | Partial<IVideo> | Partial<IAnimation>,\n): IVisual | undefined {\n if (!asset) return undefined;\n const { fields, sys } = asset;\n if (!fields) return undefined;\n const { id } = sys;\n const { file } = fields as AssetFields;\n if (!file) return undefined;\n const { contentType } = file;\n\n if (contentType?.startsWith('image/')) {\n const image = convertAssetToImage(file, fields as AssetFields, sys, options as Partial<IImage>);\n return {\n id,\n type: 'Visual',\n image,\n };\n }\n\n if (contentType?.startsWith('video/')) {\n const video = convertAssetToVideo(\n file,\n fields as AssetFields,\n sys,\n context,\n options as Partial<IVideo>,\n );\n return {\n id,\n type: 'Visual',\n video,\n };\n }\n return undefined;\n}\n\nfunction convertAssetToImage(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n options: Partial<Omit<IImage, 'id' | 'type'>>,\n): IImage {\n const { id } = sys;\n const { title, description } = fields;\n const { contentType, details, url } = file;\n const { size, image } = details;\n const { width, height } = image || {};\n\n return {\n ...options,\n id,\n type: 'Picture',\n src: `https:${url}`,\n mimeType: contentType,\n size,\n width: width || 0,\n height: height || 0,\n name: makeContentfulTitle(title, id),\n description: makeContentfulDescription(description, id),\n };\n}\n\nfunction convertAssetToVideoDetails(file: AssetFile, sys: AssetSys): IVideoDetails {\n const { id } = sys;\n const { details, url, contentType, fileName } = file;\n const { size } = details;\n return {\n id,\n videoUrl: `https:${url}`,\n size,\n mimeType: contentType,\n fileName,\n };\n}\n\nfunction convertAssetToVideo(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n options: Partial<Omit<IVideo, 'id' | 'type'>>,\n): IVideo {\n const { id } = sys;\n const { title, description } = fields;\n const { details } = file;\n const { image } = details;\n const { width, height } = image || {};\n\n const videoDetails = convertAssetToVideoDetails(file, sys);\n\n return {\n ...options,\n id,\n type: 'Local video',\n preview: videoDetails,\n videoPrefix: context.videoPrefix,\n\n width: width || 0,\n height: height || 0,\n name: makeContentfulTitle(title, id),\n description: makeContentfulDescription(description, id),\n };\n}\n\nexport function createResponsiveVisual(\n visual: IVisual | undefined,\n mobileVisual: IVisual | undefined,\n customSize?: number | null,\n): IResponsiveVisual | undefined {\n if (!visual) return undefined;\n return {\n visual,\n mobileVisual,\n visualCustomSize: customSize,\n };\n}\n\n/**\n * Converts a baseMedia entry to IVisual by looking up the asset and merging metadata\n */\nexport function convertMediaEntryToVisual(\n context: ConverterContext,\n entry: Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n): IVisual | undefined {\n const { fields, sys } = entry;\n if (!fields) return undefined;\n\n // Lookup the asset from context\n const baseVisual = lookupAsset(context, fields.asset);\n if (!baseVisual) return undefined;\n\n // Extract metadata from the media entry\n const metadata = {\n name: makeContentfulTitle(fields.name, sys.id),\n nameAsCaption: fields.nameAsCaption ?? null,\n dontCrop: fields.dontCrop ?? null,\n verticalCropPosition: fields.verticalCropPosition ?? null,\n horizontalCropPosition: fields.horizontalCropPosition ?? null,\n horizontalPosition: fields.horizontalPosition ?? null,\n widthPercent: fields.width ?? null,\n };\n\n // Merge metadata into the image or video\n const visual: IVisual = {\n ...baseVisual,\n id: sys.id,\n };\n\n if (baseVisual.image) {\n visual.image = {\n ...baseVisual.image,\n ...metadata,\n };\n } else if (baseVisual.video) {\n visual.video = {\n ...baseVisual.video,\n ...metadata,\n autoPlay: fields.autoplay ?? null,\n loop: fields.loop ?? null,\n hideControls: fields.hideControls ?? null,\n };\n }\n\n return visual;\n}\n\n/**\n * Converts a baseExternalVideo entry to IVisual with external video\n */\nexport function convertExternalVideoEntryToVisual(\n context: ConverterContext,\n entry: Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n): IVisual | undefined {\n const { fields, sys } = entry;\n if (!fields || !fields.url) return undefined;\n\n // Lookup optional preview and poster assets\n const previewVisual = lookupAsset(context, fields.preview);\n const posterVisual = lookupAsset(context, fields.posterImage);\n\n // Extract preview IVideoDetails if available\n const preview =\n previewVisual?.video?.type === 'Local video' ? previewVisual.video.preview : undefined;\n\n // Extract poster URL if available\n const poster = posterVisual?.image?.type === 'Picture' ? posterVisual.image.src : undefined;\n\n // Map Contentful's \"Center\" to our \"Middle\" type\n const mapHorizontal = (\n value: 'Left' | 'Center' | 'Right' | undefined,\n ): 'Left' | 'Middle' | 'Right' | null => {\n if (!value) return null;\n return value === 'Center' ? 'Middle' : value;\n };\n\n const video: IVideo = {\n id: sys.id,\n type: 'External video',\n name: makeContentfulTitle(fields.name, sys.id),\n nameAsCaption: fields.nameAsCaption ?? null,\n external: fields.url,\n preview,\n poster,\n autoPlay: fields.autoPlay ?? null,\n loop: fields.loop ?? null,\n hideControls: fields.hideControls ?? null,\n dontCrop: fields.dontCrop ?? null,\n verticalCropPosition: fields.verticalCropPosition ?? null,\n horizontalCropPosition: mapHorizontal(fields.horizontalCropPosition),\n horizontalPosition: fields.horizontalPosition ?? null,\n widthPercent: fields.width ?? null,\n };\n\n return {\n id: sys.id,\n type: 'Visual',\n video,\n };\n}\n\n/**\n * Looks up and converts a media or external video entry from an unresolved link\n */\nexport function lookupMediaEntry(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'> | undefined,\n): IVisual | undefined {\n if (!link) return undefined;\n\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry) {\n return undefined;\n }\n\n const { type, entry } = possibleEntry;\n\n if (type === 'media') {\n return convertMediaEntryToVisual(\n context,\n entry as Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n );\n }\n\n if (type === 'externalVideo') {\n return convertExternalVideoEntryToVisual(\n context,\n entry as Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n );\n }\n\n return undefined;\n}\n","import type { Block, Document, Inline, Text } from '@contentful/rich-text-types';\nimport type {\n CollectionContent,\n IInternalLink,\n INavigationItem,\n ITyped,\n} from '@se-studio/core-data-types';\nimport type { Entry, EntrySkeletonType, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseCollectionSkeleton } from '../baseTypes/baseCollection';\nimport type { BaseComponentSkeleton } from '../baseTypes/baseComponent';\nimport type { BaseExternalVideoSkeleton } from '../baseTypes/baseExternalVideo';\nimport type { BaseMediaSkeleton } from '../baseTypes/baseMedia';\nimport type { BaseNavigationItemSkeleton } from '../baseTypes/baseNavigationItem';\nimport type { BaseLink } from '../baseTypes/baseShared';\nimport { convertExternalVideoEntryToVisual, convertMediaEntryToVisual } from './asset';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset } from './helpers';\n\nexport function resolveHelper<TEntrySkeletonType extends EntrySkeletonType, TResult>(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n getResolver: (\n type: string,\n ) =>\n | ((\n context: ConverterContext,\n entry: Entry<TEntrySkeletonType, DefaultChainModifier, string>,\n ) => TResult)\n | undefined,\n): TResult {\n const id = entry.sys.id;\n const possibleEntry = context.includes.get(id);\n if (!possibleEntry) {\n throw new Error(`Cannot find included entry for link with id ${id}`);\n }\n if (!possibleEntry.resolved) {\n const resolver = getResolver(possibleEntry.type);\n if (!resolver) {\n throw new Error(\n `No resolver found for link type ${possibleEntry.type} (${JSON.stringify(possibleEntry)}) [${JSON.stringify(entry)}]`,\n );\n }\n if (typeof resolver !== 'function') {\n console.log('Resolver type', possibleEntry.type, typeof resolver, resolver);\n }\n\n const resolved = resolver(\n context,\n possibleEntry.entry as Entry<TEntrySkeletonType, DefaultChainModifier, string>,\n );\n possibleEntry.resolved = resolved;\n return resolved;\n }\n return possibleEntry.resolved as TResult;\n}\n\nexport function resolveLink(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): IInternalLink {\n return resolveHelper<BaseLink, IInternalLink>(context, entry, (type) =>\n context.linkResolver.get(type),\n );\n}\n\nexport function resolveLinks(\n context: ConverterContext,\n entries: UnresolvedLink<'Entry'>[] | undefined,\n): IInternalLink[] | undefined {\n return entries?.map((entry) => resolveLink(context, entry)) || [];\n}\n\nexport function resolveContent(context: ConverterContext, entry: UnresolvedLink<'Entry'>): ITyped {\n return resolveHelper<BaseLink, ITyped>(context, entry, (type) => {\n const resolver = context.contentResolver.get(type);\n return resolver as (\n context: ConverterContext,\n entry: Entry<BaseLink, DefaultChainModifier, string>,\n ) => ITyped;\n });\n}\n\nexport function resolveNavigationItem(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): INavigationItem {\n return resolveHelper<BaseNavigationItemSkeleton, INavigationItem>(\n context,\n entry,\n () => context.navigationItemResolver,\n );\n}\n\nexport function resolveCollectionContent(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): CollectionContent {\n return resolveHelper<BaseComponentSkeleton | BaseCollectionSkeleton, CollectionContent>(\n context,\n entry,\n (type) => {\n const resolver = context.contentResolver.get(type);\n return resolver as (\n context: ConverterContext,\n entry: Entry<BaseComponentSkeleton | BaseCollectionSkeleton, DefaultChainModifier, string>,\n ) => CollectionContent;\n },\n );\n}\n\n/**\n * Resolves a PageContent entry from an unresolved link\n * PageContent can be: Component, Collection, ExternalComponent, Visual (media/externalVideo), or PersonLink\n */\nexport function resolvePageContent(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): ITyped {\n const id = entry.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry) {\n throw new Error(`Cannot find included entry for content with id ${id}`);\n }\n\n const { type } = possibleEntry;\n\n // Handle Media - convert to IVisual\n if (type === 'media') {\n const visual = convertMediaEntryToVisual(\n context,\n possibleEntry.entry as Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n );\n if (!visual) {\n throw new Error(`Failed to convert media entry with id ${id}`);\n }\n return visual;\n }\n\n // Handle ExternalVideo - convert to IVisual\n if (type === 'externalVideo') {\n const visual = convertExternalVideoEntryToVisual(\n context,\n possibleEntry.entry as Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n );\n if (!visual) {\n throw new Error(`Failed to convert externalVideo entry with id ${id}`);\n }\n return visual;\n }\n\n // // Handle ExternalComponent\n // if (type === 'externalComponent') {\n // return resolveHelper<\n // TConfig,\n // BaseExternalComponentSkeleton<TConfig>,\n // TConfig['ExternalComponent']\n // >(context, entry, () => baseExternalComponentConverter);\n // }\n\n if (context.contentResolver.has(type)) {\n return resolveContent(context, entry);\n }\n\n if (context.linkResolver.has(type)) {\n return resolveLink(context, entry);\n }\n\n throw new Error(`Unknown content type \"${type}\" for entry with id ${id}`);\n}\n\n/**\n * Resolves all embedded entries and assets within a rich text document\n * Recursively traverses the document tree and resolves link references\n *\n * @param context - The converter context with includes and assets maps\n * @param richText - The unresolved rich text document from Contentful\n * @returns The rich text document with all embedded content resolved\n */\nexport function resolveRichTextDocument(context: ConverterContext, richText: Document | undefined) {\n if (!richText) {\n return undefined;\n }\n\n // Track resolved entries to prevent infinite recursion\n const resolvingEntries = new Set<string>();\n const resolvedEntries = new Set<string>();\n\n const resolveNode = (node: Block | Text | Inline): Block | Text | Inline => {\n // Handle embedded-entry-block nodes\n if (!('content' in node)) {\n return node;\n }\n const block = node as Block;\n if (\n block.data.target &&\n 'sys' in block.data.target &&\n block.data.target.sys.linkType === 'Entry'\n ) {\n const entryId = block.data.target.sys.id;\n\n // Check for circular references\n if (resolvingEntries.has(entryId)) {\n console.warn(\n `Circular reference detected in rich text resolution for entry ${entryId}. Skipping to prevent infinite recursion.`,\n );\n // Return the node as-is to break the cycle\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n\n // Check if already resolved\n if (resolvedEntries.has(entryId)) {\n // Entry already resolved, skip to avoid duplicate work\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n\n try {\n resolvingEntries.add(entryId);\n const resolvedEntry = resolvePageContent(\n context,\n block.data.target as UnresolvedLink<'Entry'>,\n );\n resolvingEntries.delete(entryId);\n resolvedEntries.add(entryId);\n\n return {\n ...block,\n data: {\n ...block.data,\n target: resolvedEntry,\n },\n content: block.content?.map(resolveNode),\n };\n } catch (error) {\n resolvingEntries.delete(entryId); // Clean up on error\n console.error(`Failed to resolve entry with id ${entryId}:`, error);\n // Return the node as-is if resolution fails\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n }\n\n if (\n block.data.target &&\n 'sys' in block.data.target &&\n block.data.target.sys.linkType === 'Asset'\n ) {\n try {\n const resolvedAsset = lookupAsset(context, block.data.target as UnresolvedLink<'Asset'>);\n if (resolvedAsset) {\n return {\n ...block,\n data: {\n ...block.data,\n target: resolvedAsset,\n },\n content: block.content?.map(resolveNode),\n };\n }\n } catch (error) {\n console.error(\n `Failed to resolve embedded-asset-block with id ${block.data.target.sys.id}:`,\n error,\n );\n // Return the node as-is if resolution fails\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n }\n\n // For all other node types, recursively process content if present\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n };\n\n // Cast the EntryFieldTypes.RichText to our working type\n // Resolve the entire document tree\n const resolved = resolveNode(richText);\n\n // Cast back to the config's RichText type\n return { json: resolved as Document };\n}\n","import type { IBaseCollection } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseCollectionSkeleton } from '../baseTypes/baseCollection';\nimport { createResponsiveVisual, lookupMediaEntry } from './asset';\nimport { type ConverterContext, DEFAULT_POSITION_FIELDS, lookupAsset } from './helpers';\nimport { resolveCollectionContent, resolveLink, resolveRichTextDocument } from './resolver';\n\n/**\n * Base converter for Contentful Collection entries to ICollection type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful entry to convert\n * @returns ICollection object\n *\n * @example\n * ```ts\n * const collection = baseCollectionConverter(context, contentfulEntry);\n * ```\n */\nexport function baseCollectionConverter(\n context: ConverterContext,\n entry: Entry<BaseCollectionSkeleton, DefaultChainModifier, string>,\n): IBaseCollection {\n const { sys, fields } = entry;\n\n // Destructure to exclude fields that need special handling\n const {\n // Fields requiring transformation\n backgroundVisual: bgVisual,\n mobileBackgroundVisual: mobileBgVisual,\n visual: visualField,\n mobileVisual: mobileVisualField,\n visualCustomSize,\n icon: iconField,\n links: linksField,\n contents: contentsField,\n body: bodyField,\n additionalCopy: additionalCopyField,\n // Field name change\n collectionType,\n showHeading,\n heading,\n // Already handled elsewhere\n cmsLabel,\n ...simpleFields // anchor, backgroundColour, textColour, preHeading, heading, postHeading, backgroundOverlayOpacity\n } = fields;\n\n // Convert background visuals to responsive visual\n const backgroundVisual = createResponsiveVisual(\n lookupAsset(context, bgVisual),\n lookupAsset(context, mobileBgVisual),\n );\n\n const visual = createResponsiveVisual(\n lookupMediaEntry(context, visualField),\n lookupMediaEntry(context, mobileVisualField),\n visualCustomSize,\n );\n\n const collection: IBaseCollection = {\n type: 'Collection',\n id: sys.id,\n name: cmsLabel,\n cmsLabel,\n collectionType,\n ...DEFAULT_POSITION_FIELDS,\n ...simpleFields,\n heading: showHeading ? heading : undefined,\n body: resolveRichTextDocument(context, bodyField),\n additionalCopy: resolveRichTextDocument(context, additionalCopyField),\n icon: lookupAsset(context, iconField),\n backgroundVisual,\n visual,\n links: linksField?.map((link) => resolveLink(context, link)),\n contents: contentsField?.map((content) => resolveCollectionContent(context, content)),\n };\n return collection;\n}\n","import type { IBaseComponent } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseComponentSkeleton } from '../baseTypes/baseComponent';\nimport { createResponsiveVisual, lookupMediaEntry } from './asset';\nimport { type ConverterContext, DEFAULT_POSITION_FIELDS, lookupAsset } from './helpers';\nimport { resolveLinks, resolveRichTextDocument } from './resolver';\n\n/**\n * Base converter for Contentful Component entries to IComponent type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful entry to convert\n * @returns IComponent object\n *\n * @example\n * ```ts\n * const component = baseComponentConverter(context, contentfulEntry);\n * ```\n */\nexport function baseComponentConverter(\n context: ConverterContext,\n entry: Entry<BaseComponentSkeleton, DefaultChainModifier, string>,\n): IBaseComponent {\n const { sys, fields } = entry;\n\n // Destructure to exclude fields that need special handling\n const {\n // Fields requiring transformation\n backgroundVisual: bgVisual,\n mobileBackgroundVisual: mobileBgVisual,\n visual: visualField,\n mobileVisual: mobileVisualField,\n visualCustomSize,\n icon: iconField,\n links: linksField,\n body: bodyField,\n additionalCopy: additionalCopyField,\n // Field name change\n componentType,\n showHeading,\n heading,\n otherMedia: _otherMedia,\n otherVisuals: _otherVisuals,\n // Already handled elsewhere\n cmsLabel,\n ...simpleFields // anchor, backgroundColour, textColour, preHeading, heading, postHeading, backgroundOverlayOpacity\n } = fields;\n\n // Convert background visuals to responsive visual\n const backgroundVisual = createResponsiveVisual(\n lookupAsset(context, bgVisual),\n lookupAsset(context, mobileBgVisual),\n );\n\n const visual = createResponsiveVisual(\n lookupMediaEntry(context, visualField),\n lookupMediaEntry(context, mobileVisualField),\n visualCustomSize,\n );\n\n const component: IBaseComponent = {\n type: 'Component',\n id: sys.id,\n name: cmsLabel,\n cmsLabel,\n componentType,\n ...DEFAULT_POSITION_FIELDS,\n ...simpleFields,\n heading: showHeading ? heading : undefined,\n body: resolveRichTextDocument(context, bodyField),\n additionalCopy: resolveRichTextDocument(context, additionalCopyField),\n icon: lookupAsset(context, iconField),\n backgroundVisual,\n visual,\n links: resolveLinks(context, linksField),\n };\n return component;\n}\n","import type {\n IBlankLink,\n IDownloadLink,\n IExternalLink,\n IInternalLink,\n} from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseLinkSkeleton } from '../baseTypes/baseLink';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset, makeContentfulTitle } from './helpers';\nimport { resolveLink } from './resolver';\n\n/**\n * Converts a Contentful link entry to an ILinkProps object\n * Handles all link types: internal, external, download, and blank\n */\nexport function baseLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseLinkSkeleton, DefaultChainModifier, string>,\n): IInternalLink | IExternalLink | IDownloadLink | IBlankLink {\n const { sys, fields } = entry;\n\n if (sys.contentType.sys.id !== 'link') {\n throw new Error(`Invalid content type: expected \"link\", got \"${sys.contentType.sys.id}\"`);\n }\n\n const id = sys.id;\n const name = fields.name;\n const useName = fields.useName;\n const text = useName\n ? name\n : (fields.linkText ?? makeContentfulTitle(fields.linkText, id, 'Link text for '));\n const icon = lookupAsset(context, fields.icon);\n const backgroundColour = fields.backgroundColour ?? null;\n const textColour = fields.textColour ?? null;\n const variant = fields.variant;\n const size = fields.size;\n\n // Common base properties\n const baseProps = {\n id,\n useName,\n name,\n text,\n icon,\n backgroundColour,\n textColour,\n variant,\n size,\n };\n\n // Determine link type based on field priority: internal > external > download > blank\n if (fields.internal) {\n // Internal link: resolve the target entry to get its href\n const internalTarget = resolveLink(context, fields.internal);\n return {\n ...baseProps,\n type: 'Internal link',\n href: internalTarget.href,\n slug: internalTarget.slug,\n indexed: internalTarget.indexed,\n hidden: internalTarget.hidden,\n tags: internalTarget.tags,\n };\n }\n\n if (fields.external) {\n // External link: use the external URL\n return {\n ...baseProps,\n type: 'External link',\n href: fields.external,\n };\n }\n\n if (fields.downloadAsset) {\n // Download link: use the asset URL\n const asset = lookupAsset(context, fields.downloadAsset);\n let href: string | null = null;\n if (asset?.image?.type === 'Picture') {\n href = asset.image.src;\n } else if (asset?.image?.type === 'Svg image') {\n href = asset.image.svgSrc;\n } else if (asset?.video) {\n if (asset.video.type === 'Local video') {\n href = asset.video.preview.videoUrl;\n } else if (asset.video.type === 'Full video') {\n href = asset.video.full.videoUrl;\n } else if (asset.video.type === 'External video') {\n href = asset.video.external;\n }\n }\n return {\n ...baseProps,\n type: 'Download link',\n href,\n visual: asset,\n };\n }\n\n // Blank link: no href\n return {\n ...baseProps,\n type: 'Blank link',\n href: null,\n };\n}\n","import type { INavigation, ITyped } from '@se-studio/core-data-types';\nimport type { Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseNavigationSkeleton } from '../baseTypes/baseNavigation';\nimport type { BaseTemplateSkeleton } from '../baseTypes/baseTemplate';\nimport type { ConverterContext } from './helpers';\nimport { resolveNavigationItem, resolvePageContent } from './resolver';\n\n/**\n * Resolved template data structure\n * Templates don't exist as a top-level type in core-data-types,\n * so this is an internal converter type only\n */\nexport interface ResolvedTemplate {\n preContent: ReadonlyArray<ITyped>;\n postContent: ReadonlyArray<ITyped>;\n menu?: INavigation;\n footer?: INavigation;\n backgroundColour?: string;\n textColour?: string;\n stickyNav: boolean;\n}\n\n/**\n * Resolves a template entry from an unresolved link\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param link - Unresolved link to template entry\n * @returns Resolved template data with content arrays and navigation\n */\nexport function resolveTemplate(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'>,\n): ResolvedTemplate | null {\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry || possibleEntry.type !== 'template') {\n return null;\n }\n\n const entry = possibleEntry.entry as Entry<BaseTemplateSkeleton, DefaultChainModifier, string>;\n const { fields } = entry;\n\n if (!fields) {\n return null;\n }\n\n // Resolve content arrays\n const preContent =\n fields.preContent?.map((content) => resolvePageContent(context, content)) ?? [];\n\n const postContent =\n fields.postContent?.map((content) => resolvePageContent(context, content)) ?? [];\n\n // Resolve navigation entries\n const menu = fields.menu ? resolveNavigation(context, fields.menu) : undefined;\n\n const footer = fields.footer ? resolveNavigation(context, fields.footer) : undefined;\n\n // Check for sticky nav flag\n const stickyNav = fields.flags?.includes('Sticky nav') ?? false;\n\n const { backgroundColour, textColour } = fields;\n return {\n preContent,\n postContent,\n menu,\n footer,\n backgroundColour,\n textColour,\n stickyNav,\n };\n}\n\n/**\n * Resolves a navigation entry from an unresolved link\n */\nfunction resolveNavigation(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'>,\n): INavigation | undefined {\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry || possibleEntry.type !== 'navigation') {\n return undefined;\n }\n\n const entry = possibleEntry.entry as Entry<BaseNavigationSkeleton, DefaultChainModifier, string>;\n const { sys, fields } = entry;\n\n if (!fields) {\n return undefined;\n }\n\n // Resolve navigation item entries\n const entries = fields.entries?.map((item) => resolveNavigationItem(context, item)) ?? [];\n\n const { name, textColour, backgroundColour } = fields;\n return {\n id: sys.id,\n name,\n entries,\n textColour,\n backgroundColour,\n };\n}\n","import type { IBasePage, IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BasePageSkeleton } from '../baseTypes/basePage';\nimport type { BasePageVariantSkeleton } from '../baseTypes/basePageVariant';\nimport {\n addPositionMetadata,\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulDescription,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveLink, resolvePageContent } from './resolver';\nimport { resolveTemplate } from './template';\n\n/**\n * Base converter for Contentful Page entries to IPage type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param entry - Contentful entry to convert\n * @returns IPage object\n *\n * @example\n * ```ts\n * const page = basePageConverter(contentfulEntry);\n * ```\n */\n\nexport function basePageConverter(\n context: ConverterContext,\n entry: Entry<BasePageSkeleton, DefaultChainModifier, string>,\n): IBasePage {\n const { sys, fields } = entry;\n const {\n slug,\n title,\n description,\n featuredImage,\n tags,\n content,\n template: templateLink,\n topContent: topContentLinks,\n bottomContent: bottomContentLinks,\n ...simpleFields\n } = fields;\n\n // Resolve template (if exists)\n const template = templateLink ? resolveTemplate(context, templateLink) : null;\n\n // Resolve all content sections\n const topContent = topContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const pageContent = content?.map((c) => resolvePageContent(context, c)) ?? [];\n const bottomContent = bottomContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const preContent = template?.preContent ?? [];\n const postContent = template?.postContent ?? [];\n\n // Merge in correct order and add position metadata\n const contents = addPositionMetadata([\n ...topContent,\n ...preContent,\n ...pageContent,\n ...postContent,\n ...bottomContent,\n ]);\n\n const page: IBasePage = {\n type: 'Page',\n id: sys.id,\n isHomePage: slug === 'index',\n slug,\n title: makeContentfulTitle(title, sys.id),\n description: makeContentfulDescription(description, sys.id),\n featuredImage: lookupAsset(context, featuredImage),\n tags: tags?.map((tag) => resolveLink(context, tag)),\n contents,\n ...simpleFields,\n menu: template?.menu,\n footer: template?.footer,\n };\n return page;\n}\n\nexport function calculatePageHref(slug: string) {\n if (slug === 'index') {\n return '/';\n }\n return `/${slug}/`;\n}\n\nexport function basePageLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePageSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'page') {\n throw new Error(`Invalid content type: expected \"page\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePageHref(fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n\n/**\n * Calculates the href for a page variant page\n * @param slug - Page variant slug\n * @returns Page variant href path with trailing slash\n */\nexport function calculatePageVariantHref(slug: string) {\n return `/${slug}/`;\n}\n\n/**\n * Base converter for PageVariant entries to IInternalLink type\n * Used when a page variant is referenced as a link in content\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful page variant entry to convert\n * @returns IInternalLink object representing the page variant link\n *\n * @example\n * ```ts\n * const pageVariantLink = basePageVariantLinkConverter(context, pageVariantEntry);\n * ```\n */\nexport function basePageVariantLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePageVariantSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'pageVariant') {\n throw new Error(\n `Invalid content type: expected \"pageVariant\", got \"${sys.contentType.sys.id}\"`,\n );\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePageVariantHref(fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n","import type { IInternalLink, IPerson } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BasePersonSkeleton } from '../baseTypes/basePerson';\nimport {\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveRichTextDocument } from './resolver';\n\n/**\n * Calculates the href for a person page\n * @param slug - Person slug\n * @returns Person href path with trailing slash\n */\nexport function calculatePersonHref(slug: string) {\n return `/people/${slug}/`;\n}\n\n/**\n * Base converter for Person entries to IInternalLink type\n * Used when a person is referenced as a link in content\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful person entry to convert\n * @returns IInternalLink object representing the person link\n *\n * @example\n * ```ts\n * const personLink = basePersonLinkConverter(context, personEntry);\n * ```\n */\nexport function basePersonLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePersonSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'person') {\n throw new Error(`Invalid content type: expected \"person\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.name, // Person has no cmsLabel, use name field\n title: fields.name,\n featuredImage: fields.media, // Person uses 'media' not 'featuredImage'\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePersonHref(fields.slug),\n );\n}\n\n/**\n * Base converter for Person entries to IPerson type\n * Used when a complete person object with bio and content is needed\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful person entry to convert\n * @returns IPerson object representing the complete person\n *\n * @example\n * ```ts\n * const person = basePersonConverter(context, personEntry);\n * ```\n */\nexport function basePersonConverter(\n context: ConverterContext,\n entry: Entry<BasePersonSkeleton, DefaultChainModifier, string>,\n): IPerson {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'person') {\n throw new Error(`Invalid content type: expected \"person\", got \"${sys.contentType.sys.id}\"`);\n }\n const {\n slug,\n hidden,\n indexed,\n backgroundColour,\n textColour,\n name,\n description,\n media,\n jobTitle,\n phoneNumber,\n emailAddress,\n location,\n linkedIn,\n bio: bioField,\n } = fields;\n\n return {\n type: 'Person',\n id: sys.id,\n slug,\n title: makeContentfulTitle(name, sys.id),\n description: description ?? `Description for ${sys.id}`,\n featuredImage: lookupAsset(context, media), // Person uses 'media' not 'featuredImage'\n backgroundColour,\n textColour,\n indexed,\n hidden,\n href: calculatePersonHref(slug),\n jobTitle: jobTitle ?? null,\n phoneNumber: phoneNumber ?? null,\n emailAddress: emailAddress ?? null,\n location: location ?? null,\n linkedIn: linkedIn ?? null,\n bio: resolveRichTextDocument(context, bioField) ?? null,\n };\n}\n","import type { IBaseArticle, IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseArticleSkeleton } from '../baseTypes/baseArticle';\nimport type { BaseArticleTypeSkeleton } from '../baseTypes/baseArticleType';\nimport {\n addPositionMetadata,\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulDescription,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveLink, resolvePageContent } from './resolver';\nimport { resolveTemplate } from './template';\n\n/**\n * Base converter for Contentful Article entries to IArticle type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param entry - Contentful entry to convert\n * @returns IArticle object\n *\n * @example\n * ```ts\n * const article = baseArticleConverter(contentfulEntry);\n * ```\n */\n\nexport function baseArticleConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleSkeleton, DefaultChainModifier, string>,\n): IBaseArticle {\n const { sys, fields } = entry;\n const {\n slug,\n title,\n description,\n featuredImage,\n tags,\n content,\n template: templateLink,\n topContent: topContentLinks,\n bottomContent: bottomContentLinks,\n articleType,\n ...simpleFields\n } = fields;\n const articleTypeLink = resolveLink(context, articleType);\n\n // Resolve template (if exists)\n const template = templateLink ? resolveTemplate(context, templateLink) : null;\n\n // Resolve all content sections\n const topContent = topContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const articleContent = content?.map((c) => resolvePageContent(context, c)) ?? [];\n const bottomContent = bottomContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const preContent = template?.preContent ?? [];\n const postContent = template?.postContent ?? [];\n\n // Merge in correct order and add position metadata\n const contents = addPositionMetadata([\n ...topContent,\n ...preContent,\n ...articleContent,\n ...postContent,\n ...bottomContent,\n ]);\n\n const article: IBaseArticle = {\n type: 'Article',\n id: sys.id,\n slug,\n title: makeContentfulTitle(title, sys.id),\n description: makeContentfulDescription(description, sys.id),\n featuredImage: lookupAsset(context, featuredImage),\n articleType: articleTypeLink,\n tags: tags?.map((tag) => resolveLink(context, tag)),\n contents,\n ...simpleFields,\n // Note: summary field exists in Contentful but is not part of IArticle interface\n // Keeping it in simpleFields for potential future use\n menu: template?.menu,\n footer: template?.footer,\n };\n return article;\n}\n\nexport function calculateArticleTypeHref(slug: string) {\n return `/${slug}/`;\n}\n\nexport function calculateArticleHref(articleTypeSlug: string, slug: string) {\n return `${calculateArticleTypeHref(articleTypeSlug)}${slug}/`;\n}\n\nexport function baseArticleLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'article') {\n throw new Error(`Invalid content type: expected \"article\", got \"${sys.contentType.sys.id}\"`);\n }\n\n const articleTypeLink = resolveLink(context, fields.articleType);\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateArticleHref(articleTypeLink.slug, fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n\nexport function baseArticleTypeLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleTypeSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'articleType') {\n throw new Error(\n `Invalid content type: expected \"articleType\", got \"${sys.contentType.sys.id}\"`,\n );\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.name,\n title: fields.name,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateArticleTypeHref(fields.slug),\n );\n}\n","import type { ILinkProps, INavigationItem } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseNavigationItemSkeleton } from '../baseTypes/baseNavigationItem';\nimport { type ConverterContext, lookupAsset, makeContentfulTitle } from './helpers';\nimport { resolveLink, resolveNavigationItem } from './resolver';\n\nfunction createLink(\n context: ConverterContext,\n entry: Entry<BaseNavigationItemSkeleton, DefaultChainModifier, string>,\n): ILinkProps | undefined {\n const {\n sys: { id },\n fields,\n } = entry;\n const { title, link, internal, icon, useTitle, ...otherFields } = fields;\n\n if (link) {\n return {\n type: 'External link',\n id,\n href: link,\n icon: lookupAsset(context, icon),\n name: makeContentfulTitle(title, id),\n ...(useTitle && { text: title }),\n ...otherFields,\n };\n }\n if (internal) {\n const resolved = resolveLink(context, internal);\n return resolved;\n }\n return undefined;\n}\n\nexport function baseNavigationItemConverter(\n context: ConverterContext,\n entry: Entry<BaseNavigationItemSkeleton, DefaultChainModifier, string>,\n): INavigationItem {\n const { sys, fields } = entry;\n\n const { navigationItems } = fields;\n\n const link = createLink(context, entry);\n\n const resolvedNavigationItems = navigationItems\n ?.map((item) => resolveNavigationItem(context, item))\n .filter((item): item is INavigationItem => item !== undefined);\n\n return {\n id: sys.id,\n link,\n entries: resolvedNavigationItems,\n };\n}\n","import type { IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseTagSkeleton } from '../baseTypes/baseTag';\nimport { type ConverterContext, createInternalLink } from './helpers';\n\nexport function calculateTagHref(slug: string) {\n return `/tag/${slug}/`;\n}\n\nexport function baseTagLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseTagSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'tag') {\n throw new Error(`Invalid content type: expected \"tag\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.name,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateTagHref(fields.slug),\n );\n}\n","import type { RetryConfig } from '../types';\nimport { getRetryAfter, isRetryableError } from './errors';\n\n/**\n * Default retry configuration\n */\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelay: 1000, // 1 second\n maxDelay: 30000, // 30 seconds\n backoffMultiplier: 2,\n};\n\n/**\n * Sleep utility for async delays\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n *\n * @param attempt - Current retry attempt (0-based)\n * @param config - Retry configuration\n * @param retryAfter - Optional retry-after value from rate limit response\n * @returns Delay in milliseconds\n */\nexport function calculateBackoffDelay(\n attempt: number,\n config: Required<RetryConfig>,\n retryAfter?: number,\n): number {\n // If server specified retry-after, use that\n if (retryAfter !== undefined) {\n return Math.min(retryAfter * 1000, config.maxDelay);\n }\n\n // Calculate exponential backoff\n const exponentialDelay = config.initialDelay * config.backoffMultiplier ** attempt;\n\n // Add jitter (random value between 0 and delay) to prevent thundering herd\n const jitter = Math.random() * exponentialDelay;\n\n return Math.min(exponentialDelay + jitter, config.maxDelay);\n}\n\n/**\n * Executes a function with retry logic\n *\n * @param fn - Async function to execute\n * @param config - Retry configuration\n * @returns Promise resolving to the function result\n *\n * @example\n * ```ts\n * const result = await withRetry(\n * async () => await client.getEntry('id'),\n * { maxRetries: 3, initialDelay: 1000 }\n * );\n * ```\n */\nexport async function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig): Promise<T> {\n const retryConfig: Required<RetryConfig> = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry if it's the last attempt\n if (attempt === retryConfig.maxRetries) {\n break;\n }\n\n // Only retry if the error is retryable\n if (!isRetryableError(error)) {\n throw error;\n }\n\n const retryAfter = getRetryAfter(error);\n const delay = calculateBackoffDelay(attempt, retryConfig, retryAfter);\n\n // Only log in development mode\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn(\n `Retry attempt ${attempt + 1}/${retryConfig.maxRetries} after ${delay}ms`,\n error,\n );\n }\n\n await sleep(delay);\n }\n }\n\n // If we get here, all retries failed\n throw lastError;\n}\n\n/**\n * Rate limiter using token bucket algorithm\n * Useful for controlling request rate to Contentful API\n */\nexport class RateLimiter {\n private tokens: number;\n private lastRefill: number;\n\n constructor(\n private readonly maxTokens: number,\n private readonly refillRate: number, // tokens per second\n ) {\n this.tokens = maxTokens;\n this.lastRefill = Date.now();\n }\n\n /**\n * Refills tokens based on time elapsed\n */\n private refill(): void {\n const now = Date.now();\n const timePassed = (now - this.lastRefill) / 1000; // in seconds\n const tokensToAdd = timePassed * this.refillRate;\n\n this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);\n this.lastRefill = now;\n }\n\n /**\n * Attempts to consume a token\n * @returns true if token was consumed, false if rate limited\n */\n tryConsume(): boolean {\n this.refill();\n\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return true;\n }\n\n return false;\n }\n\n /**\n * Waits until a token is available and consumes it\n */\n async consume(): Promise<void> {\n while (!this.tryConsume()) {\n // Wait for the time needed to get one token\n const waitTime = (1 / this.refillRate) * 1000;\n await sleep(waitTime);\n }\n }\n\n /**\n * Gets current number of available tokens\n */\n getAvailableTokens(): number {\n this.refill();\n return Math.floor(this.tokens);\n }\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: Any ok for now! */\nimport type { Document } from '@contentful/rich-text-types';\nimport type {\n IBaseArticle,\n IBasePage,\n IInternalLink,\n INavigation,\n INavigationItem,\n IPerson,\n IVisual,\n} from '@se-studio/core-data-types';\nimport type { Entry, EntrySkeletonType } from 'contentful';\nimport type { BaseArticleSkeleton } from './baseTypes/baseArticle';\nimport type { BasePageSkeleton } from './baseTypes/basePage';\nimport { type ContentfulResponse, getContentfulClient } from './client';\nimport { basePageConverter } from './converters';\nimport {\n baseArticleConverter,\n baseArticleLinkConverter,\n baseArticleTypeLinkConverter,\n} from './converters/article';\nimport { convertAssetToVisual } from './converters/asset';\nimport { baseCollectionConverter } from './converters/collection';\nimport { baseComponentConverter } from './converters/component';\nimport type {\n ContentResolverFunction,\n ContentResolverMap,\n ConverterContext,\n LinkResolverFunction,\n LinkResolverMap,\n} from './converters/helpers';\nimport { baseLinkConverter } from './converters/link';\nimport { baseNavigationItemConverter } from './converters/navigationItem';\nimport { basePageLinkConverter, basePageVariantLinkConverter } from './converters/page';\nimport { basePersonLinkConverter } from './converters/person';\nimport { baseTagLinkConverter } from './converters/tag';\nimport type { ContentfulConfig, FetchOptions } from './types';\nimport { withRetry } from './utils';\n\nexport type DefaultChainModifier = 'WITHOUT_LINK_RESOLUTION';\n\nfunction convertAllAssets(\n response: ContentfulResponse<any>,\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n): Map<string, IVisual> {\n const visuals = new Map<string, IVisual>();\n const assets = response.includes?.Asset;\n if (assets && assets.length > 0) {\n for (const asset of assets) {\n const visual = convertAssetToVisual(context, asset);\n if (visual) {\n visuals.set(visual.id, visual);\n }\n }\n }\n return visuals;\n}\n\nexport type ResolvedEntry =\n | IBasePage\n | IBaseArticle\n | INavigation\n | INavigationItem\n | IInternalLink\n | unknown // PageContent - will be narrowed at project level\n | IPerson;\n\nexport type PossibleResolvedEntry = {\n id: string;\n type: string;\n entry: Entry<EntrySkeletonType, DefaultChainModifier, string>;\n resolved?: ResolvedEntry;\n};\n\nfunction convertAllIncludes(response: ContentfulResponse<any>): Map<string, PossibleResolvedEntry> {\n const includes = new Map<string, PossibleResolvedEntry>();\n const entries = [...response.items, ...(response.includes?.Entry || [])];\n\n if (entries && entries.length > 0) {\n for (const entry of entries) {\n if (entry?.sys && entry.fields) {\n includes.set(entry.sys.id, {\n id: entry.sys.id,\n type: entry.sys.contentType.sys.id,\n entry,\n });\n }\n }\n }\n return includes;\n}\n\nexport type Converter<TEntry extends EntrySkeletonType, TResult> = (\n entry: Entry<TEntry, DefaultChainModifier, string>,\n includes: Map<string, PossibleResolvedEntry>,\n assets: Map<string, IVisual>,\n) => TResult;\n\n/**\n * Fetches a page from Contentful by slug\n *\n * @param config - Contentful configuration\n * @param slug - Page slug to fetch\n * @param options - Fetch options (locale, preview, caching, etc.)\n * @param converter - Optional custom converter function\n * @returns Promise resolving to IPage or null if not found\n *\n * @example\n * ```ts\n * const page = await contentfulPageRest(\n * {\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,\n * },\n * 'home',\n * {\n * locale: 'en-US',\n * cache: {\n * tags: ['home-page'],\n * revalidate: 3600\n * }\n * }\n * );\n * ```\n */\nexport async function contentfulPageRest(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n config: ContentfulConfig,\n slug: string,\n options?: FetchOptions,\n): Promise<IBasePage | null> {\n const client = getContentfulClient(config, options?.preview);\n\n const fetchFn = async () => {\n const response = await client.getEntries<BasePageSkeleton>(\n {\n content_type: 'page',\n 'fields.slug': slug,\n include: 10,\n locale: options?.locale,\n limit: 1,\n },\n options,\n );\n\n const pageEntry = response.items[0];\n if (!pageEntry || !pageEntry.fields) {\n return null;\n }\n\n const assets = convertAllAssets(response, context);\n const includes = convertAllIncludes(response);\n const fullContext: ConverterContext = {\n ...context,\n includes,\n assets,\n };\n\n const converted = fullContext.pageResolver(fullContext, pageEntry);\n\n return converted;\n };\n\n // Apply retry logic if configured\n if (options?.retry) {\n return await withRetry(fetchFn, options.retry);\n }\n\n return await fetchFn();\n}\n\nexport interface IContentfulRichText {\n json: Document;\n customStyles?: ReadonlyArray<string> | null;\n}\n\nexport function createBaseConverterContext(): Omit<ConverterContext, 'includes' | 'assets'> {\n const linkResolver: LinkResolverMap = new Map();\n linkResolver.set('page', basePageLinkConverter as LinkResolverFunction);\n linkResolver.set('article', baseArticleLinkConverter as LinkResolverFunction);\n linkResolver.set('articleType', baseArticleTypeLinkConverter as LinkResolverFunction);\n linkResolver.set('tag', baseTagLinkConverter as LinkResolverFunction);\n linkResolver.set('person', basePersonLinkConverter as LinkResolverFunction);\n linkResolver.set('pageVariant', basePageVariantLinkConverter as LinkResolverFunction);\n linkResolver.set('link', baseLinkConverter as LinkResolverFunction);\n\n const contentResolver: ContentResolverMap = new Map();\n contentResolver.set('collection', baseCollectionConverter as ContentResolverFunction);\n contentResolver.set('component', baseComponentConverter as ContentResolverFunction);\n contentResolver.set(\n 'externalComponent',\n baseComponentConverter as unknown as ContentResolverFunction,\n );\n\n return {\n pageResolver: basePageConverter,\n navigationItemResolver: baseNavigationItemConverter,\n articleResolver: baseArticleConverter,\n componentResolver: baseComponentConverter,\n collectionResolver: baseCollectionConverter,\n linkResolver,\n contentResolver,\n videoPrefix: '',\n };\n}\n\nexport async function contentfulArticleRest(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n config: ContentfulConfig,\n slug: string,\n articleTypeSlug: string,\n options?: FetchOptions,\n): Promise<IBaseArticle | null> {\n const client = getContentfulClient(config, options?.preview);\n\n const fetchFn = async () => {\n const response = await client.getEntries<BaseArticleSkeleton>(\n {\n content_type: 'article',\n 'fields.slug': slug,\n 'fields.articleType.sys.contentType.sys.id': 'articleType',\n 'fields.articleType.fields.slug': articleTypeSlug,\n include: 10,\n locale: options?.locale,\n limit: 1,\n },\n options,\n );\n\n const articleEntry = response.items[0];\n if (!articleEntry || !articleEntry.fields) {\n return null;\n }\n\n const assets = convertAllAssets(response, context);\n const includes = convertAllIncludes(response);\n const fullContext: ConverterContext = {\n ...context,\n includes,\n assets,\n };\n\n const converted = fullContext.articleResolver(fullContext, articleEntry);\n return converted;\n };\n\n // Apply retry logic if configured\n if (options?.retry) {\n return await withRetry(fetchFn, options.retry);\n }\n\n return await fetchFn();\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/errors.ts","../src/client.ts","../src/converters/helpers.ts","../src/converters/asset.ts","../src/utils/arrayUtils.ts","../src/utils/dateUtils.ts","../src/utils/retry.ts","../src/converters/resolver.ts","../src/converters/collection.ts","../src/converters/component.ts","../src/converters/link.ts","../src/converters/template.ts","../src/converters/page.ts","../src/converters/person.ts","../src/converters/article.ts","../src/converters/navigationItem.ts","../src/converters/tag.ts","../src/api.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Custom error classes for Contentful API errors\n */\n\n/**\n * Base error class for all Contentful-related errors\n */\nexport class ContentfulError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = 'ContentfulError';\n Object.setPrototypeOf(this, ContentfulError.prototype);\n }\n}\n\n/**\n * Error thrown when rate limit is exceeded\n */\nexport class RateLimitError extends ContentfulError {\n constructor(\n message: string,\n public readonly retryAfter?: number,\n details?: unknown,\n ) {\n super(message, 429, details);\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * Error thrown when entry is not found\n */\nexport class EntryNotFoundError extends ContentfulError {\n constructor(\n public readonly entryId: string,\n public readonly contentType?: string,\n ) {\n super(`Entry not found: ${entryId}${contentType ? ` (${contentType})` : ''}`, 404);\n this.name = 'EntryNotFoundError';\n Object.setPrototypeOf(this, EntryNotFoundError.prototype);\n }\n}\n\n/**\n * Error thrown when authentication fails\n */\nexport class AuthenticationError extends ContentfulError {\n constructor(message = 'Authentication failed') {\n super(message, 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends ContentfulError {\n constructor(\n message: string,\n public readonly validationErrors?: unknown,\n ) {\n super(message, 400, validationErrors);\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Checks if an error is a Contentful error\n */\nexport function isContentfulError(error: unknown): error is ContentfulError {\n return error instanceof ContentfulError;\n}\n\n/**\n * Checks if an error is a rate limit error\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError;\n}\n\n/**\n * Checks if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (isRateLimitError(error)) {\n return true;\n }\n\n if (isContentfulError(error)) {\n // Retry on 5xx errors and rate limits\n return error.statusCode !== undefined && (error.statusCode >= 500 || error.statusCode === 429);\n }\n\n return false;\n}\n\n/**\n * Extracts retry-after header value from error\n */\nexport function getRetryAfter(error: unknown): number | undefined {\n if (isRateLimitError(error)) {\n return error.retryAfter;\n }\n return undefined;\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: Any ok for now! */\nimport type { ContentfulConfig, FetchOptions } from './types';\nimport {\n AuthenticationError,\n ContentfulError,\n EntryNotFoundError,\n RateLimitError,\n ValidationError,\n} from './utils/errors';\n\n/**\n * Contentful REST API response structure\n * The items array contains Entry objects when T is an EntrySkeletonType\n */\nexport interface ContentfulResponse<T = any> {\n sys: {\n type: 'Array';\n };\n total: number;\n skip: number;\n limit: number;\n items: T extends import('contentful').EntrySkeletonType\n ? Array<import('contentful').Entry<T, 'WITHOUT_LINK_RESOLUTION', string>>\n : T[];\n includes?: {\n Entry?: any[];\n Asset?: any[];\n };\n}\n\n/**\n * Query parameters for Contentful API\n */\nexport interface ContentfulQuery {\n content_type?: string;\n locale?: string;\n include?: number;\n limit?: number;\n skip?: number;\n [key: string]: any;\n}\n\n/**\n * Builds query string from query parameters\n */\nfunction buildQueryString(query: ContentfulQuery): string {\n const params = new URLSearchParams();\n\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n params.append(key, String(value));\n }\n });\n\n return params.toString();\n}\n\n/**\n * Parses error response from Contentful API\n */\nasync function parseErrorResponse(response: Response): Promise<ContentfulError> {\n const statusCode = response.status;\n let errorData: any;\n\n try {\n errorData = await response.json();\n } catch {\n errorData = { message: response.statusText };\n }\n\n const message = errorData?.message || `Contentful API error: ${statusCode}`;\n\n switch (statusCode) {\n case 401:\n return new AuthenticationError(message);\n\n case 404:\n return new EntryNotFoundError(\n errorData?.sys?.id || 'unknown',\n errorData?.sys?.contentType?.sys?.id,\n );\n\n case 429: {\n // Parse retry-after header (in seconds)\n const retryAfterHeader =\n response.headers.get('X-Contentful-RateLimit-Reset') || response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : undefined;\n return new RateLimitError(message, retryAfter, errorData);\n }\n\n case 400:\n return new ValidationError(message, errorData);\n\n default:\n return new ContentfulError(message, statusCode, errorData);\n }\n}\n\ntype NextRequestInit = RequestInit & {\n next?: {\n revalidate?: number | false;\n tags?: string[];\n };\n};\n\n/**\n * Fetch-based Contentful client that participates in Next.js caching\n */\nexport class ContentfulFetchClient {\n private readonly baseUrl: string;\n private readonly accessToken: string;\n\n constructor(config: ContentfulConfig, preview = false) {\n const host = config.host || (preview ? 'preview.contentful.com' : 'cdn.contentful.com');\n const environment = config.environment || 'master';\n\n this.baseUrl = `https://${host}/spaces/${config.spaceId}/environments/${environment}`;\n this.accessToken = config.accessToken;\n }\n\n /**\n * Fetches entries from Contentful\n */\n async getEntries<T = any>(\n query: ContentfulQuery,\n options?: FetchOptions,\n ): Promise<ContentfulResponse<T>> {\n const queryString = buildQueryString(query);\n const url = `${this.baseUrl}/entries?${queryString}`;\n\n const fetchOptions: NextRequestInit = {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n 'Content-Type': 'application/json',\n },\n };\n\n // Add Next.js cache configuration if provided\n if (options?.next) {\n fetchOptions.next = options.next;\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<ContentfulResponse<T>>;\n }\n}\n\n/**\n * Creates a Contentful Content Delivery API (CDA) client\n *\n * @param config - Configuration object for the Contentful client\n * @returns Contentful CDA client instance\n *\n * @example\n * ```ts\n * const client = createContentfulClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,\n * environment: 'master'\n * });\n * ```\n */\nexport function createContentfulClient(config: ContentfulConfig): ContentfulFetchClient {\n return new ContentfulFetchClient(config, false);\n}\n\n/**\n * Creates a Contentful Content Preview API (CPA) client\n *\n * @param config - Configuration object for the Contentful preview client\n * @returns Contentful CPA client instance\n *\n * @example\n * ```ts\n * const previewClient = createContentfulPreviewClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!,\n * environment: 'master'\n * });\n * ```\n */\nexport function createContentfulPreviewClient(config: ContentfulConfig): ContentfulFetchClient {\n return new ContentfulFetchClient(config, true);\n}\n\n/**\n * Gets the appropriate Contentful client based on preview mode\n *\n * @param config - Configuration for the Contentful client\n * @param preview - Whether to use the preview API\n * @returns Contentful client instance (CDA or CPA)\n *\n * @example\n * ```ts\n * const client = getContentfulClient({\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: preview\n * ? process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!\n * : process.env.CONTENTFUL_ACCESS_TOKEN!,\n * }, preview);\n * ```\n */\nexport function getContentfulClient(\n config: ContentfulConfig,\n preview = false,\n): ContentfulFetchClient {\n return preview ? createContentfulPreviewClient(config) : createContentfulClient(config);\n}\n","import type { IInternalLink, IVisual } from '@se-studio/core-data-types';\nimport type { Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier, PossibleResolvedEntry } from '../api';\nimport type { BaseContent, BaseLink } from '../baseTypes/baseShared';\nimport type { baseArticleConverter } from './article';\nimport type { baseCollectionConverter } from './collection';\nimport type { baseComponentConverter } from './component';\nimport type { baseNavigationItemConverter } from './navigationItem';\nimport type { basePageConverter } from './page';\n\nexport function makeContentfulTitle(\n title: string | undefined | null,\n id: string,\n prefix = 'Title for ',\n) {\n return title ?? `${prefix}${id}`;\n}\n\nexport function makeContentfulDescription(description: string | undefined | null, id: string) {\n return description ?? `Description for ${id}`;\n}\n\nexport function lookupAsset(context: ConverterContext, asset: UnresolvedLink<'Asset'> | undefined) {\n if (!asset) return undefined;\n return context.assets.get(asset.sys.id);\n}\n\n/**\n * Default positioning fields for content items before they are processed\n */\nexport const DEFAULT_POSITION_FIELDS = {\n index: 0,\n isFirst: false,\n isLast: false,\n indexOfType: 0,\n} as const;\n\n/**\n * Creates an internal link object with common fields\n * Used by multiple converters (tag, page, article, person) to reduce duplication\n */\nexport function createInternalLink(\n id: string,\n fields: {\n cmsLabel?: string | null;\n title?: string | null;\n featuredImage?: UnresolvedLink<'Asset'>;\n backgroundColour?: string | null;\n textColour?: string | null;\n indexed?: boolean | null;\n hidden?: boolean | null;\n slug: string;\n },\n context: ConverterContext,\n href: string,\n additionalProps?: Partial<IInternalLink>,\n): IInternalLink {\n const { cmsLabel, title, featuredImage, backgroundColour, textColour, indexed, hidden, slug } =\n fields;\n\n return {\n type: 'Internal link',\n id,\n name: cmsLabel ?? '',\n useName: true,\n text: makeContentfulTitle(title, id),\n visual: lookupAsset(context, featuredImage),\n backgroundColour,\n textColour,\n indexed,\n hidden,\n slug,\n href,\n ...additionalProps,\n };\n}\n\nexport type ContentResolverFunction = (\n context: ConverterContext,\n entry: Entry<BaseContent, DefaultChainModifier, string>,\n) => unknown; // PageContent\nexport type ContentResolverMap = Map<string, ContentResolverFunction>;\nexport type LinkResolverFunction = (\n context: ConverterContext,\n entry: Entry<BaseLink, DefaultChainModifier, string>,\n) => IInternalLink;\nexport type LinkResolverMap = Map<string, LinkResolverFunction>;\n\nexport type ConverterContext = {\n videoPrefix: string;\n includes: Map<string, PossibleResolvedEntry>;\n assets: Map<string, IVisual>;\n linkResolver: LinkResolverMap;\n contentResolver: Map<\n string,\n (context: ConverterContext, entry: Entry<BaseContent, DefaultChainModifier, string>) => unknown\n >;\n navigationItemResolver: typeof baseNavigationItemConverter;\n pageResolver: typeof basePageConverter;\n articleResolver: typeof baseArticleConverter;\n componentResolver: typeof baseComponentConverter;\n collectionResolver: typeof baseCollectionConverter;\n};\n\n/**\n * Adds position metadata to an array of content items\n * Each item gets: index, isFirst, isLast, indexOfType\n *\n * @param items - Array of content items to add metadata to\n * @returns New array with position metadata added to each item\n */\nexport function addPositionMetadata<\n T extends {\n type: string;\n index?: number;\n isFirst?: boolean;\n isLast?: boolean;\n indexOfType?: number;\n },\n>(items: T[]): T[] {\n if (items.length === 0) return items;\n\n // Count items by type for indexOfType calculation\n const typeCount = new Map<string, number>();\n\n return items.map((item, index) => {\n const currentTypeIndex = typeCount.get(item.type) ?? 0;\n typeCount.set(item.type, currentTypeIndex + 1);\n\n return {\n ...item,\n index,\n isFirst: index === 0,\n isLast: index === items.length - 1,\n indexOfType: currentTypeIndex,\n };\n });\n}\n","import type {\n IAnimation,\n IImage,\n IPicture,\n IResponsiveVisual,\n ISvgImage,\n IVideo,\n IVideoDetails,\n IVisual,\n} from '@se-studio/core-data-types';\nimport type { Asset, AssetFields, AssetFile, AssetSys, Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseExternalVideoSkeleton } from '../baseTypes/baseExternalVideo';\nimport type { BaseMediaSkeleton } from '../baseTypes/baseMedia';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset, makeContentfulDescription, makeContentfulTitle } from './helpers';\n\nexport function convertAssetToVisual(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n asset?: Asset<DefaultChainModifier, string>,\n options?: Partial<IImage> | Partial<IVideo> | Partial<IAnimation>,\n): IVisual | undefined {\n if (!asset) return undefined;\n const { fields, sys } = asset;\n if (!fields) return undefined;\n const { id } = sys;\n const { file } = fields as AssetFields;\n if (!file) return undefined;\n const { contentType } = file;\n\n if (contentType?.startsWith('image/')) {\n const image = convertAssetToImage(file, fields as AssetFields, sys, options as Partial<IImage>);\n return {\n id,\n type: 'Visual',\n image,\n };\n }\n\n if (contentType?.startsWith('video/')) {\n const video = convertAssetToVideo(\n file,\n fields as AssetFields,\n sys,\n context,\n options as Partial<IVideo>,\n );\n return {\n id,\n type: 'Visual',\n video,\n };\n }\n return undefined;\n}\n\nfunction convertAssetToImage(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n options: Partial<Omit<IImage, 'id' | 'type'>>,\n): IImage {\n const { contentType } = file;\n if (contentType === 'image/svg+xml') {\n return convertAssetToSvgImage(file, fields, sys, options);\n } else {\n return convertAssetToPicture(file, fields, sys, options);\n }\n}\n\nfunction convertAssetToPicture(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n options: Partial<Omit<IImage, 'id' | 'type'>>,\n): IPicture {\n const { id } = sys;\n const { title, description } = fields;\n const { contentType, details, url } = file;\n const { size, image } = details;\n const { width, height } = image || {};\n\n return {\n ...options,\n id,\n type: 'Picture',\n src: `https:${url}`,\n mimeType: contentType,\n size,\n width: width || 0,\n height: height || 0,\n name: makeContentfulTitle(title, id),\n description: makeContentfulDescription(description, id),\n };\n}\n\nfunction convertAssetToSvgImage(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n options: Partial<Omit<IImage, 'id' | 'type'>>,\n): ISvgImage {\n const { id } = sys;\n const { title, description } = fields;\n const { contentType, details, url } = file;\n const { size, image } = details;\n const { width, height } = image || {};\n\n return {\n ...options,\n id,\n type: 'Svg image',\n svgSrc: `https:${url}`,\n mimeType: contentType,\n size,\n width: width || 0,\n height: height || 0,\n name: makeContentfulTitle(title, id),\n description: makeContentfulDescription(description, id),\n };\n}\n\nfunction convertAssetToVideoDetails(file: AssetFile, sys: AssetSys): IVideoDetails {\n const { id } = sys;\n const { details, url, contentType, fileName } = file;\n const { size } = details;\n return {\n id,\n videoUrl: `https:${url}`,\n size,\n mimeType: contentType,\n fileName,\n };\n}\n\nfunction convertAssetToVideo(\n file: AssetFile,\n fields: AssetFields,\n sys: AssetSys,\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n options: Partial<Omit<IVideo, 'id' | 'type'>>,\n): IVideo {\n const { id } = sys;\n const { title, description } = fields;\n const { details } = file;\n const { image } = details;\n const { width, height } = image || {};\n\n const videoDetails = convertAssetToVideoDetails(file, sys);\n\n return {\n ...options,\n id,\n type: 'Local video',\n preview: videoDetails,\n videoPrefix: context.videoPrefix,\n\n width: width || 0,\n height: height || 0,\n name: makeContentfulTitle(title, id),\n description: makeContentfulDescription(description, id),\n };\n}\n\nexport function createResponsiveVisual(\n visual: IVisual | undefined,\n mobileVisual: IVisual | undefined,\n customSize?: number | null,\n): IResponsiveVisual | undefined {\n if (!visual) return undefined;\n return {\n visual,\n mobileVisual,\n visualCustomSize: customSize,\n };\n}\n\n/**\n * Converts a baseMedia entry to IVisual by looking up the asset and merging metadata\n */\nexport function convertMediaEntryToVisual(\n context: ConverterContext,\n entry: Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n): IVisual | undefined {\n const { fields, sys } = entry;\n if (!fields) return undefined;\n\n // Lookup the asset from context\n const baseVisual = lookupAsset(context, fields.asset);\n if (!baseVisual) return undefined;\n\n // Extract metadata from the media entry\n const metadata = {\n name: makeContentfulTitle(fields.name, sys.id),\n nameAsCaption: fields.nameAsCaption ?? null,\n dontCrop: fields.dontCrop ?? null,\n verticalCropPosition: fields.verticalCropPosition ?? null,\n horizontalCropPosition: fields.horizontalCropPosition ?? null,\n horizontalPosition: fields.horizontalPosition ?? null,\n widthPercent: fields.width ?? null,\n };\n\n // Merge metadata into the image or video\n const visual: IVisual = {\n ...baseVisual,\n id: sys.id,\n };\n\n if (baseVisual.image) {\n visual.image = {\n ...baseVisual.image,\n ...metadata,\n };\n } else if (baseVisual.video) {\n visual.video = {\n ...baseVisual.video,\n ...metadata,\n autoPlay: fields.autoplay ?? null,\n loop: fields.loop ?? null,\n hideControls: fields.hideControls ?? null,\n };\n }\n\n return visual;\n}\n\n/**\n * Converts a baseExternalVideo entry to IVisual with external video\n */\nexport function convertExternalVideoEntryToVisual(\n context: ConverterContext,\n entry: Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n): IVisual | undefined {\n const { fields, sys } = entry;\n if (!fields || !fields.url) return undefined;\n\n // Lookup optional preview and poster assets\n const previewVisual = lookupAsset(context, fields.preview);\n const posterVisual = lookupAsset(context, fields.posterImage);\n\n // Extract preview IVideoDetails if available\n const preview =\n previewVisual?.video?.type === 'Local video' ? previewVisual.video.preview : undefined;\n\n // Extract poster URL if available\n const poster = posterVisual?.image?.type === 'Picture' ? posterVisual.image.src : undefined;\n\n // Map Contentful's \"Center\" to our \"Middle\" type\n const mapHorizontal = (\n value: 'Left' | 'Center' | 'Right' | undefined,\n ): 'Left' | 'Middle' | 'Right' | null => {\n if (!value) return null;\n return value === 'Center' ? 'Middle' : value;\n };\n\n const video: IVideo = {\n id: sys.id,\n type: 'External video',\n name: makeContentfulTitle(fields.name, sys.id),\n nameAsCaption: fields.nameAsCaption ?? null,\n external: fields.url,\n preview,\n poster,\n autoPlay: fields.autoPlay ?? null,\n loop: fields.loop ?? null,\n hideControls: fields.hideControls ?? null,\n dontCrop: fields.dontCrop ?? null,\n verticalCropPosition: fields.verticalCropPosition ?? null,\n horizontalCropPosition: mapHorizontal(fields.horizontalCropPosition),\n horizontalPosition: fields.horizontalPosition ?? null,\n widthPercent: fields.width ?? null,\n };\n\n return {\n id: sys.id,\n type: 'Visual',\n video,\n };\n}\n\n/**\n * Looks up and converts a media or external video entry from an unresolved link\n */\nexport function lookupMediaEntry(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'> | undefined,\n): IVisual | undefined {\n if (!link) return undefined;\n\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry) {\n return undefined;\n }\n\n const { type, entry } = possibleEntry;\n\n if (type === 'media') {\n return convertMediaEntryToVisual(\n context,\n entry as Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n );\n }\n\n if (type === 'externalVideo') {\n return convertExternalVideoEntryToVisual(\n context,\n entry as Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n );\n }\n\n return undefined;\n}\n","export function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {\n if (value === null || value === undefined) return false;\n return true;\n}\n\nexport function arrayOrUndefined<T>(array?: ReadonlyArray<T>) {\n if (array && array.length > 0) {\n return array;\n }\n return undefined;\n}\n","/**\n * Validates if a value can be converted to a valid Date object\n */\nexport function isValidDate(date: unknown): boolean {\n if (date instanceof Date) {\n return !Number.isNaN(date.getTime());\n }\n\n if (typeof date === 'string' || typeof date === 'number') {\n const parsed = new Date(date);\n return !Number.isNaN(parsed.getTime()) && parsed.getTime() > 0;\n }\n\n return false;\n}\n\n/**\n * Safely creates a Date object, returning null if invalid\n */\nexport function safeDate(date: unknown): Date | null {\n if (!isValidDate(date)) {\n return null;\n }\n\n if (date instanceof Date) {\n return date;\n }\n\n return new Date(date as string | number);\n}\n","import type { RetryConfig } from '../types';\nimport { getRetryAfter, isRetryableError } from './errors';\n\n/**\n * Default retry configuration\n */\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelay: 1000, // 1 second\n maxDelay: 30000, // 30 seconds\n backoffMultiplier: 2,\n};\n\n/**\n * Sleep utility for async delays\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n *\n * @param attempt - Current retry attempt (0-based)\n * @param config - Retry configuration\n * @param retryAfter - Optional retry-after value from rate limit response\n * @returns Delay in milliseconds\n */\nexport function calculateBackoffDelay(\n attempt: number,\n config: Required<RetryConfig>,\n retryAfter?: number,\n): number {\n // If server specified retry-after, use that\n if (retryAfter !== undefined) {\n return Math.min(retryAfter * 1000, config.maxDelay);\n }\n\n // Calculate exponential backoff\n const exponentialDelay = config.initialDelay * config.backoffMultiplier ** attempt;\n\n // Add jitter (random value between 0 and delay) to prevent thundering herd\n const jitter = Math.random() * exponentialDelay;\n\n return Math.min(exponentialDelay + jitter, config.maxDelay);\n}\n\n/**\n * Executes a function with retry logic\n *\n * @param fn - Async function to execute\n * @param config - Retry configuration\n * @returns Promise resolving to the function result\n *\n * @example\n * ```ts\n * const result = await withRetry(\n * async () => await client.getEntry('id'),\n * { maxRetries: 3, initialDelay: 1000 }\n * );\n * ```\n */\nexport async function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig): Promise<T> {\n const retryConfig: Required<RetryConfig> = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry if it's the last attempt\n if (attempt === retryConfig.maxRetries) {\n break;\n }\n\n // Only retry if the error is retryable\n if (!isRetryableError(error)) {\n throw error;\n }\n\n const retryAfter = getRetryAfter(error);\n const delay = calculateBackoffDelay(attempt, retryConfig, retryAfter);\n\n // Only log in development mode\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn(\n `Retry attempt ${attempt + 1}/${retryConfig.maxRetries} after ${delay}ms`,\n error,\n );\n }\n\n await sleep(delay);\n }\n }\n\n // If we get here, all retries failed\n throw lastError;\n}\n\n/**\n * Rate limiter using token bucket algorithm\n * Useful for controlling request rate to Contentful API\n */\nexport class RateLimiter {\n private tokens: number;\n private lastRefill: number;\n\n constructor(\n private readonly maxTokens: number,\n private readonly refillRate: number, // tokens per second\n ) {\n this.tokens = maxTokens;\n this.lastRefill = Date.now();\n }\n\n /**\n * Refills tokens based on time elapsed\n */\n private refill(): void {\n const now = Date.now();\n const timePassed = (now - this.lastRefill) / 1000; // in seconds\n const tokensToAdd = timePassed * this.refillRate;\n\n this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);\n this.lastRefill = now;\n }\n\n /**\n * Attempts to consume a token\n * @returns true if token was consumed, false if rate limited\n */\n tryConsume(): boolean {\n this.refill();\n\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return true;\n }\n\n return false;\n }\n\n /**\n * Waits until a token is available and consumes it\n */\n async consume(): Promise<void> {\n while (!this.tryConsume()) {\n // Wait for the time needed to get one token\n const waitTime = (1 / this.refillRate) * 1000;\n await sleep(waitTime);\n }\n }\n\n /**\n * Gets current number of available tokens\n */\n getAvailableTokens(): number {\n this.refill();\n return Math.floor(this.tokens);\n }\n}\n","import type { Block, Document, Inline, Text } from '@contentful/rich-text-types';\nimport type {\n CollectionContent,\n IInternalLink,\n INavigationItem,\n ITyped,\n} from '@se-studio/core-data-types';\nimport type { Entry, EntrySkeletonType, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseCollectionSkeleton } from '../baseTypes/baseCollection';\nimport type { BaseComponentSkeleton } from '../baseTypes/baseComponent';\nimport type { BaseExternalVideoSkeleton } from '../baseTypes/baseExternalVideo';\nimport type { BaseMediaSkeleton } from '../baseTypes/baseMedia';\nimport type { BaseNavigationItemSkeleton } from '../baseTypes/baseNavigationItem';\nimport type { BaseLink } from '../baseTypes/baseShared';\nimport { arrayOrUndefined } from '../utils';\nimport { convertExternalVideoEntryToVisual, convertMediaEntryToVisual } from './asset';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset } from './helpers';\n\nexport function resolveHelper<TEntrySkeletonType extends EntrySkeletonType, TResult>(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n getResolver: (\n type: string,\n ) =>\n | ((\n context: ConverterContext,\n entry: Entry<TEntrySkeletonType, DefaultChainModifier, string>,\n ) => TResult)\n | undefined,\n): TResult {\n const id = entry.sys.id;\n const possibleEntry = context.includes.get(id);\n if (!possibleEntry) {\n throw new Error(`Cannot find included entry for link with id ${id}`);\n }\n if (!possibleEntry.resolved) {\n const resolver = getResolver(possibleEntry.type);\n if (!resolver) {\n throw new Error(\n `No resolver found for link type ${possibleEntry.type} (${JSON.stringify(possibleEntry)}) [${JSON.stringify(entry)}]`,\n );\n }\n if (typeof resolver !== 'function') {\n console.log('Resolver type', possibleEntry.type, typeof resolver, resolver);\n }\n\n const resolved = resolver(\n context,\n possibleEntry.entry as Entry<TEntrySkeletonType, DefaultChainModifier, string>,\n );\n possibleEntry.resolved = resolved;\n return resolved;\n }\n return possibleEntry.resolved as TResult;\n}\n\nexport function resolveLink(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): IInternalLink {\n return resolveHelper<BaseLink, IInternalLink>(context, entry, (type) =>\n context.linkResolver.get(type),\n );\n}\n\nexport function resolveLinks(\n context: ConverterContext,\n entries: UnresolvedLink<'Entry'>[] | undefined,\n): readonly IInternalLink[] | undefined {\n return arrayOrUndefined(entries?.map((entry) => resolveLink(context, entry)));\n}\n\nexport function resolveContent(context: ConverterContext, entry: UnresolvedLink<'Entry'>): ITyped {\n return resolveHelper<BaseLink, ITyped>(context, entry, (type) => {\n const resolver = context.contentResolver.get(type);\n return resolver as (\n context: ConverterContext,\n entry: Entry<BaseLink, DefaultChainModifier, string>,\n ) => ITyped;\n });\n}\n\nexport function resolveNavigationItem(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): INavigationItem {\n return resolveHelper<BaseNavigationItemSkeleton, INavigationItem>(\n context,\n entry,\n () => context.navigationItemResolver,\n );\n}\n\nexport function resolveCollectionContent(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): CollectionContent {\n return resolveHelper<BaseComponentSkeleton | BaseCollectionSkeleton, CollectionContent>(\n context,\n entry,\n (type) => {\n const resolver = context.contentResolver.get(type);\n return resolver as (\n context: ConverterContext,\n entry: Entry<BaseComponentSkeleton | BaseCollectionSkeleton, DefaultChainModifier, string>,\n ) => CollectionContent;\n },\n );\n}\n\n/**\n * Resolves a PageContent entry from an unresolved link\n * PageContent can be: Component, Collection, ExternalComponent, Visual (media/externalVideo), or PersonLink\n */\nexport function resolvePageContent(\n context: ConverterContext,\n entry: UnresolvedLink<'Entry'>,\n): ITyped {\n const id = entry.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry) {\n throw new Error(`Cannot find included entry for content with id ${id}`);\n }\n\n const { type } = possibleEntry;\n\n // Handle Media - convert to IVisual\n if (type === 'media') {\n const visual = convertMediaEntryToVisual(\n context,\n possibleEntry.entry as Entry<BaseMediaSkeleton, DefaultChainModifier, string>,\n );\n if (!visual) {\n throw new Error(`Failed to convert media entry with id ${id}`);\n }\n return visual;\n }\n\n // Handle ExternalVideo - convert to IVisual\n if (type === 'externalVideo') {\n const visual = convertExternalVideoEntryToVisual(\n context,\n possibleEntry.entry as Entry<BaseExternalVideoSkeleton, DefaultChainModifier, string>,\n );\n if (!visual) {\n throw new Error(`Failed to convert externalVideo entry with id ${id}`);\n }\n return visual;\n }\n\n // // Handle ExternalComponent\n // if (type === 'externalComponent') {\n // return resolveHelper<\n // TConfig,\n // BaseExternalComponentSkeleton<TConfig>,\n // TConfig['ExternalComponent']\n // >(context, entry, () => baseExternalComponentConverter);\n // }\n\n if (context.contentResolver.has(type)) {\n return resolveContent(context, entry);\n }\n\n if (context.linkResolver.has(type)) {\n return resolveLink(context, entry);\n }\n\n throw new Error(`Unknown content type \"${type}\" for entry with id ${id}`);\n}\n\n/**\n * Resolves all embedded entries and assets within a rich text document\n * Recursively traverses the document tree and resolves link references\n *\n * @param context - The converter context with includes and assets maps\n * @param richText - The unresolved rich text document from Contentful\n * @returns The rich text document with all embedded content resolved\n */\nexport function resolveRichTextDocument(context: ConverterContext, richText: Document | undefined) {\n if (!richText) {\n return undefined;\n }\n\n // Track resolved entries to prevent infinite recursion\n const resolvingEntries = new Set<string>();\n const resolvedEntries = new Set<string>();\n\n const resolveNode = (node: Block | Text | Inline): Block | Text | Inline => {\n // Handle embedded-entry-block nodes\n if (!('content' in node)) {\n return node;\n }\n const block = node as Block;\n if (\n block.data.target &&\n 'sys' in block.data.target &&\n block.data.target.sys.linkType === 'Entry'\n ) {\n const entryId = block.data.target.sys.id;\n\n // Check for circular references\n if (resolvingEntries.has(entryId)) {\n console.warn(\n `Circular reference detected in rich text resolution for entry ${entryId}. Skipping to prevent infinite recursion.`,\n );\n // Return the node as-is to break the cycle\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n\n // Check if already resolved\n if (resolvedEntries.has(entryId)) {\n // Entry already resolved, skip to avoid duplicate work\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n\n try {\n resolvingEntries.add(entryId);\n const resolvedEntry = resolvePageContent(\n context,\n block.data.target as UnresolvedLink<'Entry'>,\n );\n resolvingEntries.delete(entryId);\n resolvedEntries.add(entryId);\n\n return {\n ...block,\n data: {\n ...block.data,\n target: resolvedEntry,\n },\n content: block.content?.map(resolveNode),\n };\n } catch (error) {\n resolvingEntries.delete(entryId); // Clean up on error\n console.error(`Failed to resolve entry with id ${entryId}:`, error);\n // Return the node as-is if resolution fails\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n }\n\n if (\n block.data.target &&\n 'sys' in block.data.target &&\n block.data.target.sys.linkType === 'Asset'\n ) {\n try {\n const resolvedAsset = lookupAsset(context, block.data.target as UnresolvedLink<'Asset'>);\n if (resolvedAsset) {\n return {\n ...block,\n data: {\n ...block.data,\n target: resolvedAsset,\n },\n content: block.content?.map(resolveNode),\n };\n }\n } catch (error) {\n console.error(\n `Failed to resolve embedded-asset-block with id ${block.data.target.sys.id}:`,\n error,\n );\n // Return the node as-is if resolution fails\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n }\n }\n\n // For all other node types, recursively process content if present\n return {\n ...block,\n content: block.content?.map(resolveNode),\n };\n };\n\n // Cast the EntryFieldTypes.RichText to our working type\n // Resolve the entire document tree\n const resolved = resolveNode(richText);\n\n // Cast back to the config's RichText type\n return { json: resolved as Document };\n}\n","import type { IBaseCollection } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseCollectionSkeleton } from '../baseTypes/baseCollection';\nimport { createResponsiveVisual, lookupMediaEntry } from './asset';\nimport { type ConverterContext, DEFAULT_POSITION_FIELDS, lookupAsset } from './helpers';\nimport { resolveCollectionContent, resolveLink, resolveRichTextDocument } from './resolver';\n\n/**\n * Base converter for Contentful Collection entries to ICollection type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful entry to convert\n * @returns ICollection object\n *\n * @example\n * ```ts\n * const collection = baseCollectionConverter(context, contentfulEntry);\n * ```\n */\nexport function baseCollectionConverter(\n context: ConverterContext,\n entry: Entry<BaseCollectionSkeleton, DefaultChainModifier, string>,\n): IBaseCollection {\n const { sys, fields } = entry;\n\n // Destructure to exclude fields that need special handling\n const {\n // Fields requiring transformation\n backgroundVisual: bgVisual,\n mobileBackgroundVisual: mobileBgVisual,\n visual: visualField,\n mobileVisual: mobileVisualField,\n visualCustomSize,\n icon: iconField,\n links: linksField,\n contents: contentsField,\n body: bodyField,\n additionalCopy: additionalCopyField,\n // Field name change\n collectionType,\n showHeading,\n heading,\n // Already handled elsewhere\n cmsLabel,\n ...simpleFields // anchor, backgroundColour, textColour, preHeading, heading, postHeading, backgroundOverlayOpacity\n } = fields;\n\n // Convert background visuals to responsive visual\n const backgroundVisual = createResponsiveVisual(\n lookupAsset(context, bgVisual),\n lookupAsset(context, mobileBgVisual),\n );\n\n const visual = createResponsiveVisual(\n lookupMediaEntry(context, visualField),\n lookupMediaEntry(context, mobileVisualField),\n visualCustomSize,\n );\n\n const collection: IBaseCollection = {\n type: 'Collection',\n id: sys.id,\n name: cmsLabel,\n cmsLabel,\n collectionType,\n ...DEFAULT_POSITION_FIELDS,\n ...simpleFields,\n heading: showHeading ? heading : undefined,\n body: resolveRichTextDocument(context, bodyField),\n additionalCopy: resolveRichTextDocument(context, additionalCopyField),\n icon: lookupAsset(context, iconField),\n backgroundVisual,\n visual,\n links: linksField?.map((link) => resolveLink(context, link)),\n contents: contentsField?.map((content) => resolveCollectionContent(context, content)),\n };\n return collection;\n}\n","import type { IBaseComponent } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseComponentSkeleton } from '../baseTypes/baseComponent';\nimport { createResponsiveVisual, lookupMediaEntry } from './asset';\nimport { type ConverterContext, DEFAULT_POSITION_FIELDS, lookupAsset } from './helpers';\nimport { resolveLinks, resolveRichTextDocument } from './resolver';\n\n/**\n * Base converter for Contentful Component entries to IComponent type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful entry to convert\n * @returns IComponent object\n *\n * @example\n * ```ts\n * const component = baseComponentConverter(context, contentfulEntry);\n * ```\n */\nexport function baseComponentConverter(\n context: ConverterContext,\n entry: Entry<BaseComponentSkeleton, DefaultChainModifier, string>,\n): IBaseComponent {\n const { sys, fields } = entry;\n\n // Destructure to exclude fields that need special handling\n const {\n // Fields requiring transformation\n backgroundVisual: bgVisual,\n mobileBackgroundVisual: mobileBgVisual,\n visual: visualField,\n mobileVisual: mobileVisualField,\n visualCustomSize,\n icon: iconField,\n links: linksField,\n body: bodyField,\n additionalCopy: additionalCopyField,\n // Field name change\n componentType,\n showHeading,\n heading,\n otherMedia: _otherMedia,\n otherVisuals: _otherVisuals,\n // Already handled elsewhere\n cmsLabel,\n ...simpleFields // anchor, backgroundColour, textColour, preHeading, heading, postHeading, backgroundOverlayOpacity\n } = fields;\n\n // Convert background visuals to responsive visual\n const backgroundVisual = createResponsiveVisual(\n lookupAsset(context, bgVisual),\n lookupAsset(context, mobileBgVisual),\n );\n\n const visual = createResponsiveVisual(\n lookupMediaEntry(context, visualField),\n lookupMediaEntry(context, mobileVisualField),\n visualCustomSize,\n );\n\n const component: IBaseComponent = {\n type: 'Component',\n id: sys.id,\n name: cmsLabel,\n cmsLabel,\n componentType,\n ...DEFAULT_POSITION_FIELDS,\n ...simpleFields,\n heading: showHeading ? heading : undefined,\n body: resolveRichTextDocument(context, bodyField),\n additionalCopy: resolveRichTextDocument(context, additionalCopyField),\n icon: lookupAsset(context, iconField),\n backgroundVisual,\n visual,\n links: resolveLinks(context, linksField),\n };\n return component;\n}\n","import type {\n IBlankLink,\n IDownloadLink,\n IExternalLink,\n IInternalLink,\n} from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseLinkSkeleton } from '../baseTypes/baseLink';\nimport type { ConverterContext } from './helpers';\nimport { lookupAsset, makeContentfulTitle } from './helpers';\nimport { resolveLink } from './resolver';\n\n/**\n * Converts a Contentful link entry to an ILinkProps object\n * Handles all link types: internal, external, download, and blank\n */\nexport function baseLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseLinkSkeleton, DefaultChainModifier, string>,\n): IInternalLink | IExternalLink | IDownloadLink | IBlankLink {\n const { sys, fields } = entry;\n\n if (sys.contentType.sys.id !== 'link') {\n throw new Error(`Invalid content type: expected \"link\", got \"${sys.contentType.sys.id}\"`);\n }\n\n const id = sys.id;\n const name = fields.name;\n const useName = fields.useName;\n const text = useName\n ? name\n : (fields.linkText ?? makeContentfulTitle(fields.linkText, id, 'Link text for '));\n const icon = lookupAsset(context, fields.icon);\n const backgroundColour = fields.backgroundColour ?? null;\n const textColour = fields.textColour ?? null;\n const variant = fields.variant;\n const size = fields.size;\n\n // Common base properties\n const baseProps = {\n id,\n useName,\n name,\n text,\n icon,\n backgroundColour,\n textColour,\n variant,\n size,\n };\n\n // Determine link type based on field priority: internal > external > download > blank\n if (fields.internal) {\n // Internal link: resolve the target entry to get its href\n const internalTarget = resolveLink(context, fields.internal);\n return {\n ...baseProps,\n type: 'Internal link',\n href: internalTarget.href,\n slug: internalTarget.slug,\n indexed: internalTarget.indexed,\n hidden: internalTarget.hidden,\n tags: internalTarget.tags,\n };\n }\n\n if (fields.external) {\n // External link: use the external URL\n return {\n ...baseProps,\n type: 'External link',\n href: fields.external,\n };\n }\n\n if (fields.downloadAsset) {\n // Download link: use the asset URL\n const asset = lookupAsset(context, fields.downloadAsset);\n let href: string | null = null;\n if (asset?.image?.type === 'Picture') {\n href = asset.image.src;\n } else if (asset?.image?.type === 'Svg image') {\n href = asset.image.svgSrc;\n } else if (asset?.video) {\n if (asset.video.type === 'Local video') {\n href = asset.video.preview.videoUrl;\n } else if (asset.video.type === 'Full video') {\n href = asset.video.full.videoUrl;\n } else if (asset.video.type === 'External video') {\n href = asset.video.external;\n }\n }\n return {\n ...baseProps,\n type: 'Download link',\n href,\n visual: asset,\n };\n }\n\n // Blank link: no href\n return {\n ...baseProps,\n type: 'Blank link',\n href: null,\n };\n}\n","import type { INavigation, ITyped } from '@se-studio/core-data-types';\nimport type { Entry, UnresolvedLink } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseNavigationSkeleton } from '../baseTypes/baseNavigation';\nimport type { BaseTemplateSkeleton } from '../baseTypes/baseTemplate';\nimport type { ConverterContext } from './helpers';\nimport { resolveNavigationItem, resolvePageContent } from './resolver';\n\n/**\n * Resolved template data structure\n * Templates don't exist as a top-level type in core-data-types,\n * so this is an internal converter type only\n */\nexport interface ResolvedTemplate {\n preContent: ReadonlyArray<ITyped>;\n postContent: ReadonlyArray<ITyped>;\n menu?: INavigation;\n footer?: INavigation;\n backgroundColour?: string;\n textColour?: string;\n stickyNav: boolean;\n}\n\n/**\n * Resolves a template entry from an unresolved link\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param link - Unresolved link to template entry\n * @returns Resolved template data with content arrays and navigation\n */\nexport function resolveTemplate(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'>,\n): ResolvedTemplate | null {\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry || possibleEntry.type !== 'template') {\n return null;\n }\n\n const entry = possibleEntry.entry as Entry<BaseTemplateSkeleton, DefaultChainModifier, string>;\n const { fields } = entry;\n\n if (!fields) {\n return null;\n }\n\n // Resolve content arrays\n const preContent =\n fields.preContent?.map((content) => resolvePageContent(context, content)) ?? [];\n\n const postContent =\n fields.postContent?.map((content) => resolvePageContent(context, content)) ?? [];\n\n // Resolve navigation entries\n const menu = fields.menu ? resolveNavigation(context, fields.menu) : undefined;\n\n const footer = fields.footer ? resolveNavigation(context, fields.footer) : undefined;\n\n // Check for sticky nav flag\n const stickyNav = fields.flags?.includes('Sticky nav') ?? false;\n\n const { backgroundColour, textColour } = fields;\n return {\n preContent,\n postContent,\n menu,\n footer,\n backgroundColour,\n textColour,\n stickyNav,\n };\n}\n\n/**\n * Resolves a navigation entry from an unresolved link\n */\nfunction resolveNavigation(\n context: ConverterContext,\n link: UnresolvedLink<'Entry'>,\n): INavigation | undefined {\n const id = link.sys.id;\n const possibleEntry = context.includes.get(id);\n\n if (!possibleEntry || possibleEntry.type !== 'navigation') {\n return undefined;\n }\n\n const entry = possibleEntry.entry as Entry<BaseNavigationSkeleton, DefaultChainModifier, string>;\n const { sys, fields } = entry;\n\n if (!fields) {\n return undefined;\n }\n\n // Resolve navigation item entries\n const entries = fields.entries?.map((item) => resolveNavigationItem(context, item)) ?? [];\n\n const { name, textColour, backgroundColour } = fields;\n return {\n id: sys.id,\n name,\n entries,\n textColour,\n backgroundColour,\n };\n}\n","import type { IBasePage, IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BasePageSkeleton } from '../baseTypes/basePage';\nimport type { BasePageVariantSkeleton } from '../baseTypes/basePageVariant';\nimport {\n addPositionMetadata,\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulDescription,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveLink, resolvePageContent } from './resolver';\nimport { resolveTemplate } from './template';\n\n/**\n * Base converter for Contentful Page entries to IPage type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param entry - Contentful entry to convert\n * @returns IPage object\n *\n * @example\n * ```ts\n * const page = basePageConverter(contentfulEntry);\n * ```\n */\n\nexport function basePageConverter(\n context: ConverterContext,\n entry: Entry<BasePageSkeleton, DefaultChainModifier, string>,\n): IBasePage {\n const { sys, fields } = entry;\n const {\n slug,\n title,\n description,\n featuredImage,\n tags,\n content,\n template: templateLink,\n topContent: topContentLinks,\n bottomContent: bottomContentLinks,\n ...simpleFields\n } = fields;\n\n // Resolve template (if exists)\n const template = templateLink ? resolveTemplate(context, templateLink) : null;\n\n // Resolve all content sections\n const topContent = topContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const pageContent = content?.map((c) => resolvePageContent(context, c)) ?? [];\n const bottomContent = bottomContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const preContent = template?.preContent ?? [];\n const postContent = template?.postContent ?? [];\n\n // Merge in correct order and add position metadata\n const contents = addPositionMetadata([\n ...topContent,\n ...preContent,\n ...pageContent,\n ...postContent,\n ...bottomContent,\n ]);\n\n const page: IBasePage = {\n type: 'Page',\n id: sys.id,\n isHomePage: slug === 'index',\n slug,\n title: makeContentfulTitle(title, sys.id),\n description: makeContentfulDescription(description, sys.id),\n featuredImage: lookupAsset(context, featuredImage),\n tags: tags?.map((tag) => resolveLink(context, tag)),\n contents,\n ...simpleFields,\n menu: template?.menu,\n footer: template?.footer,\n };\n return page;\n}\n\nexport function calculatePageHref(slug: string) {\n if (slug === 'index') {\n return '/';\n }\n return `/${slug}/`;\n}\n\nexport function basePageLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePageSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'page') {\n throw new Error(`Invalid content type: expected \"page\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePageHref(fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n\n/**\n * Calculates the href for a page variant page\n * @param slug - Page variant slug\n * @returns Page variant href path with trailing slash\n */\nexport function calculatePageVariantHref(slug: string) {\n return `/${slug}/`;\n}\n\n/**\n * Base converter for PageVariant entries to IInternalLink type\n * Used when a page variant is referenced as a link in content\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful page variant entry to convert\n * @returns IInternalLink object representing the page variant link\n *\n * @example\n * ```ts\n * const pageVariantLink = basePageVariantLinkConverter(context, pageVariantEntry);\n * ```\n */\nexport function basePageVariantLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePageVariantSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'pageVariant') {\n throw new Error(\n `Invalid content type: expected \"pageVariant\", got \"${sys.contentType.sys.id}\"`,\n );\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePageVariantHref(fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n","import type { IInternalLink, IPerson } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BasePersonSkeleton } from '../baseTypes/basePerson';\nimport {\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveRichTextDocument } from './resolver';\n\n/**\n * Calculates the href for a person page\n * @param slug - Person slug\n * @returns Person href path with trailing slash\n */\nexport function calculatePersonHref(slug: string) {\n return `/people/${slug}/`;\n}\n\n/**\n * Base converter for Person entries to IInternalLink type\n * Used when a person is referenced as a link in content\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful person entry to convert\n * @returns IInternalLink object representing the person link\n *\n * @example\n * ```ts\n * const personLink = basePersonLinkConverter(context, personEntry);\n * ```\n */\nexport function basePersonLinkConverter(\n context: ConverterContext,\n entry: Entry<BasePersonSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'person') {\n throw new Error(`Invalid content type: expected \"person\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.name, // Person has no cmsLabel, use name field\n title: fields.name,\n featuredImage: fields.media, // Person uses 'media' not 'featuredImage'\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculatePersonHref(fields.slug),\n );\n}\n\n/**\n * Base converter for Person entries to IPerson type\n * Used when a complete person object with bio and content is needed\n *\n * @param context - Converter context containing assets, includes, and resolvers\n * @param entry - Contentful person entry to convert\n * @returns IPerson object representing the complete person\n *\n * @example\n * ```ts\n * const person = basePersonConverter(context, personEntry);\n * ```\n */\nexport function basePersonConverter(\n context: ConverterContext,\n entry: Entry<BasePersonSkeleton, DefaultChainModifier, string>,\n): IPerson {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'person') {\n throw new Error(`Invalid content type: expected \"person\", got \"${sys.contentType.sys.id}\"`);\n }\n const {\n slug,\n hidden,\n indexed,\n backgroundColour,\n textColour,\n name,\n description,\n media,\n jobTitle,\n phoneNumber,\n emailAddress,\n location,\n linkedIn,\n bio: bioField,\n } = fields;\n\n return {\n type: 'Person',\n id: sys.id,\n slug,\n title: makeContentfulTitle(name, sys.id),\n description: description ?? `Description for ${sys.id}`,\n featuredImage: lookupAsset(context, media), // Person uses 'media' not 'featuredImage'\n backgroundColour,\n textColour,\n indexed,\n hidden,\n href: calculatePersonHref(slug),\n jobTitle: jobTitle ?? null,\n phoneNumber: phoneNumber ?? null,\n emailAddress: emailAddress ?? null,\n location: location ?? null,\n linkedIn: linkedIn ?? null,\n bio: resolveRichTextDocument(context, bioField) ?? null,\n };\n}\n","import type { IBaseArticle, IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseArticleSkeleton } from '../baseTypes/baseArticle';\nimport type { BaseArticleTypeSkeleton } from '../baseTypes/baseArticleType';\nimport {\n addPositionMetadata,\n type ConverterContext,\n createInternalLink,\n lookupAsset,\n makeContentfulDescription,\n makeContentfulTitle,\n} from './helpers';\nimport { resolveLink, resolvePageContent } from './resolver';\nimport { resolveTemplate } from './template';\n\n/**\n * Base converter for Contentful Article entries to IArticle type\n *\n * This is a minimal implementation that can be extended using\n * the functional composition pattern.\n *\n * @param entry - Contentful entry to convert\n * @returns IArticle object\n *\n * @example\n * ```ts\n * const article = baseArticleConverter(contentfulEntry);\n * ```\n */\n\nexport function baseArticleConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleSkeleton, DefaultChainModifier, string>,\n): IBaseArticle {\n const { sys, fields } = entry;\n const {\n slug,\n title,\n description,\n featuredImage,\n tags,\n content,\n template: templateLink,\n topContent: topContentLinks,\n bottomContent: bottomContentLinks,\n articleType,\n ...simpleFields\n } = fields;\n const articleTypeLink = resolveLink(context, articleType);\n\n // Resolve template (if exists)\n const template = templateLink ? resolveTemplate(context, templateLink) : null;\n\n // Resolve all content sections\n const topContent = topContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const articleContent = content?.map((c) => resolvePageContent(context, c)) ?? [];\n const bottomContent = bottomContentLinks?.map((c) => resolvePageContent(context, c)) ?? [];\n const preContent = template?.preContent ?? [];\n const postContent = template?.postContent ?? [];\n\n // Merge in correct order and add position metadata\n const contents = addPositionMetadata([\n ...topContent,\n ...preContent,\n ...articleContent,\n ...postContent,\n ...bottomContent,\n ]);\n\n const article: IBaseArticle = {\n type: 'Article',\n id: sys.id,\n slug,\n title: makeContentfulTitle(title, sys.id),\n description: makeContentfulDescription(description, sys.id),\n featuredImage: lookupAsset(context, featuredImage),\n articleType: articleTypeLink,\n tags: tags?.map((tag) => resolveLink(context, tag)),\n contents,\n ...simpleFields,\n // Note: summary field exists in Contentful but is not part of IArticle interface\n // Keeping it in simpleFields for potential future use\n menu: template?.menu,\n footer: template?.footer,\n };\n return article;\n}\n\nexport function calculateArticleTypeHref(slug: string) {\n return `/${slug}/`;\n}\n\nexport function calculateArticleHref(articleTypeSlug: string, slug: string) {\n return `${calculateArticleTypeHref(articleTypeSlug)}${slug}/`;\n}\n\nexport function baseArticleLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'article') {\n throw new Error(`Invalid content type: expected \"article\", got \"${sys.contentType.sys.id}\"`);\n }\n\n const articleTypeLink = resolveLink(context, fields.articleType);\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.title,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateArticleHref(articleTypeLink.slug, fields.slug),\n { tags: fields.tags?.map((tag) => resolveLink(context, tag)) },\n );\n}\n\nexport function baseArticleTypeLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseArticleTypeSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'articleType') {\n throw new Error(\n `Invalid content type: expected \"articleType\", got \"${sys.contentType.sys.id}\"`,\n );\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.name,\n title: fields.name,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateArticleTypeHref(fields.slug),\n );\n}\n","import type { ILinkProps, INavigationItem } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseNavigationItemSkeleton } from '../baseTypes/baseNavigationItem';\nimport { type ConverterContext, lookupAsset, makeContentfulTitle } from './helpers';\nimport { resolveLink, resolveNavigationItem } from './resolver';\n\nfunction createLink(\n context: ConverterContext,\n entry: Entry<BaseNavigationItemSkeleton, DefaultChainModifier, string>,\n): ILinkProps | undefined {\n const {\n sys: { id },\n fields,\n } = entry;\n const { title, link, internal, icon, useTitle, ...otherFields } = fields;\n\n if (link) {\n return {\n type: 'External link',\n id,\n href: link,\n icon: lookupAsset(context, icon),\n name: makeContentfulTitle(title, id),\n ...(useTitle && { text: title }),\n ...otherFields,\n };\n }\n if (internal) {\n const resolved = resolveLink(context, internal);\n return resolved;\n }\n return undefined;\n}\n\nexport function baseNavigationItemConverter(\n context: ConverterContext,\n entry: Entry<BaseNavigationItemSkeleton, DefaultChainModifier, string>,\n): INavigationItem {\n const { sys, fields } = entry;\n\n const { navigationItems } = fields;\n\n const link = createLink(context, entry);\n\n const resolvedNavigationItems = navigationItems\n ?.map((item) => resolveNavigationItem(context, item))\n .filter((item): item is INavigationItem => item !== undefined);\n\n return {\n id: sys.id,\n link,\n entries: resolvedNavigationItems,\n };\n}\n","import type { IInternalLink } from '@se-studio/core-data-types';\nimport type { Entry } from 'contentful';\nimport type { DefaultChainModifier } from '../api';\nimport type { BaseTagSkeleton } from '../baseTypes/baseTag';\nimport { type ConverterContext, createInternalLink } from './helpers';\n\nexport function calculateTagHref(slug: string) {\n return `/tag/${slug}/`;\n}\n\nexport function baseTagLinkConverter(\n context: ConverterContext,\n entry: Entry<BaseTagSkeleton, DefaultChainModifier, string>,\n): IInternalLink {\n const { sys, fields } = entry;\n if (sys.contentType.sys.id !== 'tag') {\n throw new Error(`Invalid content type: expected \"tag\", got \"${sys.contentType.sys.id}\"`);\n }\n\n return createInternalLink(\n sys.id,\n {\n cmsLabel: fields.cmsLabel,\n title: fields.name,\n featuredImage: fields.featuredImage,\n backgroundColour: fields.backgroundColour,\n textColour: fields.textColour,\n indexed: fields.indexed,\n hidden: fields.hidden,\n slug: fields.slug,\n },\n context,\n calculateTagHref(fields.slug),\n );\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: Any ok for now! */\nimport type { Document } from '@contentful/rich-text-types';\nimport type {\n IBaseArticle,\n IBasePage,\n IInternalLink,\n INavigation,\n INavigationItem,\n IPerson,\n IVisual,\n} from '@se-studio/core-data-types';\nimport type { Entry, EntrySkeletonType } from 'contentful';\nimport type { BaseArticleSkeleton } from './baseTypes/baseArticle';\nimport type { BasePageSkeleton } from './baseTypes/basePage';\nimport { type ContentfulResponse, getContentfulClient } from './client';\nimport { basePageConverter } from './converters';\nimport {\n baseArticleConverter,\n baseArticleLinkConverter,\n baseArticleTypeLinkConverter,\n} from './converters/article';\nimport { convertAssetToVisual } from './converters/asset';\nimport { baseCollectionConverter } from './converters/collection';\nimport { baseComponentConverter } from './converters/component';\nimport type {\n ContentResolverFunction,\n ContentResolverMap,\n ConverterContext,\n LinkResolverFunction,\n LinkResolverMap,\n} from './converters/helpers';\nimport { baseLinkConverter } from './converters/link';\nimport { baseNavigationItemConverter } from './converters/navigationItem';\nimport { basePageLinkConverter, basePageVariantLinkConverter } from './converters/page';\nimport { basePersonLinkConverter } from './converters/person';\nimport { baseTagLinkConverter } from './converters/tag';\nimport type { ContentfulConfig, FetchOptions } from './types';\nimport { withRetry } from './utils';\n\nexport type DefaultChainModifier = 'WITHOUT_LINK_RESOLUTION';\n\nfunction convertAllAssets(\n response: ContentfulResponse<any>,\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n): Map<string, IVisual> {\n const visuals = new Map<string, IVisual>();\n const assets = response.includes?.Asset;\n if (assets && assets.length > 0) {\n for (const asset of assets) {\n const visual = convertAssetToVisual(context, asset);\n if (visual) {\n visuals.set(visual.id, visual);\n }\n }\n }\n return visuals;\n}\n\nexport type ResolvedEntry =\n | IBasePage\n | IBaseArticle\n | INavigation\n | INavigationItem\n | IInternalLink\n | unknown // PageContent - will be narrowed at project level\n | IPerson;\n\nexport type PossibleResolvedEntry = {\n id: string;\n type: string;\n entry: Entry<EntrySkeletonType, DefaultChainModifier, string>;\n resolved?: ResolvedEntry;\n};\n\nfunction convertAllIncludes(response: ContentfulResponse<any>): Map<string, PossibleResolvedEntry> {\n const includes = new Map<string, PossibleResolvedEntry>();\n const entries = [...response.items, ...(response.includes?.Entry || [])];\n\n if (entries && entries.length > 0) {\n for (const entry of entries) {\n if (entry?.sys && entry.fields) {\n includes.set(entry.sys.id, {\n id: entry.sys.id,\n type: entry.sys.contentType.sys.id,\n entry,\n });\n }\n }\n }\n return includes;\n}\n\nexport type Converter<TEntry extends EntrySkeletonType, TResult> = (\n entry: Entry<TEntry, DefaultChainModifier, string>,\n includes: Map<string, PossibleResolvedEntry>,\n assets: Map<string, IVisual>,\n) => TResult;\n\n/**\n * Fetches a page from Contentful by slug\n *\n * @param config - Contentful configuration\n * @param slug - Page slug to fetch\n * @param options - Fetch options (locale, preview, caching, etc.)\n * @param converter - Optional custom converter function\n * @returns Promise resolving to IPage or null if not found\n *\n * @example\n * ```ts\n * const page = await contentfulPageRest(\n * {\n * spaceId: process.env.CONTENTFUL_SPACE_ID!,\n * accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,\n * },\n * 'home',\n * {\n * locale: 'en-US',\n * cache: {\n * tags: ['home-page'],\n * revalidate: 3600\n * }\n * }\n * );\n * ```\n */\nexport async function contentfulPageRest(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n config: ContentfulConfig,\n slug: string,\n options?: FetchOptions,\n): Promise<IBasePage | null> {\n const client = getContentfulClient(config, options?.preview);\n\n const fetchFn = async () => {\n const response = await client.getEntries<BasePageSkeleton>(\n {\n content_type: 'page',\n 'fields.slug': slug,\n include: 10,\n locale: options?.locale,\n limit: 1,\n },\n options,\n );\n\n const pageEntry = response.items[0];\n if (!pageEntry || !pageEntry.fields) {\n return null;\n }\n\n const assets = convertAllAssets(response, context);\n const includes = convertAllIncludes(response);\n const fullContext: ConverterContext = {\n ...context,\n includes,\n assets,\n };\n\n const converted = fullContext.pageResolver(fullContext, pageEntry);\n\n return converted;\n };\n\n // Apply retry logic if configured\n if (options?.retry) {\n return await withRetry(fetchFn, options.retry);\n }\n\n return await fetchFn();\n}\n\nexport interface IContentfulRichText {\n json: Document;\n customStyles?: ReadonlyArray<string> | null;\n}\n\nexport function createBaseConverterContext(): Omit<ConverterContext, 'includes' | 'assets'> {\n const linkResolver: LinkResolverMap = new Map();\n linkResolver.set('page', basePageLinkConverter as LinkResolverFunction);\n linkResolver.set('article', baseArticleLinkConverter as LinkResolverFunction);\n linkResolver.set('articleType', baseArticleTypeLinkConverter as LinkResolverFunction);\n linkResolver.set('tag', baseTagLinkConverter as LinkResolverFunction);\n linkResolver.set('person', basePersonLinkConverter as LinkResolverFunction);\n linkResolver.set('pageVariant', basePageVariantLinkConverter as LinkResolverFunction);\n linkResolver.set('link', baseLinkConverter as LinkResolverFunction);\n\n const contentResolver: ContentResolverMap = new Map();\n contentResolver.set('collection', baseCollectionConverter as ContentResolverFunction);\n contentResolver.set('component', baseComponentConverter as ContentResolverFunction);\n contentResolver.set(\n 'externalComponent',\n baseComponentConverter as unknown as ContentResolverFunction,\n );\n\n return {\n pageResolver: basePageConverter,\n navigationItemResolver: baseNavigationItemConverter,\n articleResolver: baseArticleConverter,\n componentResolver: baseComponentConverter,\n collectionResolver: baseCollectionConverter,\n linkResolver,\n contentResolver,\n videoPrefix: '',\n };\n}\n\nexport async function contentfulArticleRest(\n context: Omit<ConverterContext, 'includes' | 'assets'>,\n config: ContentfulConfig,\n slug: string,\n articleTypeSlug: string,\n options?: FetchOptions,\n): Promise<IBaseArticle | null> {\n const client = getContentfulClient(config, options?.preview);\n\n const fetchFn = async () => {\n const response = await client.getEntries<BaseArticleSkeleton>(\n {\n content_type: 'article',\n 'fields.slug': slug,\n 'fields.articleType.sys.contentType.sys.id': 'articleType',\n 'fields.articleType.fields.slug': articleTypeSlug,\n include: 10,\n locale: options?.locale,\n limit: 1,\n },\n options,\n );\n\n const articleEntry = response.items[0];\n if (!articleEntry || !articleEntry.fields) {\n return null;\n }\n\n const assets = convertAllAssets(response, context);\n const includes = convertAllIncludes(response);\n const fullContext: ConverterContext = {\n ...context,\n includes,\n assets,\n };\n\n const converted = fullContext.articleResolver(fullContext, articleEntry);\n return converted;\n };\n\n // Apply retry logic if configured\n if (options?.retry) {\n return await withRetry(fetchFn, options.retry);\n }\n\n return await fetchFn();\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/contentful-rest-api",
3
- "version": "0.1.1",
3
+ "version": "1.0.0-next.0",
4
4
  "description": "Type-safe Contentful REST API client with caching and rate limiting for Next.js applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "@contentful/rich-text-types": "^17.2.5",
33
33
  "contentful": "^11.8.11",
34
- "@se-studio/core-data-types": "0.1.1"
34
+ "@se-studio/core-data-types": "1.0.0-next.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@biomejs/biome": "^2.3.4",