@utilsy/cms-nextjs 0.2.0 → 0.4.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 CHANGED
@@ -125,7 +125,107 @@ function Engagement({ postId }: { postId: string }) {
125
125
  }
126
126
  ```
127
127
 
128
- ### 5. Client content list (hooks)
128
+ ### 5. Lead capture (custom form via Server Action)
129
+
130
+ Use a **LEAD_CAPTURE** content type in CMS (with field mapping configured). Submit from your own form UI—no hosted-form embed.
131
+
132
+ ```ts
133
+ // app/actions/submit-lead.ts
134
+ "use server";
135
+
136
+ import { cms } from "@/lib/cms";
137
+
138
+ export async function submitContactLead(data: Record<string, unknown>) {
139
+ return cms.leads.submit("contact-enquiries", data);
140
+ }
141
+ ```
142
+
143
+ ```tsx
144
+ "use client";
145
+
146
+ import { submitContactLead } from "@/app/actions/submit-lead";
147
+
148
+ export function ContactForm() {
149
+ return (
150
+ <form
151
+ action={async (formData) => {
152
+ await submitContactLead({
153
+ firstName: String(formData.get("firstName") ?? ""),
154
+ email: String(formData.get("email") ?? ""),
155
+ message: String(formData.get("message") ?? ""),
156
+ });
157
+ }}
158
+ >
159
+ {/* your fields */}
160
+ </form>
161
+ );
162
+ }
163
+ ```
164
+
165
+ Optional honeypot: include `_honeypot` in `data`; submissions with a non-empty value are rejected.
166
+
167
+ ### 6. Newsletter (subscribe, unsubscribe, preferences)
168
+
169
+ Use your own signup / preference-center UI—no hosted form embed.
170
+
171
+ ```ts
172
+ // app/actions/newsletter.ts
173
+ "use server";
174
+
175
+ import { cms } from "@/lib/cms";
176
+
177
+ export async function subscribeNewsletter(email: string) {
178
+ return cms.newsletter.subscribe({ email, source: "footer" });
179
+ }
180
+
181
+ export async function unsubscribeNewsletter(email: string) {
182
+ return cms.newsletter.unsubscribe({ email });
183
+ }
184
+
185
+ export async function updateNewsletterPrefs(
186
+ token: string,
187
+ customFields: Record<string, unknown>,
188
+ ) {
189
+ return cms.newsletter.updatePreferences({ token, customFields });
190
+ }
191
+ ```
192
+
193
+ ```tsx
194
+ "use client";
195
+
196
+ import { CmsProvider, useNewsletterSubscribe } from "@utilsy/cms-nextjs/react";
197
+ import { cms } from "@/lib/cms";
198
+
199
+ export function NewsletterSignup() {
200
+ return (
201
+ <CmsProvider client={cms}>
202
+ <NewsletterSignupInner />
203
+ </CmsProvider>
204
+ );
205
+ }
206
+
207
+ function NewsletterSignupInner() {
208
+ const { subscribe, submitting, error } = useNewsletterSubscribe();
209
+
210
+ return (
211
+ <form
212
+ onSubmit={async (e) => {
213
+ e.preventDefault();
214
+ const fd = new FormData(e.currentTarget);
215
+ await subscribe({ email: String(fd.get("email") ?? "") });
216
+ }}
217
+ >
218
+ <input name="email" type="email" required />
219
+ <button type="submit" disabled={submitting}>Subscribe</button>
220
+ {error && <p>{error.message}</p>}
221
+ </form>
222
+ );
223
+ }
224
+ ```
225
+
226
+ Confirmation links from email hit `GET /public/newsletter/confirm/:token` (no `siteId` required on the server; the SDK still sends `siteId` when configured).
227
+
228
+ ### 7. Client content list (hooks)
129
229
 
130
230
  ```tsx
131
231
  "use client";
@@ -217,6 +317,30 @@ Query params for `listEntries` / `listMappedEntries`: `page`, `limit`, `search`,
217
317
 
