@utilsy/cms-nextjs 0.4.0 → 0.6.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/README.md +53 -2
- package/dist/{client-I3rZOjS6.d.cts → client-awWyf-VL.d.cts} +9 -0
- package/dist/{client-I3rZOjS6.d.ts → client-awWyf-VL.d.ts} +9 -0
- package/dist/index.cjs +107 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -3
- package/dist/index.d.ts +109 -3
- package/dist/index.js +96 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +26 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +12 -2
- package/dist/react.d.ts +12 -2
- package/dist/react.js +26 -1
- package/dist/react.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -284,6 +284,41 @@ For local dev or gateway-only deployments, always set `siteId` in the client con
|
|
|
284
284
|
- `filters` are exact matches on `data.<field>` (JSON query param). Example: `{ category: "news" }`.
|
|
285
285
|
- Use `contentTypeApiId` (kebab-case slug from CMS), not the Mongo content type id.
|
|
286
286
|
|
|
287
|
+
### COMPONENT and DYNAMIC_ZONE fields
|
|
288
|
+
|
|
289
|
+
Published entry `data` may include nested structures from the CMS builder:
|
|
290
|
+
|
|
291
|
+
| Field type | Shape in `entry.data` |
|
|
292
|
+
|------------|------------------------|
|
|
293
|
+
| **COMPONENT** (single) | `{ title: "…", … }` |
|
|
294
|
+
| **COMPONENT** (repeatable) | `[{ … }, { … }]` |
|
|
295
|
+
| **DYNAMIC_ZONE** | `[{ __component: "<apiId>", …fields }, …]` |
|
|
296
|
+
|
|
297
|
+
Helpers (no extra API calls):
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
import {
|
|
301
|
+
getComponentItems,
|
|
302
|
+
getDynamicZoneBlocks,
|
|
303
|
+
filterDynamicZoneByComponent,
|
|
304
|
+
parseContentTypeFields,
|
|
305
|
+
} from "@utilsy/cms-nextjs";
|
|
306
|
+
|
|
307
|
+
const entry = await cms.content.getMappedEntry("landing", "home");
|
|
308
|
+
if (!entry) return;
|
|
309
|
+
|
|
310
|
+
const slides = getComponentItems(entry, "slides");
|
|
311
|
+
const ctas = filterDynamicZoneByComponent(
|
|
312
|
+
getDynamicZoneBlocks(entry, "blocks"),
|
|
313
|
+
"cta",
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
// Optional: inspect schema from populated contentType on the entry DTO
|
|
317
|
+
const fields = parseContentTypeFields(entry.contentType?.fields);
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Types: `FieldType`, `ContentTypeField`, `DynamicZoneBlock`, `ContentTypeCategory`.
|
|
321
|
+
|
|
287
322
|
## API reference
|
|
288
323
|
|
|
289
324
|
### Client (`createCmsClient`)
|
|
@@ -312,10 +347,25 @@ For local dev or gateway-only deployments, always set `siteId` in the client con
|
|
|
312
347
|
| `content.getEntry(contentTypeApiId, idOrSlug, init?)` | Single raw DTO |
|
|
313
348
|
| `content.listMappedEntries(...)` | List + `mapCmsEntryToContentEntry` |
|
|
314
349
|
| `content.getMappedEntry(...)` | Single mapped `ContentEntry` |
|
|
350
|
+
| `content.getSingleMappedEntry(...)` | First mapped entry for SINGLE types (`limit=1`) |
|
|
351
|
+
|
|
352
|
+
Query params for `listEntries` / `listMappedEntries`: `page`, `limit`, `search`, `sort`, `order`, `filters` (object). For **SINGLE** content types the public API caps `limit` at 1 and may include `category: "SINGLE"` and `maxEntries: 1` in the list response.
|
|
353
|
+
|
|
354
|
+
#### Single content types
|
|
355
|
+
|
|
356
|
+
Use a CMS content type with category **SINGLE** for one document per site (homepage settings, global SEO, etc.). Admin creates the type and edits the auto-created draft on the **Content** tab.
|
|
357
|
+
|
|
358
|
+
```tsx
|
|
359
|
+
// Prefer for singleton types — no entry id/slug required
|
|
360
|
+
const settings = await client.content.getSingleMappedEntry("site-settings");
|
|
361
|
+
|
|
362
|
+
// Or with React
|
|
363
|
+
const { entry, loading } = useSingleContentEntry("site-settings");
|
|
364
|
+
```
|
|
315
365
|
|
|
316
|
-
|
|
366
|
+
`listEntries` / `listMappedEntries` still work; pass `limit: 1` or use `getSingleMappedEntry`.
|
|
317
367
|
|
|
318
|
-
Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`.
|
|
368
|
+
Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`, `getComponentItems`, `getDynamicZoneBlocks`, `filterDynamicZoneByComponent`, `parseContentTypeFields`.
|
|
319
369
|
|
|
320
370
|
#### Leads
|
|
321
371
|
|
|
@@ -353,6 +403,7 @@ Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`.
|
|
|
353
403
|
| `useBlogComments` | List + submit comments |
|
|
354
404
|
| `useContentEntries` | List mapped entries by content type |
|
|
355
405
|
| `useContentEntry` | Single mapped entry by id or slug |
|
|
406
|
+
| `useSingleContentEntry` | Mapped entry for SINGLE types (no id/slug) |
|
|
356
407
|
| `useSubmitLead` | Submit lead from client (prefer Server Action for forms) |
|
|
357
408
|
| `useNewsletterSubscribe` | Subscribe from client (prefer Server Action) |
|
|
358
409
|
| `useNewsletterUnsubscribe` | Unsubscribe by token or email |
|
|
@@ -181,6 +181,8 @@ type CmsContentTypeDto = {
|
|
|
181
181
|
id?: string;
|
|
182
182
|
name?: string;
|
|
183
183
|
apiId?: string;
|
|
184
|
+
/** COLLECTION (many entries), SINGLE (one entry), or COMPONENT (embedded schema only). */
|
|
185
|
+
category?: string;
|
|
184
186
|
fields?: unknown[];
|
|
185
187
|
status?: string;
|
|
186
188
|
};
|
|
@@ -199,11 +201,15 @@ type CmsContentEntriesPage = {
|
|
|
199
201
|
message?: string;
|
|
200
202
|
docs: CmsContentEntryDto[];
|
|
201
203
|
totalDocs: number;
|
|
204
|
+
/** Present when the content type category is SINGLE (at most one entry per site). */
|
|
205
|
+
category?: string;
|
|
206
|
+
maxEntries?: number;
|
|
202
207
|
};
|
|
203
208
|
type ContentTypeMeta = {
|
|
204
209
|
id: string;
|
|
205
210
|
name: string;
|
|
206
211
|
apiId: string;
|
|
212
|
+
category?: string;
|
|
207
213
|
fields?: unknown[];
|
|
208
214
|
status?: string;
|
|
209
215
|
};
|
|
@@ -219,6 +225,8 @@ type ContentEntry = {
|
|
|
219
225
|
type MappedContentEntriesPage = {
|
|
220
226
|
entries: ContentEntry[];
|
|
221
227
|
totalDocs: number;
|
|
228
|
+
category?: string;
|
|
229
|
+
maxEntries?: number;
|
|
222
230
|
};
|
|
223
231
|
|
|
224
232
|
type ContentRequestContext = RequestContext & {
|
|
@@ -229,6 +237,7 @@ declare function createContentApi(ctx: ContentRequestContext): {
|
|
|
229
237
|
getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<CmsContentEntryDto | null>;
|
|
230
238
|
listMappedEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<MappedContentEntriesPage | null>;
|
|
231
239
|
getMappedEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
240
|
+
getSingleMappedEntry(contentTypeApiId: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
232
241
|
};
|
|
233
242
|
type ContentApi = ReturnType<typeof createContentApi>;
|
|
234
243
|
|
|
@@ -181,6 +181,8 @@ type CmsContentTypeDto = {
|
|
|
181
181
|
id?: string;
|
|
182
182
|
name?: string;
|
|
183
183
|
apiId?: string;
|
|
184
|
+
/** COLLECTION (many entries), SINGLE (one entry), or COMPONENT (embedded schema only). */
|
|
185
|
+
category?: string;
|
|
184
186
|
fields?: unknown[];
|
|
185
187
|
status?: string;
|
|
186
188
|
};
|
|
@@ -199,11 +201,15 @@ type CmsContentEntriesPage = {
|
|
|
199
201
|
message?: string;
|
|
200
202
|
docs: CmsContentEntryDto[];
|
|
201
203
|
totalDocs: number;
|
|
204
|
+
/** Present when the content type category is SINGLE (at most one entry per site). */
|
|
205
|
+
category?: string;
|
|
206
|
+
maxEntries?: number;
|
|
202
207
|
};
|
|
203
208
|
type ContentTypeMeta = {
|
|
204
209
|
id: string;
|
|
205
210
|
name: string;
|
|
206
211
|
apiId: string;
|
|
212
|
+
category?: string;
|
|
207
213
|
fields?: unknown[];
|
|
208
214
|
status?: string;
|
|
209
215
|
};
|
|
@@ -219,6 +225,8 @@ type ContentEntry = {
|
|
|
219
225
|
type MappedContentEntriesPage = {
|
|
220
226
|
entries: ContentEntry[];
|
|
221
227
|
totalDocs: number;
|
|
228
|
+
category?: string;
|
|
229
|
+
maxEntries?: number;
|
|
222
230
|
};
|
|
223
231
|
|
|
224
232
|
type ContentRequestContext = RequestContext & {
|
|
@@ -229,6 +237,7 @@ declare function createContentApi(ctx: ContentRequestContext): {
|
|
|
229
237
|
getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<CmsContentEntryDto | null>;
|
|
230
238
|
listMappedEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<MappedContentEntriesPage | null>;
|
|
231
239
|
getMappedEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
240
|
+
getSingleMappedEntry(contentTypeApiId: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
232
241
|
};
|
|
233
242
|
type ContentApi = ReturnType<typeof createContentApi>;
|
|
234
243
|
|
package/dist/index.cjs
CHANGED
|
@@ -239,6 +239,7 @@ function mapContentType(dto) {
|
|
|
239
239
|
id,
|
|
240
240
|
name: dto.name ?? "",
|
|
241
241
|
apiId: dto.apiId ?? "",
|
|
242
|
+
category: dto.category,
|
|
242
243
|
fields: dto.fields,
|
|
243
244
|
status: dto.status
|
|
244
245
|
};
|
|
@@ -289,13 +290,23 @@ function createContentApi(ctx) {
|
|
|
289
290
|
if (!page?.docs) return null;
|
|
290
291
|
return {
|
|
291
292
|
entries: page.docs.map(mapCmsEntryToContentEntry),
|
|
292
|
-
totalDocs: page.totalDocs
|
|
293
|
+
totalDocs: page.totalDocs,
|
|
294
|
+
...page.category ? { category: page.category } : {},
|
|
295
|
+
...page.maxEntries != null ? { maxEntries: page.maxEntries } : {}
|
|
293
296
|
};
|
|
294
297
|
},
|
|
295
298
|
async getMappedEntry(contentTypeApiId, idOrSlug, init) {
|
|
296
299
|
const dto = await this.getEntry(contentTypeApiId, idOrSlug, init);
|
|
297
300
|
if (!dto) return null;
|
|
298
301
|
return mapCmsEntryToContentEntry(dto);
|
|
302
|
+
},
|
|
303
|
+
async getSingleMappedEntry(contentTypeApiId, init) {
|
|
304
|
+
const page = await this.listMappedEntries(
|
|
305
|
+
contentTypeApiId,
|
|
306
|
+
{ limit: 1, page: 1 },
|
|
307
|
+
init
|
|
308
|
+
);
|
|
309
|
+
return page?.entries?.[0] ?? null;
|
|
299
310
|
}
|
|
300
311
|
};
|
|
301
312
|
}
|
|
@@ -380,12 +391,107 @@ function createCmsClient(config) {
|
|
|
380
391
|
};
|
|
381
392
|
}
|
|
382
393
|
|
|
394
|
+
// src/content/field-types.ts
|
|
395
|
+
var ContentTypeCategory = {
|
|
396
|
+
COLLECTION: "COLLECTION",
|
|
397
|
+
SINGLE: "SINGLE",
|
|
398
|
+
COMPONENT: "COMPONENT"
|
|
399
|
+
};
|
|
400
|
+
var FieldType = {
|
|
401
|
+
TEXT: "TEXT",
|
|
402
|
+
TEXTAREA: "TEXTAREA",
|
|
403
|
+
RICHTEXT: "RICHTEXT",
|
|
404
|
+
NUMBER: "NUMBER",
|
|
405
|
+
BOOLEAN: "BOOLEAN",
|
|
406
|
+
DATE: "DATE",
|
|
407
|
+
DATETIME: "DATETIME",
|
|
408
|
+
TIME: "TIME",
|
|
409
|
+
EMAIL: "EMAIL",
|
|
410
|
+
URL: "URL",
|
|
411
|
+
MEDIA: "MEDIA",
|
|
412
|
+
RELATION: "RELATION",
|
|
413
|
+
JSON: "JSON",
|
|
414
|
+
ENUM: "ENUM",
|
|
415
|
+
PHONE: "PHONE",
|
|
416
|
+
WEEKDAY: "WEEKDAY",
|
|
417
|
+
COMPONENT: "COMPONENT",
|
|
418
|
+
DYNAMIC_ZONE: "DYNAMIC_ZONE",
|
|
419
|
+
PAGE_EDITOR: "PAGE_EDITOR"
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// src/content/structured-data.ts
|
|
423
|
+
function isPlainObject(value) {
|
|
424
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
425
|
+
}
|
|
426
|
+
function parseContentTypeFields(raw) {
|
|
427
|
+
if (!Array.isArray(raw)) return [];
|
|
428
|
+
const out = [];
|
|
429
|
+
for (const item of raw) {
|
|
430
|
+
if (!isPlainObject(item)) continue;
|
|
431
|
+
const name = item.name;
|
|
432
|
+
const type = item.type;
|
|
433
|
+
if (typeof name !== "string" || !name.trim()) continue;
|
|
434
|
+
if (typeof type !== "string" || !type.trim()) continue;
|
|
435
|
+
out.push(item);
|
|
436
|
+
}
|
|
437
|
+
return out;
|
|
438
|
+
}
|
|
439
|
+
function findContentTypeField(fields, fieldName) {
|
|
440
|
+
return fields?.find((f) => f.name === fieldName);
|
|
441
|
+
}
|
|
442
|
+
function getEntryFieldValue(entry, fieldName) {
|
|
443
|
+
return entry.data[fieldName];
|
|
444
|
+
}
|
|
445
|
+
function getComponentItems(entry, fieldName) {
|
|
446
|
+
const value = entry.data[fieldName];
|
|
447
|
+
if (value == null) return [];
|
|
448
|
+
if (Array.isArray(value)) {
|
|
449
|
+
return value.filter(isPlainObject);
|
|
450
|
+
}
|
|
451
|
+
if (isPlainObject(value)) {
|
|
452
|
+
return [value];
|
|
453
|
+
}
|
|
454
|
+
return [];
|
|
455
|
+
}
|
|
456
|
+
function getComponentItem(entry, fieldName) {
|
|
457
|
+
const items = getComponentItems(entry, fieldName);
|
|
458
|
+
return items[0];
|
|
459
|
+
}
|
|
460
|
+
function getDynamicZoneBlocks(entry, fieldName) {
|
|
461
|
+
const value = entry.data[fieldName];
|
|
462
|
+
if (!Array.isArray(value)) return [];
|
|
463
|
+
return value.filter(
|
|
464
|
+
(item) => isPlainObject(item) && typeof item.__component === "string" && item.__component.length > 0
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
function filterDynamicZoneByComponent(blocks, componentApiId) {
|
|
468
|
+
return blocks.filter((b) => b.__component === componentApiId);
|
|
469
|
+
}
|
|
470
|
+
function isRepeatableComponentField(field) {
|
|
471
|
+
return field.type === FieldType.COMPONENT && field.component?.repeatable === true;
|
|
472
|
+
}
|
|
473
|
+
function isDynamicZoneField(field) {
|
|
474
|
+
return field.type === FieldType.DYNAMIC_ZONE;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
exports.ContentTypeCategory = ContentTypeCategory;
|
|
478
|
+
exports.FieldType = FieldType;
|
|
383
479
|
exports.createCmsClient = createCmsClient;
|
|
480
|
+
exports.filterDynamicZoneByComponent = filterDynamicZoneByComponent;
|
|
481
|
+
exports.findContentTypeField = findContentTypeField;
|
|
482
|
+
exports.getComponentItem = getComponentItem;
|
|
483
|
+
exports.getComponentItems = getComponentItems;
|
|
484
|
+
exports.getDynamicZoneBlocks = getDynamicZoneBlocks;
|
|
485
|
+
exports.getEntryFieldValue = getEntryFieldValue;
|
|
486
|
+
exports.isDynamicZoneField = isDynamicZoneField;
|
|
487
|
+
exports.isPlainObject = isPlainObject;
|
|
488
|
+
exports.isRepeatableComponentField = isRepeatableComponentField;
|
|
384
489
|
exports.mapCmsCategoryToBlogCategory = mapCmsCategoryToBlogCategory;
|
|
385
490
|
exports.mapCmsCommentToBlogComment = mapCmsCommentToBlogComment;
|
|
386
491
|
exports.mapCmsEntryToContentEntry = mapCmsEntryToContentEntry;
|
|
387
492
|
exports.mapCmsPostToBlogPost = mapCmsPostToBlogPost;
|
|
388
493
|
exports.mediaUrl = mediaUrl;
|
|
494
|
+
exports.parseContentTypeFields = parseContentTypeFields;
|
|
389
495
|
exports.serializeContentFilters = serializeContentFilters;
|
|
390
496
|
//# sourceMappingURL=index.cjs.map
|
|
391
497
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http.ts","../src/blog/mappers.ts","../src/blog/endpoints.ts","../src/content/filters.ts","../src/content/mappers.ts","../src/content/endpoints.ts","../src/leads/endpoints.ts","../src/newsletter/endpoints.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CmsApiResponse, FetchRequestInit } from \"./types.js\";\n\nexport type RequestContext = {\n baseUrl: string;\n siteId?: string;\n fetchFn: typeof fetch;\n defaultHeaders: Record<string, string>;\n};\n\nexport function appendSiteId(path: string, siteId?: string): string {\n if (!siteId) return path;\n const sep = path.includes(\"?\") ? \"&\" : \"?\";\n return `${path}${sep}siteId=${encodeURIComponent(siteId)}`;\n}\n\nexport function buildPublicUrl(ctx: RequestContext, path: string): string {\n return `${ctx.baseUrl}${appendSiteId(path, ctx.siteId)}`;\n}\n\nexport async function unwrapResponse<T>(res: Response): Promise<T> {\n const json = (await res.json()) as CmsApiResponse<T> & Record<string, unknown>;\n if (!res.ok) {\n const message =\n (json as CmsApiResponse<T>).message ??\n (`Request failed (${res.status})` as string);\n throw new Error(message);\n }\n const hasEntryIdentity = \"_id\" in json || \"id\" in json;\n const hasListDocs = \"docs\" in json && Array.isArray(json.docs);\n const isDataEnvelope =\n json.data !== undefined &&\n \"message\" in json &&\n !hasListDocs &&\n !hasEntryIdentity;\n\n if (isDataEnvelope) {\n return json.data as T;\n }\n return json as T;\n}\n\n/** @deprecated Use unwrapResponse — kept as alias for blog module */\nexport const unwrap = unwrapResponse;\n\nexport async function publicGet<T>(\n ctx: RequestContext,\n path: string,\n init?: FetchRequestInit,\n): Promise<T> {\n const res = await ctx.fetchFn(buildPublicUrl(ctx, path), {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n });\n return unwrapResponse<T>(res);\n}\n\nexport async function publicGetNullable<T>(\n ctx: RequestContext,\n path: string,\n init?: FetchRequestInit,\n): Promise<T | null> {\n try {\n return await publicGet<T>(ctx, path, init);\n } catch {\n return null;\n }\n}\n\nexport async function publicPost<T>(\n ctx: RequestContext,\n path: string,\n body: unknown,\n init?: FetchRequestInit,\n): Promise<T> {\n const res = await ctx.fetchFn(buildPublicUrl(ctx, path), {\n ...init,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n body: JSON.stringify(body),\n });\n return unwrapResponse<T>(res);\n}\n","import type {\n BlogCategory,\n BlogComment,\n BlogPost,\n CmsBlogCategoryDto,\n CmsBlogCommentDto,\n CmsBlogPostDto,\n} from \"./types.js\";\n\nexport function mediaUrl(value: unknown): string | undefined {\n if (!value) return undefined;\n if (typeof value === \"string\") return value;\n if (typeof value === \"object\" && value !== null && \"url\" in value) {\n return String((value as { url: string }).url);\n }\n return undefined;\n}\n\nexport function mapCmsPostToBlogPost(dto: CmsBlogPostDto): BlogPost {\n const data = dto.data ?? {};\n const title = String(dto.title ?? data.title ?? \"Untitled\");\n const slug = String(dto.slug ?? data.slug ?? dto.id);\n const excerpt = String(dto.excerpt ?? data.excerpt ?? \"\");\n const body = String(dto.content ?? data.content ?? \"\");\n const tags = dto.tags ?? (Array.isArray(data.tags) ? (data.tags as string[]) : []);\n const category = dto.categories?.[0]?.name ?? \"General\";\n const publishedAt = String(\n dto.published_at ?? data.published_at ?? dto.createdAt ?? new Date().toISOString(),\n );\n const authorName = String(data.author_name ?? \"Editor\");\n const imageSrc = mediaUrl(dto.featured_image ?? data.featured_image);\n\n const wordCount = body.replace(/<[^>]+>/g, \" \").split(/\\s+/).filter(Boolean).length;\n\n return {\n postId: dto.id,\n slug,\n title,\n excerpt,\n category,\n tags,\n publishedAt,\n readMinutes: Math.max(1, Math.ceil(wordCount / 200)),\n author: {\n name: authorName,\n avatarInitials: authorName.slice(0, 2).toUpperCase(),\n },\n imageSrc,\n imageAlt: title,\n body,\n stats: dto.stats,\n };\n}\n\nexport function mapCmsCommentToBlogComment(dto: CmsBlogCommentDto): BlogComment {\n return {\n id: dto.id,\n name: dto.name,\n message: dto.message,\n avatarUrl: dto.avatarUrl,\n postedAt: dto.postedAt,\n replies: (dto.replyComment ?? []).map((r) => ({\n id: r.id,\n userId: r.userId,\n message: r.message,\n postedAt: r.postedAt,\n })),\n };\n}\n\nexport function mapCmsCategoryToBlogCategory(dto: CmsBlogCategoryDto): BlogCategory {\n return {\n id: dto.id,\n name: dto.name,\n slug: dto.slug,\n description: dto.description,\n sortOrder: dto.sortOrder,\n };\n}\n","import {\n appendSiteId,\n buildPublicUrl,\n publicGetNullable,\n unwrapResponse,\n type RequestContext,\n} from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport {\n mapCmsCategoryToBlogCategory,\n mapCmsCommentToBlogComment,\n mapCmsPostToBlogPost,\n} from \"./mappers.js\";\nimport type {\n BlogCategory,\n BlogComment,\n BlogEngagement,\n BlogLikeResult,\n BlogPost,\n CmsBlogCategoryDto,\n CmsBlogCommentDto,\n CmsBlogPostDto,\n CmsBlogPostsPage,\n CreateBlogCommentInput,\n CreateBlogCommentResult,\n ListBlogPostsQuery,\n} from \"./types.js\";\n\nexport type BlogRequestContext = RequestContext & {\n blogBasePath: string;\n};\n\nexport function createBlogApi(ctx: BlogRequestContext) {\n const prefix = ctx.blogBasePath;\n\n return {\n listPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit) {\n const qs = new URLSearchParams();\n if (query?.page) qs.set(\"page\", String(query.page));\n if (query?.limit) qs.set(\"limit\", String(query.limit));\n if (query?.search) qs.set(\"search\", query.search);\n if (query?.tag) qs.set(\"tag\", query.tag);\n const queryStr = qs.toString();\n const path = `${prefix}/posts${queryStr ? `?${queryStr}` : \"\"}`;\n return publicGetNullable<CmsBlogPostsPage>(ctx, path, init);\n },\n\n getPostBySlug(slug: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogPostDto>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(slug)}`,\n init,\n );\n },\n\n listCategories(init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogCategoryDto[]>(ctx, `${prefix}/categories`, init);\n },\n\n listComments(postId: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogCommentDto[]>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/comments`,\n init,\n );\n },\n\n async createComment(postId: string, body: CreateBlogCommentInput) {\n const url = buildPublicUrl(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/comments`,\n );\n const res = await ctx.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n },\n body: JSON.stringify(body),\n });\n return unwrapResponse<CreateBlogCommentResult>(res);\n },\n\n getEngagement(postId: string, options?: { visitorId?: string }, init?: FetchRequestInit) {\n return publicGetNullable<BlogEngagement>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/engagement`,\n {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n ...(options?.visitorId ? { \"x-visitor-id\": options.visitorId } : {}),\n },\n },\n );\n },\n\n async toggleLike(postId: string, options?: { visitorId?: string }) {\n const url = buildPublicUrl(ctx, `${prefix}/posts/${encodeURIComponent(postId)}/like`);\n const res = await ctx.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(options?.visitorId ? { \"x-visitor-id\": options.visitorId } : {}),\n },\n });\n return unwrapResponse<BlogLikeResult>(res);\n },\n\n async listMappedPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit) {\n const page = await this.listPosts(query, init);\n if (!page?.docs?.length) return null;\n return {\n posts: page.docs.map(mapCmsPostToBlogPost),\n total: page.total,\n page: page.page,\n limit: page.limit,\n };\n },\n\n async getMappedPostBySlug(slug: string, init?: FetchRequestInit): Promise<BlogPost | null> {\n const dto = await this.getPostBySlug(slug, init);\n if (!dto) return null;\n return mapCmsPostToBlogPost(dto);\n },\n\n async listMappedCategories(init?: FetchRequestInit): Promise<BlogCategory[] | null> {\n const dtos = await this.listCategories(init);\n if (!dtos) return null;\n return dtos.map(mapCmsCategoryToBlogCategory);\n },\n\n async listMappedComments(postId: string, init?: FetchRequestInit): Promise<BlogComment[] | null> {\n const dtos = await this.listComments(postId, init);\n if (!dtos) return null;\n return dtos.map(mapCmsCommentToBlogComment);\n },\n };\n}\n\nexport type BlogApi = ReturnType<typeof createBlogApi>;\n","export type ContentFilters = Record<string, unknown>;\n\nexport function serializeContentFilters(filters: ContentFilters): string {\n return JSON.stringify(filters);\n}\n","import type {\n CmsContentEntryDto,\n CmsContentTypeDto,\n ContentEntry,\n ContentTypeMeta,\n} from \"./types.js\";\n\nfunction resolveId(dto: { _id?: string; id?: string }): string {\n if (dto.id) return String(dto.id);\n if (dto._id) return String(dto._id);\n return \"\";\n}\n\nfunction mapContentType(dto?: CmsContentTypeDto): ContentTypeMeta | undefined {\n if (!dto) return undefined;\n const id = resolveId(dto);\n return {\n id,\n name: dto.name ?? \"\",\n apiId: dto.apiId ?? \"\",\n fields: dto.fields,\n status: dto.status,\n };\n}\n\nexport function mapCmsEntryToContentEntry(dto: CmsContentEntryDto): ContentEntry {\n const contentTypeId =\n dto.contentTypeId != null\n ? String(dto.contentTypeId)\n : dto.contentType\n ? resolveId(dto.contentType)\n : \"\";\n\n return {\n id: resolveId(dto),\n contentTypeId,\n contentType: mapContentType(dto.contentType),\n status: dto.status ?? \"PUBLISHED\",\n data: dto.data ?? {},\n createdAt: dto.createdAt,\n updatedAt: dto.updatedAt,\n };\n}\n","import { publicGetNullable, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport { serializeContentFilters } from \"./filters.js\";\nimport { mapCmsEntryToContentEntry } from \"./mappers.js\";\nimport type {\n CmsContentEntriesPage,\n CmsContentEntryDto,\n ContentEntry,\n ListContentEntriesQuery,\n MappedContentEntriesPage,\n} from \"./types.js\";\n\nexport type ContentRequestContext = RequestContext & {\n contentBasePath: string;\n};\n\nfunction buildListQueryString(query?: ListContentEntriesQuery): string {\n const qs = new URLSearchParams();\n if (query?.page != null) qs.set(\"page\", String(query.page));\n if (query?.limit != null) qs.set(\"limit\", String(query.limit));\n if (query?.search) qs.set(\"search\", query.search);\n if (query?.sort) qs.set(\"sort\", query.sort);\n if (query?.order) qs.set(\"order\", query.order);\n if (query?.filters && Object.keys(query.filters).length > 0) {\n qs.set(\"filters\", serializeContentFilters(query.filters));\n }\n return qs.toString();\n}\n\nexport function createContentApi(ctx: ContentRequestContext) {\n const prefix = ctx.contentBasePath;\n\n return {\n listEntries(\n contentTypeApiId: string,\n query?: ListContentEntriesQuery,\n init?: FetchRequestInit,\n ) {\n const queryStr = buildListQueryString(query);\n const path = `${prefix}/${encodeURIComponent(contentTypeApiId)}${\n queryStr ? `?${queryStr}` : \"\"\n }`;\n return publicGetNullable<CmsContentEntriesPage>(ctx, path, init);\n },\n\n getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsContentEntryDto>(\n ctx,\n `${prefix}/${encodeURIComponent(contentTypeApiId)}/${encodeURIComponent(idOrSlug)}`,\n init,\n );\n },\n\n async listMappedEntries(\n contentTypeApiId: string,\n query?: ListContentEntriesQuery,\n init?: FetchRequestInit,\n ): Promise<MappedContentEntriesPage | null> {\n const page = await this.listEntries(contentTypeApiId, query, init);\n if (!page?.docs) return null;\n return {\n entries: page.docs.map(mapCmsEntryToContentEntry),\n totalDocs: page.totalDocs,\n };\n },\n\n async getMappedEntry(\n contentTypeApiId: string,\n idOrSlug: string,\n init?: FetchRequestInit,\n ): Promise<ContentEntry | null> {\n const dto = await this.getEntry(contentTypeApiId, idOrSlug, init);\n if (!dto) return null;\n return mapCmsEntryToContentEntry(dto);\n },\n };\n}\n\nexport type ContentApi = ReturnType<typeof createContentApi>;\n","import { buildPublicUrl, unwrapResponse, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport type { LeadSubmissionData, SubmitLeadOptions, SubmitLeadResult } from \"./types.js\";\n\nexport type LeadsRequestContext = RequestContext & {\n contentBasePath: string;\n};\n\nexport function createLeadsApi(ctx: LeadsRequestContext) {\n const prefix = ctx.contentBasePath;\n\n return {\n async submit(\n contentTypeApiId: string,\n data: LeadSubmissionData,\n options?: SubmitLeadOptions,\n init?: FetchRequestInit,\n ): Promise<SubmitLeadResult> {\n const url = buildPublicUrl(\n ctx,\n `${prefix}/${encodeURIComponent(contentTypeApiId)}/submissions`,\n );\n\n const body: { data: LeadSubmissionData; status?: string } = { data };\n if (options?.status) {\n body.status = options.status;\n }\n\n const res = await ctx.fetchFn(url, {\n ...init,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n body: JSON.stringify(body),\n });\n\n return unwrapResponse<SubmitLeadResult>(res);\n },\n };\n}\n\nexport type LeadsApi = ReturnType<typeof createLeadsApi>;\n","import { publicGet, publicPost, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport type {\n ConfirmNewsletterResult,\n NewsletterActionResult,\n SubscribeNewsletterInput,\n UnsubscribeNewsletterInput,\n UpdateNewsletterPreferencesInput,\n} from \"./types.js\";\n\nexport type NewsletterRequestContext = RequestContext & {\n newsletterBasePath: string;\n};\n\nexport function createNewsletterApi(ctx: NewsletterRequestContext) {\n const prefix = ctx.newsletterBasePath;\n\n return {\n subscribe(input: SubscribeNewsletterInput, init?: FetchRequestInit) {\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/subscribe`, input, init);\n },\n\n unsubscribe(input: UnsubscribeNewsletterInput, init?: FetchRequestInit) {\n const body: UnsubscribeNewsletterInput = {};\n if (input.token) body.token = input.token;\n if (input.email) body.email = input.email;\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/unsubscribe`, body, init);\n },\n\n confirm(token: string, init?: FetchRequestInit) {\n const path = `${prefix}/confirm/${encodeURIComponent(token)}`;\n return publicGet<ConfirmNewsletterResult>(ctx, path, init);\n },\n\n updatePreferences(input: UpdateNewsletterPreferencesInput, init?: FetchRequestInit) {\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/preferences`, input, init);\n },\n };\n}\n\nexport type NewsletterApi = ReturnType<typeof createNewsletterApi>;\n","import { createBlogApi } from \"./blog/endpoints.js\";\nimport type { BlogApi } from \"./blog/endpoints.js\";\nimport { createContentApi } from \"./content/endpoints.js\";\nimport type { ContentApi } from \"./content/endpoints.js\";\nimport { createLeadsApi } from \"./leads/endpoints.js\";\nimport type { LeadsApi } from \"./leads/endpoints.js\";\nimport { createNewsletterApi } from \"./newsletter/endpoints.js\";\nimport type { NewsletterApi } from \"./newsletter/endpoints.js\";\n\nexport type CmsClientConfig = {\n /** Base URL, e.g. https://cms-gateway.example.com */\n baseUrl: string;\n /** CMS site Mongo id — appended as ?siteId= on every public request */\n siteId?: string;\n /**\n * Path prefix before /public/blog, /public/api, and /public/newsletter.\n * Default '' for gateway-cms direct (/public/blog/..., etc.).\n * Use '/api/backend/cms' when routing through the main API gateway.\n */\n pathPrefix?: string;\n fetch?: typeof fetch;\n defaultHeaders?: Record<string, string>;\n};\n\nexport type CmsClient = {\n blog: BlogApi;\n content: ContentApi;\n leads: LeadsApi;\n newsletter: NewsletterApi;\n};\n\nfunction normalizeBaseUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePathPrefix(prefix: string): string {\n const trimmed = prefix.replace(/\\/$/, \"\");\n if (!trimmed) return \"\";\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n\nexport function createCmsClient(config: CmsClientConfig): CmsClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl);\n const pathPrefix = normalizePathPrefix(config.pathPrefix ?? \"\");\n const blogBasePath = `${pathPrefix}/public/blog`.replace(/\\/+/g, \"/\");\n const contentBasePath = `${pathPrefix}/public/api`.replace(/\\/+/g, \"/\");\n const newsletterBasePath = `${pathPrefix}/public/newsletter`.replace(/\\/+/g, \"/\");\n\n const ctx = {\n baseUrl,\n siteId: config.siteId,\n fetchFn: config.fetch ?? globalThis.fetch.bind(globalThis),\n defaultHeaders: config.defaultHeaders ?? {},\n };\n\n return {\n blog: createBlogApi({ ...ctx, blogBasePath }),\n content: createContentApi({ ...ctx, contentBasePath }),\n leads: createLeadsApi({ ...ctx, contentBasePath }),\n newsletter: createNewsletterApi({ ...ctx, newsletterBasePath }),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/http.ts","../src/blog/mappers.ts","../src/blog/endpoints.ts","../src/content/filters.ts","../src/content/mappers.ts","../src/content/endpoints.ts","../src/leads/endpoints.ts","../src/newsletter/endpoints.ts","../src/client.ts","../src/content/field-types.ts","../src/content/structured-data.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CmsApiResponse, FetchRequestInit } from \"./types.js\";\n\nexport type RequestContext = {\n baseUrl: string;\n siteId?: string;\n fetchFn: typeof fetch;\n defaultHeaders: Record<string, string>;\n};\n\nexport function appendSiteId(path: string, siteId?: string): string {\n if (!siteId) return path;\n const sep = path.includes(\"?\") ? \"&\" : \"?\";\n return `${path}${sep}siteId=${encodeURIComponent(siteId)}`;\n}\n\nexport function buildPublicUrl(ctx: RequestContext, path: string): string {\n return `${ctx.baseUrl}${appendSiteId(path, ctx.siteId)}`;\n}\n\nexport async function unwrapResponse<T>(res: Response): Promise<T> {\n const json = (await res.json()) as CmsApiResponse<T> & Record<string, unknown>;\n if (!res.ok) {\n const message =\n (json as CmsApiResponse<T>).message ??\n (`Request failed (${res.status})` as string);\n throw new Error(message);\n }\n const hasEntryIdentity = \"_id\" in json || \"id\" in json;\n const hasListDocs = \"docs\" in json && Array.isArray(json.docs);\n const isDataEnvelope =\n json.data !== undefined &&\n \"message\" in json &&\n !hasListDocs &&\n !hasEntryIdentity;\n\n if (isDataEnvelope) {\n return json.data as T;\n }\n return json as T;\n}\n\n/** @deprecated Use unwrapResponse — kept as alias for blog module */\nexport const unwrap = unwrapResponse;\n\nexport async function publicGet<T>(\n ctx: RequestContext,\n path: string,\n init?: FetchRequestInit,\n): Promise<T> {\n const res = await ctx.fetchFn(buildPublicUrl(ctx, path), {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n });\n return unwrapResponse<T>(res);\n}\n\nexport async function publicGetNullable<T>(\n ctx: RequestContext,\n path: string,\n init?: FetchRequestInit,\n): Promise<T | null> {\n try {\n return await publicGet<T>(ctx, path, init);\n } catch {\n return null;\n }\n}\n\nexport async function publicPost<T>(\n ctx: RequestContext,\n path: string,\n body: unknown,\n init?: FetchRequestInit,\n): Promise<T> {\n const res = await ctx.fetchFn(buildPublicUrl(ctx, path), {\n ...init,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n body: JSON.stringify(body),\n });\n return unwrapResponse<T>(res);\n}\n","import type {\n BlogCategory,\n BlogComment,\n BlogPost,\n CmsBlogCategoryDto,\n CmsBlogCommentDto,\n CmsBlogPostDto,\n} from \"./types.js\";\n\nexport function mediaUrl(value: unknown): string | undefined {\n if (!value) return undefined;\n if (typeof value === \"string\") return value;\n if (typeof value === \"object\" && value !== null && \"url\" in value) {\n return String((value as { url: string }).url);\n }\n return undefined;\n}\n\nexport function mapCmsPostToBlogPost(dto: CmsBlogPostDto): BlogPost {\n const data = dto.data ?? {};\n const title = String(dto.title ?? data.title ?? \"Untitled\");\n const slug = String(dto.slug ?? data.slug ?? dto.id);\n const excerpt = String(dto.excerpt ?? data.excerpt ?? \"\");\n const body = String(dto.content ?? data.content ?? \"\");\n const tags = dto.tags ?? (Array.isArray(data.tags) ? (data.tags as string[]) : []);\n const category = dto.categories?.[0]?.name ?? \"General\";\n const publishedAt = String(\n dto.published_at ?? data.published_at ?? dto.createdAt ?? new Date().toISOString(),\n );\n const authorName = String(data.author_name ?? \"Editor\");\n const imageSrc = mediaUrl(dto.featured_image ?? data.featured_image);\n\n const wordCount = body.replace(/<[^>]+>/g, \" \").split(/\\s+/).filter(Boolean).length;\n\n return {\n postId: dto.id,\n slug,\n title,\n excerpt,\n category,\n tags,\n publishedAt,\n readMinutes: Math.max(1, Math.ceil(wordCount / 200)),\n author: {\n name: authorName,\n avatarInitials: authorName.slice(0, 2).toUpperCase(),\n },\n imageSrc,\n imageAlt: title,\n body,\n stats: dto.stats,\n };\n}\n\nexport function mapCmsCommentToBlogComment(dto: CmsBlogCommentDto): BlogComment {\n return {\n id: dto.id,\n name: dto.name,\n message: dto.message,\n avatarUrl: dto.avatarUrl,\n postedAt: dto.postedAt,\n replies: (dto.replyComment ?? []).map((r) => ({\n id: r.id,\n userId: r.userId,\n message: r.message,\n postedAt: r.postedAt,\n })),\n };\n}\n\nexport function mapCmsCategoryToBlogCategory(dto: CmsBlogCategoryDto): BlogCategory {\n return {\n id: dto.id,\n name: dto.name,\n slug: dto.slug,\n description: dto.description,\n sortOrder: dto.sortOrder,\n };\n}\n","import {\n appendSiteId,\n buildPublicUrl,\n publicGetNullable,\n unwrapResponse,\n type RequestContext,\n} from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport {\n mapCmsCategoryToBlogCategory,\n mapCmsCommentToBlogComment,\n mapCmsPostToBlogPost,\n} from \"./mappers.js\";\nimport type {\n BlogCategory,\n BlogComment,\n BlogEngagement,\n BlogLikeResult,\n BlogPost,\n CmsBlogCategoryDto,\n CmsBlogCommentDto,\n CmsBlogPostDto,\n CmsBlogPostsPage,\n CreateBlogCommentInput,\n CreateBlogCommentResult,\n ListBlogPostsQuery,\n} from \"./types.js\";\n\nexport type BlogRequestContext = RequestContext & {\n blogBasePath: string;\n};\n\nexport function createBlogApi(ctx: BlogRequestContext) {\n const prefix = ctx.blogBasePath;\n\n return {\n listPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit) {\n const qs = new URLSearchParams();\n if (query?.page) qs.set(\"page\", String(query.page));\n if (query?.limit) qs.set(\"limit\", String(query.limit));\n if (query?.search) qs.set(\"search\", query.search);\n if (query?.tag) qs.set(\"tag\", query.tag);\n const queryStr = qs.toString();\n const path = `${prefix}/posts${queryStr ? `?${queryStr}` : \"\"}`;\n return publicGetNullable<CmsBlogPostsPage>(ctx, path, init);\n },\n\n getPostBySlug(slug: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogPostDto>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(slug)}`,\n init,\n );\n },\n\n listCategories(init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogCategoryDto[]>(ctx, `${prefix}/categories`, init);\n },\n\n listComments(postId: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsBlogCommentDto[]>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/comments`,\n init,\n );\n },\n\n async createComment(postId: string, body: CreateBlogCommentInput) {\n const url = buildPublicUrl(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/comments`,\n );\n const res = await ctx.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n },\n body: JSON.stringify(body),\n });\n return unwrapResponse<CreateBlogCommentResult>(res);\n },\n\n getEngagement(postId: string, options?: { visitorId?: string }, init?: FetchRequestInit) {\n return publicGetNullable<BlogEngagement>(\n ctx,\n `${prefix}/posts/${encodeURIComponent(postId)}/engagement`,\n {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n ...(options?.visitorId ? { \"x-visitor-id\": options.visitorId } : {}),\n },\n },\n );\n },\n\n async toggleLike(postId: string, options?: { visitorId?: string }) {\n const url = buildPublicUrl(ctx, `${prefix}/posts/${encodeURIComponent(postId)}/like`);\n const res = await ctx.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(options?.visitorId ? { \"x-visitor-id\": options.visitorId } : {}),\n },\n });\n return unwrapResponse<BlogLikeResult>(res);\n },\n\n async listMappedPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit) {\n const page = await this.listPosts(query, init);\n if (!page?.docs?.length) return null;\n return {\n posts: page.docs.map(mapCmsPostToBlogPost),\n total: page.total,\n page: page.page,\n limit: page.limit,\n };\n },\n\n async getMappedPostBySlug(slug: string, init?: FetchRequestInit): Promise<BlogPost | null> {\n const dto = await this.getPostBySlug(slug, init);\n if (!dto) return null;\n return mapCmsPostToBlogPost(dto);\n },\n\n async listMappedCategories(init?: FetchRequestInit): Promise<BlogCategory[] | null> {\n const dtos = await this.listCategories(init);\n if (!dtos) return null;\n return dtos.map(mapCmsCategoryToBlogCategory);\n },\n\n async listMappedComments(postId: string, init?: FetchRequestInit): Promise<BlogComment[] | null> {\n const dtos = await this.listComments(postId, init);\n if (!dtos) return null;\n return dtos.map(mapCmsCommentToBlogComment);\n },\n };\n}\n\nexport type BlogApi = ReturnType<typeof createBlogApi>;\n","export type ContentFilters = Record<string, unknown>;\n\nexport function serializeContentFilters(filters: ContentFilters): string {\n return JSON.stringify(filters);\n}\n","import type {\n CmsContentEntryDto,\n CmsContentTypeDto,\n ContentEntry,\n ContentTypeMeta,\n} from \"./types.js\";\n\nfunction resolveId(dto: { _id?: string; id?: string }): string {\n if (dto.id) return String(dto.id);\n if (dto._id) return String(dto._id);\n return \"\";\n}\n\nfunction mapContentType(dto?: CmsContentTypeDto): ContentTypeMeta | undefined {\n if (!dto) return undefined;\n const id = resolveId(dto);\n return {\n id,\n name: dto.name ?? \"\",\n apiId: dto.apiId ?? \"\",\n category: dto.category,\n fields: dto.fields,\n status: dto.status,\n };\n}\n\nexport function mapCmsEntryToContentEntry(dto: CmsContentEntryDto): ContentEntry {\n const contentTypeId =\n dto.contentTypeId != null\n ? String(dto.contentTypeId)\n : dto.contentType\n ? resolveId(dto.contentType)\n : \"\";\n\n return {\n id: resolveId(dto),\n contentTypeId,\n contentType: mapContentType(dto.contentType),\n status: dto.status ?? \"PUBLISHED\",\n data: dto.data ?? {},\n createdAt: dto.createdAt,\n updatedAt: dto.updatedAt,\n };\n}\n","import { publicGetNullable, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport { serializeContentFilters } from \"./filters.js\";\nimport { mapCmsEntryToContentEntry } from \"./mappers.js\";\nimport type {\n CmsContentEntriesPage,\n CmsContentEntryDto,\n ContentEntry,\n ListContentEntriesQuery,\n MappedContentEntriesPage,\n} from \"./types.js\";\n\nexport type ContentRequestContext = RequestContext & {\n contentBasePath: string;\n};\n\nfunction buildListQueryString(query?: ListContentEntriesQuery): string {\n const qs = new URLSearchParams();\n if (query?.page != null) qs.set(\"page\", String(query.page));\n if (query?.limit != null) qs.set(\"limit\", String(query.limit));\n if (query?.search) qs.set(\"search\", query.search);\n if (query?.sort) qs.set(\"sort\", query.sort);\n if (query?.order) qs.set(\"order\", query.order);\n if (query?.filters && Object.keys(query.filters).length > 0) {\n qs.set(\"filters\", serializeContentFilters(query.filters));\n }\n return qs.toString();\n}\n\nexport function createContentApi(ctx: ContentRequestContext) {\n const prefix = ctx.contentBasePath;\n\n return {\n listEntries(\n contentTypeApiId: string,\n query?: ListContentEntriesQuery,\n init?: FetchRequestInit,\n ) {\n const queryStr = buildListQueryString(query);\n const path = `${prefix}/${encodeURIComponent(contentTypeApiId)}${\n queryStr ? `?${queryStr}` : \"\"\n }`;\n return publicGetNullable<CmsContentEntriesPage>(ctx, path, init);\n },\n\n getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit) {\n return publicGetNullable<CmsContentEntryDto>(\n ctx,\n `${prefix}/${encodeURIComponent(contentTypeApiId)}/${encodeURIComponent(idOrSlug)}`,\n init,\n );\n },\n\n async listMappedEntries(\n contentTypeApiId: string,\n query?: ListContentEntriesQuery,\n init?: FetchRequestInit,\n ): Promise<MappedContentEntriesPage | null> {\n const page = await this.listEntries(contentTypeApiId, query, init);\n if (!page?.docs) return null;\n return {\n entries: page.docs.map(mapCmsEntryToContentEntry),\n totalDocs: page.totalDocs,\n ...(page.category ? { category: page.category } : {}),\n ...(page.maxEntries != null ? { maxEntries: page.maxEntries } : {}),\n };\n },\n\n async getMappedEntry(\n contentTypeApiId: string,\n idOrSlug: string,\n init?: FetchRequestInit,\n ): Promise<ContentEntry | null> {\n const dto = await this.getEntry(contentTypeApiId, idOrSlug, init);\n if (!dto) return null;\n return mapCmsEntryToContentEntry(dto);\n },\n\n async getSingleMappedEntry(\n contentTypeApiId: string,\n init?: FetchRequestInit,\n ): Promise<ContentEntry | null> {\n const page = await this.listMappedEntries(\n contentTypeApiId,\n { limit: 1, page: 1 },\n init,\n );\n return page?.entries?.[0] ?? null;\n },\n };\n}\n\nexport type ContentApi = ReturnType<typeof createContentApi>;\n","import { buildPublicUrl, unwrapResponse, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport type { LeadSubmissionData, SubmitLeadOptions, SubmitLeadResult } from \"./types.js\";\n\nexport type LeadsRequestContext = RequestContext & {\n contentBasePath: string;\n};\n\nexport function createLeadsApi(ctx: LeadsRequestContext) {\n const prefix = ctx.contentBasePath;\n\n return {\n async submit(\n contentTypeApiId: string,\n data: LeadSubmissionData,\n options?: SubmitLeadOptions,\n init?: FetchRequestInit,\n ): Promise<SubmitLeadResult> {\n const url = buildPublicUrl(\n ctx,\n `${prefix}/${encodeURIComponent(contentTypeApiId)}/submissions`,\n );\n\n const body: { data: LeadSubmissionData; status?: string } = { data };\n if (options?.status) {\n body.status = options.status;\n }\n\n const res = await ctx.fetchFn(url, {\n ...init,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...ctx.defaultHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n body: JSON.stringify(body),\n });\n\n return unwrapResponse<SubmitLeadResult>(res);\n },\n };\n}\n\nexport type LeadsApi = ReturnType<typeof createLeadsApi>;\n","import { publicGet, publicPost, type RequestContext } from \"../http.js\";\nimport type { FetchRequestInit } from \"../types.js\";\nimport type {\n ConfirmNewsletterResult,\n NewsletterActionResult,\n SubscribeNewsletterInput,\n UnsubscribeNewsletterInput,\n UpdateNewsletterPreferencesInput,\n} from \"./types.js\";\n\nexport type NewsletterRequestContext = RequestContext & {\n newsletterBasePath: string;\n};\n\nexport function createNewsletterApi(ctx: NewsletterRequestContext) {\n const prefix = ctx.newsletterBasePath;\n\n return {\n subscribe(input: SubscribeNewsletterInput, init?: FetchRequestInit) {\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/subscribe`, input, init);\n },\n\n unsubscribe(input: UnsubscribeNewsletterInput, init?: FetchRequestInit) {\n const body: UnsubscribeNewsletterInput = {};\n if (input.token) body.token = input.token;\n if (input.email) body.email = input.email;\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/unsubscribe`, body, init);\n },\n\n confirm(token: string, init?: FetchRequestInit) {\n const path = `${prefix}/confirm/${encodeURIComponent(token)}`;\n return publicGet<ConfirmNewsletterResult>(ctx, path, init);\n },\n\n updatePreferences(input: UpdateNewsletterPreferencesInput, init?: FetchRequestInit) {\n return publicPost<NewsletterActionResult>(ctx, `${prefix}/preferences`, input, init);\n },\n };\n}\n\nexport type NewsletterApi = ReturnType<typeof createNewsletterApi>;\n","import { createBlogApi } from \"./blog/endpoints.js\";\nimport type { BlogApi } from \"./blog/endpoints.js\";\nimport { createContentApi } from \"./content/endpoints.js\";\nimport type { ContentApi } from \"./content/endpoints.js\";\nimport { createLeadsApi } from \"./leads/endpoints.js\";\nimport type { LeadsApi } from \"./leads/endpoints.js\";\nimport { createNewsletterApi } from \"./newsletter/endpoints.js\";\nimport type { NewsletterApi } from \"./newsletter/endpoints.js\";\n\nexport type CmsClientConfig = {\n /** Base URL, e.g. https://cms-gateway.example.com */\n baseUrl: string;\n /** CMS site Mongo id — appended as ?siteId= on every public request */\n siteId?: string;\n /**\n * Path prefix before /public/blog, /public/api, and /public/newsletter.\n * Default '' for gateway-cms direct (/public/blog/..., etc.).\n * Use '/api/backend/cms' when routing through the main API gateway.\n */\n pathPrefix?: string;\n fetch?: typeof fetch;\n defaultHeaders?: Record<string, string>;\n};\n\nexport type CmsClient = {\n blog: BlogApi;\n content: ContentApi;\n leads: LeadsApi;\n newsletter: NewsletterApi;\n};\n\nfunction normalizeBaseUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePathPrefix(prefix: string): string {\n const trimmed = prefix.replace(/\\/$/, \"\");\n if (!trimmed) return \"\";\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n\nexport function createCmsClient(config: CmsClientConfig): CmsClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl);\n const pathPrefix = normalizePathPrefix(config.pathPrefix ?? \"\");\n const blogBasePath = `${pathPrefix}/public/blog`.replace(/\\/+/g, \"/\");\n const contentBasePath = `${pathPrefix}/public/api`.replace(/\\/+/g, \"/\");\n const newsletterBasePath = `${pathPrefix}/public/newsletter`.replace(/\\/+/g, \"/\");\n\n const ctx = {\n baseUrl,\n siteId: config.siteId,\n fetchFn: config.fetch ?? globalThis.fetch.bind(globalThis),\n defaultHeaders: config.defaultHeaders ?? {},\n };\n\n return {\n blog: createBlogApi({ ...ctx, blogBasePath }),\n content: createContentApi({ ...ctx, contentBasePath }),\n leads: createLeadsApi({ ...ctx, contentBasePath }),\n newsletter: createNewsletterApi({ ...ctx, newsletterBasePath }),\n };\n}\n","/**\n * Aligns with Utilsy CMS content-type field definitions (admin schema).\n * Entry `data` uses these shapes at runtime for COMPONENT and DYNAMIC_ZONE fields.\n */\n\nexport const ContentTypeCategory = {\n COLLECTION: \"COLLECTION\",\n SINGLE: \"SINGLE\",\n COMPONENT: \"COMPONENT\",\n} as const;\n\nexport type ContentTypeCategory =\n (typeof ContentTypeCategory)[keyof typeof ContentTypeCategory];\n\nexport const FieldType = {\n TEXT: \"TEXT\",\n TEXTAREA: \"TEXTAREA\",\n RICHTEXT: \"RICHTEXT\",\n NUMBER: \"NUMBER\",\n BOOLEAN: \"BOOLEAN\",\n DATE: \"DATE\",\n DATETIME: \"DATETIME\",\n TIME: \"TIME\",\n EMAIL: \"EMAIL\",\n URL: \"URL\",\n MEDIA: \"MEDIA\",\n RELATION: \"RELATION\",\n JSON: \"JSON\",\n ENUM: \"ENUM\",\n PHONE: \"PHONE\",\n WEEKDAY: \"WEEKDAY\",\n COMPONENT: \"COMPONENT\",\n DYNAMIC_ZONE: \"DYNAMIC_ZONE\",\n PAGE_EDITOR: \"PAGE_EDITOR\",\n} as const;\n\nexport type FieldType = (typeof FieldType)[keyof typeof FieldType];\n\nexport type ComponentFieldConfig = {\n componentId: string;\n repeatable?: boolean;\n};\n\nexport type DynamicZoneFieldConfig = {\n components: string[];\n};\n\nexport type ContentTypeField = {\n name: string;\n type: FieldType | string;\n label?: string;\n description?: string;\n required?: boolean;\n unique?: boolean;\n default?: unknown;\n validation?: {\n min?: number;\n max?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n };\n options?: {\n multiple?: boolean;\n placeholder?: string;\n helpText?: string;\n [key: string]: unknown;\n };\n component?: ComponentFieldConfig;\n dynamicZone?: DynamicZoneFieldConfig;\n relation?: {\n contentTypeId: string;\n relationType: string;\n displayField?: string;\n };\n sortOrder?: number;\n};\n\n/** Discriminator for dynamic zone blocks (`__component` = component content type apiId). */\nexport type DynamicZoneBlock = {\n __component: string;\n [key: string]: unknown;\n};\n","import type { ContentEntry } from \"./types.js\";\nimport type { ContentTypeField, DynamicZoneBlock } from \"./field-types.js\";\nimport { FieldType } from \"./field-types.js\";\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Safely coerce CMS `fields` JSON to typed field definitions (skips invalid entries).\n */\nexport function parseContentTypeFields(raw: unknown): ContentTypeField[] {\n if (!Array.isArray(raw)) return [];\n const out: ContentTypeField[] = [];\n for (const item of raw) {\n if (!isPlainObject(item)) continue;\n const name = item.name;\n const type = item.type;\n if (typeof name !== \"string\" || !name.trim()) continue;\n if (typeof type !== \"string\" || !type.trim()) continue;\n out.push(item as ContentTypeField);\n }\n return out;\n}\n\nexport function findContentTypeField(\n fields: ContentTypeField[] | undefined,\n fieldName: string,\n): ContentTypeField | undefined {\n return fields?.find((f) => f.name === fieldName);\n}\n\n/**\n * Read a top-level field from entry data.\n */\nexport function getEntryFieldValue(\n entry: Pick<ContentEntry, \"data\">,\n fieldName: string,\n): unknown {\n return entry.data[fieldName];\n}\n\n/**\n * COMPONENT field: single object or repeatable array of objects.\n * Returns a normalized array (empty if missing/invalid).\n */\nexport function getComponentItems(\n entry: Pick<ContentEntry, \"data\">,\n fieldName: string,\n): Record<string, unknown>[] {\n const value = entry.data[fieldName];\n if (value == null) return [];\n if (Array.isArray(value)) {\n return value.filter(isPlainObject);\n }\n if (isPlainObject(value)) {\n return [value];\n }\n return [];\n}\n\n/**\n * Single COMPONENT instance (first item when repeatable, or the object when not).\n */\nexport function getComponentItem(\n entry: Pick<ContentEntry, \"data\">,\n fieldName: string,\n): Record<string, unknown> | undefined {\n const items = getComponentItems(entry, fieldName);\n return items[0];\n}\n\n/**\n * DYNAMIC_ZONE field: array of blocks with `__component` apiId discriminator.\n */\nexport function getDynamicZoneBlocks(\n entry: Pick<ContentEntry, \"data\">,\n fieldName: string,\n): DynamicZoneBlock[] {\n const value = entry.data[fieldName];\n if (!Array.isArray(value)) return [];\n return value.filter(\n (item): item is DynamicZoneBlock =>\n isPlainObject(item) &&\n typeof item.__component === \"string\" &&\n item.__component.length > 0,\n );\n}\n\n/** Blocks in a dynamic zone that match a component apiId. */\nexport function filterDynamicZoneByComponent(\n blocks: DynamicZoneBlock[],\n componentApiId: string,\n): DynamicZoneBlock[] {\n return blocks.filter((b) => b.__component === componentApiId);\n}\n\n/** Whether a field definition is a repeatable component. */\nexport function isRepeatableComponentField(field: ContentTypeField): boolean {\n return (\n field.type === FieldType.COMPONENT && field.component?.repeatable === true\n );\n}\n\n/** Whether a field definition is a dynamic zone. */\nexport function isDynamicZoneField(field: ContentTypeField): boolean {\n return field.type === FieldType.DYNAMIC_ZONE;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as CmsBlogCategoryDto, b as BlogCategory, i as CmsBlogCommentDto, c as BlogComment, j as CmsBlogPostDto, g as BlogPost, o as CmsContentEntryDto, s as ContentEntry } from './client-
|
|
2
|
-
export { B as BlogApi, a as BlogAuthor, d as BlogCommentReply, e as BlogEngagement, f as BlogLikeResult, C as CmsApiResponse, k as CmsBlogPostsPage, l as CmsClient, m as CmsClientConfig, n as CmsContentEntriesPage, p as CmsContentTypeDto, q as ConfirmNewsletterResult, r as ContentApi, t as ContentFilters, u as ContentTypeMeta, v as CreateBlogCommentInput, w as CreateBlogCommentResult, F as FetchRequestInit, L as LeadSubmissionData, x as LeadsApi, y as ListBlogPostsQuery, z as ListContentEntriesQuery, M as MappedContentEntriesPage, N as NewsletterActionResult, A as NewsletterApi, D as NewsletterSubscriberSummary, S as SubmitLeadOptions, E as SubmitLeadResult, G as SubscribeNewsletterInput, U as UnsubscribeNewsletterInput, H as UpdateNewsletterPreferencesInput, I as createCmsClient, J as serializeContentFilters } from './client-
|
|
1
|
+
import { h as CmsBlogCategoryDto, b as BlogCategory, i as CmsBlogCommentDto, c as BlogComment, j as CmsBlogPostDto, g as BlogPost, o as CmsContentEntryDto, s as ContentEntry } from './client-awWyf-VL.cjs';
|
|
2
|
+
export { B as BlogApi, a as BlogAuthor, d as BlogCommentReply, e as BlogEngagement, f as BlogLikeResult, C as CmsApiResponse, k as CmsBlogPostsPage, l as CmsClient, m as CmsClientConfig, n as CmsContentEntriesPage, p as CmsContentTypeDto, q as ConfirmNewsletterResult, r as ContentApi, t as ContentFilters, u as ContentTypeMeta, v as CreateBlogCommentInput, w as CreateBlogCommentResult, F as FetchRequestInit, L as LeadSubmissionData, x as LeadsApi, y as ListBlogPostsQuery, z as ListContentEntriesQuery, M as MappedContentEntriesPage, N as NewsletterActionResult, A as NewsletterApi, D as NewsletterSubscriberSummary, S as SubmitLeadOptions, E as SubmitLeadResult, G as SubscribeNewsletterInput, U as UnsubscribeNewsletterInput, H as UpdateNewsletterPreferencesInput, I as createCmsClient, J as serializeContentFilters } from './client-awWyf-VL.cjs';
|
|
3
3
|
|
|
4
4
|
declare function mediaUrl(value: unknown): string | undefined;
|
|
5
5
|
declare function mapCmsPostToBlogPost(dto: CmsBlogPostDto): BlogPost;
|
|
@@ -8,4 +8,110 @@ declare function mapCmsCategoryToBlogCategory(dto: CmsBlogCategoryDto): BlogCate
|
|
|
8
8
|
|
|
9
9
|
declare function mapCmsEntryToContentEntry(dto: CmsContentEntryDto): ContentEntry;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Aligns with Utilsy CMS content-type field definitions (admin schema).
|
|
13
|
+
* Entry `data` uses these shapes at runtime for COMPONENT and DYNAMIC_ZONE fields.
|
|
14
|
+
*/
|
|
15
|
+
declare const ContentTypeCategory: {
|
|
16
|
+
readonly COLLECTION: "COLLECTION";
|
|
17
|
+
readonly SINGLE: "SINGLE";
|
|
18
|
+
readonly COMPONENT: "COMPONENT";
|
|
19
|
+
};
|
|
20
|
+
type ContentTypeCategory = (typeof ContentTypeCategory)[keyof typeof ContentTypeCategory];
|
|
21
|
+
declare const FieldType: {
|
|
22
|
+
readonly TEXT: "TEXT";
|
|
23
|
+
readonly TEXTAREA: "TEXTAREA";
|
|
24
|
+
readonly RICHTEXT: "RICHTEXT";
|
|
25
|
+
readonly NUMBER: "NUMBER";
|
|
26
|
+
readonly BOOLEAN: "BOOLEAN";
|
|
27
|
+
readonly DATE: "DATE";
|
|
28
|
+
readonly DATETIME: "DATETIME";
|
|
29
|
+
readonly TIME: "TIME";
|
|
30
|
+
readonly EMAIL: "EMAIL";
|
|
31
|
+
readonly URL: "URL";
|
|
32
|
+
readonly MEDIA: "MEDIA";
|
|
33
|
+
readonly RELATION: "RELATION";
|
|
34
|
+
readonly JSON: "JSON";
|
|
35
|
+
readonly ENUM: "ENUM";
|
|
36
|
+
readonly PHONE: "PHONE";
|
|
37
|
+
readonly WEEKDAY: "WEEKDAY";
|
|
38
|
+
readonly COMPONENT: "COMPONENT";
|
|
39
|
+
readonly DYNAMIC_ZONE: "DYNAMIC_ZONE";
|
|
40
|
+
readonly PAGE_EDITOR: "PAGE_EDITOR";
|
|
41
|
+
};
|
|
42
|
+
type FieldType = (typeof FieldType)[keyof typeof FieldType];
|
|
43
|
+
type ComponentFieldConfig = {
|
|
44
|
+
componentId: string;
|
|
45
|
+
repeatable?: boolean;
|
|
46
|
+
};
|
|
47
|
+
type DynamicZoneFieldConfig = {
|
|
48
|
+
components: string[];
|
|
49
|
+
};
|
|
50
|
+
type ContentTypeField = {
|
|
51
|
+
name: string;
|
|
52
|
+
type: FieldType | string;
|
|
53
|
+
label?: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
required?: boolean;
|
|
56
|
+
unique?: boolean;
|
|
57
|
+
default?: unknown;
|
|
58
|
+
validation?: {
|
|
59
|
+
min?: number;
|
|
60
|
+
max?: number;
|
|
61
|
+
minLength?: number;
|
|
62
|
+
maxLength?: number;
|
|
63
|
+
pattern?: string;
|
|
64
|
+
enum?: string[];
|
|
65
|
+
};
|
|
66
|
+
options?: {
|
|
67
|
+
multiple?: boolean;
|
|
68
|
+
placeholder?: string;
|
|
69
|
+
helpText?: string;
|
|
70
|
+
[key: string]: unknown;
|
|
71
|
+
};
|
|
72
|
+
component?: ComponentFieldConfig;
|
|
73
|
+
dynamicZone?: DynamicZoneFieldConfig;
|
|
74
|
+
relation?: {
|
|
75
|
+
contentTypeId: string;
|
|
76
|
+
relationType: string;
|
|
77
|
+
displayField?: string;
|
|
78
|
+
};
|
|
79
|
+
sortOrder?: number;
|
|
80
|
+
};
|
|
81
|
+
/** Discriminator for dynamic zone blocks (`__component` = component content type apiId). */
|
|
82
|
+
type DynamicZoneBlock = {
|
|
83
|
+
__component: string;
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
88
|
+
/**
|
|
89
|
+
* Safely coerce CMS `fields` JSON to typed field definitions (skips invalid entries).
|
|
90
|
+
*/
|
|
91
|
+
declare function parseContentTypeFields(raw: unknown): ContentTypeField[];
|
|
92
|
+
declare function findContentTypeField(fields: ContentTypeField[] | undefined, fieldName: string): ContentTypeField | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Read a top-level field from entry data.
|
|
95
|
+
*/
|
|
96
|
+
declare function getEntryFieldValue(entry: Pick<ContentEntry, "data">, fieldName: string): unknown;
|
|
97
|
+
/**
|
|
98
|
+
* COMPONENT field: single object or repeatable array of objects.
|
|
99
|
+
* Returns a normalized array (empty if missing/invalid).
|
|
100
|
+
*/
|
|
101
|
+
declare function getComponentItems(entry: Pick<ContentEntry, "data">, fieldName: string): Record<string, unknown>[];
|
|
102
|
+
/**
|
|
103
|
+
* Single COMPONENT instance (first item when repeatable, or the object when not).
|
|
104
|
+
*/
|
|
105
|
+
declare function getComponentItem(entry: Pick<ContentEntry, "data">, fieldName: string): Record<string, unknown> | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* DYNAMIC_ZONE field: array of blocks with `__component` apiId discriminator.
|
|
108
|
+
*/
|
|
109
|
+
declare function getDynamicZoneBlocks(entry: Pick<ContentEntry, "data">, fieldName: string): DynamicZoneBlock[];
|
|
110
|
+
/** Blocks in a dynamic zone that match a component apiId. */
|
|
111
|
+
declare function filterDynamicZoneByComponent(blocks: DynamicZoneBlock[], componentApiId: string): DynamicZoneBlock[];
|
|
112
|
+
/** Whether a field definition is a repeatable component. */
|
|
113
|
+
declare function isRepeatableComponentField(field: ContentTypeField): boolean;
|
|
114
|
+
/** Whether a field definition is a dynamic zone. */
|
|
115
|
+
declare function isDynamicZoneField(field: ContentTypeField): boolean;
|
|
116
|
+
|
|
117
|
+
export { BlogCategory, BlogComment, BlogPost, CmsBlogCategoryDto, CmsBlogCommentDto, CmsBlogPostDto, CmsContentEntryDto, type ComponentFieldConfig, ContentEntry, ContentTypeCategory, type ContentTypeField, type DynamicZoneBlock, type DynamicZoneFieldConfig, FieldType, filterDynamicZoneByComponent, findContentTypeField, getComponentItem, getComponentItems, getDynamicZoneBlocks, getEntryFieldValue, isDynamicZoneField, isPlainObject, isRepeatableComponentField, mapCmsCategoryToBlogCategory, mapCmsCommentToBlogComment, mapCmsEntryToContentEntry, mapCmsPostToBlogPost, mediaUrl, parseContentTypeFields };
|