@forjacms/client 1.2.6
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 +282 -0
- package/dist/angular/index.cjs +1 -0
- package/dist/angular/index.d.cts +140 -0
- package/dist/angular/index.d.mts +140 -0
- package/dist/angular/index.mjs +1 -0
- package/dist/client-BBAKLM2r.d.cts +1673 -0
- package/dist/client-DTfhjUoX.mjs +1 -0
- package/dist/client-d-QwwKUW.d.mts +1673 -0
- package/dist/client-eFMh_n88.cjs +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +104 -0
- package/dist/index.d.mts +104 -0
- package/dist/index.mjs +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,1673 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface ForjaClientConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
siteId: string;
|
|
6
|
+
fetch?: typeof globalThis.fetch;
|
|
7
|
+
}
|
|
8
|
+
interface PaginationMeta {
|
|
9
|
+
page: number;
|
|
10
|
+
page_size: number;
|
|
11
|
+
total_pages: number;
|
|
12
|
+
total_items: number;
|
|
13
|
+
}
|
|
14
|
+
interface Paginated<T> {
|
|
15
|
+
data: T[];
|
|
16
|
+
meta: PaginationMeta;
|
|
17
|
+
}
|
|
18
|
+
interface PaginationParams {
|
|
19
|
+
page?: number;
|
|
20
|
+
pageSize?: number;
|
|
21
|
+
}
|
|
22
|
+
interface LocaleFilterParams extends PaginationParams {
|
|
23
|
+
/** Filter to content with a localization in this locale (UUID). */
|
|
24
|
+
localeId?: string;
|
|
25
|
+
}
|
|
26
|
+
interface SearchablePaginationParams extends PaginationParams {
|
|
27
|
+
search?: string;
|
|
28
|
+
sortBy?: string;
|
|
29
|
+
sortDir?: 'asc' | 'desc';
|
|
30
|
+
}
|
|
31
|
+
type ContentStatus = 'Draft' | 'InReview' | 'Scheduled' | 'Published' | 'Archived';
|
|
32
|
+
type TranslationStatus = 'Pending' | 'InProgress' | 'Review' | 'Approved' | 'Outdated';
|
|
33
|
+
type PageType = 'Static' | 'Landing' | 'Contact' | 'BlogIndex' | 'Custom';
|
|
34
|
+
type SectionType = 'Hero' | 'Features' | 'Cta' | 'Gallery' | 'Testimonials' | 'Pricing' | 'Faq' | 'Contact' | 'Custom' | 'Stats' | 'Team' | 'Timeline' | 'LogoCloud' | 'Newsletter' | 'Video' | 'Divider' | 'Text' | 'Portfolio' | 'TagCloud' | 'Projects' | 'Blog' | 'Legal';
|
|
35
|
+
type CvEntryType = 'Work' | 'Education' | 'Volunteer' | 'Certification' | 'Project';
|
|
36
|
+
type SkillCategory = 'Programming' | 'Framework' | 'Database' | 'Devops' | 'Language' | 'SoftSkill' | 'Tool' | 'Other';
|
|
37
|
+
type LegalDocType = 'CookieConsent' | 'PrivacyPolicy' | 'TermsOfService' | 'Imprint' | 'Disclaimer';
|
|
38
|
+
interface LocalizationResponse {
|
|
39
|
+
id: string;
|
|
40
|
+
content_id: string;
|
|
41
|
+
locale_id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
subtitle: string | null;
|
|
44
|
+
excerpt: string | null;
|
|
45
|
+
body: string | null;
|
|
46
|
+
meta_title: string | null;
|
|
47
|
+
meta_description: string | null;
|
|
48
|
+
translation_status: TranslationStatus;
|
|
49
|
+
created_at: string;
|
|
50
|
+
updated_at: string;
|
|
51
|
+
}
|
|
52
|
+
interface BlogListItem {
|
|
53
|
+
id: string;
|
|
54
|
+
content_id: string;
|
|
55
|
+
slug: string | null;
|
|
56
|
+
author: string;
|
|
57
|
+
published_date: string;
|
|
58
|
+
reading_time_minutes: number | null;
|
|
59
|
+
cover_image_id: string | null;
|
|
60
|
+
header_image_id: string | null;
|
|
61
|
+
is_featured: boolean;
|
|
62
|
+
is_sample: boolean;
|
|
63
|
+
status: ContentStatus;
|
|
64
|
+
publish_start: string | null;
|
|
65
|
+
publish_end: string | null;
|
|
66
|
+
created_at: string;
|
|
67
|
+
updated_at: string;
|
|
68
|
+
}
|
|
69
|
+
interface BlogResponse {
|
|
70
|
+
id: string;
|
|
71
|
+
content_id: string;
|
|
72
|
+
slug: string | null;
|
|
73
|
+
author: string;
|
|
74
|
+
published_date: string;
|
|
75
|
+
reading_time_minutes: number | null;
|
|
76
|
+
cover_image_id: string | null;
|
|
77
|
+
header_image_id: string | null;
|
|
78
|
+
is_featured: boolean;
|
|
79
|
+
is_sample: boolean;
|
|
80
|
+
allow_comments: boolean;
|
|
81
|
+
status: ContentStatus;
|
|
82
|
+
published_at: string | null;
|
|
83
|
+
publish_start: string | null;
|
|
84
|
+
publish_end: string | null;
|
|
85
|
+
created_at: string;
|
|
86
|
+
updated_at: string;
|
|
87
|
+
}
|
|
88
|
+
interface BlogDocumentResponse {
|
|
89
|
+
id: string;
|
|
90
|
+
blog_id: string;
|
|
91
|
+
document_id: string;
|
|
92
|
+
display_order: number;
|
|
93
|
+
url: string | null;
|
|
94
|
+
document_type: string;
|
|
95
|
+
file_name: string | null;
|
|
96
|
+
has_file: boolean;
|
|
97
|
+
localizations: DocumentLocalizationResponse[];
|
|
98
|
+
created_at: string;
|
|
99
|
+
}
|
|
100
|
+
interface DocumentLocalizationResponse {
|
|
101
|
+
id: string;
|
|
102
|
+
document_id: string;
|
|
103
|
+
locale_id: string;
|
|
104
|
+
name: string;
|
|
105
|
+
description: string | null;
|
|
106
|
+
created_at: string;
|
|
107
|
+
updated_at: string;
|
|
108
|
+
}
|
|
109
|
+
interface BlogDetailResponse extends BlogResponse {
|
|
110
|
+
localizations: LocalizationResponse[];
|
|
111
|
+
categories: CategoryResponse[];
|
|
112
|
+
documents: BlogDocumentResponse[];
|
|
113
|
+
og_image_url: string | null;
|
|
114
|
+
}
|
|
115
|
+
interface PageListItem {
|
|
116
|
+
id: string;
|
|
117
|
+
route: string;
|
|
118
|
+
page_type: PageType;
|
|
119
|
+
slug: string | null;
|
|
120
|
+
is_in_navigation: boolean;
|
|
121
|
+
status: ContentStatus;
|
|
122
|
+
publish_start: string | null;
|
|
123
|
+
publish_end: string | null;
|
|
124
|
+
created_at: string;
|
|
125
|
+
}
|
|
126
|
+
interface PageResponse {
|
|
127
|
+
id: string;
|
|
128
|
+
content_id: string;
|
|
129
|
+
route: string;
|
|
130
|
+
page_type: PageType;
|
|
131
|
+
template: string | null;
|
|
132
|
+
is_in_navigation: boolean;
|
|
133
|
+
navigation_order: number | null;
|
|
134
|
+
parent_page_id: string | null;
|
|
135
|
+
slug: string | null;
|
|
136
|
+
status: ContentStatus;
|
|
137
|
+
published_at: string | null;
|
|
138
|
+
publish_start: string | null;
|
|
139
|
+
publish_end: string | null;
|
|
140
|
+
created_at: string;
|
|
141
|
+
updated_at: string;
|
|
142
|
+
}
|
|
143
|
+
interface PageDetailResponse extends PageResponse {
|
|
144
|
+
localizations: LocalizationResponse[];
|
|
145
|
+
og_image_url: string | null;
|
|
146
|
+
}
|
|
147
|
+
interface PageSectionResponse {
|
|
148
|
+
id: string;
|
|
149
|
+
page_id: string;
|
|
150
|
+
section_type: SectionType;
|
|
151
|
+
display_order: number;
|
|
152
|
+
cover_image_id: string | null;
|
|
153
|
+
call_to_action_route: string | null;
|
|
154
|
+
settings: Record<string, unknown> | null;
|
|
155
|
+
}
|
|
156
|
+
interface SectionLocalizationResponse {
|
|
157
|
+
id: string;
|
|
158
|
+
page_section_id: string;
|
|
159
|
+
locale_id: string;
|
|
160
|
+
title: string | null;
|
|
161
|
+
text: string | null;
|
|
162
|
+
button_text: string | null;
|
|
163
|
+
}
|
|
164
|
+
interface NavigationMenuResponse {
|
|
165
|
+
id: string;
|
|
166
|
+
site_id: string;
|
|
167
|
+
slug: string;
|
|
168
|
+
description: string | null;
|
|
169
|
+
max_depth: number;
|
|
170
|
+
is_active: boolean;
|
|
171
|
+
item_count: number;
|
|
172
|
+
created_at: string;
|
|
173
|
+
}
|
|
174
|
+
interface NavigationItemResponse {
|
|
175
|
+
id: string;
|
|
176
|
+
menu_id: string;
|
|
177
|
+
parent_id: string | null;
|
|
178
|
+
page_id: string | null;
|
|
179
|
+
external_url: string | null;
|
|
180
|
+
icon: string | null;
|
|
181
|
+
display_order: number;
|
|
182
|
+
open_in_new_tab: boolean;
|
|
183
|
+
title: string | null;
|
|
184
|
+
}
|
|
185
|
+
interface NavigationTree {
|
|
186
|
+
id: string;
|
|
187
|
+
parent_id: string | null;
|
|
188
|
+
page_id: string | null;
|
|
189
|
+
external_url: string | null;
|
|
190
|
+
icon: string | null;
|
|
191
|
+
display_order: number;
|
|
192
|
+
open_in_new_tab: boolean;
|
|
193
|
+
title: string | null;
|
|
194
|
+
page_slug: string | null;
|
|
195
|
+
children: NavigationTree[];
|
|
196
|
+
}
|
|
197
|
+
interface NavigationItemLocalizationResponse {
|
|
198
|
+
id: string;
|
|
199
|
+
navigation_item_id: string;
|
|
200
|
+
locale_id: string;
|
|
201
|
+
title: string;
|
|
202
|
+
}
|
|
203
|
+
interface TagResponse {
|
|
204
|
+
id: string;
|
|
205
|
+
slug: string;
|
|
206
|
+
is_global: boolean;
|
|
207
|
+
created_at: string;
|
|
208
|
+
}
|
|
209
|
+
interface CategoryResponse {
|
|
210
|
+
id: string;
|
|
211
|
+
parent_id: string | null;
|
|
212
|
+
slug: string;
|
|
213
|
+
is_global: boolean;
|
|
214
|
+
created_at: string;
|
|
215
|
+
}
|
|
216
|
+
interface CategoryTree {
|
|
217
|
+
id: string;
|
|
218
|
+
slug: string;
|
|
219
|
+
is_global: boolean;
|
|
220
|
+
children: CategoryTree[];
|
|
221
|
+
}
|
|
222
|
+
interface CategoryWithCountResponse {
|
|
223
|
+
id: string;
|
|
224
|
+
parent_id: string | null;
|
|
225
|
+
slug: string;
|
|
226
|
+
is_global: boolean;
|
|
227
|
+
created_at: string;
|
|
228
|
+
blog_count: number;
|
|
229
|
+
}
|
|
230
|
+
interface TopContentItem {
|
|
231
|
+
path: string;
|
|
232
|
+
total_views: number;
|
|
233
|
+
unique_visitors: number;
|
|
234
|
+
}
|
|
235
|
+
interface TrendDataPoint {
|
|
236
|
+
date: string;
|
|
237
|
+
total_views: number;
|
|
238
|
+
unique_visitors: number;
|
|
239
|
+
}
|
|
240
|
+
interface AnalyticsReportResponse {
|
|
241
|
+
total_views: number;
|
|
242
|
+
total_unique_visitors: number;
|
|
243
|
+
top_content: TopContentItem[];
|
|
244
|
+
trend: TrendDataPoint[];
|
|
245
|
+
}
|
|
246
|
+
interface ReferrerItem {
|
|
247
|
+
domain: string;
|
|
248
|
+
views: number;
|
|
249
|
+
}
|
|
250
|
+
interface AnalyticsPageDetailResponse {
|
|
251
|
+
path: string;
|
|
252
|
+
total_views: number;
|
|
253
|
+
total_unique_visitors: number;
|
|
254
|
+
trend: TrendDataPoint[];
|
|
255
|
+
referrers: ReferrerItem[];
|
|
256
|
+
}
|
|
257
|
+
interface TrackPageviewRequest {
|
|
258
|
+
path: string;
|
|
259
|
+
referrer?: string;
|
|
260
|
+
}
|
|
261
|
+
interface TrackPageviewResponse {
|
|
262
|
+
ok: boolean;
|
|
263
|
+
}
|
|
264
|
+
interface AnalyticsReportParams {
|
|
265
|
+
days?: number;
|
|
266
|
+
topN?: number;
|
|
267
|
+
startDate?: string;
|
|
268
|
+
endDate?: string;
|
|
269
|
+
}
|
|
270
|
+
interface AnalyticsPageParams {
|
|
271
|
+
path: string;
|
|
272
|
+
days?: number;
|
|
273
|
+
startDate?: string;
|
|
274
|
+
endDate?: string;
|
|
275
|
+
}
|
|
276
|
+
interface SkillResponse {
|
|
277
|
+
id: string;
|
|
278
|
+
name: string;
|
|
279
|
+
slug: string;
|
|
280
|
+
category: SkillCategory | null;
|
|
281
|
+
icon: string | null;
|
|
282
|
+
proficiency_level: number | null;
|
|
283
|
+
}
|
|
284
|
+
interface CvEntryResponse {
|
|
285
|
+
id: string;
|
|
286
|
+
company: string;
|
|
287
|
+
company_url: string | null;
|
|
288
|
+
company_logo_id: string | null;
|
|
289
|
+
location: string;
|
|
290
|
+
start_date: string;
|
|
291
|
+
end_date: string | null;
|
|
292
|
+
is_current: boolean;
|
|
293
|
+
entry_type: CvEntryType;
|
|
294
|
+
display_order: number;
|
|
295
|
+
created_at: string;
|
|
296
|
+
updated_at: string;
|
|
297
|
+
}
|
|
298
|
+
interface CvEntryParams extends SearchablePaginationParams {
|
|
299
|
+
entryType?: CvEntryType;
|
|
300
|
+
}
|
|
301
|
+
interface LegalDocumentResponse {
|
|
302
|
+
id: string;
|
|
303
|
+
cookie_name: string;
|
|
304
|
+
document_type: LegalDocType;
|
|
305
|
+
created_at: string;
|
|
306
|
+
updated_at: string;
|
|
307
|
+
}
|
|
308
|
+
interface LegalDocLocalizationResponse {
|
|
309
|
+
id: string;
|
|
310
|
+
locale_id: string;
|
|
311
|
+
title: string;
|
|
312
|
+
intro: string | null;
|
|
313
|
+
}
|
|
314
|
+
interface LegalDocumentDetailResponse {
|
|
315
|
+
id: string;
|
|
316
|
+
cookie_name: string;
|
|
317
|
+
document_type: LegalDocType;
|
|
318
|
+
localizations: LegalDocLocalizationResponse[];
|
|
319
|
+
created_at: string;
|
|
320
|
+
updated_at: string;
|
|
321
|
+
}
|
|
322
|
+
interface LegalGroupResponse {
|
|
323
|
+
id: string;
|
|
324
|
+
cookie_name: string;
|
|
325
|
+
display_order: number;
|
|
326
|
+
is_required: boolean;
|
|
327
|
+
default_enabled: boolean;
|
|
328
|
+
}
|
|
329
|
+
interface LegalItemResponse {
|
|
330
|
+
id: string;
|
|
331
|
+
cookie_name: string;
|
|
332
|
+
display_order: number;
|
|
333
|
+
is_required: boolean;
|
|
334
|
+
}
|
|
335
|
+
interface LegalGroupWithItems {
|
|
336
|
+
id: string;
|
|
337
|
+
cookie_name: string;
|
|
338
|
+
display_order: number;
|
|
339
|
+
is_required: boolean;
|
|
340
|
+
default_enabled: boolean;
|
|
341
|
+
items: LegalItemResponse[];
|
|
342
|
+
}
|
|
343
|
+
interface LegalDocumentWithGroups {
|
|
344
|
+
id: string;
|
|
345
|
+
cookie_name: string;
|
|
346
|
+
document_type: LegalDocType;
|
|
347
|
+
groups: LegalGroupWithItems[];
|
|
348
|
+
}
|
|
349
|
+
interface SiteResponse {
|
|
350
|
+
id: string;
|
|
351
|
+
name: string;
|
|
352
|
+
slug: string;
|
|
353
|
+
description: string | null;
|
|
354
|
+
logo_url: string | null;
|
|
355
|
+
favicon_url: string | null;
|
|
356
|
+
base_url: string | null;
|
|
357
|
+
theme: Record<string, unknown> | null;
|
|
358
|
+
default_locale_id: string | null;
|
|
359
|
+
timezone: string;
|
|
360
|
+
is_active: boolean;
|
|
361
|
+
created_at: string;
|
|
362
|
+
updated_at: string;
|
|
363
|
+
}
|
|
364
|
+
interface MediaVariantResponse {
|
|
365
|
+
id: string;
|
|
366
|
+
variant_name: string;
|
|
367
|
+
width: number;
|
|
368
|
+
height: number;
|
|
369
|
+
file_size: number;
|
|
370
|
+
public_url: string | null;
|
|
371
|
+
}
|
|
372
|
+
interface MediaResponse {
|
|
373
|
+
id: string;
|
|
374
|
+
filename: string;
|
|
375
|
+
original_filename: string;
|
|
376
|
+
mime_type: string;
|
|
377
|
+
file_size: number;
|
|
378
|
+
storage_provider: string;
|
|
379
|
+
public_url: string | null;
|
|
380
|
+
width: number | null;
|
|
381
|
+
height: number | null;
|
|
382
|
+
duration: number | null;
|
|
383
|
+
is_global: boolean;
|
|
384
|
+
created_at: string;
|
|
385
|
+
updated_at: string;
|
|
386
|
+
variants: MediaVariantResponse[];
|
|
387
|
+
}
|
|
388
|
+
interface SocialLinkResponse {
|
|
389
|
+
id: string;
|
|
390
|
+
title: string;
|
|
391
|
+
url: string;
|
|
392
|
+
icon: string;
|
|
393
|
+
alt_text: string | null;
|
|
394
|
+
display_order: number;
|
|
395
|
+
}
|
|
396
|
+
/** Link type for project resources (repository, demo, docs, etc.). */
|
|
397
|
+
type ProjectLinkType = 'repository' | 'demo' | 'documentation' | 'website' | 'other';
|
|
398
|
+
/** Project summary for list views. */
|
|
399
|
+
interface ProjectResponse {
|
|
400
|
+
id: string;
|
|
401
|
+
slug: string;
|
|
402
|
+
display_order: number;
|
|
403
|
+
is_featured: boolean;
|
|
404
|
+
start_date: string | null;
|
|
405
|
+
end_date: string | null;
|
|
406
|
+
is_ongoing: boolean;
|
|
407
|
+
status: ContentStatus;
|
|
408
|
+
published_at: string | null;
|
|
409
|
+
created_at: string;
|
|
410
|
+
updated_at: string;
|
|
411
|
+
}
|
|
412
|
+
/** Localized content for a project. */
|
|
413
|
+
interface ProjectLocalizationResponse {
|
|
414
|
+
id: string;
|
|
415
|
+
locale_id: string;
|
|
416
|
+
title: string;
|
|
417
|
+
short_description: string | null;
|
|
418
|
+
description: string | null;
|
|
419
|
+
}
|
|
420
|
+
/** External link attached to a project. */
|
|
421
|
+
interface ProjectLinkResponse {
|
|
422
|
+
id: string;
|
|
423
|
+
label: string;
|
|
424
|
+
url: string;
|
|
425
|
+
link_type: ProjectLinkType;
|
|
426
|
+
icon: string | null;
|
|
427
|
+
display_order: number;
|
|
428
|
+
}
|
|
429
|
+
/** Media attachment on a project (cover image, screenshots). */
|
|
430
|
+
interface ProjectMediaResponse {
|
|
431
|
+
media_id: string;
|
|
432
|
+
display_order: number;
|
|
433
|
+
is_cover: boolean;
|
|
434
|
+
}
|
|
435
|
+
/** Full project detail including localizations, links, and media. */
|
|
436
|
+
interface ProjectDetailResponse extends ProjectResponse {
|
|
437
|
+
localizations: ProjectLocalizationResponse[];
|
|
438
|
+
links: ProjectLinkResponse[];
|
|
439
|
+
media: ProjectMediaResponse[];
|
|
440
|
+
skill_ids: string[];
|
|
441
|
+
cv_entry_ids: string[];
|
|
442
|
+
}
|
|
443
|
+
/** Pagination and filter params for project listings. */
|
|
444
|
+
interface ProjectListParams extends PaginationParams {
|
|
445
|
+
/** Sort field (e.g. `"display_order"`, `"start_date"`). */
|
|
446
|
+
sortBy?: string;
|
|
447
|
+
/** Sort direction. */
|
|
448
|
+
sortDir?: 'asc' | 'desc';
|
|
449
|
+
/** Filter to featured projects only. */
|
|
450
|
+
isFeatured?: boolean;
|
|
451
|
+
}
|
|
452
|
+
/** A URL redirect rule. */
|
|
453
|
+
interface RedirectResponse {
|
|
454
|
+
id: string;
|
|
455
|
+
site_id: string;
|
|
456
|
+
source_path: string;
|
|
457
|
+
destination_path: string;
|
|
458
|
+
status_code: number;
|
|
459
|
+
is_active: boolean;
|
|
460
|
+
description: string | null;
|
|
461
|
+
created_at: string;
|
|
462
|
+
updated_at: string;
|
|
463
|
+
}
|
|
464
|
+
/** Result of a redirect path lookup. */
|
|
465
|
+
interface RedirectLookupResponse {
|
|
466
|
+
destination_path: string;
|
|
467
|
+
status_code: number;
|
|
468
|
+
}
|
|
469
|
+
/** A locale configured for a site. */
|
|
470
|
+
interface SiteLocaleResponse {
|
|
471
|
+
locale_id: string;
|
|
472
|
+
code: string;
|
|
473
|
+
name: string;
|
|
474
|
+
native_name: string | null;
|
|
475
|
+
direction: 'ltr' | 'rtl';
|
|
476
|
+
is_default: boolean;
|
|
477
|
+
is_active: boolean;
|
|
478
|
+
}
|
|
479
|
+
/** Media item summary for list views (lighter than full MediaResponse). */
|
|
480
|
+
interface MediaListItem {
|
|
481
|
+
id: string;
|
|
482
|
+
filename: string;
|
|
483
|
+
original_filename: string;
|
|
484
|
+
mime_type: string;
|
|
485
|
+
file_size: number;
|
|
486
|
+
public_url: string | null;
|
|
487
|
+
width: number | null;
|
|
488
|
+
height: number | null;
|
|
489
|
+
is_global: boolean;
|
|
490
|
+
folder_id: string | null;
|
|
491
|
+
created_at: string;
|
|
492
|
+
}
|
|
493
|
+
/** Filter params for media listings. */
|
|
494
|
+
interface MediaListParams extends SearchablePaginationParams {
|
|
495
|
+
/** Filter by MIME category (e.g. `"image"`, `"video"`, `"document"`). */
|
|
496
|
+
mimeCategory?: string;
|
|
497
|
+
/** Filter to a specific folder. */
|
|
498
|
+
folderId?: string;
|
|
499
|
+
}
|
|
500
|
+
/** Full legal document detail including content localizations. */
|
|
501
|
+
interface LegalDocumentFullDetailResponse {
|
|
502
|
+
id: string;
|
|
503
|
+
content_id: string;
|
|
504
|
+
cookie_name: string;
|
|
505
|
+
document_type: LegalDocType;
|
|
506
|
+
status: ContentStatus;
|
|
507
|
+
slug: string | null;
|
|
508
|
+
version: number;
|
|
509
|
+
parent_version_id: string | null;
|
|
510
|
+
publish_start: string | null;
|
|
511
|
+
publish_end: string | null;
|
|
512
|
+
localizations: LocalizationResponse[];
|
|
513
|
+
doc_localizations: LegalDocLocalizationResponse[];
|
|
514
|
+
created_at: string;
|
|
515
|
+
updated_at: string;
|
|
516
|
+
}
|
|
517
|
+
/** A version entry in a legal document's version history. */
|
|
518
|
+
interface LegalVersionResponse {
|
|
519
|
+
id: string;
|
|
520
|
+
version: number;
|
|
521
|
+
status: ContentStatus;
|
|
522
|
+
created_at: string;
|
|
523
|
+
}
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region src/http.d.ts
|
|
526
|
+
/**
|
|
527
|
+
* Low-level HTTP client interface used by all resource classes.
|
|
528
|
+
*
|
|
529
|
+
* Handles authentication (X-API-Key header), JSON serialization, and
|
|
530
|
+
* error mapping. You don't interact with this directly — use
|
|
531
|
+
* {@link ForjaClient} instead.
|
|
532
|
+
*/
|
|
533
|
+
interface HttpClient {
|
|
534
|
+
/** Send a GET request. Query params with `undefined` values are omitted. */
|
|
535
|
+
get<T>(path: string, params?: Record<string, string | undefined>): Promise<T>;
|
|
536
|
+
/** Send a GET request and return the response as plain text (for XML, HTML, etc.). */
|
|
537
|
+
getText(path: string, params?: Record<string, string | undefined>): Promise<string>;
|
|
538
|
+
/** Send a POST request with a JSON body. */
|
|
539
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* A paginated API response enriched with navigation helpers.
|
|
543
|
+
*
|
|
544
|
+
* Extends the raw {@link Paginated} response with methods to fetch
|
|
545
|
+
* subsequent pages or collect all items.
|
|
546
|
+
*
|
|
547
|
+
* @typeParam T - The type of items in the paginated collection.
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* ```ts
|
|
551
|
+
* const page1 = await forja.blogs.listPublished({ pageSize: 10 });
|
|
552
|
+
*
|
|
553
|
+
* // Navigate to next page
|
|
554
|
+
* const page2 = await page1.fetchNext();
|
|
555
|
+
*
|
|
556
|
+
* // Or collect everything
|
|
557
|
+
* const allBlogs = await page1.fetchAll();
|
|
558
|
+
*
|
|
559
|
+
* // Or iterate page by page
|
|
560
|
+
* for await (const page of page1) {
|
|
561
|
+
* console.log(page.data);
|
|
562
|
+
* }
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
interface PaginatedResult<T> extends Paginated<T> {
|
|
566
|
+
/** Fetch the next page. Returns `null` if this is the last page. */
|
|
567
|
+
fetchNext(): Promise<PaginatedResult<T> | null>;
|
|
568
|
+
/** Fetch all remaining pages and return every item as a flat array. */
|
|
569
|
+
fetchAll(): Promise<T[]>;
|
|
570
|
+
/** Async iterator that yields each page (including the current one). */
|
|
571
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<Paginated<T>>;
|
|
572
|
+
}
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region src/resources/analytics.d.ts
|
|
575
|
+
/**
|
|
576
|
+
* Privacy-first analytics operations.
|
|
577
|
+
*
|
|
578
|
+
* Track pageviews and retrieve analytics reports. Forja analytics is
|
|
579
|
+
* cookie-free, GDPR-compliant by design — no PII is stored, visitor
|
|
580
|
+
* hashes are rotated daily, and raw data is pruned after a configurable retention period.
|
|
581
|
+
*
|
|
582
|
+
* Pageview tracking requires an API key with `Read` permission.
|
|
583
|
+
* Reports require `Read` permission.
|
|
584
|
+
*/
|
|
585
|
+
declare class AnalyticsResource {
|
|
586
|
+
private readonly http;
|
|
587
|
+
private readonly siteId;
|
|
588
|
+
constructor(http: HttpClient, siteId: string);
|
|
589
|
+
/**
|
|
590
|
+
* Track a pageview.
|
|
591
|
+
*
|
|
592
|
+
* **Endpoint:** `POST /sites/{siteId}/analytics/pageview`
|
|
593
|
+
*
|
|
594
|
+
* The server computes the visitor hash from the client IP and user agent.
|
|
595
|
+
* No cookies or PII are stored.
|
|
596
|
+
*
|
|
597
|
+
* @param request - The pageview data.
|
|
598
|
+
* @param request.path - The page path (e.g. `"/blog/hello-world"`).
|
|
599
|
+
* @param request.referrer - Optional full referrer URL (only the domain is stored).
|
|
600
|
+
* @returns Acknowledgement (`{ ok: true }`).
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
* ```ts
|
|
604
|
+
* await forja.analytics.trackPageview({ path: '/blog/hello-world' });
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
trackPageview(request: TrackPageviewRequest): Promise<TrackPageviewResponse>;
|
|
608
|
+
/**
|
|
609
|
+
* Fetch an analytics summary report for the site.
|
|
610
|
+
*
|
|
611
|
+
* **Endpoint:** `GET /sites/{siteId}/analytics/report?days=&top_n=&start_date=&end_date=`
|
|
612
|
+
*
|
|
613
|
+
* Returns total views, unique visitors, top content pages, and daily trends.
|
|
614
|
+
*
|
|
615
|
+
* @param params - Report parameters.
|
|
616
|
+
* @param params.days - Number of days to look back (default: 30). Ignored if date range is set.
|
|
617
|
+
* @param params.topN - Number of top content pages to include (default: 10).
|
|
618
|
+
* @param params.startDate - Start date in `YYYY-MM-DD` format.
|
|
619
|
+
* @param params.endDate - End date in `YYYY-MM-DD` format.
|
|
620
|
+
* @returns The analytics report with totals, top content, and daily trend data.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```ts
|
|
624
|
+
* const report = await forja.analytics.getReport({ days: 7, topN: 5 });
|
|
625
|
+
* console.log(`${report.total_views} views, ${report.total_unique_visitors} unique`);
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
getReport(params?: AnalyticsReportParams): Promise<AnalyticsReportResponse>;
|
|
629
|
+
/**
|
|
630
|
+
* Fetch analytics for a specific page path.
|
|
631
|
+
*
|
|
632
|
+
* **Endpoint:** `GET /sites/{siteId}/analytics/report/page?path=&days=&start_date=&end_date=`
|
|
633
|
+
*
|
|
634
|
+
* Returns views, unique visitors, daily trend, and top referrer domains for a single page.
|
|
635
|
+
*
|
|
636
|
+
* @param params - Page analytics parameters.
|
|
637
|
+
* @param params.path - The page path to query (e.g. `"/blog/hello-world"`).
|
|
638
|
+
* @param params.days - Number of days to look back.
|
|
639
|
+
* @param params.startDate - Start date in `YYYY-MM-DD` format.
|
|
640
|
+
* @param params.endDate - End date in `YYYY-MM-DD` format.
|
|
641
|
+
* @returns Page-level analytics with trend and referrer data.
|
|
642
|
+
*
|
|
643
|
+
* @example
|
|
644
|
+
* ```ts
|
|
645
|
+
* const stats = await forja.analytics.getPageAnalytics({
|
|
646
|
+
* path: '/blog/hello-world',
|
|
647
|
+
* days: 30,
|
|
648
|
+
* });
|
|
649
|
+
* console.log(stats.referrers); // [{ domain: "google.com", views: 42 }, ...]
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
getPageAnalytics(params: AnalyticsPageParams): Promise<AnalyticsPageDetailResponse>;
|
|
653
|
+
}
|
|
654
|
+
//#endregion
|
|
655
|
+
//#region src/resources/blogs.d.ts
|
|
656
|
+
/**
|
|
657
|
+
* Blog post operations.
|
|
658
|
+
*
|
|
659
|
+
* Provides access to published blog content, featured posts, category filtering,
|
|
660
|
+
* similar post discovery, and individual blog retrieval by ID or slug.
|
|
661
|
+
*
|
|
662
|
+
* All read operations require an API key with `Read` permission.
|
|
663
|
+
*/
|
|
664
|
+
declare class BlogsResource {
|
|
665
|
+
private readonly http;
|
|
666
|
+
private readonly siteId;
|
|
667
|
+
constructor(http: HttpClient, siteId: string);
|
|
668
|
+
/**
|
|
669
|
+
* Fetch a paginated list of published blog posts.
|
|
670
|
+
*
|
|
671
|
+
* **Endpoint:** `GET /sites/{siteId}/blogs/published?page=&page_size=&locale_id=`
|
|
672
|
+
*
|
|
673
|
+
* @param params - Pagination and locale filter options.
|
|
674
|
+
* @param params.page - 1-indexed page number (default: 1).
|
|
675
|
+
* @param params.pageSize - Items per page (default: server-side, typically 10).
|
|
676
|
+
* @param params.localeId - Filter to blogs with content in this locale (UUID).
|
|
677
|
+
* @returns A paginated result with {@link PaginatedResult.fetchNext | fetchNext()},
|
|
678
|
+
* {@link PaginatedResult.fetchAll | fetchAll()}, and async iteration support.
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```ts
|
|
682
|
+
* // All locales
|
|
683
|
+
* const page1 = await forja.blogs.listPublished({ page: 1, pageSize: 10 });
|
|
684
|
+
*
|
|
685
|
+
* // Filtered to a specific locale
|
|
686
|
+
* const german = await forja.blogs.listPublished({ page: 1, localeId: 'de-locale-uuid' });
|
|
687
|
+
* ```
|
|
688
|
+
*/
|
|
689
|
+
listPublished(params?: LocaleFilterParams): Promise<PaginatedResult<BlogListItem>>;
|
|
690
|
+
/**
|
|
691
|
+
* Fetch published blog posts filtered by category.
|
|
692
|
+
*
|
|
693
|
+
* **Endpoint:** `GET /sites/{siteId}/blogs/published/category/{categorySlug}?page=&page_size=&locale_id=`
|
|
694
|
+
*
|
|
695
|
+
* @param categorySlug - The category slug to filter by (e.g. `"tech"`, `"travel"`).
|
|
696
|
+
* @param params - Pagination and locale filter options.
|
|
697
|
+
* @returns A paginated result of blogs in the given category.
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* ```ts
|
|
701
|
+
* const techBlogs = await forja.blogs.listByCategory('tech', { page: 1, localeId: 'uuid' });
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
listByCategory(categorySlug: string, params?: LocaleFilterParams): Promise<PaginatedResult<BlogListItem>>;
|
|
705
|
+
/**
|
|
706
|
+
* Fetch featured blog posts.
|
|
707
|
+
*
|
|
708
|
+
* **Endpoint:** `GET /sites/{siteId}/blogs/featured?limit=`
|
|
709
|
+
*
|
|
710
|
+
* @param opts.limit - Maximum number of featured posts to return (default: server-side).
|
|
711
|
+
* @returns Array of blog detail responses (includes localizations, categories, documents).
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```ts
|
|
715
|
+
* const featured = await forja.blogs.listFeatured({ limit: 3 });
|
|
716
|
+
* ```
|
|
717
|
+
*/
|
|
718
|
+
listFeatured(opts?: {
|
|
719
|
+
limit?: number;
|
|
720
|
+
}): Promise<BlogDetailResponse[]>;
|
|
721
|
+
/**
|
|
722
|
+
* Fetch blog posts similar to a given blog (by shared categories/tags).
|
|
723
|
+
*
|
|
724
|
+
* **Endpoint:** `GET /sites/{siteId}/blogs/{blogId}/similar?limit=`
|
|
725
|
+
*
|
|
726
|
+
* @param blogId - The UUID of the blog to find similar content for.
|
|
727
|
+
* @param opts.limit - Maximum number of similar posts (default: server-side, typically 3).
|
|
728
|
+
* @returns Array of similar blog list items.
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```ts
|
|
732
|
+
* const similar = await forja.blogs.listSimilar('blog-uuid', { limit: 3 });
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
listSimilar(blogId: string, opts?: {
|
|
736
|
+
limit?: number;
|
|
737
|
+
}): Promise<BlogListItem[]>;
|
|
738
|
+
/**
|
|
739
|
+
* Fetch a blog post's full detail by its URL slug.
|
|
740
|
+
*
|
|
741
|
+
* Performs a two-step lookup:
|
|
742
|
+
* 1. **Endpoint:** `GET /sites/{siteId}/blogs/by-slug/{slug}` — resolves slug to ID.
|
|
743
|
+
* 2. **Endpoint:** `GET /blogs/{id}/detail` — fetches the full detail response.
|
|
744
|
+
*
|
|
745
|
+
* @param slug - The blog's URL slug (e.g. `"my-first-post"`).
|
|
746
|
+
* @returns The full blog detail (with localizations, categories, documents), or `null` if not found.
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```ts
|
|
750
|
+
* const blog = await forja.blogs.getBySlug('my-first-post');
|
|
751
|
+
* if (blog) {
|
|
752
|
+
* console.log(blog.localizations[0]?.title);
|
|
753
|
+
* }
|
|
754
|
+
* ```
|
|
755
|
+
*/
|
|
756
|
+
getBySlug(slug: string): Promise<BlogDetailResponse | null>;
|
|
757
|
+
/**
|
|
758
|
+
* Fetch a blog post's full detail by its UUID.
|
|
759
|
+
*
|
|
760
|
+
* **Endpoint:** `GET /blogs/{id}/detail`
|
|
761
|
+
*
|
|
762
|
+
* @param idOrSlug - The blog's UUID.
|
|
763
|
+
* @returns The full blog detail (with localizations, categories, documents), or `null` if not found.
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* ```ts
|
|
767
|
+
* const blog = await forja.blogs.get('550e8400-e29b-41d4-a716-446655440000');
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
get(idOrSlug: string): Promise<BlogDetailResponse | null>;
|
|
771
|
+
/**
|
|
772
|
+
* Fetch the site's RSS feed as raw XML.
|
|
773
|
+
*
|
|
774
|
+
* **Endpoint:** `GET /sites/{siteId}/feed.rss`
|
|
775
|
+
*
|
|
776
|
+
* @returns RSS 2.0 XML string.
|
|
777
|
+
*/
|
|
778
|
+
rss(): Promise<string>;
|
|
779
|
+
}
|
|
780
|
+
//#endregion
|
|
781
|
+
//#region src/resources/cv.d.ts
|
|
782
|
+
/**
|
|
783
|
+
* CV / resume operations.
|
|
784
|
+
*
|
|
785
|
+
* Provides access to skills (technologies, languages, tools) and CV entries
|
|
786
|
+
* (work experience, education, certifications, projects).
|
|
787
|
+
*
|
|
788
|
+
* All operations require an API key with `Read` permission.
|
|
789
|
+
*/
|
|
790
|
+
declare class CvResource {
|
|
791
|
+
private readonly http;
|
|
792
|
+
private readonly siteId;
|
|
793
|
+
constructor(http: HttpClient, siteId: string);
|
|
794
|
+
/**
|
|
795
|
+
* Fetch a paginated list of skills.
|
|
796
|
+
*
|
|
797
|
+
* **Endpoint:** `GET /sites/{siteId}/skills?page=&page_size=&search=&sort_by=&sort_dir=`
|
|
798
|
+
*
|
|
799
|
+
* @param params - Pagination, search, and sort options.
|
|
800
|
+
* @returns A paginated result of skills (name, slug, category, proficiency level).
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```ts
|
|
804
|
+
* const skills = await forja.cv.listSkills({ page: 1, pageSize: 50 });
|
|
805
|
+
* const programming = skills.data.filter(s => s.category === 'Programming');
|
|
806
|
+
* ```
|
|
807
|
+
*/
|
|
808
|
+
listSkills(params?: SearchablePaginationParams): Promise<PaginatedResult<SkillResponse>>;
|
|
809
|
+
/**
|
|
810
|
+
* Fetch a skill by its UUID.
|
|
811
|
+
*
|
|
812
|
+
* **Endpoint:** `GET /skills/{id}`
|
|
813
|
+
*
|
|
814
|
+
* @param id - The skill's UUID.
|
|
815
|
+
* @returns The skill, or `null` if not found.
|
|
816
|
+
*/
|
|
817
|
+
getSkill(id: string): Promise<SkillResponse | null>;
|
|
818
|
+
/**
|
|
819
|
+
* Fetch a skill by its URL slug.
|
|
820
|
+
*
|
|
821
|
+
* **Endpoint:** `GET /skills/by-slug/{slug}`
|
|
822
|
+
*
|
|
823
|
+
* @param slug - The skill's slug (e.g. `"typescript"`, `"rust"`).
|
|
824
|
+
* @returns The skill, or `null` if not found.
|
|
825
|
+
*
|
|
826
|
+
* @example
|
|
827
|
+
* ```ts
|
|
828
|
+
* const ts = await forja.cv.getSkillBySlug('typescript');
|
|
829
|
+
* if (ts) console.log(`${ts.name}: level ${ts.proficiency_level}`);
|
|
830
|
+
* ```
|
|
831
|
+
*/
|
|
832
|
+
getSkillBySlug(slug: string): Promise<SkillResponse | null>;
|
|
833
|
+
/**
|
|
834
|
+
* Fetch a paginated list of CV entries (work, education, certifications, etc.).
|
|
835
|
+
*
|
|
836
|
+
* **Endpoint:** `GET /sites/{siteId}/cv?entry_type=&page=&page_size=&search=&sort_by=&sort_dir=`
|
|
837
|
+
*
|
|
838
|
+
* @param params - Pagination and filter options.
|
|
839
|
+
* @param params.entryType - Filter by entry type: `"Work"`, `"Education"`, `"Volunteer"`, `"Certification"`, or `"Project"`.
|
|
840
|
+
* @returns A paginated result of CV entries.
|
|
841
|
+
*
|
|
842
|
+
* @example
|
|
843
|
+
* ```ts
|
|
844
|
+
* const work = await forja.cv.listEntries({ entryType: 'Work' });
|
|
845
|
+
* const education = await forja.cv.listEntries({ entryType: 'Education' });
|
|
846
|
+
* ```
|
|
847
|
+
*/
|
|
848
|
+
listEntries(params?: CvEntryParams): Promise<PaginatedResult<CvEntryResponse>>;
|
|
849
|
+
}
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/resources/legal.d.ts
|
|
852
|
+
/**
|
|
853
|
+
* Legal document operations.
|
|
854
|
+
*
|
|
855
|
+
* Provides access to legal documents (privacy policy, terms of service, cookie consent, etc.),
|
|
856
|
+
* their consent groups, and individual consent items for building cookie banners and legal pages.
|
|
857
|
+
*
|
|
858
|
+
* All operations require an API key with `Read` permission.
|
|
859
|
+
*/
|
|
860
|
+
declare class LegalResource {
|
|
861
|
+
private readonly http;
|
|
862
|
+
private readonly siteId;
|
|
863
|
+
constructor(http: HttpClient, siteId: string);
|
|
864
|
+
/**
|
|
865
|
+
* Fetch a paginated list of legal documents for the site.
|
|
866
|
+
*
|
|
867
|
+
* **Endpoint:** `GET /sites/{siteId}/legal?page=&page_size=&search=&sort_by=&sort_dir=`
|
|
868
|
+
*
|
|
869
|
+
* @param params - Pagination, search, and sort options.
|
|
870
|
+
* @returns A paginated result of legal document summaries.
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* ```ts
|
|
874
|
+
* const docs = await forja.legal.list();
|
|
875
|
+
* ```
|
|
876
|
+
*/
|
|
877
|
+
list(params?: SearchablePaginationParams): Promise<PaginatedResult<LegalDocumentResponse>>;
|
|
878
|
+
/**
|
|
879
|
+
* Fetch a legal document by its UUID, including localizations.
|
|
880
|
+
*
|
|
881
|
+
* **Endpoint:** `GET /legal/{id}`
|
|
882
|
+
*
|
|
883
|
+
* @param id - The legal document's UUID.
|
|
884
|
+
* @returns The document with all localizations, or `null` if not found.
|
|
885
|
+
*/
|
|
886
|
+
get(id: string): Promise<LegalDocumentDetailResponse | null>;
|
|
887
|
+
/**
|
|
888
|
+
* Fetch a legal document by its URL slug.
|
|
889
|
+
*
|
|
890
|
+
* **Endpoint:** `GET /sites/{siteId}/legal/by-slug/{slug}`
|
|
891
|
+
*
|
|
892
|
+
* @param slug - The document slug (e.g. `"privacy-policy"`, `"terms-of-service"`).
|
|
893
|
+
* @returns The document with all localizations, or `null` if not found.
|
|
894
|
+
*
|
|
895
|
+
* @example
|
|
896
|
+
* ```ts
|
|
897
|
+
* const privacy = await forja.legal.getBySlug('privacy-policy');
|
|
898
|
+
* if (privacy) {
|
|
899
|
+
* const enLocale = privacy.localizations.find(l => l.locale_id === enLocaleId);
|
|
900
|
+
* }
|
|
901
|
+
* ```
|
|
902
|
+
*/
|
|
903
|
+
getBySlug(slug: string): Promise<LegalDocumentDetailResponse | null>;
|
|
904
|
+
/**
|
|
905
|
+
* Fetch the cookie consent document with its consent groups and items.
|
|
906
|
+
*
|
|
907
|
+
* **Endpoint:** `GET /sites/{siteId}/legal/cookie-consent`
|
|
908
|
+
*
|
|
909
|
+
* Returns a structured document with groups (e.g. "Essential", "Analytics", "Marketing")
|
|
910
|
+
* and their items, including `is_required` and `default_enabled` flags for building
|
|
911
|
+
* GDPR-compliant cookie consent banners.
|
|
912
|
+
*
|
|
913
|
+
* @returns The cookie consent document with groups and items, or `null` if not configured.
|
|
914
|
+
*
|
|
915
|
+
* @example
|
|
916
|
+
* ```ts
|
|
917
|
+
* const consent = await forja.legal.getCookieConsent();
|
|
918
|
+
* if (consent) {
|
|
919
|
+
* consent.groups.forEach(group => {
|
|
920
|
+
* console.log(group.cookie_name, group.is_required ? '(required)' : '(optional)');
|
|
921
|
+
* });
|
|
922
|
+
* }
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
getCookieConsent(): Promise<LegalDocumentWithGroups | null>;
|
|
926
|
+
/**
|
|
927
|
+
* Fetch consent groups (with their items) for a legal document.
|
|
928
|
+
*
|
|
929
|
+
* **Endpoint:** `GET /legal/{documentId}/groups`
|
|
930
|
+
*
|
|
931
|
+
* @param documentId - The legal document's UUID.
|
|
932
|
+
* @returns Array of consent groups, each containing their items.
|
|
933
|
+
*/
|
|
934
|
+
getGroups(documentId: string): Promise<LegalGroupWithItems[]>;
|
|
935
|
+
/**
|
|
936
|
+
* Fetch consent items within a specific group.
|
|
937
|
+
*
|
|
938
|
+
* **Endpoint:** `GET /legal/groups/{groupId}/items`
|
|
939
|
+
*
|
|
940
|
+
* @param groupId - The consent group's UUID.
|
|
941
|
+
* @returns Array of consent items (cookie name, required flag, display order).
|
|
942
|
+
*/
|
|
943
|
+
getGroupItems(groupId: string): Promise<LegalItemResponse[]>;
|
|
944
|
+
/**
|
|
945
|
+
* Fetch the full detail of a legal document, including content localizations.
|
|
946
|
+
*
|
|
947
|
+
* **Endpoint:** `GET /legal/{id}/detail`
|
|
948
|
+
*
|
|
949
|
+
* Unlike {@link get}, this returns the full content body localizations
|
|
950
|
+
* (rendered text), document status, slug, version, and publish window.
|
|
951
|
+
* Use for rendering the full legal document page.
|
|
952
|
+
*
|
|
953
|
+
* @param id - The legal document's UUID.
|
|
954
|
+
* @returns The full document detail with content and doc localizations, or `null` if not found.
|
|
955
|
+
*
|
|
956
|
+
* @example
|
|
957
|
+
* ```ts
|
|
958
|
+
* const detail = await forja.legal.getDetail('doc-uuid');
|
|
959
|
+
* if (detail) {
|
|
960
|
+
* console.log(detail.version); // 3
|
|
961
|
+
* console.log(detail.document_type); // "PrivacyPolicy"
|
|
962
|
+
* console.log(detail.localizations); // content body per locale
|
|
963
|
+
* console.log(detail.doc_localizations); // title + intro per locale
|
|
964
|
+
* }
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
967
|
+
getDetail(id: string): Promise<LegalDocumentFullDetailResponse | null>;
|
|
968
|
+
/**
|
|
969
|
+
* Fetch the version history of a legal document.
|
|
970
|
+
*
|
|
971
|
+
* **Endpoint:** `GET /legal/{id}/versions`
|
|
972
|
+
*
|
|
973
|
+
* Returns all versions of the document, ordered by version number.
|
|
974
|
+
* Each entry includes the version number, content status, and creation date.
|
|
975
|
+
* Use for displaying a "Version history" section on legal pages.
|
|
976
|
+
*
|
|
977
|
+
* @param id - The legal document's UUID.
|
|
978
|
+
* @returns Array of version entries, newest first.
|
|
979
|
+
*
|
|
980
|
+
* @example
|
|
981
|
+
* ```ts
|
|
982
|
+
* const versions = await forja.legal.listVersions('doc-uuid');
|
|
983
|
+
* versions.forEach(v => {
|
|
984
|
+
* console.log(`v${v.version} — ${v.status} — ${v.created_at}`);
|
|
985
|
+
* });
|
|
986
|
+
* ```
|
|
987
|
+
*/
|
|
988
|
+
listVersions(id: string): Promise<LegalVersionResponse[]>;
|
|
989
|
+
}
|
|
990
|
+
//#endregion
|
|
991
|
+
//#region src/resources/media.d.ts
|
|
992
|
+
/**
|
|
993
|
+
* Media asset operations.
|
|
994
|
+
*
|
|
995
|
+
* Provides access to media assets (images, videos, documents) stored in the CMS.
|
|
996
|
+
* Each media item includes its public URL, dimensions, file metadata, and
|
|
997
|
+
* responsive variants (thumbnails, different sizes).
|
|
998
|
+
*
|
|
999
|
+
* Requires an API key with `Read` permission.
|
|
1000
|
+
*/
|
|
1001
|
+
declare class MediaResource {
|
|
1002
|
+
private readonly http;
|
|
1003
|
+
private readonly siteId;
|
|
1004
|
+
constructor(http: HttpClient, siteId: string);
|
|
1005
|
+
/**
|
|
1006
|
+
* Fetch a paginated list of media assets for the site.
|
|
1007
|
+
*
|
|
1008
|
+
* **Endpoint:** `GET /sites/{siteId}/media?page=&page_size=&search=&sort_by=&sort_dir=&mime_category=&folder_id=`
|
|
1009
|
+
*
|
|
1010
|
+
* Returns a lightweight list without variants. Use {@link get} to fetch full
|
|
1011
|
+
* detail with responsive variants for a specific asset.
|
|
1012
|
+
*
|
|
1013
|
+
* @param params - Pagination, search, sort, and filter options.
|
|
1014
|
+
* @param params.search - Search by filename.
|
|
1015
|
+
* @param params.mimeCategory - Filter by MIME category: `"image"`, `"video"`, `"document"`, `"audio"`.
|
|
1016
|
+
* @param params.folderId - Filter to a specific media folder (UUID).
|
|
1017
|
+
* @returns A paginated result of media list items.
|
|
1018
|
+
*
|
|
1019
|
+
* @example
|
|
1020
|
+
* ```ts
|
|
1021
|
+
* // Browse all images
|
|
1022
|
+
* const images = await forja.media.list({ mimeCategory: 'image', pageSize: 20 });
|
|
1023
|
+
*
|
|
1024
|
+
* // Search by filename
|
|
1025
|
+
* const results = await forja.media.list({ search: 'hero-banner' });
|
|
1026
|
+
*
|
|
1027
|
+
* // Browse a specific folder
|
|
1028
|
+
* const folder = await forja.media.list({ folderId: 'folder-uuid' });
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
list(params?: MediaListParams): Promise<PaginatedResult<MediaListItem>>;
|
|
1032
|
+
/**
|
|
1033
|
+
* Fetch a media asset by its UUID.
|
|
1034
|
+
*
|
|
1035
|
+
* **Endpoint:** `GET /media/{id}`
|
|
1036
|
+
*
|
|
1037
|
+
* Returns the full media metadata including filename, MIME type, dimensions,
|
|
1038
|
+
* public URL, and all responsive variants (thumbnails, different sizes).
|
|
1039
|
+
*
|
|
1040
|
+
* @param id - The media asset's UUID.
|
|
1041
|
+
* @returns The media asset with variants, or `null` if not found.
|
|
1042
|
+
*
|
|
1043
|
+
* @example
|
|
1044
|
+
* ```ts
|
|
1045
|
+
* const cover = await forja.media.get(blog.cover_image_id);
|
|
1046
|
+
* if (cover) {
|
|
1047
|
+
* console.log(cover.public_url); // original image URL
|
|
1048
|
+
* console.log(cover.variants); // [{ variant_name, width, height, public_url }, ...]
|
|
1049
|
+
* console.log(cover.mime_type); // "image/jpeg"
|
|
1050
|
+
* }
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
1053
|
+
get(id: string): Promise<MediaResponse | null>;
|
|
1054
|
+
}
|
|
1055
|
+
//#endregion
|
|
1056
|
+
//#region src/resources/navigation.d.ts
|
|
1057
|
+
/**
|
|
1058
|
+
* Navigation menu operations.
|
|
1059
|
+
*
|
|
1060
|
+
* Provides access to navigation menus, their hierarchical tree structure,
|
|
1061
|
+
* and individual menu items. Used to render site headers, footers, and sidebars.
|
|
1062
|
+
*
|
|
1063
|
+
* All operations require an API key with `Read` permission.
|
|
1064
|
+
*/
|
|
1065
|
+
declare class NavigationResource {
|
|
1066
|
+
private readonly http;
|
|
1067
|
+
private readonly siteId;
|
|
1068
|
+
constructor(http: HttpClient, siteId: string);
|
|
1069
|
+
/**
|
|
1070
|
+
* Fetch all navigation menus for the site.
|
|
1071
|
+
*
|
|
1072
|
+
* **Endpoint:** `GET /sites/{siteId}/menus`
|
|
1073
|
+
*
|
|
1074
|
+
* @returns Array of menu metadata (slug, description, depth, item count).
|
|
1075
|
+
*
|
|
1076
|
+
* @example
|
|
1077
|
+
* ```ts
|
|
1078
|
+
* const menus = await forja.navigation.listMenus();
|
|
1079
|
+
* const primary = menus.find(m => m.slug === 'primary');
|
|
1080
|
+
* ```
|
|
1081
|
+
*/
|
|
1082
|
+
listMenus(): Promise<NavigationMenuResponse[]>;
|
|
1083
|
+
/**
|
|
1084
|
+
* Fetch a navigation menu by its UUID.
|
|
1085
|
+
*
|
|
1086
|
+
* **Endpoint:** `GET /menus/{menuId}`
|
|
1087
|
+
*
|
|
1088
|
+
* @param menuId - The menu's UUID.
|
|
1089
|
+
* @returns Menu metadata, or `null` if not found.
|
|
1090
|
+
*/
|
|
1091
|
+
getMenu(menuId: string): Promise<NavigationMenuResponse | null>;
|
|
1092
|
+
/**
|
|
1093
|
+
* Fetch a navigation menu by its slug.
|
|
1094
|
+
*
|
|
1095
|
+
* **Endpoint:** `GET /sites/{siteId}/menus/slug/{slug}`
|
|
1096
|
+
*
|
|
1097
|
+
* @param slug - The menu's slug (e.g. `"primary"`, `"footer"`).
|
|
1098
|
+
* @returns Menu metadata, or `null` if not found.
|
|
1099
|
+
*
|
|
1100
|
+
* @example
|
|
1101
|
+
* ```ts
|
|
1102
|
+
* const primary = await forja.navigation.getMenuBySlug('primary');
|
|
1103
|
+
* if (primary) {
|
|
1104
|
+
* const tree = await forja.navigation.getTree(primary.id);
|
|
1105
|
+
* }
|
|
1106
|
+
* ```
|
|
1107
|
+
*/
|
|
1108
|
+
getMenuBySlug(slug: string): Promise<NavigationMenuResponse | null>;
|
|
1109
|
+
/**
|
|
1110
|
+
* Fetch the hierarchical navigation tree for a menu.
|
|
1111
|
+
*
|
|
1112
|
+
* **Endpoint:** `GET /menus/{menuId}/tree?locale=`
|
|
1113
|
+
*
|
|
1114
|
+
* Returns a recursive tree of navigation items with children, page slugs,
|
|
1115
|
+
* external URLs, and icons. Optionally filtered by locale for multi-language sites.
|
|
1116
|
+
*
|
|
1117
|
+
* @param menuId - The menu's UUID.
|
|
1118
|
+
* @param opts.locale - Optional locale code (e.g. `"en"`, `"de"`) to filter localized titles.
|
|
1119
|
+
* @returns Array of root-level navigation tree nodes (each may have nested children).
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* ```ts
|
|
1123
|
+
* const tree = await forja.navigation.getTree('menu-uuid', { locale: 'de' });
|
|
1124
|
+
* tree.forEach(node => {
|
|
1125
|
+
* console.log(node.title, node.page_slug, node.children.length);
|
|
1126
|
+
* });
|
|
1127
|
+
* ```
|
|
1128
|
+
*/
|
|
1129
|
+
getTree(menuId: string, opts?: {
|
|
1130
|
+
locale?: string;
|
|
1131
|
+
}): Promise<NavigationTree[]>;
|
|
1132
|
+
/**
|
|
1133
|
+
* Fetch all flat (non-hierarchical) items in a menu.
|
|
1134
|
+
*
|
|
1135
|
+
* **Endpoint:** `GET /menus/{menuId}/items`
|
|
1136
|
+
*
|
|
1137
|
+
* @param menuId - The menu's UUID.
|
|
1138
|
+
* @returns Array of navigation items (use `parent_id` to reconstruct hierarchy if needed).
|
|
1139
|
+
*/
|
|
1140
|
+
listItems(menuId: string): Promise<NavigationItemResponse[]>;
|
|
1141
|
+
/**
|
|
1142
|
+
* Fetch a single navigation item by its UUID.
|
|
1143
|
+
*
|
|
1144
|
+
* **Endpoint:** `GET /navigation/{itemId}`
|
|
1145
|
+
*
|
|
1146
|
+
* @param itemId - The navigation item's UUID.
|
|
1147
|
+
* @returns The navigation item, or `null` if not found.
|
|
1148
|
+
*/
|
|
1149
|
+
getItem(itemId: string): Promise<NavigationItemResponse | null>;
|
|
1150
|
+
}
|
|
1151
|
+
//#endregion
|
|
1152
|
+
//#region src/resources/pages.d.ts
|
|
1153
|
+
/**
|
|
1154
|
+
* Extended pagination params for page listings.
|
|
1155
|
+
* Supports filtering by status, page type, and exclusion.
|
|
1156
|
+
*/
|
|
1157
|
+
interface PageListParams extends SearchablePaginationParams {
|
|
1158
|
+
/** Filter by content status (e.g. `"Published"`, `"Draft"`). */
|
|
1159
|
+
status?: string;
|
|
1160
|
+
/** Filter by page type (e.g. `"Static"`, `"Landing"`, `"Contact"`). */
|
|
1161
|
+
pageType?: string;
|
|
1162
|
+
/** Exclude pages with this status. */
|
|
1163
|
+
excludeStatus?: string;
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* CMS page operations.
|
|
1167
|
+
*
|
|
1168
|
+
* Provides access to page listings, route-based lookup, page sections,
|
|
1169
|
+
* and section localizations for multi-language content rendering.
|
|
1170
|
+
*
|
|
1171
|
+
* All operations require an API key with `Read` permission.
|
|
1172
|
+
*/
|
|
1173
|
+
declare class PagesResource {
|
|
1174
|
+
private readonly http;
|
|
1175
|
+
private readonly siteId;
|
|
1176
|
+
constructor(http: HttpClient, siteId: string);
|
|
1177
|
+
/**
|
|
1178
|
+
* Fetch a paginated list of CMS pages.
|
|
1179
|
+
*
|
|
1180
|
+
* **Endpoint:** `GET /sites/{siteId}/pages?page=&page_size=&search=&status=&page_type=&sort_by=&sort_dir=&exclude_status=`
|
|
1181
|
+
*
|
|
1182
|
+
* @param params - Pagination, search, and filter options.
|
|
1183
|
+
* @returns A paginated result of page list items.
|
|
1184
|
+
*
|
|
1185
|
+
* @example
|
|
1186
|
+
* ```ts
|
|
1187
|
+
* const pages = await forja.pages.list({ page: 1, pageSize: 100 });
|
|
1188
|
+
* const allPages = await pages.fetchAll();
|
|
1189
|
+
* ```
|
|
1190
|
+
*/
|
|
1191
|
+
list(params?: PageListParams): Promise<PaginatedResult<PageListItem>>;
|
|
1192
|
+
/**
|
|
1193
|
+
* Fetch a page by its URL route path.
|
|
1194
|
+
*
|
|
1195
|
+
* **Endpoint:** `GET /sites/{siteId}/pages/by-route/{route}`
|
|
1196
|
+
*
|
|
1197
|
+
* Leading slashes are stripped automatically (`"/about"` and `"about"` both work).
|
|
1198
|
+
*
|
|
1199
|
+
* @param route - The page's route path (e.g. `"/about"` or `"contact"`).
|
|
1200
|
+
* @returns The page detail with localizations and OG image, or `null` if not found.
|
|
1201
|
+
*
|
|
1202
|
+
* @example
|
|
1203
|
+
* ```ts
|
|
1204
|
+
* const aboutPage = await forja.pages.getByRoute('/about');
|
|
1205
|
+
* if (aboutPage) {
|
|
1206
|
+
* console.log(aboutPage.localizations[0]?.title);
|
|
1207
|
+
* }
|
|
1208
|
+
* ```
|
|
1209
|
+
*/
|
|
1210
|
+
getByRoute(route: string): Promise<PageDetailResponse | null>;
|
|
1211
|
+
/**
|
|
1212
|
+
* Fetch all sections for a page.
|
|
1213
|
+
*
|
|
1214
|
+
* **Endpoint:** `GET /pages/{pageId}/sections`
|
|
1215
|
+
*
|
|
1216
|
+
* Sections are returned in display order and include type, settings,
|
|
1217
|
+
* cover image reference, and call-to-action route.
|
|
1218
|
+
*
|
|
1219
|
+
* @param pageId - The page's UUID.
|
|
1220
|
+
* @returns Array of page sections.
|
|
1221
|
+
*/
|
|
1222
|
+
getSections(pageId: string): Promise<PageSectionResponse[]>;
|
|
1223
|
+
/**
|
|
1224
|
+
* Fetch localizations for a single section.
|
|
1225
|
+
*
|
|
1226
|
+
* **Endpoint:** `GET /pages/sections/{sectionId}/localizations`
|
|
1227
|
+
*
|
|
1228
|
+
* @param sectionId - The section's UUID.
|
|
1229
|
+
* @returns Array of localized content (title, text, button text) per locale.
|
|
1230
|
+
*/
|
|
1231
|
+
getSectionLocalizations(sectionId: string): Promise<SectionLocalizationResponse[]>;
|
|
1232
|
+
/**
|
|
1233
|
+
* Fetch localizations for all sections of a page in a single request.
|
|
1234
|
+
*
|
|
1235
|
+
* **Endpoint:** `GET /pages/{pageId}/sections/localizations`
|
|
1236
|
+
*
|
|
1237
|
+
* More efficient than calling {@link getSectionLocalizations} per section.
|
|
1238
|
+
*
|
|
1239
|
+
* @param pageId - The page's UUID.
|
|
1240
|
+
* @returns Array of all section localizations for the page.
|
|
1241
|
+
*/
|
|
1242
|
+
getPageSectionLocalizations(pageId: string): Promise<SectionLocalizationResponse[]>;
|
|
1243
|
+
}
|
|
1244
|
+
//#endregion
|
|
1245
|
+
//#region src/resources/projects.d.ts
|
|
1246
|
+
/**
|
|
1247
|
+
* Portfolio project operations.
|
|
1248
|
+
*
|
|
1249
|
+
* Provides access to published projects with localizations, links, media
|
|
1250
|
+
* attachments, and skill/CV associations. Use for portfolio pages, project
|
|
1251
|
+
* showcases, and case studies.
|
|
1252
|
+
*
|
|
1253
|
+
* All read operations require an API key with `Read` permission.
|
|
1254
|
+
*/
|
|
1255
|
+
declare class ProjectsResource {
|
|
1256
|
+
private readonly http;
|
|
1257
|
+
private readonly siteId;
|
|
1258
|
+
constructor(http: HttpClient, siteId: string);
|
|
1259
|
+
/**
|
|
1260
|
+
* Fetch a paginated list of published projects.
|
|
1261
|
+
*
|
|
1262
|
+
* **Endpoint:** `GET /sites/{siteId}/projects/public?page=&page_size=&sort_by=&sort_dir=&is_featured=`
|
|
1263
|
+
*
|
|
1264
|
+
* Returns projects with `published` or `scheduled` status that are within
|
|
1265
|
+
* their publish window. Results can be sorted and filtered to featured only.
|
|
1266
|
+
*
|
|
1267
|
+
* @param params - Pagination, sort, and filter options.
|
|
1268
|
+
* @param params.page - 1-indexed page number (default: 1).
|
|
1269
|
+
* @param params.pageSize - Items per page, 1–100 (default: 10).
|
|
1270
|
+
* @param params.sortBy - Sort field (e.g. `"display_order"`, `"start_date"`, `"created_at"`).
|
|
1271
|
+
* @param params.sortDir - Sort direction: `"asc"` or `"desc"`.
|
|
1272
|
+
* @param params.isFeatured - When `true`, returns only featured projects.
|
|
1273
|
+
* @returns A paginated result with {@link PaginatedResult.fetchNext | fetchNext()},
|
|
1274
|
+
* {@link PaginatedResult.fetchAll | fetchAll()}, and async iteration support.
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* ```ts
|
|
1278
|
+
* // All published projects
|
|
1279
|
+
* const projects = await forja.projects.listPublished({ page: 1, pageSize: 12 });
|
|
1280
|
+
*
|
|
1281
|
+
* // Featured projects only, sorted by display order
|
|
1282
|
+
* const featured = await forja.projects.listPublished({
|
|
1283
|
+
* isFeatured: true,
|
|
1284
|
+
* sortBy: 'display_order',
|
|
1285
|
+
* sortDir: 'asc',
|
|
1286
|
+
* });
|
|
1287
|
+
* ```
|
|
1288
|
+
*/
|
|
1289
|
+
listPublished(params?: ProjectListParams): Promise<PaginatedResult<ProjectResponse>>;
|
|
1290
|
+
/**
|
|
1291
|
+
* Fetch a project's full detail by its UUID.
|
|
1292
|
+
*
|
|
1293
|
+
* **Endpoint:** `GET /projects/{id}`
|
|
1294
|
+
*
|
|
1295
|
+
* Returns the complete project with localizations (title, description per locale),
|
|
1296
|
+
* external links (repository, demo, docs), media attachments (cover image,
|
|
1297
|
+
* screenshots), and associations to skills and CV entries.
|
|
1298
|
+
*
|
|
1299
|
+
* @param id - The project's UUID.
|
|
1300
|
+
* @returns The full project detail, or `null` if not found.
|
|
1301
|
+
*
|
|
1302
|
+
* @example
|
|
1303
|
+
* ```ts
|
|
1304
|
+
* const project = await forja.projects.get('project-uuid');
|
|
1305
|
+
* if (project) {
|
|
1306
|
+
* const loc = project.localizations.find(l => l.locale_id === localeId);
|
|
1307
|
+
* console.log(loc?.title, loc?.short_description);
|
|
1308
|
+
* console.log(project.links); // [{ label, url, link_type }]
|
|
1309
|
+
* }
|
|
1310
|
+
* ```
|
|
1311
|
+
*/
|
|
1312
|
+
get(id: string): Promise<ProjectDetailResponse | null>;
|
|
1313
|
+
/**
|
|
1314
|
+
* Fetch a project by its URL slug.
|
|
1315
|
+
*
|
|
1316
|
+
* **Endpoint:** `GET /sites/{siteId}/projects/by-slug/{slug}`
|
|
1317
|
+
*
|
|
1318
|
+
* @param slug - The project's URL slug (e.g. `"forja-cms"`, `"my-portfolio"`).
|
|
1319
|
+
* @returns The project summary, or `null` if not found.
|
|
1320
|
+
*
|
|
1321
|
+
* @example
|
|
1322
|
+
* ```ts
|
|
1323
|
+
* const project = await forja.projects.getBySlug('forja-cms');
|
|
1324
|
+
* ```
|
|
1325
|
+
*/
|
|
1326
|
+
getBySlug(slug: string): Promise<ProjectResponse | null>;
|
|
1327
|
+
}
|
|
1328
|
+
//#endregion
|
|
1329
|
+
//#region src/resources/redirects.d.ts
|
|
1330
|
+
/**
|
|
1331
|
+
* URL redirect operations.
|
|
1332
|
+
*
|
|
1333
|
+
* Provides server-side redirect lookup for SSR frameworks. When a request
|
|
1334
|
+
* arrives at a path that has a redirect configured, use {@link lookup} to
|
|
1335
|
+
* check if the path should be redirected and to which destination.
|
|
1336
|
+
*
|
|
1337
|
+
* Requires an API key with `Read` permission.
|
|
1338
|
+
*/
|
|
1339
|
+
declare class RedirectsResource {
|
|
1340
|
+
private readonly http;
|
|
1341
|
+
private readonly siteId;
|
|
1342
|
+
constructor(http: HttpClient, siteId: string);
|
|
1343
|
+
/**
|
|
1344
|
+
* Look up a redirect for a given request path.
|
|
1345
|
+
*
|
|
1346
|
+
* **Endpoint:** `GET /sites/{siteId}/redirects/lookup?path=`
|
|
1347
|
+
*
|
|
1348
|
+
* Checks if the site has an active redirect configured for the given path.
|
|
1349
|
+
* Returns the destination URL and HTTP status code (301 permanent, 302 temporary,
|
|
1350
|
+
* 307 temporary preserve method, 308 permanent preserve method).
|
|
1351
|
+
*
|
|
1352
|
+
* Use this in SSR middleware to handle redirects before rendering the page.
|
|
1353
|
+
*
|
|
1354
|
+
* @param path - The request path to check (e.g. `"/old-blog-post"`, `"/legacy/page"`).
|
|
1355
|
+
* @returns The redirect destination and status code, or `null` if no redirect exists for this path.
|
|
1356
|
+
*
|
|
1357
|
+
* @example
|
|
1358
|
+
* ```ts
|
|
1359
|
+
* // In Astro middleware or Next.js middleware:
|
|
1360
|
+
* const redirect = await forja.redirects.lookup('/old-url');
|
|
1361
|
+
* if (redirect) {
|
|
1362
|
+
* return Response.redirect(redirect.destination_path, redirect.status_code);
|
|
1363
|
+
* }
|
|
1364
|
+
* ```
|
|
1365
|
+
*
|
|
1366
|
+
* @example
|
|
1367
|
+
* ```ts
|
|
1368
|
+
* // In Express:
|
|
1369
|
+
* app.use(async (req, res, next) => {
|
|
1370
|
+
* const redirect = await forja.redirects.lookup(req.path);
|
|
1371
|
+
* if (redirect) {
|
|
1372
|
+
* return res.redirect(redirect.status_code, redirect.destination_path);
|
|
1373
|
+
* }
|
|
1374
|
+
* next();
|
|
1375
|
+
* });
|
|
1376
|
+
* ```
|
|
1377
|
+
*/
|
|
1378
|
+
lookup(path: string): Promise<RedirectLookupResponse | null>;
|
|
1379
|
+
}
|
|
1380
|
+
//#endregion
|
|
1381
|
+
//#region src/resources/site.d.ts
|
|
1382
|
+
/**
|
|
1383
|
+
* Site configuration operations.
|
|
1384
|
+
*
|
|
1385
|
+
* Provides access to the site's metadata (name, slug, timezone, etc.)
|
|
1386
|
+
* and configured locales (languages available for content).
|
|
1387
|
+
*
|
|
1388
|
+
* Requires an API key with `Read` permission.
|
|
1389
|
+
*/
|
|
1390
|
+
declare class SiteResource {
|
|
1391
|
+
private readonly http;
|
|
1392
|
+
private readonly siteId;
|
|
1393
|
+
constructor(http: HttpClient, siteId: string);
|
|
1394
|
+
/**
|
|
1395
|
+
* Fetch the site's configuration.
|
|
1396
|
+
*
|
|
1397
|
+
* **Endpoint:** `GET /sites/{siteId}`
|
|
1398
|
+
*
|
|
1399
|
+
* Returns the site's name, slug, description, logo/favicon URLs, timezone,
|
|
1400
|
+
* theme settings, and default locale. Useful for rendering site-wide UI
|
|
1401
|
+
* elements (header, footer, SEO defaults).
|
|
1402
|
+
*
|
|
1403
|
+
* @returns The site configuration.
|
|
1404
|
+
*
|
|
1405
|
+
* @example
|
|
1406
|
+
* ```ts
|
|
1407
|
+
* const site = await forja.site.get();
|
|
1408
|
+
* console.log(site.name); // "My Website"
|
|
1409
|
+
* console.log(site.timezone); // "Europe/Vienna"
|
|
1410
|
+
* console.log(site.favicon_url); // "https://cdn.example.com/favicon.ico"
|
|
1411
|
+
* ```
|
|
1412
|
+
*/
|
|
1413
|
+
get(): Promise<SiteResponse>;
|
|
1414
|
+
/**
|
|
1415
|
+
* Fetch all locales configured for the site.
|
|
1416
|
+
*
|
|
1417
|
+
* **Endpoint:** `GET /sites/{siteId}/locales`
|
|
1418
|
+
*
|
|
1419
|
+
* Returns the languages available for content on this site, including
|
|
1420
|
+
* the default locale, locale codes, text direction (LTR/RTL), and
|
|
1421
|
+
* active status. Use to build language switchers and determine which
|
|
1422
|
+
* locale to pass to other API calls (e.g. blog listing with `localeId`).
|
|
1423
|
+
*
|
|
1424
|
+
* @returns Array of site locales, with the default locale marked via `is_default`.
|
|
1425
|
+
*
|
|
1426
|
+
* @example
|
|
1427
|
+
* ```ts
|
|
1428
|
+
* const locales = await forja.site.listLocales();
|
|
1429
|
+
* const defaultLocale = locales.find(l => l.is_default);
|
|
1430
|
+
* console.log(defaultLocale?.code); // "en"
|
|
1431
|
+
*
|
|
1432
|
+
* // Build a language switcher
|
|
1433
|
+
* locales
|
|
1434
|
+
* .filter(l => l.is_active)
|
|
1435
|
+
* .forEach(l => console.log(`${l.name} (${l.code})`));
|
|
1436
|
+
* ```
|
|
1437
|
+
*/
|
|
1438
|
+
listLocales(): Promise<SiteLocaleResponse[]>;
|
|
1439
|
+
}
|
|
1440
|
+
//#endregion
|
|
1441
|
+
//#region src/resources/social.d.ts
|
|
1442
|
+
/**
|
|
1443
|
+
* Social media link operations.
|
|
1444
|
+
*
|
|
1445
|
+
* Provides access to the site's configured social media links
|
|
1446
|
+
* (GitHub, Twitter/X, LinkedIn, etc.) for rendering in headers, footers,
|
|
1447
|
+
* and about pages.
|
|
1448
|
+
*
|
|
1449
|
+
* Requires an API key with `Read` permission.
|
|
1450
|
+
*/
|
|
1451
|
+
declare class SocialResource {
|
|
1452
|
+
private readonly http;
|
|
1453
|
+
private readonly siteId;
|
|
1454
|
+
constructor(http: HttpClient, siteId: string);
|
|
1455
|
+
/**
|
|
1456
|
+
* Fetch all social media links for the site.
|
|
1457
|
+
*
|
|
1458
|
+
* **Endpoint:** `GET /sites/{siteId}/social`
|
|
1459
|
+
*
|
|
1460
|
+
* Returns links sorted by `display_order`. Each link includes a title,
|
|
1461
|
+
* URL, icon identifier, and optional alt text for accessibility.
|
|
1462
|
+
*
|
|
1463
|
+
* @returns Array of social links.
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```ts
|
|
1467
|
+
* const links = await forja.social.list();
|
|
1468
|
+
* links.forEach(link => {
|
|
1469
|
+
* console.log(`${link.title}: ${link.url} (icon: ${link.icon})`);
|
|
1470
|
+
* });
|
|
1471
|
+
* ```
|
|
1472
|
+
*/
|
|
1473
|
+
list(): Promise<SocialLinkResponse[]>;
|
|
1474
|
+
}
|
|
1475
|
+
//#endregion
|
|
1476
|
+
//#region src/resources/taxonomy.d.ts
|
|
1477
|
+
/**
|
|
1478
|
+
* Taxonomy operations (tags and categories).
|
|
1479
|
+
*
|
|
1480
|
+
* Tags and categories are used to organize blog posts and other content.
|
|
1481
|
+
* Categories support hierarchy (parent/child), while tags are flat labels.
|
|
1482
|
+
*
|
|
1483
|
+
* All operations require an API key with `Read` permission.
|
|
1484
|
+
*/
|
|
1485
|
+
declare class TaxonomyResource {
|
|
1486
|
+
private readonly http;
|
|
1487
|
+
private readonly siteId;
|
|
1488
|
+
constructor(http: HttpClient, siteId: string);
|
|
1489
|
+
/**
|
|
1490
|
+
* Fetch a paginated list of tags for the site.
|
|
1491
|
+
*
|
|
1492
|
+
* **Endpoint:** `GET /sites/{siteId}/tags?page=&page_size=&search=&sort_by=&sort_dir=`
|
|
1493
|
+
*
|
|
1494
|
+
* @param params - Pagination, search, and sort options.
|
|
1495
|
+
* @returns A paginated result of tags.
|
|
1496
|
+
*
|
|
1497
|
+
* @example
|
|
1498
|
+
* ```ts
|
|
1499
|
+
* const tags = await forja.taxonomy.listTags({ search: 'rust', sortBy: 'slug' });
|
|
1500
|
+
* ```
|
|
1501
|
+
*/
|
|
1502
|
+
listTags(params?: SearchablePaginationParams): Promise<PaginatedResult<TagResponse>>;
|
|
1503
|
+
/**
|
|
1504
|
+
* Fetch a paginated list of categories for the site.
|
|
1505
|
+
*
|
|
1506
|
+
* **Endpoint:** `GET /sites/{siteId}/categories?page=&page_size=&search=&sort_by=&sort_dir=`
|
|
1507
|
+
*
|
|
1508
|
+
* @param params - Pagination, search, and sort options.
|
|
1509
|
+
* @returns A paginated result of categories.
|
|
1510
|
+
*
|
|
1511
|
+
* @example
|
|
1512
|
+
* ```ts
|
|
1513
|
+
* const categories = await forja.taxonomy.listCategories({ page: 1, pageSize: 50 });
|
|
1514
|
+
* ```
|
|
1515
|
+
*/
|
|
1516
|
+
listCategories(params?: SearchablePaginationParams): Promise<PaginatedResult<CategoryResponse>>;
|
|
1517
|
+
/**
|
|
1518
|
+
* Fetch all categories with their associated blog post counts.
|
|
1519
|
+
*
|
|
1520
|
+
* **Endpoint:** `GET /sites/{siteId}/categories/blog-counts`
|
|
1521
|
+
*
|
|
1522
|
+
* Useful for rendering category sidebars with post counts.
|
|
1523
|
+
*
|
|
1524
|
+
* @returns Array of categories, each with a `blog_count` field.
|
|
1525
|
+
*
|
|
1526
|
+
* @example
|
|
1527
|
+
* ```ts
|
|
1528
|
+
* const categories = await forja.taxonomy.getCategoriesWithBlogCounts();
|
|
1529
|
+
* categories.forEach(c => console.log(`${c.slug}: ${c.blog_count} posts`));
|
|
1530
|
+
* ```
|
|
1531
|
+
*/
|
|
1532
|
+
getCategoriesWithBlogCounts(): Promise<CategoryWithCountResponse[]>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Fetch all tags associated with a specific content item (blog, page, etc.).
|
|
1535
|
+
*
|
|
1536
|
+
* **Endpoint:** `GET /content/{contentId}/tags`
|
|
1537
|
+
*
|
|
1538
|
+
* @param contentId - The content item's UUID (the `content_id` field, not the blog/page ID).
|
|
1539
|
+
* @returns Array of tags assigned to the content.
|
|
1540
|
+
*/
|
|
1541
|
+
getContentTags(contentId: string): Promise<TagResponse[]>;
|
|
1542
|
+
/**
|
|
1543
|
+
* Fetch all categories associated with a specific content item.
|
|
1544
|
+
*
|
|
1545
|
+
* **Endpoint:** `GET /content/{contentId}/categories`
|
|
1546
|
+
*
|
|
1547
|
+
* @param contentId - The content item's UUID (the `content_id` field, not the blog/page ID).
|
|
1548
|
+
* @returns Array of categories assigned to the content.
|
|
1549
|
+
*/
|
|
1550
|
+
getContentCategories(contentId: string): Promise<CategoryResponse[]>;
|
|
1551
|
+
/**
|
|
1552
|
+
* Fetch a single tag by its UUID.
|
|
1553
|
+
*
|
|
1554
|
+
* **Endpoint:** `GET /tags/{id}`
|
|
1555
|
+
*
|
|
1556
|
+
* @param id - The tag's UUID.
|
|
1557
|
+
* @returns The tag, or `null` if not found.
|
|
1558
|
+
*
|
|
1559
|
+
* @example
|
|
1560
|
+
* ```ts
|
|
1561
|
+
* const tag = await forja.taxonomy.getTag('tag-uuid');
|
|
1562
|
+
* ```
|
|
1563
|
+
*/
|
|
1564
|
+
getTag(id: string): Promise<TagResponse | null>;
|
|
1565
|
+
/**
|
|
1566
|
+
* Fetch a single tag by its URL slug.
|
|
1567
|
+
*
|
|
1568
|
+
* **Endpoint:** `GET /tags/by-slug/{slug}`
|
|
1569
|
+
*
|
|
1570
|
+
* @param slug - The tag's URL slug (e.g. `"typescript"`, `"web-components"`).
|
|
1571
|
+
* @returns The tag, or `null` if not found.
|
|
1572
|
+
*
|
|
1573
|
+
* @example
|
|
1574
|
+
* ```ts
|
|
1575
|
+
* const tag = await forja.taxonomy.getTagBySlug('typescript');
|
|
1576
|
+
* if (tag) {
|
|
1577
|
+
* console.log(tag.name, tag.slug);
|
|
1578
|
+
* }
|
|
1579
|
+
* ```
|
|
1580
|
+
*/
|
|
1581
|
+
getTagBySlug(slug: string): Promise<TagResponse | null>;
|
|
1582
|
+
/**
|
|
1583
|
+
* Fetch a single category by its UUID.
|
|
1584
|
+
*
|
|
1585
|
+
* **Endpoint:** `GET /categories/{id}`
|
|
1586
|
+
*
|
|
1587
|
+
* @param id - The category's UUID.
|
|
1588
|
+
* @returns The category, or `null` if not found.
|
|
1589
|
+
*
|
|
1590
|
+
* @example
|
|
1591
|
+
* ```ts
|
|
1592
|
+
* const category = await forja.taxonomy.getCategory('cat-uuid');
|
|
1593
|
+
* ```
|
|
1594
|
+
*/
|
|
1595
|
+
getCategory(id: string): Promise<CategoryResponse | null>;
|
|
1596
|
+
/**
|
|
1597
|
+
* Fetch child categories of a parent category.
|
|
1598
|
+
*
|
|
1599
|
+
* **Endpoint:** `GET /categories/{parentId}/children`
|
|
1600
|
+
*
|
|
1601
|
+
* Use to build hierarchical category trees (e.g. nested navigation menus,
|
|
1602
|
+
* category sidebars with subcategories).
|
|
1603
|
+
*
|
|
1604
|
+
* @param parentId - The parent category's UUID.
|
|
1605
|
+
* @returns Array of child categories.
|
|
1606
|
+
*
|
|
1607
|
+
* @example
|
|
1608
|
+
* ```ts
|
|
1609
|
+
* const subcategories = await forja.taxonomy.getCategoryChildren('parent-uuid');
|
|
1610
|
+
* subcategories.forEach(child => console.log(child.slug));
|
|
1611
|
+
* ```
|
|
1612
|
+
*/
|
|
1613
|
+
getCategoryChildren(parentId: string): Promise<CategoryResponse[]>;
|
|
1614
|
+
}
|
|
1615
|
+
//#endregion
|
|
1616
|
+
//#region src/client.d.ts
|
|
1617
|
+
/**
|
|
1618
|
+
* The main entry point for the Forja CMS content SDK.
|
|
1619
|
+
*
|
|
1620
|
+
* Create an instance with your API credentials and use the resource
|
|
1621
|
+
* properties to interact with the Forja content API.
|
|
1622
|
+
*
|
|
1623
|
+
* @example
|
|
1624
|
+
* ```ts
|
|
1625
|
+
* import { ForjaClient } from '@forjacms/client';
|
|
1626
|
+
*
|
|
1627
|
+
* const forja = new ForjaClient({
|
|
1628
|
+
* baseUrl: 'https://cms.example.com/api/v1',
|
|
1629
|
+
* apiKey: 'your-read-api-key',
|
|
1630
|
+
* siteId: 'your-site-uuid',
|
|
1631
|
+
* });
|
|
1632
|
+
*
|
|
1633
|
+
* const blogs = await forja.blogs.listPublished({ page: 1 });
|
|
1634
|
+
* const site = await forja.site.get();
|
|
1635
|
+
* const locales = await forja.site.listLocales();
|
|
1636
|
+
* ```
|
|
1637
|
+
*/
|
|
1638
|
+
declare class ForjaClient {
|
|
1639
|
+
/** Blog posts — published listings, featured, similar, detail by slug/ID. */
|
|
1640
|
+
readonly blogs: BlogsResource;
|
|
1641
|
+
/** CMS pages — list, fetch by route, sections and localizations. */
|
|
1642
|
+
readonly pages: PagesResource;
|
|
1643
|
+
/** Navigation menus — menu metadata, tree structure, items. */
|
|
1644
|
+
readonly navigation: NavigationResource;
|
|
1645
|
+
/** Tags and categories — listing, lookup by slug, content associations, blog counts. */
|
|
1646
|
+
readonly taxonomy: TaxonomyResource;
|
|
1647
|
+
/** Privacy-first analytics — pageview tracking and reports. */
|
|
1648
|
+
readonly analytics: AnalyticsResource;
|
|
1649
|
+
/** CV / resume — skills and work/education entries. */
|
|
1650
|
+
readonly cv: CvResource;
|
|
1651
|
+
/** Legal documents — privacy policy, cookie consent, terms, version history. */
|
|
1652
|
+
readonly legal: LegalResource;
|
|
1653
|
+
/** Portfolio projects — published listings, detail, skill/CV associations. */
|
|
1654
|
+
readonly projects: ProjectsResource;
|
|
1655
|
+
/** URL redirects — path-based lookup for SSR middleware. */
|
|
1656
|
+
readonly redirects: RedirectsResource;
|
|
1657
|
+
/** Site configuration — name, slug, logo, timezone, locales. */
|
|
1658
|
+
readonly site: SiteResource;
|
|
1659
|
+
/** Media assets — browse, search, filter by type, full detail with variants. */
|
|
1660
|
+
readonly media: MediaResource;
|
|
1661
|
+
/** Social media links — GitHub, Twitter, LinkedIn, etc. */
|
|
1662
|
+
readonly social: SocialResource;
|
|
1663
|
+
/**
|
|
1664
|
+
* @param config - API connection settings.
|
|
1665
|
+
* @param config.baseUrl - Full URL to the Forja API (e.g. `https://cms.example.com/api/v1`).
|
|
1666
|
+
* @param config.apiKey - API key with at least `Read` permission.
|
|
1667
|
+
* @param config.siteId - UUID of the site to query.
|
|
1668
|
+
* @param config.fetch - Optional custom `fetch` implementation for edge runtimes or testing.
|
|
1669
|
+
*/
|
|
1670
|
+
constructor(config: ForjaClientConfig);
|
|
1671
|
+
}
|
|
1672
|
+
//#endregion
|
|
1673
|
+
export { ProjectLocalizationResponse as $, LegalVersionResponse as A, NavigationTree as B, LegalDocumentDetailResponse as C, LegalGroupResponse as D, LegalDocumentWithGroups as E, MediaResponse as F, PageType as G, PageListItem as H, MediaVariantResponse as I, PaginationParams as J, Paginated as K, NavigationItemLocalizationResponse as L, LocalizationResponse as M, MediaListItem as N, LegalGroupWithItems as O, MediaListParams as P, ProjectListParams as Q, NavigationItemResponse as R, LegalDocType as S, LegalDocumentResponse as T, PageResponse as U, PageDetailResponse as V, PageSectionResponse as W, ProjectLinkResponse as X, ProjectDetailResponse as Y, ProjectLinkType as Z, CvEntryResponse as _, TranslationStatus as _t, AnalyticsPageParams as a, SearchablePaginationParams as at, ForjaClientConfig as b, BlogDetailResponse as c, SiteLocaleResponse as ct, BlogResponse as d, SkillResponse as dt, ProjectMediaResponse as et, CategoryResponse as f, SocialLinkResponse as ft, CvEntryParams as g, TrackPageviewResponse as gt, ContentStatus as h, TrackPageviewRequest as ht, AnalyticsPageDetailResponse as i, ReferrerItem as it, LocaleFilterParams as j, LegalItemResponse as k, BlogDocumentResponse as l, SiteResponse as lt, CategoryWithCountResponse as m, TopContentItem as mt, HttpClient as n, RedirectLookupResponse as nt, AnalyticsReportParams as o, SectionLocalizationResponse as ot, CategoryTree as p, TagResponse as pt, PaginationMeta as q, PaginatedResult as r, RedirectResponse as rt, AnalyticsReportResponse as s, SectionType as st, ForjaClient as t, ProjectResponse as tt, BlogListItem as u, SkillCategory as ut, CvEntryType as v, TrendDataPoint as vt, LegalDocumentFullDetailResponse as w, LegalDocLocalizationResponse as x, DocumentLocalizationResponse as y, NavigationMenuResponse as z };
|