218
318
  Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`.
219
319
 
320
+ #### Leads
321
+
322
+ | Method | Description |
323
+ |--------|-------------|
324
+ | `leads.submit(contentTypeApiId, data, options?)` | Submit lead fields; creates content entry + CRM enquiry (throws on error) |
325
+
326
+ - Endpoint: `POST /public/api/{contentTypeApiId}/submissions`
327
+ - Content type must be `LEAD_CAPTURE` and `apiAccess: PUBLIC`
328
+ - Field keys in `data` must match the content type schema; CRM mapping uses `leadCaptureConfig` in admin
329
+
330
+ #### Newsletter
331
+
332
+ | Method | Description |
333
+ |--------|-------------|
334
+ | `newsletter.subscribe(input, init?)` | Subscribe by email; may send confirmation email |
335
+ | `newsletter.unsubscribe(input, init?)` | Unsubscribe by `token` (from email) or `email` |
336
+ | `newsletter.confirm(token, init?)` | Confirm subscription from email link |
337
+ | `newsletter.updatePreferences(input, init?)` | Update `customFields`, `tags`, and/or `listId` |
338
+
339
+ - Base path: `/public/newsletter` (plus optional `pathPrefix`)
340
+ - `subscribe`: `email` required; optional `source`, `listId`, `customFields`
341
+ - `unsubscribe` / `updatePreferences`: provide `token` or `email`
342
+ - `updatePreferences`: at least one of `customFields`, `tags`, or `listId`; optional `tagsAction` (`set` \| `add` \| `remove`)
343
+
220
344
  ### React (`@utilsy/cms-nextjs/react`)
221
345
 
222
346
  | Export | Description |
@@ -229,6 +353,11 @@ Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`.
229
353
  | `useBlogComments` | List + submit comments |
230
354
  | `useContentEntries` | List mapped entries by content type |
231
355
  | `useContentEntry` | Single mapped entry by id or slug |
356
+ | `useSubmitLead` | Submit lead from client (prefer Server Action for forms) |
357
+ | `useNewsletterSubscribe` | Subscribe from client (prefer Server Action) |
358
+ | `useNewsletterUnsubscribe` | Unsubscribe by token or email |
359
+ | `useNewsletterUpdatePreferences` | Update subscriber preferences |
360
+ | `useNewsletterConfirm` | Confirm subscription token (e.g. preference page) |
232
361
 
233
362
  ## CORS
234
363
 
@@ -237,7 +366,7 @@ Public CMS reads from the browser require either:
237
366
  - Same-origin proxy (e.g. Next.js Route Handler forwarding to gateway), or
238
367
  - Server Components / Route Handlers calling the SDK server-side.
239
368
 
240
- Mutations (comments, likes) should run client-side with a proxy or configured CORS on the gateway.
369
+ Mutations (comments, likes, lead submit, newsletter subscribe/unsubscribe/preferences) should run server-side (Server Action / Route Handler) or via a same-origin proxy with CORS configured on the gateway.
241
370
 
242
371
  ## License
243
372
 
@@ -232,14 +232,83 @@ declare function createContentApi(ctx: ContentRequestContext): {
232
232
  };
233
233
  type ContentApi = ReturnType<typeof createContentApi>;
234
234
 
