@utilsy/cms-nextjs 0.1.0 → 0.3.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 +142 -5
- package/dist/{client-C3E94syg.d.cts → client-Ba-p3TtH.d.cts} +99 -9
- package/dist/{client-C3E94syg.d.ts → client-Ba-p3TtH.d.ts} +99 -9
- package/dist/index.cjs +162 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +161 -49
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +80 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +29 -2
- package/dist/react.d.ts +29 -2
- package/dist/react.js +78 -1
- package/dist/react.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilsy/cms-nextjs
|
|
2
2
|
|
|
3
|
-
Headless Next.js SDK for [Utilsy gateway-cms](https://github.com/utilsy/utilsy-cms-nextjs-sdk) public blog
|
|
3
|
+
Headless Next.js SDK for [Utilsy gateway-cms](https://github.com/utilsy/utilsy-cms-nextjs-sdk) public CMS APIs: blog (`/public/blog`) and dynamic content types (`/public/api`). Provides a typed HTTP client, domain mappers, server-friendly fetch helpers, and React data hooks—bring your own UI.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -25,7 +25,7 @@ export const cms = createCmsClient({
|
|
|
25
25
|
});
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
**Main API gateway** (prefix before `/public/blog`):
|
|
28
|
+
**Main API gateway** (prefix before `/public/blog` and `/public/api`):
|
|
29
29
|
|
|
30
30
|
```ts
|
|
31
31
|
export const cms = createCmsClient({
|
|
@@ -62,7 +62,35 @@ export default async function BlogPage() {
|
|
|
62
62
|
}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
### 3.
|
|
65
|
+
### 3. Server Component (filtered content by type)
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { cms } from "@/lib/cms";
|
|
69
|
+
|
|
70
|
+
export default async function ServicesPage() {
|
|
71
|
+
const result = await cms.content.listMappedEntries(
|
|
72
|
+
"services",
|
|
73
|
+
{ page: 1, limit: 12, filters: { featured: true } },
|
|
74
|
+
{ next: { revalidate: 60, tags: ["cms:services"] } },
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (!result?.entries.length) {
|
|
78
|
+
return <p>No services yet.</p>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<ul>
|
|
83
|
+
{result.entries.map((entry) => (
|
|
84
|
+
<li key={entry.id}>
|
|
85
|
+
<a href={`/services/${entry.data.slug}`}>{String(entry.data.title ?? "")}</a>
|
|
86
|
+
</li>
|
|
87
|
+
))}
|
|
88
|
+
</ul>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 4. Client engagement (likes & comments)
|
|
66
94
|
|
|
67
95
|
```tsx
|
|
68
96
|
"use client";
|
|
@@ -97,6 +125,80 @@ function Engagement({ postId }: { postId: string }) {
|
|
|
97
125
|
}
|
|
98
126
|
```
|
|
99
127
|
|
|
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. Client content list (hooks)
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
"use client";
|
|
171
|
+
|
|
172
|
+
import { CmsProvider, useContentEntries } from "@utilsy/cms-nextjs/react";
|
|
173
|
+
import { cms } from "@/lib/cms";
|
|
174
|
+
|
|
175
|
+
export function ServicesList() {
|
|
176
|
+
return (
|
|
177
|
+
<CmsProvider client={cms}>
|
|
178
|
+
<ServicesListInner />
|
|
179
|
+
</CmsProvider>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function ServicesListInner() {
|
|
184
|
+
const { entries, loading, error } = useContentEntries("services", {
|
|
185
|
+
page: 1,
|
|
186
|
+
limit: 20,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (loading) return <p>Loading…</p>;
|
|
190
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<ul>
|
|
194
|
+
{entries.map((e) => (
|
|
195
|
+
<li key={e.id}>{String(e.data.title ?? "")}</li>
|
|
196
|
+
))}
|
|
197
|
+
</ul>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
100
202
|
## Environment variables
|
|
101
203
|
|
|
102
204
|
| Variable | Description |
|
|
@@ -114,10 +216,19 @@ The CMS resolves the site from:
|
|
|
114
216
|
|
|
115
217
|
For local dev or gateway-only deployments, always set `siteId` in the client config.
|
|
116
218
|
|
|
219
|
+
## Content types and filters
|
|
220
|
+
|
|
221
|
+
- Endpoint: `GET /public/api/{contentTypeApiId}` (published entries only).
|
|
222
|
+
- Content types must have `apiAccess: PUBLIC`.
|
|
223
|
+
- `filters` are exact matches on `data.<field>` (JSON query param). Example: `{ category: "news" }`.
|
|
224
|
+
- Use `contentTypeApiId` (kebab-case slug from CMS), not the Mongo content type id.
|
|
225
|
+
|
|
117
226
|
## API reference
|
|
118
227
|
|
|
119
228
|
### Client (`createCmsClient`)
|
|
120
229
|
|
|
230
|
+
#### Blog
|
|
231
|
+
|
|
121
232
|
| Method | Description |
|
|
122
233
|
|--------|-------------|
|
|
123
234
|
| `blog.listPosts(query?, init?)` | Paginated list (summary fields only) |
|
|
@@ -132,6 +243,29 @@ For local dev or gateway-only deployments, always set `siteId` in the client con
|
|
|
132
243
|
| `blog.listMappedCategories(...)` | Mapped categories |
|
|
133
244
|
| `blog.listMappedComments(...)` | Mapped comments |
|
|
134
245
|
|
|
246
|
+
#### Content
|
|
247
|
+
|
|
248
|
+
| Method | Description |
|
|
249
|
+
|--------|-------------|
|
|
250
|
+
| `content.listEntries(contentTypeApiId, query?, init?)` | Paginated raw DTOs |
|
|
251
|
+
| `content.getEntry(contentTypeApiId, idOrSlug, init?)` | Single raw DTO |
|
|
252
|
+
| `content.listMappedEntries(...)` | List + `mapCmsEntryToContentEntry` |
|
|
253
|
+
| `content.getMappedEntry(...)` | Single mapped `ContentEntry` |
|
|
254
|
+
|
|
255
|
+
Query params for `listEntries` / `listMappedEntries`: `page`, `limit`, `search`, `sort`, `order`, `filters` (object).
|
|
256
|
+
|
|
257
|
+
Helpers: `serializeContentFilters`, `mapCmsEntryToContentEntry`.
|
|
258
|
+
|
|
259
|
+
#### Leads
|
|
260
|
+
|
|
261
|
+
| Method | Description |
|
|
262
|
+
|--------|-------------|
|
|
263
|
+
| `leads.submit(contentTypeApiId, data, options?)` | Submit lead fields; creates content entry + CRM enquiry (throws on error) |
|
|
264
|
+
|
|
265
|
+
- Endpoint: `POST /public/api/{contentTypeApiId}/submissions`
|
|
266
|
+
- Content type must be `LEAD_CAPTURE` and `apiAccess: PUBLIC`
|
|
267
|
+
- Field keys in `data` must match the content type schema; CRM mapping uses `leadCaptureConfig` in admin
|
|
268
|
+
|
|
135
269
|
### React (`@utilsy/cms-nextjs/react`)
|
|
136
270
|
|
|
137
271
|
| Export | Description |
|
|
@@ -142,15 +276,18 @@ For local dev or gateway-only deployments, always set `siteId` in the client con
|
|
|
142
276
|
| `useBlogEngagement` | Load engagement stats |
|
|
143
277
|
| `useBlogLike` | Like toggle + counts |
|
|
144
278
|
| `useBlogComments` | List + submit comments |
|
|
279
|
+
| `useContentEntries` | List mapped entries by content type |
|
|
280
|
+
| `useContentEntry` | Single mapped entry by id or slug |
|
|
281
|
+
| `useSubmitLead` | Submit lead from client (prefer Server Action for forms) |
|
|
145
282
|
|
|
146
283
|
## CORS
|
|
147
284
|
|
|
148
|
-
Public
|
|
285
|
+
Public CMS reads from the browser require either:
|
|
149
286
|
|
|
150
287
|
- Same-origin proxy (e.g. Next.js Route Handler forwarding to gateway), or
|
|
151
288
|
- Server Components / Route Handlers calling the SDK server-side.
|
|
152
289
|
|
|
153
|
-
Mutations (comments, likes) should run
|
|
290
|
+
Mutations (comments, likes, lead submit) should run server-side (Server Action / Route Handler) or via a same-origin proxy with CORS configured on the gateway.
|
|
154
291
|
|
|
155
292
|
## License
|
|
156
293
|
|
|
@@ -11,6 +11,13 @@ type FetchRequestInit = RequestInit & {
|
|
|
11
11
|
cache?: RequestCache;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
type RequestContext = {
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
siteId?: string;
|
|
17
|
+
fetchFn: typeof fetch;
|
|
18
|
+
defaultHeaders: Record<string, string>;
|
|
19
|
+
};
|
|
20
|
+
|
|
14
21
|
/** Wire DTO from CMS public blog API */
|
|
15
22
|
type CmsBlogPostDto = {
|
|
16
23
|
id: string;
|
|
@@ -131,12 +138,8 @@ type ListBlogPostsQuery = {
|
|
|
131
138
|
tag?: string;
|
|
132
139
|
};
|
|
133
140
|
|
|
134
|
-
type BlogRequestContext = {
|
|
135
|
-
baseUrl: string;
|
|
141
|
+
type BlogRequestContext = RequestContext & {
|
|
136
142
|
blogBasePath: string;
|
|
137
|
-
siteId?: string;
|
|
138
|
-
fetchFn: typeof fetch;
|
|
139
|
-
defaultHeaders: Record<string, string>;
|
|
140
143
|
};
|
|
141
144
|
declare function createBlogApi(ctx: BlogRequestContext): {
|
|
142
145
|
listPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit): Promise<CmsBlogPostsPage | null>;
|
|
@@ -162,14 +165,99 @@ declare function createBlogApi(ctx: BlogRequestContext): {
|
|
|
162
165
|
};
|
|
163
166
|
type BlogApi = ReturnType<typeof createBlogApi>;
|
|
164
167
|
|
|
168
|
+
type ContentFilters = Record<string, unknown>;
|
|
169
|
+
declare function serializeContentFilters(filters: ContentFilters): string;
|
|
170
|
+
|
|
171
|
+
type ListContentEntriesQuery = {
|
|
172
|
+
page?: number;
|
|
173
|
+
limit?: number;
|
|
174
|
+
search?: string;
|
|
175
|
+
sort?: string;
|
|
176
|
+
order?: "asc" | "desc";
|
|
177
|
+
filters?: ContentFilters;
|
|
178
|
+
};
|
|
179
|
+
type CmsContentTypeDto = {
|
|
180
|
+
_id?: string;
|
|
181
|
+
id?: string;
|
|
182
|
+
name?: string;
|
|
183
|
+
apiId?: string;
|
|
184
|
+
fields?: unknown[];
|
|
185
|
+
status?: string;
|
|
186
|
+
};
|
|
187
|
+
type CmsContentEntryDto = {
|
|
188
|
+
_id?: string;
|
|
189
|
+
id?: string;
|
|
190
|
+
contentTypeId?: string;
|
|
191
|
+
contentType?: CmsContentTypeDto;
|
|
192
|
+
siteId?: string;
|
|
193
|
+
status?: string;
|
|
194
|
+
data?: Record<string, unknown>;
|
|
195
|
+
createdAt?: string;
|
|
196
|
+
updatedAt?: string;
|
|
197
|
+
};
|
|
198
|
+
type CmsContentEntriesPage = {
|
|
199
|
+
message?: string;
|
|
200
|
+
docs: CmsContentEntryDto[];
|
|
201
|
+
totalDocs: number;
|
|
202
|
+
};
|
|
203
|
+
type ContentTypeMeta = {
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
apiId: string;
|
|
207
|
+
fields?: unknown[];
|
|
208
|
+
status?: string;
|
|
209
|
+
};
|
|
210
|
+
type ContentEntry = {
|
|
211
|
+
id: string;
|
|
212
|
+
contentTypeId: string;
|
|
213
|
+
contentType?: ContentTypeMeta;
|
|
214
|
+
status: string;
|
|
215
|
+
data: Record<string, unknown>;
|
|
216
|
+
createdAt?: string;
|
|
217
|
+
updatedAt?: string;
|
|
218
|
+
};
|
|
219
|
+
type MappedContentEntriesPage = {
|
|
220
|
+
entries: ContentEntry[];
|
|
221
|
+
totalDocs: number;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
type ContentRequestContext = RequestContext & {
|
|
225
|
+
contentBasePath: string;
|
|
226
|
+
};
|
|
227
|
+
declare function createContentApi(ctx: ContentRequestContext): {
|
|
228
|
+
listEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<CmsContentEntriesPage | null>;
|
|
229
|
+
getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<CmsContentEntryDto | null>;
|
|
230
|
+
listMappedEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<MappedContentEntriesPage | null>;
|
|
231
|
+
getMappedEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
232
|
+
};
|
|
233
|
+
type ContentApi = ReturnType<typeof createContentApi>;
|
|
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
|
+
|
|
165
253
|
type CmsClientConfig = {
|
|
166
254
|
/** Base URL, e.g. https://cms-gateway.example.com */
|
|
167
255
|
baseUrl: string;
|
|
168
|
-
/** CMS site Mongo id — appended as ?siteId= on every
|
|
256
|
+
/** CMS site Mongo id — appended as ?siteId= on every public request */
|
|
169
257
|
siteId?: string;
|
|
170
258
|
/**
|
|
171
|
-
* Path prefix before /public/blog.
|
|
172
|
-
* Default '' for gateway-cms direct (/public/blog/...).
|
|
259
|
+
* Path prefix before /public/blog and /public/api.
|
|
260
|
+
* Default '' for gateway-cms direct (/public/blog/..., /public/api/...).
|
|
173
261
|
* Use '/api/backend/cms' when routing through the main API gateway.
|
|
174
262
|
*/
|
|
175
263
|
pathPrefix?: string;
|
|
@@ -178,7 +266,9 @@ type CmsClientConfig = {
|
|
|
178
266
|
};
|
|
179
267
|
type CmsClient = {
|
|
180
268
|
blog: BlogApi;
|
|
269
|
+
content: ContentApi;
|
|
270
|
+
leads: LeadsApi;
|
|
181
271
|
};
|
|
182
272
|
declare function createCmsClient(config: CmsClientConfig): CmsClient;
|
|
183
273
|
|
|
184
|
-
export { type BlogApi as B, type CmsApiResponse as C, type FetchRequestInit as F, type
|
|
274
|
+
export { createCmsClient as A, type BlogApi as B, type CmsApiResponse as C, serializeContentFilters as D, type FetchRequestInit as F, type LeadSubmissionData as L, type MappedContentEntriesPage as M, type SubmitLeadOptions as S, 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 LeadsApi as w, type ListBlogPostsQuery as x, type ListContentEntriesQuery as y, type SubmitLeadResult as z };
|
|
@@ -11,6 +11,13 @@ type FetchRequestInit = RequestInit & {
|
|
|
11
11
|
cache?: RequestCache;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
type RequestContext = {
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
siteId?: string;
|
|
17
|
+
fetchFn: typeof fetch;
|
|
18
|
+
defaultHeaders: Record<string, string>;
|
|
19
|
+
};
|
|
20
|
+
|
|
14
21
|
/** Wire DTO from CMS public blog API */
|
|
15
22
|
type CmsBlogPostDto = {
|
|
16
23
|
id: string;
|
|
@@ -131,12 +138,8 @@ type ListBlogPostsQuery = {
|
|
|
131
138
|
tag?: string;
|
|
132
139
|
};
|
|
133
140
|
|
|
134
|
-
type BlogRequestContext = {
|
|
135
|
-
baseUrl: string;
|
|
141
|
+
type BlogRequestContext = RequestContext & {
|
|
136
142
|
blogBasePath: string;
|
|
137
|
-
siteId?: string;
|
|
138
|
-
fetchFn: typeof fetch;
|
|
139
|
-
defaultHeaders: Record<string, string>;
|
|
140
143
|
};
|
|
141
144
|
declare function createBlogApi(ctx: BlogRequestContext): {
|
|
142
145
|
listPosts(query?: ListBlogPostsQuery, init?: FetchRequestInit): Promise<CmsBlogPostsPage | null>;
|
|
@@ -162,14 +165,99 @@ declare function createBlogApi(ctx: BlogRequestContext): {
|
|
|
162
165
|
};
|
|
163
166
|
type BlogApi = ReturnType<typeof createBlogApi>;
|
|
164
167
|
|
|
168
|
+
type ContentFilters = Record<string, unknown>;
|
|
169
|
+
declare function serializeContentFilters(filters: ContentFilters): string;
|
|
170
|
+
|
|
171
|
+
type ListContentEntriesQuery = {
|
|
172
|
+
page?: number;
|
|
173
|
+
limit?: number;
|
|
174
|
+
search?: string;
|
|
175
|
+
sort?: string;
|
|
176
|
+
order?: "asc" | "desc";
|
|
177
|
+
filters?: ContentFilters;
|
|
178
|
+
};
|
|
179
|
+
type CmsContentTypeDto = {
|
|
180
|
+
_id?: string;
|
|
181
|
+
id?: string;
|
|
182
|
+
name?: string;
|
|
183
|
+
apiId?: string;
|
|
184
|
+
fields?: unknown[];
|
|
185
|
+
status?: string;
|
|
186
|
+
};
|
|
187
|
+
type CmsContentEntryDto = {
|
|
188
|
+
_id?: string;
|
|
189
|
+
id?: string;
|
|
190
|
+
contentTypeId?: string;
|
|
191
|
+
contentType?: CmsContentTypeDto;
|
|
192
|
+
siteId?: string;
|
|
193
|
+
status?: string;
|
|
194
|
+
data?: Record<string, unknown>;
|
|
195
|
+
createdAt?: string;
|
|
196
|
+
updatedAt?: string;
|
|
197
|
+
};
|
|
198
|
+
type CmsContentEntriesPage = {
|
|
199
|
+
message?: string;
|
|
200
|
+
docs: CmsContentEntryDto[];
|
|
201
|
+
totalDocs: number;
|
|
202
|
+
};
|
|
203
|
+
type ContentTypeMeta = {
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
apiId: string;
|
|
207
|
+
fields?: unknown[];
|
|
208
|
+
status?: string;
|
|
209
|
+
};
|
|
210
|
+
type ContentEntry = {
|
|
211
|
+
id: string;
|
|
212
|
+
contentTypeId: string;
|
|
213
|
+
contentType?: ContentTypeMeta;
|
|
214
|
+
status: string;
|
|
215
|
+
data: Record<string, unknown>;
|
|
216
|
+
createdAt?: string;
|
|
217
|
+
updatedAt?: string;
|
|
218
|
+
};
|
|
219
|
+
type MappedContentEntriesPage = {
|
|
220
|
+
entries: ContentEntry[];
|
|
221
|
+
totalDocs: number;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
type ContentRequestContext = RequestContext & {
|
|
225
|
+
contentBasePath: string;
|
|
226
|
+
};
|
|
227
|
+
declare function createContentApi(ctx: ContentRequestContext): {
|
|
228
|
+
listEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<CmsContentEntriesPage | null>;
|
|
229
|
+
getEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<CmsContentEntryDto | null>;
|
|
230
|
+
listMappedEntries(contentTypeApiId: string, query?: ListContentEntriesQuery, init?: FetchRequestInit): Promise<MappedContentEntriesPage | null>;
|
|
231
|
+
getMappedEntry(contentTypeApiId: string, idOrSlug: string, init?: FetchRequestInit): Promise<ContentEntry | null>;
|
|
232
|
+
};
|
|
233
|
+
type ContentApi = ReturnType<typeof createContentApi>;
|
|
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
|
+
|
|
165
253
|
type CmsClientConfig = {
|
|
166
254
|
/** Base URL, e.g. https://cms-gateway.example.com */
|
|
167
255
|
baseUrl: string;
|
|
168
|
-
/** CMS site Mongo id — appended as ?siteId= on every
|
|
256
|
+
/** CMS site Mongo id — appended as ?siteId= on every public request */
|
|
169
257
|
siteId?: string;
|
|
170
258
|
/**
|
|
171
|
-
* Path prefix before /public/blog.
|
|
172
|
-
* Default '' for gateway-cms direct (/public/blog/...).
|
|
259
|
+
* Path prefix before /public/blog and /public/api.
|
|
260
|
+
* Default '' for gateway-cms direct (/public/blog/..., /public/api/...).
|
|
173
261
|
* Use '/api/backend/cms' when routing through the main API gateway.
|
|
174
262
|
*/
|
|
175
263
|
pathPrefix?: string;
|
|
@@ -178,7 +266,9 @@ type CmsClientConfig = {
|
|
|
178
266
|
};
|
|
179
267
|
type CmsClient = {
|
|
180
268
|
blog: BlogApi;
|
|
269
|
+
content: ContentApi;
|
|
270
|
+
leads: LeadsApi;
|
|
181
271
|
};
|
|
182
272
|
declare function createCmsClient(config: CmsClientConfig): CmsClient;
|
|
183
273
|
|
|
184
|
-
export { type BlogApi as B, type CmsApiResponse as C, type FetchRequestInit as F, type
|
|
274
|
+
export { createCmsClient as A, type BlogApi as B, type CmsApiResponse as C, serializeContentFilters as D, type FetchRequestInit as F, type LeadSubmissionData as L, type MappedContentEntriesPage as M, type SubmitLeadOptions as S, 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 LeadsApi as w, type ListBlogPostsQuery as x, type ListContentEntriesQuery as y, type SubmitLeadResult as z };
|