235
+ type LeadSubmissionData = Record<string, unknown>;
236
+ type SubmitLeadOptions = {
237
+ /** Entry status (defaults to PUBLISHED on the server) */
238
+ status?: "DRAFT" | "PUBLISHED" | "ARCHIVED";
239
+ };
240
+ type SubmitLeadResult = {
241
+ entryId: string;
242
+ enquiryId?: string;
243
+ };
244
+
245
+ type LeadsRequestContext = RequestContext & {
246
+ contentBasePath: string;
247
+ };
248
+ declare function createLeadsApi(ctx: LeadsRequestContext): {
249
+ submit(contentTypeApiId: string, data: LeadSubmissionData, options?: SubmitLeadOptions, init?: FetchRequestInit): Promise<SubmitLeadResult>;
250
+ };
251
+ type LeadsApi = ReturnType<typeof createLeadsApi>;
252
+
253
+ type NewsletterSubscriberSummary = {
254
+ id: string;
255
+ email?: string;
256
+ status?: string;
257
+ tags?: string[];
258
+ customFields?: Record<string, unknown>;
259
+ };
260
+ type NewsletterActionResult = {
261
+ ok: boolean;
262
+ message: string;
263
+ subscriberId?: string;
264
+ email?: string;
265
+ subscriber?: NewsletterSubscriberSummary;
266
+ };
267
+ type SubscribeNewsletterInput = {
268
+ email: string;
269
+ source?: string;
270
+ listId?: string;
271
+ customFields?: Record<string, unknown>;
272
+ };
273
+ type UnsubscribeNewsletterInput = {
274
+ /** Token from confirmation or unsubscribe email link */
275
+ token?: string;
276
+ email?: string;
277
+ };
278
+ type UpdateNewsletterPreferencesInput = {
279
+ token?: string;
280
+ email?: string;
281
+ /** Merged into existing customFields on the server */
282
+ customFields?: Record<string, unknown>;
283
+ tags?: string[];
284
+ tagsAction?: "set" | "add" | "remove";
285
+ listId?: string;
286
+ };
287
+ type ConfirmNewsletterResult = {
288
+ ok: boolean;
289
+ message: string;
290
+ email?: string;
291
+ };
292
+
293
+ type NewsletterRequestContext = RequestContext & {
294
+ newsletterBasePath: string;
295
+ };
296
+ declare function createNewsletterApi(ctx: NewsletterRequestContext): {
297
+ subscribe(input: SubscribeNewsletterInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
298
+ unsubscribe(input: UnsubscribeNewsletterInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
299
+ confirm(token: string, init?: FetchRequestInit): Promise<ConfirmNewsletterResult>;
300
+ updatePreferences(input: UpdateNewsletterPreferencesInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
301
+ };
302
+ type NewsletterApi = ReturnType<typeof createNewsletterApi>;
303
+
235
304
  type CmsClientConfig = {
236
305
  /** Base URL, e.g. https://cms-gateway.example.com */
237
306
  baseUrl: string;
238
307
  /** CMS site Mongo id — appended as ?siteId= on every public request */
239
308
  siteId?: string;
240
309
  /**
241
- * Path prefix before /public/blog and /public/api.
242
- * Default '' for gateway-cms direct (/public/blog/..., /public/api/...).
310
+ * Path prefix before /public/blog, /public/api, and /public/newsletter.
311
+ * Default '' for gateway-cms direct (/public/blog/..., etc.).
243
312
  * Use '/api/backend/cms' when routing through the main API gateway.
244
313
  */
245
314
  pathPrefix?: string;
@@ -249,7 +318,9 @@ type CmsClientConfig = {
249
318
  type CmsClient = {
250
319
  blog: BlogApi;
251
320
  content: ContentApi;
321
+ leads: LeadsApi;
322
+ newsletter: NewsletterApi;
252
323
  };
253
324
  declare function createCmsClient(config: CmsClientConfig): CmsClient;
254
325
 
255
- export { type BlogApi as B, type CmsApiResponse as C, type FetchRequestInit as F, type ListBlogPostsQuery as L, type MappedContentEntriesPage as M, type BlogAuthor as a, type BlogCategory as b, type BlogComment as c, type BlogCommentReply as d, type BlogEngagement as e, type BlogLikeResult as f, type BlogPost as g, type CmsBlogCategoryDto as h, type CmsBlogCommentDto as i, type CmsBlogPostDto as j, type CmsBlogPostsPage as k, type CmsClient as l, type CmsClientConfig as m, type CmsContentEntriesPage as n, type CmsContentEntryDto as o, type CmsContentTypeDto as p, type ContentApi as q, type ContentEntry as r, type ContentFilters as s, type ContentTypeMeta as t, type CreateBlogCommentInput as u, type CreateBlogCommentResult as v, type ListContentEntriesQuery as w, createCmsClient as x, serializeContentFilters as y };
326
+ export { type NewsletterApi as A, type BlogApi as B, type CmsApiResponse as C, type NewsletterSubscriberSummary as D, type SubmitLeadResult as E, type FetchRequestInit as F, type SubscribeNewsletterInput as G, type UpdateNewsletterPreferencesInput as H, createCmsClient as I, serializeContentFilters as J, type LeadSubmissionData as L, type MappedContentEntriesPage as M, type NewsletterActionResult as N, type SubmitLeadOptions as S, type UnsubscribeNewsletterInput as U, type BlogAuthor as a, type BlogCategory as b, type BlogComment as c, type BlogCommentReply as d, type BlogEngagement as e, type BlogLikeResult as f, type BlogPost as g, type CmsBlogCategoryDto as h, type CmsBlogCommentDto as i, type CmsBlogPostDto as j, type CmsBlogPostsPage as k, type CmsClient as l, type CmsClientConfig as m, type CmsContentEntriesPage as n, type CmsContentEntryDto as o, type CmsContentTypeDto as p, type ConfirmNewsletterResult as q, type ContentApi as r, type ContentEntry as s, type ContentFilters as t, type ContentTypeMeta as u, type CreateBlogCommentInput as v, type CreateBlogCommentResult as w, type LeadsApi as x, type ListBlogPostsQuery as y, type ListContentEntriesQuery as z };
@@ -232,14 +232,83 @@ declare function createContentApi(ctx: ContentRequestContext): {
232
232
  };
233
233
  type ContentApi = ReturnType<typeof createContentApi>;
234
234
 
235
+ type LeadSubmissionData = Record<string, unknown>;
236
+ type SubmitLeadOptions = {
237
+ /** Entry status (defaults to PUBLISHED on the server) */
238
+ status?: "DRAFT" | "PUBLISHED" | "ARCHIVED";
239
+ };
240
+ type SubmitLeadResult = {
241
+ entryId: string;
242
+ enquiryId?: string;
243
+ };
244
+
245
+ type LeadsRequestContext = RequestContext & {
246
+ contentBasePath: string;
247
+ };
248
+ declare function createLeadsApi(ctx: LeadsRequestContext): {
249
+ submit(contentTypeApiId: string, data: LeadSubmissionData, options?: SubmitLeadOptions, init?: FetchRequestInit): Promise<SubmitLeadResult>;
250
+ };
251
+ type LeadsApi = ReturnType<typeof createLeadsApi>;
252
+
253
+ type NewsletterSubscriberSummary = {
254
+ id: string;
255
+ email?: string;
256
+ status?: string;
257
+ tags?: string[];
258
+ customFields?: Record<string, unknown>;
259
+ };
260
+ type NewsletterActionResult = {
261
+ ok: boolean;
262
+ message: string;
263
+ subscriberId?: string;
264
+ email?: string;
265
+ subscriber?: NewsletterSubscriberSummary;
266
+ };
267
+ type SubscribeNewsletterInput = {
268
+ email: string;
269
+ source?: string;
270
+ listId?: string;
271
+ customFields?: Record<string, unknown>;
272
+ };
273
+ type UnsubscribeNewsletterInput = {
274
+ /** Token from confirmation or unsubscribe email link */
275
+ token?: string;
276
+ email?: string;
277
+ };
278
+ type UpdateNewsletterPreferencesInput = {
279
+ token?: string;
280
+ email?: string;
281
+ /** Merged into existing customFields on the server */
282
+ customFields?: Record<string, unknown>;
283
+ tags?: string[];
284
+ tagsAction?: "set" | "add" | "remove";
285
+ listId?: string;
286
+ };
287
+ type ConfirmNewsletterResult = {
288
+ ok: boolean;
289
+ message: string;
290
+ email?: string;
291
+ };
292
+
293
+ type NewsletterRequestContext = RequestContext & {
294
+ newsletterBasePath: string;
295
+ };
296
+ declare function createNewsletterApi(ctx: NewsletterRequestContext): {
297
+ subscribe(input: SubscribeNewsletterInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
298
+ unsubscribe(input: UnsubscribeNewsletterInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
299
+ confirm(token: string, init?: FetchRequestInit): Promise<ConfirmNewsletterResult>;
300
+ updatePreferences(input: UpdateNewsletterPreferencesInput, init?: FetchRequestInit): Promise<NewsletterActionResult>;
301
+ };
302
+ type NewsletterApi = ReturnType<typeof createNewsletterApi>;
303
+
235
304
  type CmsClientConfig = {
236
305
  /** Base URL, e.g. https://cms-gateway.example.com */
237
306
  baseUrl: string;
238
307
  /** CMS site Mongo id — appended as ?siteId= on every public request */
239
308
  siteId?: string;
240
309
  /**
241
- * Path prefix before /public/blog and /public/api.
242
- * Default '' for gateway-cms direct (/public/blog/..., /public/api/...).
310
+ * Path prefix before /public/blog, /public/api, and /public/newsletter.
311
+ * Default '' for gateway-cms direct (/public/blog/..., etc.).
243
312
  * Use '/api/backend/cms' when routing through the main API gateway.
244
313
  */
245
314
  pathPrefix?: string;
@@ -249,7 +318,9 @@ type CmsClientConfig = {
249
318
  type CmsClient = {
250
319
  blog: BlogApi;
251
320
  content: ContentApi;
321
+ leads: LeadsApi;
322
+ newsletter: NewsletterApi;
252
323
  };
253
324
  declare function createCmsClient(config: CmsClientConfig): CmsClient;
254
325
 
255
- export { type BlogApi as B, type CmsApiResponse as C, type FetchRequestInit as F, type ListBlogPostsQuery as L, type MappedContentEntriesPage as M, type BlogAuthor as a, type BlogCategory as b, type BlogComment as c, type BlogCommentReply as d, type BlogEngagement as e, type BlogLikeResult as f, type BlogPost as g, type CmsBlogCategoryDto as h, type CmsBlogCommentDto as i, type CmsBlogPostDto as j, type CmsBlogPostsPage as k, type CmsClient as l, type CmsClientConfig as m, type CmsContentEntriesPage as n, type CmsContentEntryDto as o, type CmsContentTypeDto as p, type ContentApi as q, type ContentEntry as r, type ContentFilters as s, type ContentTypeMeta as t, type CreateBlogCommentInput as u, type CreateBlogCommentResult as v, type ListContentEntriesQuery as w, createCmsClient as x, serializeContentFilters as y };
326
+ export { type NewsletterApi as A, type BlogApi as B, type CmsApiResponse as C, type NewsletterSubscriberSummary as D, type SubmitLeadResult as E, type FetchRequestInit as F, type SubscribeNewsletterInput as G, type UpdateNewsletterPreferencesInput as H, createCmsClient as I, serializeContentFilters as J, type LeadSubmissionData as L, type MappedContentEntriesPage as M, type NewsletterActionResult as N, type SubmitLeadOptions as S, type UnsubscribeNewsletterInput as U, type BlogAuthor as a, type BlogCategory as b, type BlogComment as c, type BlogCommentReply as d, type BlogEngagement as e, type BlogLikeResult as f, type BlogPost as g, type CmsBlogCategoryDto as h, type CmsBlogCommentDto as i, type CmsBlogPostDto as j, type CmsBlogPostsPage as k, type CmsClient as l, type CmsClientConfig as m, type CmsContentEntriesPage as n, type CmsContentEntryDto as o, type CmsContentTypeDto as p, type ConfirmNewsletterResult as q, type ContentApi as r, type ContentEntry as s, type ContentFilters as t, type ContentTypeMeta as u, type CreateBlogCommentInput as v, type CreateBlogCommentResult as w, type LeadsApi as x, type ListBlogPostsQuery as y, type ListContentEntriesQuery as z };
package/dist/index.cjs CHANGED
@@ -41,6 +41,19 @@ async function publicGetNullable(ctx, path, init) {
41
41
  return null;
42
42
  }
43
43
  }
44
+ async function publicPost(ctx, path, body, init) {
45
+ const res = await ctx.fetchFn(buildPublicUrl(ctx, path), {
46
+ ...init,
47
+ method: "POST",
48
+ headers: {
49
+ "Content-Type": "application/json",
50
+ ...ctx.defaultHeaders,
51
+ ...init?.headers
52
+ },
53
+ body: JSON.stringify(body)
54
+ });
55
+ return unwrapResponse(res);
56
+ }
44
57
 
45
58
  // src/blog/mappers.ts
46
59
  function mediaUrl(value) {
@@ -287,6 +300,57 @@ function createContentApi(ctx) {
287
300
  };
288
301
  }
289
302
 
303
+ // src/leads/endpoints.ts
304
+ function createLeadsApi(ctx) {
305
+ const prefix = ctx.contentBasePath;
306
+ return {
307
+ async submit(contentTypeApiId, data, options, init) {
308
+ const url = buildPublicUrl(
309
+ ctx,
310
+ `${prefix}/${encodeURIComponent(contentTypeApiId)}/submissions`
311
+ );
312
+ const body = { data };
313
+ if (options?.status) {
314
+ body.status = options.status;
315
+ }
316
+ const res = await ctx.fetchFn(url, {
317
+ ...init,
318
+ method: "POST",
319
+ headers: {
320
+ "Content-Type": "application/json",
321
+ ...ctx.defaultHeaders,
322
+ ...init?.headers
323
+ },
324
+ body: JSON.stringify(body)
325
+ });
326
+ return unwrapResponse(res);
327
+ }
328
+ };
329
+ }
330
+
331
+ // src/newsletter/endpoints.ts
332
+ function createNewsletterApi(ctx) {
333
+ const prefix = ctx.newsletterBasePath;
334
+ return {
335
+ subscribe(input, init) {
336
+ return publicPost(ctx, `${prefix}/subscribe`, input, init);
337
+ },
338
+ unsubscribe(input, init) {
339
+ const body = {};
340
+ if (input.token) body.token = input.token;
341
+ if (input.email) body.email = input.email;
342
+ return publicPost(ctx, `${prefix}/unsubscribe`, body, init);
343
+ },
344
+ confirm(token, init) {
345
+ const path = `${prefix}/confirm/${encodeURIComponent(token)}`;
346
+ return publicGet(ctx, path, init);
347
+ },
348
+ updatePreferences(input, init) {
349
+ return publicPost(ctx, `${prefix}/preferences`, input, init);
350
+ }
351
+ };
352
+ }
353
+
290
354
  // src/client.ts
291
355
  function normalizeBaseUrl(url) {
292
356
  return url.replace(/\/$/, "");
@@ -301,6 +365,7 @@ function createCmsClient(config) {
301
365
  const pathPrefix = normalizePathPrefix(config.pathPrefix ?? "");
302
366
  const blogBasePath = `${pathPrefix}/public/blog`.replace(/\/+/g, "/");
303
367
  const contentBasePath = `${pathPrefix}/public/api`.replace(/\/+/g, "/");
368
+ const newsletterBasePath = `${pathPrefix}/public/newsletter`.replace(/\/+/g, "/");
304
369
  const ctx = {
305
370
  baseUrl,
306
371
  siteId: config.siteId,
@@ -309,7 +374,9 @@ function createCmsClient(config) {
309
374
  };
310
375
  return {
311
376
  blog: createBlogApi({ ...ctx, blogBasePath }),
312
- content: createContentApi({ ...ctx, contentBasePath })
377
+ content: createContentApi({ ...ctx, contentBasePath }),
378
+ leads: createLeadsApi({ ...ctx, contentBasePath }),
379
+ newsletter: createNewsletterApi({ ...ctx, newsletterBasePath })
313
380
  };
314
381
  }
315
382
 
@@ -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/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","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 { 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\";\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 and /public/api.\n * Default '' for gateway-cms direct (/public/blog/..., /public/api/...).\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};\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\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 };\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"],"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"]}
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, r as ContentEntry } from './client-DEovSyC5.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 ContentApi, s as ContentFilters, t as ContentTypeMeta, u as CreateBlogCommentInput, v as CreateBlogCommentResult, F as FetchRequestInit, L as ListBlogPostsQuery, w as ListContentEntriesQuery, M as MappedContentEntriesPage, x as createCmsClient, y as serializeContentFilters } from './client-DEovSyC5.cjs';
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-I3rZOjS6.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-I3rZOjS6.cjs';
3
3
 
4
4
  declare function mediaUrl(value: unknown): string | undefined;
5
5
  declare function mapCmsPostToBlogPost(dto: CmsBlogPostDto): BlogPost;
package/dist/index.d.ts 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, r as ContentEntry } from './client-DEovSyC5.js';
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 ContentApi, s as ContentFilters, t as ContentTypeMeta, u as CreateBlogCommentInput, v as CreateBlogCommentResult, F as FetchRequestInit, L as ListBlogPostsQuery, w as ListContentEntriesQuery, M as MappedContentEntriesPage, x as createCmsClient, y as serializeContentFilters } from './client-DEovSyC5.js';
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-I3rZOjS6.js';
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-I3rZOjS6.js';
3
3
 
4
4
  declare function mediaUrl(value: unknown): string | undefined;
5
5
  declare function mapCmsPostToBlogPost(dto: CmsBlogPostDto): BlogPost;