@forjacms/client 1.7.0 → 1.7.3
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 +56 -0
- package/dist/angular/index.cjs +1 -1
- package/dist/angular/index.d.cts +1 -1
- package/dist/angular/index.d.mts +1 -1
- package/dist/angular/index.mjs +1 -1
- package/dist/{client-BTbTifpr.d.mts → client-CUbs1rkJ.d.cts} +211 -24
- package/dist/client-CWajZ1IX.mjs +1 -0
- package/dist/client-DVY5u6LJ.cjs +1 -0
- package/dist/{client-CvbFQ08l.d.cts → client-HGIKi26O.d.mts} +211 -24
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/dist/client-C-2JZF6o.mjs +0 -1
- package/dist/client-FailsuXv.cjs +0 -1
package/README.md
CHANGED
|
@@ -130,6 +130,62 @@ const privacy = await forja.legal.getBySlug('privacy-policy');
|
|
|
130
130
|
const consent = await forja.legal.getCookieConsent();
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
## Site Locales
|
|
134
|
+
|
|
135
|
+
`SiteLocaleResponse` is the canonical shape returned by every endpoint that
|
|
136
|
+
lists or resolves the locales configured for a site. Pinning this contract
|
|
137
|
+
here because consumers have drifted in the past (inventing a `text_direction`
|
|
138
|
+
field, expecting a top-level `id`, treating `url_prefix` as required).
|
|
139
|
+
|
|
140
|
+
**Example payload:**
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"site_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
145
|
+
"locale_id": "660e8400-e29b-41d4-a716-446655440000",
|
|
146
|
+
"is_default": true,
|
|
147
|
+
"is_active": true,
|
|
148
|
+
"url_prefix": null,
|
|
149
|
+
"created_at": "2024-01-15T10:30:00Z",
|
|
150
|
+
"code": "en",
|
|
151
|
+
"name": "English",
|
|
152
|
+
"native_name": "English",
|
|
153
|
+
"direction": "ltr"
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Identity.** The natural key is the composite `(site_id, locale_id)`. There
|
|
158
|
+
is no top-level `id` — a locale can be attached to many sites, and a site
|
|
159
|
+
can carry many locales.
|
|
160
|
+
|
|
161
|
+
**Field reference:**
|
|
162
|
+
|
|
163
|
+
| Field | Type | Notes |
|
|
164
|
+
| ------------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| `site_id` | UUID | Composite-key half #1. |
|
|
166
|
+
| `locale_id` | UUID | Composite-key half #2. |
|
|
167
|
+
| `is_default` | boolean | Exactly one row per site has this `true`. |
|
|
168
|
+
| `is_active` | boolean | Configured-but-not-served when `false`. Consumers usually filter to `is_active = true`. |
|
|
169
|
+
| `url_prefix` | string \| null | Path segment selecting this locale. Nullable; the default locale conventionally has none. |
|
|
170
|
+
| `created_at` | ISO-8601 (UTC) | When the assignment was created. |
|
|
171
|
+
| `code` | string | BCP-47 (e.g. `"en"`, `"de-AT"`), denormalised from the `locales` row. |
|
|
172
|
+
| `name` | string | English-language label (e.g. `"English"`), denormalised. |
|
|
173
|
+
| `native_name` | string \| null | Locale's own name (e.g. `"Deutsch"`), denormalised. Nullable for locales without a defined native form. |
|
|
174
|
+
| `direction` | `"ltr"` \| `"rtl"` | Text direction. **The field is `direction` — NOT `text_direction`.** |
|
|
175
|
+
|
|
176
|
+
**Denormalisation rationale.** `code`, `name`, `native_name`, and `direction`
|
|
177
|
+
live on the `locales` table but are inlined into the response so a consumer
|
|
178
|
+
can render a locale switcher without a second round-trip. The trade-off is
|
|
179
|
+
deliberate: assignment-rate-of-change is much lower than read-rate.
|
|
180
|
+
|
|
181
|
+
**Anti-patterns to avoid in consumers:**
|
|
182
|
+
|
|
183
|
+
- ❌ Renaming `direction` → `text_direction` (the upstream name wins).
|
|
184
|
+
- ❌ Expecting a top-level `id` (use the `(site_id, locale_id)` composite).
|
|
185
|
+
- ❌ Treating `url_prefix` as required (it's nullable; the default locale typically has none).
|
|
186
|
+
|
|
187
|
+
See [issue #742](https://github.com/dominikdorfstetter/forja/issues/742) for the canonical-contract discussion.
|
|
188
|
+
|
|
133
189
|
## Pagination
|
|
134
190
|
|
|
135
191
|
All paginated responses include helpers for navigating pages:
|
package/dist/angular/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../client-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../client-DVY5u6LJ.cjs`);let t=require(`@angular/core`);const n=new t.InjectionToken(`ForjaClient`);function r(r){return(0,t.makeEnvironmentProviders)([{provide:n,useFactory:()=>new e.t(r)}])}function i(){return(0,t.inject)(n)}function a(e){let n=(0,t.signal)(void 0),r=(0,t.signal)(!0),i=(0,t.signal)(null),a=()=>{r.set(!0),i.set(null),e().then(e=>n.set(e)).catch(e=>i.set(e instanceof Error?e:Error(String(e)))).finally(()=>r.set(!1))};return a(),{value:n.asReadonly(),isLoading:r.asReadonly(),error:i.asReadonly(),reload:a}}exports.FORJA_CLIENT=n,exports.forjaResource=a,exports.injectForja=i,exports.provideForja=r;
|
package/dist/angular/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as ForjaClientConfig, t as ForjaClient } from "../client-
|
|
1
|
+
import { N as ForjaClientConfig, t as ForjaClient } from "../client-CUbs1rkJ.cjs";
|
|
2
2
|
import { EnvironmentProviders, InjectionToken, Signal } from "@angular/core";
|
|
3
3
|
|
|
4
4
|
//#region src/angular/provider.d.ts
|
package/dist/angular/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as ForjaClientConfig, t as ForjaClient } from "../client-
|
|
1
|
+
import { N as ForjaClientConfig, t as ForjaClient } from "../client-HGIKi26O.mjs";
|
|
2
2
|
import { EnvironmentProviders, InjectionToken, Signal } from "@angular/core";
|
|
3
3
|
|
|
4
4
|
//#region src/angular/provider.d.ts
|
package/dist/angular/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"../client-
|
|
1
|
+
import{t as e}from"../client-CWajZ1IX.mjs";import{InjectionToken as t,inject as n,makeEnvironmentProviders as r,signal as i}from"@angular/core";const a=new t(`ForjaClient`);function o(t){return r([{provide:a,useFactory:()=>new e(t)}])}function s(){return n(a)}function c(e){let t=i(void 0),n=i(!0),r=i(null),a=()=>{n.set(!0),r.set(null),e().then(e=>t.set(e)).catch(e=>r.set(e instanceof Error?e:Error(String(e)))).finally(()=>n.set(!1))};return a(),{value:t.asReadonly(),isLoading:n.asReadonly(),error:r.asReadonly(),reload:a}}export{a as FORJA_CLIENT,c as forjaResource,s as injectForja,o as provideForja};
|
|
@@ -120,6 +120,18 @@ interface BlogDetailResponse extends BlogResponse {
|
|
|
120
120
|
documents: BlogDocumentResponse[];
|
|
121
121
|
og_image_url: string | null;
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Options for blog detail lookups (`get`, `getBySlug`). The list shape
|
|
125
|
+
* does not yet carry `localizations[]` so the resolver only applies to
|
|
126
|
+
* the detail endpoint — list canonicalization is tracked separately.
|
|
127
|
+
*/
|
|
128
|
+
interface BlogDetailParams {
|
|
129
|
+
/**
|
|
130
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
131
|
+
* collapses to one resolved entry. See ADR 0002.
|
|
132
|
+
*/
|
|
133
|
+
locale?: string;
|
|
134
|
+
}
|
|
123
135
|
interface PageListItem {
|
|
124
136
|
id: string;
|
|
125
137
|
route: string;
|
|
@@ -281,6 +293,12 @@ interface AnalyticsPageParams {
|
|
|
281
293
|
startDate?: string;
|
|
282
294
|
endDate?: string;
|
|
283
295
|
}
|
|
296
|
+
interface SkillLocalizationResponse {
|
|
297
|
+
id: string;
|
|
298
|
+
locale_id: string;
|
|
299
|
+
name: string;
|
|
300
|
+
description: string | null;
|
|
301
|
+
}
|
|
284
302
|
interface SkillResponse {
|
|
285
303
|
id: string;
|
|
286
304
|
name: string;
|
|
@@ -288,6 +306,19 @@ interface SkillResponse {
|
|
|
288
306
|
category: SkillCategory | null;
|
|
289
307
|
icon: string | null;
|
|
290
308
|
proficiency_level: number | null;
|
|
309
|
+
/**
|
|
310
|
+
* Per-locale display names. Empty array when no localizations exist
|
|
311
|
+
* (never null / missing). Clients pick the matching locale and fall
|
|
312
|
+
* back per their own rules.
|
|
313
|
+
*/
|
|
314
|
+
localizations: SkillLocalizationResponse[];
|
|
315
|
+
}
|
|
316
|
+
interface CvEntryLocalizationResponse {
|
|
317
|
+
id: string;
|
|
318
|
+
locale_id: string;
|
|
319
|
+
position: string;
|
|
320
|
+
description: string | null;
|
|
321
|
+
achievements: unknown | null;
|
|
291
322
|
}
|
|
292
323
|
interface CvEntryResponse {
|
|
293
324
|
id: string;
|
|
@@ -302,9 +333,52 @@ interface CvEntryResponse {
|
|
|
302
333
|
display_order: number;
|
|
303
334
|
created_at: string;
|
|
304
335
|
updated_at: string;
|
|
336
|
+
/**
|
|
337
|
+
* Per-locale position + description. Empty array when no localizations
|
|
338
|
+
* exist (never null / missing).
|
|
339
|
+
*/
|
|
340
|
+
localizations: CvEntryLocalizationResponse[];
|
|
341
|
+
/**
|
|
342
|
+
* Skill IDs linked to this CV entry. Empty array when no skills are
|
|
343
|
+
* linked (never null / missing).
|
|
344
|
+
*/
|
|
345
|
+
skill_ids: string[];
|
|
346
|
+
}
|
|
347
|
+
/** Pagination, search, and locale-resolver params for skill listings. */
|
|
348
|
+
interface SkillListParams extends SearchablePaginationParams {
|
|
349
|
+
/**
|
|
350
|
+
* Optional locale code (e.g. `"en"`). When set, each skill's
|
|
351
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
352
|
+
* fallback chain. See ADR 0002.
|
|
353
|
+
*/
|
|
354
|
+
locale?: string;
|
|
355
|
+
}
|
|
356
|
+
/** Options for skill detail lookups (`getSkill`, `getSkillBySlug`). */
|
|
357
|
+
interface SkillDetailParams {
|
|
358
|
+
/**
|
|
359
|
+
* Optional locale code. When set, `localizations` collapses to one
|
|
360
|
+
* resolved entry. See ADR 0002.
|
|
361
|
+
*/
|
|
362
|
+
locale?: string;
|
|
305
363
|
}
|
|
306
364
|
interface CvEntryParams extends SearchablePaginationParams {
|
|
307
365
|
entryType?: CvEntryType;
|
|
366
|
+
/**
|
|
367
|
+
* Optional locale code (e.g. `"en"`, `"de-AT"`). When set, each entry's
|
|
368
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
369
|
+
* fallback chain. Omit to receive every localization.
|
|
370
|
+
*
|
|
371
|
+
* See ADR 0002 (`docs/adr/0002-locale-resolver.md`).
|
|
372
|
+
*/
|
|
373
|
+
locale?: string;
|
|
374
|
+
}
|
|
375
|
+
/** Options for CV-entry detail lookups (`getEntry`). */
|
|
376
|
+
interface CvEntryDetailParams {
|
|
377
|
+
/**
|
|
378
|
+
* Optional locale code. When set, `localizations` collapses to one
|
|
379
|
+
* resolved entry. See ADR 0002.
|
|
380
|
+
*/
|
|
381
|
+
locale?: string;
|
|
308
382
|
}
|
|
309
383
|
interface LegalDocumentResponse {
|
|
310
384
|
id: string;
|
|
@@ -327,6 +401,19 @@ interface LegalDocumentDetailResponse {
|
|
|
327
401
|
created_at: string;
|
|
328
402
|
updated_at: string;
|
|
329
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Options for legal-document detail lookups (`getBySlug`, `getDetail`).
|
|
406
|
+
* The list shape (`LegalDocumentResponse`) does not yet carry
|
|
407
|
+
* `localizations[]` — tracked separately.
|
|
408
|
+
*/
|
|
409
|
+
interface LegalDetailParams {
|
|
410
|
+
/**
|
|
411
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
412
|
+
* (and `doc_localizations[]` on the full-detail endpoint) collapses
|
|
413
|
+
* to one resolved entry. See ADR 0002.
|
|
414
|
+
*/
|
|
415
|
+
locale?: string;
|
|
416
|
+
}
|
|
330
417
|
interface LegalGroupResponse {
|
|
331
418
|
id: string;
|
|
332
419
|
cookie_name: string;
|
|
@@ -410,7 +497,16 @@ interface SocialLinkResponse {
|
|
|
410
497
|
}
|
|
411
498
|
/** Link type for project resources (repository, demo, docs, etc.). */
|
|
412
499
|
type ProjectLinkType = 'repository' | 'demo' | 'documentation' | 'website' | 'other';
|
|
413
|
-
/**
|
|
500
|
+
/** Localized content for a project. */
|
|
501
|
+
interface ProjectLocalizationResponse {
|
|
502
|
+
id: string;
|
|
503
|
+
locale_id: string;
|
|
504
|
+
title: string;
|
|
505
|
+
short_description: string | null;
|
|
506
|
+
description: string | null;
|
|
507
|
+
}
|
|
508
|
+
/** Project summary for list views. Always carries `localizations` — empty
|
|
509
|
+
* array when the project has none, never `null` or missing. */
|
|
414
510
|
interface ProjectResponse {
|
|
415
511
|
id: string;
|
|
416
512
|
slug: string;
|
|
@@ -423,14 +519,9 @@ interface ProjectResponse {
|
|
|
423
519
|
published_at: string | null;
|
|
424
520
|
created_at: string;
|
|
425
521
|
updated_at: string;
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
id: string;
|
|
430
|
-
locale_id: string;
|
|
431
|
-
title: string;
|
|
432
|
-
short_description: string | null;
|
|
433
|
-
description: string | null;
|
|
522
|
+
/** Skill IDs linked to the project. Always present — empty array when none. */
|
|
523
|
+
skill_ids: string[];
|
|
524
|
+
localizations: ProjectLocalizationResponse[];
|
|
434
525
|
}
|
|
435
526
|
/** External link attached to a project. */
|
|
436
527
|
interface ProjectLinkResponse {
|
|
@@ -447,12 +538,11 @@ interface ProjectMediaResponse {
|
|
|
447
538
|
display_order: number;
|
|
448
539
|
is_cover: boolean;
|
|
449
540
|
}
|
|
450
|
-
/** Full project detail
|
|
541
|
+
/** Full project detail. Inherits `skill_ids` and `localizations` from
|
|
542
|
+
* {@link ProjectResponse}; adds links, media, and relation id sets. */
|
|
451
543
|
interface ProjectDetailResponse extends ProjectResponse {
|
|
452
|
-
localizations: ProjectLocalizationResponse[];
|
|
453
544
|
links: ProjectLinkResponse[];
|
|
454
545
|
media: ProjectMediaResponse[];
|
|
455
|
-
skill_ids: string[];
|
|
456
546
|
cv_entry_ids: string[];
|
|
457
547
|
}
|
|
458
548
|
/** Pagination and filter params for project listings. */
|
|
@@ -463,33 +553,79 @@ interface ProjectListParams extends PaginationParams {
|
|
|
463
553
|
sortDir?: 'asc' | 'desc';
|
|
464
554
|
/** Filter to featured projects only. */
|
|
465
555
|
isFeatured?: boolean;
|
|
556
|
+
/**
|
|
557
|
+
* Optional locale code (e.g. `"en"`, `"de-AT"`). When set, each project's
|
|
558
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
559
|
+
* fallback chain (requested → site default → first available). Omit to
|
|
560
|
+
* receive every localization, which is the existing default.
|
|
561
|
+
*
|
|
562
|
+
* See ADR 0002 (`docs/adr/0002-locale-resolver.md`).
|
|
563
|
+
*/
|
|
564
|
+
locale?: string;
|
|
466
565
|
}
|
|
566
|
+
/** Options for project detail lookups (`get`, `getBySlug`). */
|
|
567
|
+
interface ProjectDetailParams {
|
|
568
|
+
/**
|
|
569
|
+
* Optional locale code. When set, `localizations` collapses to one entry
|
|
570
|
+
* resolved by the server's fallback chain. See ADR 0002.
|
|
571
|
+
*/
|
|
572
|
+
locale?: string;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* The set of HTTP status codes a Forja redirect may use.
|
|
576
|
+
*
|
|
577
|
+
* Pinned by issue #743. The same domain is enforced server-side by the
|
|
578
|
+
* `validate_redirect_status_code` DTO validator and the
|
|
579
|
+
* `chk_redirect_status_code` DB CHECK constraint, so consumers may rely
|
|
580
|
+
* on this value without runtime coercion.
|
|
581
|
+
*/
|
|
582
|
+
type RedirectStatusCode = 301 | 302 | 307 | 308;
|
|
467
583
|
/** A URL redirect rule. */
|
|
468
584
|
interface RedirectResponse {
|
|
469
585
|
id: string;
|
|
470
586
|
site_id: string;
|
|
471
587
|
source_path: string;
|
|
472
588
|
destination_path: string;
|
|
473
|
-
status_code:
|
|
589
|
+
status_code: RedirectStatusCode;
|
|
474
590
|
is_active: boolean;
|
|
475
591
|
description: string | null;
|
|
476
592
|
created_at: string;
|
|
477
593
|
updated_at: string;
|
|
478
594
|
}
|
|
479
|
-
/**
|
|
595
|
+
/**
|
|
596
|
+
* Result of a redirect path lookup.
|
|
597
|
+
*
|
|
598
|
+
* Returned with HTTP 200 by `GET /sites/{site_id}/redirects/lookup` on
|
|
599
|
+
* match. No-match is signalled by **404** (RFC 7807 ProblemDetails) —
|
|
600
|
+
* never a 200 with a null body, never a `{ redirects: [] }` list.
|
|
601
|
+
*/
|
|
480
602
|
interface RedirectLookupResponse {
|
|
481
603
|
destination_path: string;
|
|
482
|
-
status_code:
|
|
604
|
+
status_code: RedirectStatusCode;
|
|
483
605
|
}
|
|
484
606
|
/** A locale configured for a site. */
|
|
485
607
|
interface SiteLocaleResponse {
|
|
608
|
+
/** Composite-key half #1 — which site this assignment belongs to. */
|
|
609
|
+
site_id: string;
|
|
610
|
+
/** Composite-key half #2 — which locale is attached. */
|
|
486
611
|
locale_id: string;
|
|
612
|
+
/** BCP-47 code, denormalised from `locales.code`. */
|
|
487
613
|
code: string;
|
|
614
|
+
/** English-language label, denormalised from `locales.name`. */
|
|
488
615
|
name: string;
|
|
616
|
+
/** Locale's own name, denormalised from `locales.native_name`. */
|
|
489
617
|
native_name: string | null;
|
|
490
618
|
direction: 'ltr' | 'rtl';
|
|
619
|
+
/** Exactly one row per site has this set to `true`. */
|
|
491
620
|
is_default: boolean;
|
|
621
|
+
/** Configured-but-not-served when `false`. Consumers usually filter to `true`. */
|
|
492
622
|
is_active: boolean;
|
|
623
|
+
/**
|
|
624
|
+
* Path segment selecting this locale. `null` for the default locale
|
|
625
|
+
* (served at the site root without a prefix).
|
|
626
|
+
*/
|
|
627
|
+
url_prefix: string | null;
|
|
628
|
+
created_at: string;
|
|
493
629
|
}
|
|
494
630
|
/** Media item summary for list views (lighter than full MediaResponse). */
|
|
495
631
|
interface MediaListItem {
|
|
@@ -770,7 +906,7 @@ declare class BlogsResource {
|
|
|
770
906
|
* }
|
|
771
907
|
* ```
|
|
772
908
|
*/
|
|
773
|
-
getBySlug(slug: string): Promise<BlogDetailResponse | null>;
|
|
909
|
+
getBySlug(slug: string, params?: BlogDetailParams): Promise<BlogDetailResponse | null>;
|
|
774
910
|
/**
|
|
775
911
|
* Fetch a blog post's full detail by its UUID.
|
|
776
912
|
*
|
|
@@ -784,7 +920,7 @@ declare class BlogsResource {
|
|
|
784
920
|
* const blog = await forja.blogs.get('550e8400-e29b-41d4-a716-446655440000');
|
|
785
921
|
* ```
|
|
786
922
|
*/
|
|
787
|
-
get(idOrSlug: string): Promise<BlogDetailResponse | null>;
|
|
923
|
+
get(idOrSlug: string, params?: BlogDetailParams): Promise<BlogDetailResponse | null>;
|
|
788
924
|
/**
|
|
789
925
|
* Fetch the site's RSS feed as raw XML.
|
|
790
926
|
*
|
|
@@ -822,7 +958,7 @@ declare class CvResource {
|
|
|
822
958
|
* const programming = skills.data.filter(s => s.category === 'Programming');
|
|
823
959
|
* ```
|
|
824
960
|
*/
|
|
825
|
-
listSkills(params?:
|
|
961
|
+
listSkills(params?: SkillListParams): Promise<PaginatedResult<SkillResponse>>;
|
|
826
962
|
/**
|
|
827
963
|
* Fetch a skill by its UUID.
|
|
828
964
|
*
|
|
@@ -831,7 +967,7 @@ declare class CvResource {
|
|
|
831
967
|
* @param id - The skill's UUID.
|
|
832
968
|
* @returns The skill, or `null` if not found.
|
|
833
969
|
*/
|
|
834
|
-
getSkill(id: string): Promise<SkillResponse | null>;
|
|
970
|
+
getSkill(id: string, params?: SkillDetailParams): Promise<SkillResponse | null>;
|
|
835
971
|
/**
|
|
836
972
|
* Fetch a skill by its URL slug.
|
|
837
973
|
*
|
|
@@ -846,7 +982,7 @@ declare class CvResource {
|
|
|
846
982
|
* if (ts) console.log(`${ts.name}: level ${ts.proficiency_level}`);
|
|
847
983
|
* ```
|
|
848
984
|
*/
|
|
849
|
-
getSkillBySlug(slug: string): Promise<SkillResponse | null>;
|
|
985
|
+
getSkillBySlug(slug: string, params?: SkillDetailParams): Promise<SkillResponse | null>;
|
|
850
986
|
/**
|
|
851
987
|
* Fetch a paginated list of CV entries (work, education, certifications, etc.).
|
|
852
988
|
*
|
|
@@ -863,6 +999,25 @@ declare class CvResource {
|
|
|
863
999
|
* ```
|
|
864
1000
|
*/
|
|
865
1001
|
listEntries(params?: CvEntryParams): Promise<PaginatedResult<CvEntryResponse>>;
|
|
1002
|
+
/**
|
|
1003
|
+
* Fetch a CV entry by its UUID.
|
|
1004
|
+
*
|
|
1005
|
+
* **Endpoint:** `GET /cv/{id}`
|
|
1006
|
+
*
|
|
1007
|
+
* @param id - The CV entry's UUID.
|
|
1008
|
+
* @param params - Optional locale resolver per ADR 0002.
|
|
1009
|
+
* @returns The CV entry, or `null` if not found.
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
1012
|
+
* ```ts
|
|
1013
|
+
* // All localizations (default)
|
|
1014
|
+
* const entry = await forja.cv.getEntry('entry-uuid');
|
|
1015
|
+
*
|
|
1016
|
+
* // Single-locale collapse
|
|
1017
|
+
* const enEntry = await forja.cv.getEntry('entry-uuid', { locale: 'en' });
|
|
1018
|
+
* ```
|
|
1019
|
+
*/
|
|
1020
|
+
getEntry(id: string, params?: CvEntryDetailParams): Promise<CvEntryResponse | null>;
|
|
866
1021
|
}
|
|
867
1022
|
//#endregion
|
|
868
1023
|
//#region src/resources/forms.d.ts
|
|
@@ -1029,7 +1184,7 @@ declare class LegalResource {
|
|
|
1029
1184
|
* }
|
|
1030
1185
|
* ```
|
|
1031
1186
|
*/
|
|
1032
|
-
getBySlug(slug: string): Promise<LegalDocumentDetailResponse | null>;
|
|
1187
|
+
getBySlug(slug: string, params?: LegalDetailParams): Promise<LegalDocumentDetailResponse | null>;
|
|
1033
1188
|
/**
|
|
1034
1189
|
* Fetch the cookie consent document with its consent groups and items.
|
|
1035
1190
|
*
|
|
@@ -1093,7 +1248,7 @@ declare class LegalResource {
|
|
|
1093
1248
|
* }
|
|
1094
1249
|
* ```
|
|
1095
1250
|
*/
|
|
1096
|
-
getDetail(id: string): Promise<LegalDocumentFullDetailResponse | null>;
|
|
1251
|
+
getDetail(id: string, params?: LegalDetailParams): Promise<LegalDocumentFullDetailResponse | null>;
|
|
1097
1252
|
/**
|
|
1098
1253
|
* Fetch the version history of a legal document.
|
|
1099
1254
|
*
|
|
@@ -1291,6 +1446,19 @@ interface PageListParams extends SearchablePaginationParams {
|
|
|
1291
1446
|
/** Exclude pages with this status. */
|
|
1292
1447
|
excludeStatus?: string;
|
|
1293
1448
|
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Options for page-detail lookups (`getDetail`). The list shape
|
|
1451
|
+
* (`PageResponse`) does not carry `localizations[]` today — adding it is
|
|
1452
|
+
* tracked as a separate canonicalization gap; until then the resolver
|
|
1453
|
+
* applies only to the detail endpoint.
|
|
1454
|
+
*/
|
|
1455
|
+
interface PageDetailParams {
|
|
1456
|
+
/**
|
|
1457
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
1458
|
+
* collapses to one resolved entry. See ADR 0002.
|
|
1459
|
+
*/
|
|
1460
|
+
locale?: string;
|
|
1461
|
+
}
|
|
1294
1462
|
/**
|
|
1295
1463
|
* CMS page operations.
|
|
1296
1464
|
*
|
|
@@ -1337,6 +1505,25 @@ declare class PagesResource {
|
|
|
1337
1505
|
* ```
|
|
1338
1506
|
*/
|
|
1339
1507
|
getByRoute(route: string): Promise<PageDetailResponse | null>;
|
|
1508
|
+
/**
|
|
1509
|
+
* Fetch a page's full detail (content localizations + computed OG image).
|
|
1510
|
+
*
|
|
1511
|
+
* **Endpoint:** `GET /pages/{id}/detail`
|
|
1512
|
+
*
|
|
1513
|
+
* @param id - The page's UUID.
|
|
1514
|
+
* @param params - Optional locale resolver (ADR 0002).
|
|
1515
|
+
* @returns The page detail, or `null` if not found.
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* ```ts
|
|
1519
|
+
* // Every localization (admin/editor use case)
|
|
1520
|
+
* const detail = await forja.pages.getDetail('page-uuid');
|
|
1521
|
+
*
|
|
1522
|
+
* // Server-side rendering — single locale
|
|
1523
|
+
* const en = await forja.pages.getDetail('page-uuid', { locale: 'en' });
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1526
|
+
getDetail(id: string, params?: PageDetailParams): Promise<PageDetailResponse | null>;
|
|
1340
1527
|
/**
|
|
1341
1528
|
* Fetch all sections for a page.
|
|
1342
1529
|
*
|
|
@@ -1438,7 +1625,7 @@ declare class ProjectsResource {
|
|
|
1438
1625
|
* }
|
|
1439
1626
|
* ```
|
|
1440
1627
|
*/
|
|
1441
|
-
get(id: string): Promise<ProjectDetailResponse | null>;
|
|
1628
|
+
get(id: string, params?: ProjectDetailParams): Promise<ProjectDetailResponse | null>;
|
|
1442
1629
|
/**
|
|
1443
1630
|
* Fetch a project by its URL slug.
|
|
1444
1631
|
*
|
|
@@ -1452,7 +1639,7 @@ declare class ProjectsResource {
|
|
|
1452
1639
|
* const project = await forja.projects.getBySlug('forja-cms');
|
|
1453
1640
|
* ```
|
|
1454
1641
|
*/
|
|
1455
|
-
getBySlug(slug: string): Promise<ProjectResponse | null>;
|
|
1642
|
+
getBySlug(slug: string, params?: ProjectDetailParams): Promise<ProjectResponse | null>;
|
|
1456
1643
|
}
|
|
1457
1644
|
//#endregion
|
|
1458
1645
|
//#region src/resources/redirects.d.ts
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class extends Error{constructor(e,t){super(e),this.code=t,this.name=`ForjaError`}},t=class extends e{constructor(e=`Invalid or missing API key`){super(e,`AUTH_ERROR`),this.name=`ForjaAuthError`}},n=class extends e{constructor(e=`Insufficient permissions`){super(e,`PERMISSION_ERROR`),this.name=`ForjaPermissionError`}},r=class extends e{constructor(e=`Resource not found`){super(e,`NOT_FOUND`),this.name=`ForjaNotFoundError`}},i=class extends e{constructor(e=`Rate limit exceeded`,t){super(e,`RATE_LIMIT`),this.retryAfter=t,this.name=`ForjaRateLimitError`}},a=class extends e{constructor(e=`Validation error`,t){super(e,`VALIDATION_ERROR`),this.details=t,this.name=`ForjaValidationError`}},o=class extends e{constructor(e=`Internal server error`,t=500){super(e,`SERVER_ERROR`),this.status=t,this.name=`ForjaServerError`}},s=class extends e{constructor(e=`Network error`,t){super(e,`NETWORK_ERROR`),this.cause=t,this.name=`ForjaNetworkError`}};function c(e,t,n){let r=e.replace(/\/+$/,``),i=t.startsWith(`/`)?t:`/${t}`,a=new URL(`${r}${i}`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&a.searchParams.set(e,t);return a.toString()}function l(e){let t={};for(let[n,r]of Object.entries(e))r!=null&&(t[u(n)]=String(r));return t}function u(e){return e.replace(/[A-Z]/g,e=>`_${e.toLowerCase()}`)}async function d(e){let s;try{let t=await e.json();s=t.detail||t.message||t.title||e.statusText}catch{s=e.statusText}switch(e.status){case 401:throw new t(s);case 403:throw new n(s);case 404:throw new r(s);case 422:throw new a(s);case 429:{let t=e.headers.get(`retry-after`);throw new i(s,t?parseInt(t,10):void 0)}default:throw e.status,new o(s,e.status)}}function f(e){let t=e.fetch??globalThis.fetch,n=e.baseUrl.replace(/\/+$/,``),r={"X-API-Key":e.apiKey,"Content-Type":`application/json`};e.siteDomain&&(r[`X-Site-Domain`]=e.siteDomain);async function i(e,i,a,o){let l=c(n,i,a),u;try{u=await t(l,{method:e,headers:r,body:o===void 0?void 0:JSON.stringify(o)})}catch(e){throw new s(`Failed to connect to the Forja API`,e instanceof Error?e:void 0)}return u.ok?u:d(u)}return{get:(e,t)=>i(`GET`,e,t).then(e=>e.json()),getText:(e,t)=>i(`GET`,e,t).then(e=>e.text()),post:(e,t)=>i(`POST`,e,void 0,t).then(e=>e.json()),delete:e=>i(`DELETE`,e).then(()=>void 0)}}function p(e,t,n){return{data:e,meta:t,async fetchNext(){if(t.page>=t.total_pages)return null;let e=await n(t.page+1);return p(e.data,e.meta,n)},async fetchAll(){let r=[...e],i=t.page;for(;i<t.total_pages;){i++;let e=await n(i);r.push(...e.data)}return r},async*[Symbol.asyncIterator](){yield{data:e,meta:t};let r=t.page;for(;r<t.total_pages;)r++,yield await n(r)}}}var m=class{constructor(e,t){this.http=e,this.siteId=t}async trackPageview(e){return this.http.post(`/sites/${this.siteId}/analytics/pageview`,e)}async getReport(e){let t=e?l({days:e.days,top_n:e.topN,start_date:e.startDate,end_date:e.endDate}):void 0;return this.http.get(`/sites/${this.siteId}/analytics/report`,t)}async getPageAnalytics(e){let t=l({path:e.path,days:e.days,start_date:e.startDate,end_date:e.endDate});return this.http.get(`/sites/${this.siteId}/analytics/report/page`,t)}},h=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=e?.localeId?{locale_id:e.localeId}:{},r=async e=>this.http.get(`/sites/${this.siteId}/blogs/published`,{...t,...n,page:String(e)}),i=await r(e?.page??1);return p(i.data,i.meta,r)}async listByCategory(e,t){let n=t?l(t):void 0,r=t?.localeId?{locale_id:t.localeId}:{},i=async t=>this.http.get(`/sites/${this.siteId}/blogs/published/category/${encodeURIComponent(e)}`,{...n,...r,page:String(t)}),a=await i(t?.page??1);return p(a.data,a.meta,i)}async listFeatured(e){return this.http.get(`/sites/${this.siteId}/blogs/featured`,e?.limit===void 0?void 0:{limit:String(e.limit)})}async listSimilar(e,t){return this.http.get(`/sites/${this.siteId}/blogs/${encodeURIComponent(e)}/similar`,t?.limit===void 0?void 0:{limit:String(t.limit)})}async getBySlug(e,t){try{let n=`/blogs/${(await this.http.get(`/sites/${this.siteId}/blogs/by-slug/${encodeURIComponent(e)}`)).id}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async get(e,t){try{let n=`/blogs/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async rss(){return this.http.getText(`/sites/${this.siteId}/feed.rss`)}},g=class{constructor(e,t){this.http=e,this.siteId=t}async listSkills(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/skills`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getSkill(e,t){try{let n=`/skills/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getSkillBySlug(e,t){try{let n=`/skills/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async listEntries(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/cv`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getEntry(e,t){try{let n=`/cv/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}},_=class{constructor(e){this.http=e}async getForm(e,t){let n=t?.locale?{locale:t.locale}:void 0;return this.http.get(`/public/forms/${encodeURIComponent(e)}`,n)}async submitForm(e,t,n={}){return this.http.post(`/public/forms/${encodeURIComponent(e)}/submit`,{data:t,consent_given:n.consentGiven??!1,bot_protection_token:n.botProtectionToken})}async lookupSubmission(e){return this.http.post(`/public/submissions/lookup`,{reference_code:e})}async getSubmission(e){return this.http.get(`/public/submissions/${encodeURIComponent(e)}`)}async deleteSubmission(e){return this.http.delete(`/public/submissions/${encodeURIComponent(e)}`)}};const v=/^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;function y(e,t){let n={};for(let r of e.fields){let e=t[r.label],i=b(r,e);i&&(n[r.label]=i)}return n}function b(e,t){let n=t,r=n==null||typeof n==`string`&&n===``||Array.isArray(n)&&n.length===0;if((e.is_required||e.validation.required)&&r)return`${e.label} is required`;if(r)return null;switch(e.field_type){case`text`:case`textarea`:case`custom`:if(typeof n!=`string`)return`Must be a string`;if(e.validation.min_length!==void 0&&n.length<e.validation.min_length)return`Must be at least ${e.validation.min_length} characters`;if(e.validation.max_length!==void 0&&n.length>e.validation.max_length)return`Must be at most ${e.validation.max_length} characters`;if(e.validation.pattern)try{if(!new RegExp(e.validation.pattern).test(n))return`Value does not match the required pattern`}catch{return`Field has an invalid validation pattern`}return null;case`email`:return typeof n==`string`?v.test(n)?null:`Invalid email format`:`Must be a string`;case`number`:{let t=typeof n==`number`?n:Number(n);return Number.isNaN(t)?`Must be a number`:e.validation.min!==void 0&&t<e.validation.min?`Must be at least ${e.validation.min}`:e.validation.max!==void 0&&t>e.validation.max?`Must be at most ${e.validation.max}`:null}case`date`:return typeof n!=`string`||Number.isNaN(Date.parse(n))&&!/^\d{4}-\d{2}-\d{2}$/.test(n)?`Invalid date format`:null;case`select`:case`radio`:case`checkbox`:return null}}var x=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/legal`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e,t){try{let n=`/sites/${this.siteId}/legal/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getCookieConsent(){try{return await this.http.get(`/sites/${this.siteId}/legal/cookie-consent`)}catch(e){if(e instanceof r)return null;throw e}}async getGroups(e){return this.http.get(`/legal/${encodeURIComponent(e)}/groups`)}async getGroupItems(e){return this.http.get(`/legal/groups/${encodeURIComponent(e)}/items`)}async getDetail(e,t){try{let n=`/legal/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async listVersions(e){return this.http.get(`/legal/${encodeURIComponent(e)}/versions`)}},S=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/media`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/media/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},C=class{constructor(e,t){this.http=e,this.siteId=t}async listMenus(){return this.http.get(`/sites/${this.siteId}/menus`)}async getMenu(e){try{return await this.http.get(`/menus/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getMenuBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/menus/slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTree(e,t){return this.http.get(`/menus/${encodeURIComponent(e)}/tree`,t?.locale?{locale:t.locale}:void 0)}async listItems(e){return this.http.get(`/menus/${encodeURIComponent(e)}/items`)}async getItem(e){try{return await this.http.get(`/navigation/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},w=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/pages`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getByRoute(e){let t=e.startsWith(`/`)?e.slice(1):e;try{return await this.http.get(`/sites/${this.siteId}/pages/by-route/${encodeURIComponent(t)}`)}catch(e){if(e instanceof r)return null;throw e}}async getDetail(e,t){try{let n=`/pages/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getSections(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections`)}async getSectionLocalizations(e){return this.http.get(`/pages/sections/${encodeURIComponent(e)}/localizations`)}async getPageSectionLocalizations(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections/localizations`)}},T=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/projects/public`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e,t){try{let n=`/projects/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e,t){try{let n=`/sites/${this.siteId}/projects/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}},E=class{constructor(e,t){this.http=e,this.siteId=t}async lookup(e){try{return await this.http.get(`/sites/${this.siteId}/redirects/lookup`,{path:e})}catch(e){if(e instanceof r)return null;throw e}}},D=class{constructor(e,t){this.http=e,this.siteId=t}async get(){return this.http.get(`/sites/${this.siteId}`)}async listLocales(){return this.http.get(`/sites/${this.siteId}/locales`)}async getCodeInjection(){let e=await this.http.get(`/sites/${this.siteId}/settings`);return{code_injection_head:e.code_injection_head??``,code_injection_footer:e.code_injection_footer??``}}},O=class{constructor(e,t){this.http=e,this.siteId=t}async list(){return this.http.get(`/sites/${this.siteId}/social`)}},k=class{constructor(e,t){this.http=e,this.siteId=t}async listTags(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/tags`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async listCategories(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/categories`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getCategoriesWithBlogCounts(){return this.http.get(`/sites/${this.siteId}/categories/blog-counts`)}async getContentTags(e){return this.http.get(`/content/${encodeURIComponent(e)}/tags`)}async getContentCategories(e){return this.http.get(`/content/${encodeURIComponent(e)}/categories`)}async getTag(e){try{return await this.http.get(`/tags/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTagBySlug(e){try{return await this.http.get(`/tags/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategory(e){try{return await this.http.get(`/categories/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategoryChildren(e){return this.http.get(`/categories/${encodeURIComponent(e)}/children`)}},A=class{constructor(e){let t=f(e);this.blogs=new h(t,e.siteId),this.pages=new w(t,e.siteId),this.navigation=new C(t,e.siteId),this.taxonomy=new k(t,e.siteId),this.analytics=new m(t,e.siteId),this.cv=new g(t,e.siteId),this.legal=new x(t,e.siteId),this.projects=new T(t,e.siteId),this.redirects=new E(t,e.siteId),this.site=new D(t,e.siteId),this.media=new S(t,e.siteId),this.social=new O(t,e.siteId),this.forms=new _(t)}};export{s as a,i as c,e as i,o as l,y as n,r as o,t as r,n as s,A as t,a as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class extends Error{constructor(e,t){super(e),this.code=t,this.name=`ForjaError`}},t=class extends e{constructor(e=`Invalid or missing API key`){super(e,`AUTH_ERROR`),this.name=`ForjaAuthError`}},n=class extends e{constructor(e=`Insufficient permissions`){super(e,`PERMISSION_ERROR`),this.name=`ForjaPermissionError`}},r=class extends e{constructor(e=`Resource not found`){super(e,`NOT_FOUND`),this.name=`ForjaNotFoundError`}},i=class extends e{constructor(e=`Rate limit exceeded`,t){super(e,`RATE_LIMIT`),this.retryAfter=t,this.name=`ForjaRateLimitError`}},a=class extends e{constructor(e=`Validation error`,t){super(e,`VALIDATION_ERROR`),this.details=t,this.name=`ForjaValidationError`}},o=class extends e{constructor(e=`Internal server error`,t=500){super(e,`SERVER_ERROR`),this.status=t,this.name=`ForjaServerError`}},s=class extends e{constructor(e=`Network error`,t){super(e,`NETWORK_ERROR`),this.cause=t,this.name=`ForjaNetworkError`}};function c(e,t,n){let r=e.replace(/\/+$/,``),i=t.startsWith(`/`)?t:`/${t}`,a=new URL(`${r}${i}`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&a.searchParams.set(e,t);return a.toString()}function l(e){let t={};for(let[n,r]of Object.entries(e))r!=null&&(t[u(n)]=String(r));return t}function u(e){return e.replace(/[A-Z]/g,e=>`_${e.toLowerCase()}`)}async function d(e){let s;try{let t=await e.json();s=t.detail||t.message||t.title||e.statusText}catch{s=e.statusText}switch(e.status){case 401:throw new t(s);case 403:throw new n(s);case 404:throw new r(s);case 422:throw new a(s);case 429:{let t=e.headers.get(`retry-after`);throw new i(s,t?parseInt(t,10):void 0)}default:throw e.status,new o(s,e.status)}}function f(e){let t=e.fetch??globalThis.fetch,n=e.baseUrl.replace(/\/+$/,``),r={"X-API-Key":e.apiKey,"Content-Type":`application/json`};e.siteDomain&&(r[`X-Site-Domain`]=e.siteDomain);async function i(e,i,a,o){let l=c(n,i,a),u;try{u=await t(l,{method:e,headers:r,body:o===void 0?void 0:JSON.stringify(o)})}catch(e){throw new s(`Failed to connect to the Forja API`,e instanceof Error?e:void 0)}return u.ok?u:d(u)}return{get:(e,t)=>i(`GET`,e,t).then(e=>e.json()),getText:(e,t)=>i(`GET`,e,t).then(e=>e.text()),post:(e,t)=>i(`POST`,e,void 0,t).then(e=>e.json()),delete:e=>i(`DELETE`,e).then(()=>void 0)}}function p(e,t,n){return{data:e,meta:t,async fetchNext(){if(t.page>=t.total_pages)return null;let e=await n(t.page+1);return p(e.data,e.meta,n)},async fetchAll(){let r=[...e],i=t.page;for(;i<t.total_pages;){i++;let e=await n(i);r.push(...e.data)}return r},async*[Symbol.asyncIterator](){yield{data:e,meta:t};let r=t.page;for(;r<t.total_pages;)r++,yield await n(r)}}}var m=class{constructor(e,t){this.http=e,this.siteId=t}async trackPageview(e){return this.http.post(`/sites/${this.siteId}/analytics/pageview`,e)}async getReport(e){let t=e?l({days:e.days,top_n:e.topN,start_date:e.startDate,end_date:e.endDate}):void 0;return this.http.get(`/sites/${this.siteId}/analytics/report`,t)}async getPageAnalytics(e){let t=l({path:e.path,days:e.days,start_date:e.startDate,end_date:e.endDate});return this.http.get(`/sites/${this.siteId}/analytics/report/page`,t)}},h=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=e?.localeId?{locale_id:e.localeId}:{},r=async e=>this.http.get(`/sites/${this.siteId}/blogs/published`,{...t,...n,page:String(e)}),i=await r(e?.page??1);return p(i.data,i.meta,r)}async listByCategory(e,t){let n=t?l(t):void 0,r=t?.localeId?{locale_id:t.localeId}:{},i=async t=>this.http.get(`/sites/${this.siteId}/blogs/published/category/${encodeURIComponent(e)}`,{...n,...r,page:String(t)}),a=await i(t?.page??1);return p(a.data,a.meta,i)}async listFeatured(e){return this.http.get(`/sites/${this.siteId}/blogs/featured`,e?.limit===void 0?void 0:{limit:String(e.limit)})}async listSimilar(e,t){return this.http.get(`/sites/${this.siteId}/blogs/${encodeURIComponent(e)}/similar`,t?.limit===void 0?void 0:{limit:String(t.limit)})}async getBySlug(e,t){try{let n=`/blogs/${(await this.http.get(`/sites/${this.siteId}/blogs/by-slug/${encodeURIComponent(e)}`)).id}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async get(e,t){try{let n=`/blogs/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async rss(){return this.http.getText(`/sites/${this.siteId}/feed.rss`)}},g=class{constructor(e,t){this.http=e,this.siteId=t}async listSkills(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/skills`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getSkill(e,t){try{let n=`/skills/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getSkillBySlug(e,t){try{let n=`/skills/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async listEntries(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/cv`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getEntry(e,t){try{let n=`/cv/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}},_=class{constructor(e){this.http=e}async getForm(e,t){let n=t?.locale?{locale:t.locale}:void 0;return this.http.get(`/public/forms/${encodeURIComponent(e)}`,n)}async submitForm(e,t,n={}){return this.http.post(`/public/forms/${encodeURIComponent(e)}/submit`,{data:t,consent_given:n.consentGiven??!1,bot_protection_token:n.botProtectionToken})}async lookupSubmission(e){return this.http.post(`/public/submissions/lookup`,{reference_code:e})}async getSubmission(e){return this.http.get(`/public/submissions/${encodeURIComponent(e)}`)}async deleteSubmission(e){return this.http.delete(`/public/submissions/${encodeURIComponent(e)}`)}};const v=/^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;function y(e,t){let n={};for(let r of e.fields){let e=t[r.label],i=b(r,e);i&&(n[r.label]=i)}return n}function b(e,t){let n=t,r=n==null||typeof n==`string`&&n===``||Array.isArray(n)&&n.length===0;if((e.is_required||e.validation.required)&&r)return`${e.label} is required`;if(r)return null;switch(e.field_type){case`text`:case`textarea`:case`custom`:if(typeof n!=`string`)return`Must be a string`;if(e.validation.min_length!==void 0&&n.length<e.validation.min_length)return`Must be at least ${e.validation.min_length} characters`;if(e.validation.max_length!==void 0&&n.length>e.validation.max_length)return`Must be at most ${e.validation.max_length} characters`;if(e.validation.pattern)try{if(!new RegExp(e.validation.pattern).test(n))return`Value does not match the required pattern`}catch{return`Field has an invalid validation pattern`}return null;case`email`:return typeof n==`string`?v.test(n)?null:`Invalid email format`:`Must be a string`;case`number`:{let t=typeof n==`number`?n:Number(n);return Number.isNaN(t)?`Must be a number`:e.validation.min!==void 0&&t<e.validation.min?`Must be at least ${e.validation.min}`:e.validation.max!==void 0&&t>e.validation.max?`Must be at most ${e.validation.max}`:null}case`date`:return typeof n!=`string`||Number.isNaN(Date.parse(n))&&!/^\d{4}-\d{2}-\d{2}$/.test(n)?`Invalid date format`:null;case`select`:case`radio`:case`checkbox`:return null}}var x=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/legal`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e,t){try{let n=`/sites/${this.siteId}/legal/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getCookieConsent(){try{return await this.http.get(`/sites/${this.siteId}/legal/cookie-consent`)}catch(e){if(e instanceof r)return null;throw e}}async getGroups(e){return this.http.get(`/legal/${encodeURIComponent(e)}/groups`)}async getGroupItems(e){return this.http.get(`/legal/groups/${encodeURIComponent(e)}/items`)}async getDetail(e,t){try{let n=`/legal/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async listVersions(e){return this.http.get(`/legal/${encodeURIComponent(e)}/versions`)}},S=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/media`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/media/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},C=class{constructor(e,t){this.http=e,this.siteId=t}async listMenus(){return this.http.get(`/sites/${this.siteId}/menus`)}async getMenu(e){try{return await this.http.get(`/menus/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getMenuBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/menus/slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTree(e,t){return this.http.get(`/menus/${encodeURIComponent(e)}/tree`,t?.locale?{locale:t.locale}:void 0)}async listItems(e){return this.http.get(`/menus/${encodeURIComponent(e)}/items`)}async getItem(e){try{return await this.http.get(`/navigation/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},w=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/pages`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getByRoute(e){let t=e.startsWith(`/`)?e.slice(1):e;try{return await this.http.get(`/sites/${this.siteId}/pages/by-route/${encodeURIComponent(t)}`)}catch(e){if(e instanceof r)return null;throw e}}async getDetail(e,t){try{let n=`/pages/${encodeURIComponent(e)}/detail`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getSections(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections`)}async getSectionLocalizations(e){return this.http.get(`/pages/sections/${encodeURIComponent(e)}/localizations`)}async getPageSectionLocalizations(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections/localizations`)}},T=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/projects/public`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e,t){try{let n=`/projects/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e,t){try{let n=`/sites/${this.siteId}/projects/by-slug/${encodeURIComponent(e)}`;return t?.locale?await this.http.get(n,{locale:t.locale}):await this.http.get(n)}catch(e){if(e instanceof r)return null;throw e}}},E=class{constructor(e,t){this.http=e,this.siteId=t}async lookup(e){try{return await this.http.get(`/sites/${this.siteId}/redirects/lookup`,{path:e})}catch(e){if(e instanceof r)return null;throw e}}},D=class{constructor(e,t){this.http=e,this.siteId=t}async get(){return this.http.get(`/sites/${this.siteId}`)}async listLocales(){return this.http.get(`/sites/${this.siteId}/locales`)}async getCodeInjection(){let e=await this.http.get(`/sites/${this.siteId}/settings`);return{code_injection_head:e.code_injection_head??``,code_injection_footer:e.code_injection_footer??``}}},O=class{constructor(e,t){this.http=e,this.siteId=t}async list(){return this.http.get(`/sites/${this.siteId}/social`)}},k=class{constructor(e,t){this.http=e,this.siteId=t}async listTags(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/tags`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async listCategories(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/categories`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getCategoriesWithBlogCounts(){return this.http.get(`/sites/${this.siteId}/categories/blog-counts`)}async getContentTags(e){return this.http.get(`/content/${encodeURIComponent(e)}/tags`)}async getContentCategories(e){return this.http.get(`/content/${encodeURIComponent(e)}/categories`)}async getTag(e){try{return await this.http.get(`/tags/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTagBySlug(e){try{return await this.http.get(`/tags/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategory(e){try{return await this.http.get(`/categories/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategoryChildren(e){return this.http.get(`/categories/${encodeURIComponent(e)}/children`)}},A=class{constructor(e){let t=f(e);this.blogs=new h(t,e.siteId),this.pages=new w(t,e.siteId),this.navigation=new C(t,e.siteId),this.taxonomy=new k(t,e.siteId),this.analytics=new m(t,e.siteId),this.cv=new g(t,e.siteId),this.legal=new x(t,e.siteId),this.projects=new T(t,e.siteId),this.redirects=new E(t,e.siteId),this.site=new D(t,e.siteId),this.media=new S(t,e.siteId),this.social=new O(t,e.siteId),this.forms=new _(t)}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return a}});
|
|
@@ -120,6 +120,18 @@ interface BlogDetailResponse extends BlogResponse {
|
|
|
120
120
|
documents: BlogDocumentResponse[];
|
|
121
121
|
og_image_url: string | null;
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Options for blog detail lookups (`get`, `getBySlug`). The list shape
|
|
125
|
+
* does not yet carry `localizations[]` so the resolver only applies to
|
|
126
|
+
* the detail endpoint — list canonicalization is tracked separately.
|
|
127
|
+
*/
|
|
128
|
+
interface BlogDetailParams {
|
|
129
|
+
/**
|
|
130
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
131
|
+
* collapses to one resolved entry. See ADR 0002.
|
|
132
|
+
*/
|
|
133
|
+
locale?: string;
|
|
134
|
+
}
|
|
123
135
|
interface PageListItem {
|
|
124
136
|
id: string;
|
|
125
137
|
route: string;
|
|
@@ -281,6 +293,12 @@ interface AnalyticsPageParams {
|
|
|
281
293
|
startDate?: string;
|
|
282
294
|
endDate?: string;
|
|
283
295
|
}
|
|
296
|
+
interface SkillLocalizationResponse {
|
|
297
|
+
id: string;
|
|
298
|
+
locale_id: string;
|
|
299
|
+
name: string;
|
|
300
|
+
description: string | null;
|
|
301
|
+
}
|
|
284
302
|
interface SkillResponse {
|
|
285
303
|
id: string;
|
|
286
304
|
name: string;
|
|
@@ -288,6 +306,19 @@ interface SkillResponse {
|
|
|
288
306
|
category: SkillCategory | null;
|
|
289
307
|
icon: string | null;
|
|
290
308
|
proficiency_level: number | null;
|
|
309
|
+
/**
|
|
310
|
+
* Per-locale display names. Empty array when no localizations exist
|
|
311
|
+
* (never null / missing). Clients pick the matching locale and fall
|
|
312
|
+
* back per their own rules.
|
|
313
|
+
*/
|
|
314
|
+
localizations: SkillLocalizationResponse[];
|
|
315
|
+
}
|
|
316
|
+
interface CvEntryLocalizationResponse {
|
|
317
|
+
id: string;
|
|
318
|
+
locale_id: string;
|
|
319
|
+
position: string;
|
|
320
|
+
description: string | null;
|
|
321
|
+
achievements: unknown | null;
|
|
291
322
|
}
|
|
292
323
|
interface CvEntryResponse {
|
|
293
324
|
id: string;
|
|
@@ -302,9 +333,52 @@ interface CvEntryResponse {
|
|
|
302
333
|
display_order: number;
|
|
303
334
|
created_at: string;
|
|
304
335
|
updated_at: string;
|
|
336
|
+
/**
|
|
337
|
+
* Per-locale position + description. Empty array when no localizations
|
|
338
|
+
* exist (never null / missing).
|
|
339
|
+
*/
|
|
340
|
+
localizations: CvEntryLocalizationResponse[];
|
|
341
|
+
/**
|
|
342
|
+
* Skill IDs linked to this CV entry. Empty array when no skills are
|
|
343
|
+
* linked (never null / missing).
|
|
344
|
+
*/
|
|
345
|
+
skill_ids: string[];
|
|
346
|
+
}
|
|
347
|
+
/** Pagination, search, and locale-resolver params for skill listings. */
|
|
348
|
+
interface SkillListParams extends SearchablePaginationParams {
|
|
349
|
+
/**
|
|
350
|
+
* Optional locale code (e.g. `"en"`). When set, each skill's
|
|
351
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
352
|
+
* fallback chain. See ADR 0002.
|
|
353
|
+
*/
|
|
354
|
+
locale?: string;
|
|
355
|
+
}
|
|
356
|
+
/** Options for skill detail lookups (`getSkill`, `getSkillBySlug`). */
|
|
357
|
+
interface SkillDetailParams {
|
|
358
|
+
/**
|
|
359
|
+
* Optional locale code. When set, `localizations` collapses to one
|
|
360
|
+
* resolved entry. See ADR 0002.
|
|
361
|
+
*/
|
|
362
|
+
locale?: string;
|
|
305
363
|
}
|
|
306
364
|
interface CvEntryParams extends SearchablePaginationParams {
|
|
307
365
|
entryType?: CvEntryType;
|
|
366
|
+
/**
|
|
367
|
+
* Optional locale code (e.g. `"en"`, `"de-AT"`). When set, each entry's
|
|
368
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
369
|
+
* fallback chain. Omit to receive every localization.
|
|
370
|
+
*
|
|
371
|
+
* See ADR 0002 (`docs/adr/0002-locale-resolver.md`).
|
|
372
|
+
*/
|
|
373
|
+
locale?: string;
|
|
374
|
+
}
|
|
375
|
+
/** Options for CV-entry detail lookups (`getEntry`). */
|
|
376
|
+
interface CvEntryDetailParams {
|
|
377
|
+
/**
|
|
378
|
+
* Optional locale code. When set, `localizations` collapses to one
|
|
379
|
+
* resolved entry. See ADR 0002.
|
|
380
|
+
*/
|
|
381
|
+
locale?: string;
|
|
308
382
|
}
|
|
309
383
|
interface LegalDocumentResponse {
|
|
310
384
|
id: string;
|
|
@@ -327,6 +401,19 @@ interface LegalDocumentDetailResponse {
|
|
|
327
401
|
created_at: string;
|
|
328
402
|
updated_at: string;
|
|
329
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Options for legal-document detail lookups (`getBySlug`, `getDetail`).
|
|
406
|
+
* The list shape (`LegalDocumentResponse`) does not yet carry
|
|
407
|
+
* `localizations[]` — tracked separately.
|
|
408
|
+
*/
|
|
409
|
+
interface LegalDetailParams {
|
|
410
|
+
/**
|
|
411
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
412
|
+
* (and `doc_localizations[]` on the full-detail endpoint) collapses
|
|
413
|
+
* to one resolved entry. See ADR 0002.
|
|
414
|
+
*/
|
|
415
|
+
locale?: string;
|
|
416
|
+
}
|
|
330
417
|
interface LegalGroupResponse {
|
|
331
418
|
id: string;
|
|
332
419
|
cookie_name: string;
|
|
@@ -410,7 +497,16 @@ interface SocialLinkResponse {
|
|
|
410
497
|
}
|
|
411
498
|
/** Link type for project resources (repository, demo, docs, etc.). */
|
|
412
499
|
type ProjectLinkType = 'repository' | 'demo' | 'documentation' | 'website' | 'other';
|
|
413
|
-
/**
|
|
500
|
+
/** Localized content for a project. */
|
|
501
|
+
interface ProjectLocalizationResponse {
|
|
502
|
+
id: string;
|
|
503
|
+
locale_id: string;
|
|
504
|
+
title: string;
|
|
505
|
+
short_description: string | null;
|
|
506
|
+
description: string | null;
|
|
507
|
+
}
|
|
508
|
+
/** Project summary for list views. Always carries `localizations` — empty
|
|
509
|
+
* array when the project has none, never `null` or missing. */
|
|
414
510
|
interface ProjectResponse {
|
|
415
511
|
id: string;
|
|
416
512
|
slug: string;
|
|
@@ -423,14 +519,9 @@ interface ProjectResponse {
|
|
|
423
519
|
published_at: string | null;
|
|
424
520
|
created_at: string;
|
|
425
521
|
updated_at: string;
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
id: string;
|
|
430
|
-
locale_id: string;
|
|
431
|
-
title: string;
|
|
432
|
-
short_description: string | null;
|
|
433
|
-
description: string | null;
|
|
522
|
+
/** Skill IDs linked to the project. Always present — empty array when none. */
|
|
523
|
+
skill_ids: string[];
|
|
524
|
+
localizations: ProjectLocalizationResponse[];
|
|
434
525
|
}
|
|
435
526
|
/** External link attached to a project. */
|
|
436
527
|
interface ProjectLinkResponse {
|
|
@@ -447,12 +538,11 @@ interface ProjectMediaResponse {
|
|
|
447
538
|
display_order: number;
|
|
448
539
|
is_cover: boolean;
|
|
449
540
|
}
|
|
450
|
-
/** Full project detail
|
|
541
|
+
/** Full project detail. Inherits `skill_ids` and `localizations` from
|
|
542
|
+
* {@link ProjectResponse}; adds links, media, and relation id sets. */
|
|
451
543
|
interface ProjectDetailResponse extends ProjectResponse {
|
|
452
|
-
localizations: ProjectLocalizationResponse[];
|
|
453
544
|
links: ProjectLinkResponse[];
|
|
454
545
|
media: ProjectMediaResponse[];
|
|
455
|
-
skill_ids: string[];
|
|
456
546
|
cv_entry_ids: string[];
|
|
457
547
|
}
|
|
458
548
|
/** Pagination and filter params for project listings. */
|
|
@@ -463,33 +553,79 @@ interface ProjectListParams extends PaginationParams {
|
|
|
463
553
|
sortDir?: 'asc' | 'desc';
|
|
464
554
|
/** Filter to featured projects only. */
|
|
465
555
|
isFeatured?: boolean;
|
|
556
|
+
/**
|
|
557
|
+
* Optional locale code (e.g. `"en"`, `"de-AT"`). When set, each project's
|
|
558
|
+
* `localizations` array collapses to one entry resolved by the server's
|
|
559
|
+
* fallback chain (requested → site default → first available). Omit to
|
|
560
|
+
* receive every localization, which is the existing default.
|
|
561
|
+
*
|
|
562
|
+
* See ADR 0002 (`docs/adr/0002-locale-resolver.md`).
|
|
563
|
+
*/
|
|
564
|
+
locale?: string;
|
|
466
565
|
}
|
|
566
|
+
/** Options for project detail lookups (`get`, `getBySlug`). */
|
|
567
|
+
interface ProjectDetailParams {
|
|
568
|
+
/**
|
|
569
|
+
* Optional locale code. When set, `localizations` collapses to one entry
|
|
570
|
+
* resolved by the server's fallback chain. See ADR 0002.
|
|
571
|
+
*/
|
|
572
|
+
locale?: string;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* The set of HTTP status codes a Forja redirect may use.
|
|
576
|
+
*
|
|
577
|
+
* Pinned by issue #743. The same domain is enforced server-side by the
|
|
578
|
+
* `validate_redirect_status_code` DTO validator and the
|
|
579
|
+
* `chk_redirect_status_code` DB CHECK constraint, so consumers may rely
|
|
580
|
+
* on this value without runtime coercion.
|
|
581
|
+
*/
|
|
582
|
+
type RedirectStatusCode = 301 | 302 | 307 | 308;
|
|
467
583
|
/** A URL redirect rule. */
|
|
468
584
|
interface RedirectResponse {
|
|
469
585
|
id: string;
|
|
470
586
|
site_id: string;
|
|
471
587
|
source_path: string;
|
|
472
588
|
destination_path: string;
|
|
473
|
-
status_code:
|
|
589
|
+
status_code: RedirectStatusCode;
|
|
474
590
|
is_active: boolean;
|
|
475
591
|
description: string | null;
|
|
476
592
|
created_at: string;
|
|
477
593
|
updated_at: string;
|
|
478
594
|
}
|
|
479
|
-
/**
|
|
595
|
+
/**
|
|
596
|
+
* Result of a redirect path lookup.
|
|
597
|
+
*
|
|
598
|
+
* Returned with HTTP 200 by `GET /sites/{site_id}/redirects/lookup` on
|
|
599
|
+
* match. No-match is signalled by **404** (RFC 7807 ProblemDetails) —
|
|
600
|
+
* never a 200 with a null body, never a `{ redirects: [] }` list.
|
|
601
|
+
*/
|
|
480
602
|
interface RedirectLookupResponse {
|
|
481
603
|
destination_path: string;
|
|
482
|
-
status_code:
|
|
604
|
+
status_code: RedirectStatusCode;
|
|
483
605
|
}
|
|
484
606
|
/** A locale configured for a site. */
|
|
485
607
|
interface SiteLocaleResponse {
|
|
608
|
+
/** Composite-key half #1 — which site this assignment belongs to. */
|
|
609
|
+
site_id: string;
|
|
610
|
+
/** Composite-key half #2 — which locale is attached. */
|
|
486
611
|
locale_id: string;
|
|
612
|
+
/** BCP-47 code, denormalised from `locales.code`. */
|
|
487
613
|
code: string;
|
|
614
|
+
/** English-language label, denormalised from `locales.name`. */
|
|
488
615
|
name: string;
|
|
616
|
+
/** Locale's own name, denormalised from `locales.native_name`. */
|
|
489
617
|
native_name: string | null;
|
|
490
618
|
direction: 'ltr' | 'rtl';
|
|
619
|
+
/** Exactly one row per site has this set to `true`. */
|
|
491
620
|
is_default: boolean;
|
|
621
|
+
/** Configured-but-not-served when `false`. Consumers usually filter to `true`. */
|
|
492
622
|
is_active: boolean;
|
|
623
|
+
/**
|
|
624
|
+
* Path segment selecting this locale. `null` for the default locale
|
|
625
|
+
* (served at the site root without a prefix).
|
|
626
|
+
*/
|
|
627
|
+
url_prefix: string | null;
|
|
628
|
+
created_at: string;
|
|
493
629
|
}
|
|
494
630
|
/** Media item summary for list views (lighter than full MediaResponse). */
|
|
495
631
|
interface MediaListItem {
|
|
@@ -770,7 +906,7 @@ declare class BlogsResource {
|
|
|
770
906
|
* }
|
|
771
907
|
* ```
|
|
772
908
|
*/
|
|
773
|
-
getBySlug(slug: string): Promise<BlogDetailResponse | null>;
|
|
909
|
+
getBySlug(slug: string, params?: BlogDetailParams): Promise<BlogDetailResponse | null>;
|
|
774
910
|
/**
|
|
775
911
|
* Fetch a blog post's full detail by its UUID.
|
|
776
912
|
*
|
|
@@ -784,7 +920,7 @@ declare class BlogsResource {
|
|
|
784
920
|
* const blog = await forja.blogs.get('550e8400-e29b-41d4-a716-446655440000');
|
|
785
921
|
* ```
|
|
786
922
|
*/
|
|
787
|
-
get(idOrSlug: string): Promise<BlogDetailResponse | null>;
|
|
923
|
+
get(idOrSlug: string, params?: BlogDetailParams): Promise<BlogDetailResponse | null>;
|
|
788
924
|
/**
|
|
789
925
|
* Fetch the site's RSS feed as raw XML.
|
|
790
926
|
*
|
|
@@ -822,7 +958,7 @@ declare class CvResource {
|
|
|
822
958
|
* const programming = skills.data.filter(s => s.category === 'Programming');
|
|
823
959
|
* ```
|
|
824
960
|
*/
|
|
825
|
-
listSkills(params?:
|
|
961
|
+
listSkills(params?: SkillListParams): Promise<PaginatedResult<SkillResponse>>;
|
|
826
962
|
/**
|
|
827
963
|
* Fetch a skill by its UUID.
|
|
828
964
|
*
|
|
@@ -831,7 +967,7 @@ declare class CvResource {
|
|
|
831
967
|
* @param id - The skill's UUID.
|
|
832
968
|
* @returns The skill, or `null` if not found.
|
|
833
969
|
*/
|
|
834
|
-
getSkill(id: string): Promise<SkillResponse | null>;
|
|
970
|
+
getSkill(id: string, params?: SkillDetailParams): Promise<SkillResponse | null>;
|
|
835
971
|
/**
|
|
836
972
|
* Fetch a skill by its URL slug.
|
|
837
973
|
*
|
|
@@ -846,7 +982,7 @@ declare class CvResource {
|
|
|
846
982
|
* if (ts) console.log(`${ts.name}: level ${ts.proficiency_level}`);
|
|
847
983
|
* ```
|
|
848
984
|
*/
|
|
849
|
-
getSkillBySlug(slug: string): Promise<SkillResponse | null>;
|
|
985
|
+
getSkillBySlug(slug: string, params?: SkillDetailParams): Promise<SkillResponse | null>;
|
|
850
986
|
/**
|
|
851
987
|
* Fetch a paginated list of CV entries (work, education, certifications, etc.).
|
|
852
988
|
*
|
|
@@ -863,6 +999,25 @@ declare class CvResource {
|
|
|
863
999
|
* ```
|
|
864
1000
|
*/
|
|
865
1001
|
listEntries(params?: CvEntryParams): Promise<PaginatedResult<CvEntryResponse>>;
|
|
1002
|
+
/**
|
|
1003
|
+
* Fetch a CV entry by its UUID.
|
|
1004
|
+
*
|
|
1005
|
+
* **Endpoint:** `GET /cv/{id}`
|
|
1006
|
+
*
|
|
1007
|
+
* @param id - The CV entry's UUID.
|
|
1008
|
+
* @param params - Optional locale resolver per ADR 0002.
|
|
1009
|
+
* @returns The CV entry, or `null` if not found.
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
1012
|
+
* ```ts
|
|
1013
|
+
* // All localizations (default)
|
|
1014
|
+
* const entry = await forja.cv.getEntry('entry-uuid');
|
|
1015
|
+
*
|
|
1016
|
+
* // Single-locale collapse
|
|
1017
|
+
* const enEntry = await forja.cv.getEntry('entry-uuid', { locale: 'en' });
|
|
1018
|
+
* ```
|
|
1019
|
+
*/
|
|
1020
|
+
getEntry(id: string, params?: CvEntryDetailParams): Promise<CvEntryResponse | null>;
|
|
866
1021
|
}
|
|
867
1022
|
//#endregion
|
|
868
1023
|
//#region src/resources/forms.d.ts
|
|
@@ -1029,7 +1184,7 @@ declare class LegalResource {
|
|
|
1029
1184
|
* }
|
|
1030
1185
|
* ```
|
|
1031
1186
|
*/
|
|
1032
|
-
getBySlug(slug: string): Promise<LegalDocumentDetailResponse | null>;
|
|
1187
|
+
getBySlug(slug: string, params?: LegalDetailParams): Promise<LegalDocumentDetailResponse | null>;
|
|
1033
1188
|
/**
|
|
1034
1189
|
* Fetch the cookie consent document with its consent groups and items.
|
|
1035
1190
|
*
|
|
@@ -1093,7 +1248,7 @@ declare class LegalResource {
|
|
|
1093
1248
|
* }
|
|
1094
1249
|
* ```
|
|
1095
1250
|
*/
|
|
1096
|
-
getDetail(id: string): Promise<LegalDocumentFullDetailResponse | null>;
|
|
1251
|
+
getDetail(id: string, params?: LegalDetailParams): Promise<LegalDocumentFullDetailResponse | null>;
|
|
1097
1252
|
/**
|
|
1098
1253
|
* Fetch the version history of a legal document.
|
|
1099
1254
|
*
|
|
@@ -1291,6 +1446,19 @@ interface PageListParams extends SearchablePaginationParams {
|
|
|
1291
1446
|
/** Exclude pages with this status. */
|
|
1292
1447
|
excludeStatus?: string;
|
|
1293
1448
|
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Options for page-detail lookups (`getDetail`). The list shape
|
|
1451
|
+
* (`PageResponse`) does not carry `localizations[]` today — adding it is
|
|
1452
|
+
* tracked as a separate canonicalization gap; until then the resolver
|
|
1453
|
+
* applies only to the detail endpoint.
|
|
1454
|
+
*/
|
|
1455
|
+
interface PageDetailParams {
|
|
1456
|
+
/**
|
|
1457
|
+
* Optional locale code (e.g. `"en"`). When set, `localizations[]`
|
|
1458
|
+
* collapses to one resolved entry. See ADR 0002.
|
|
1459
|
+
*/
|
|
1460
|
+
locale?: string;
|
|
1461
|
+
}
|
|
1294
1462
|
/**
|
|
1295
1463
|
* CMS page operations.
|
|
1296
1464
|
*
|
|
@@ -1337,6 +1505,25 @@ declare class PagesResource {
|
|
|
1337
1505
|
* ```
|
|
1338
1506
|
*/
|
|
1339
1507
|
getByRoute(route: string): Promise<PageDetailResponse | null>;
|
|
1508
|
+
/**
|
|
1509
|
+
* Fetch a page's full detail (content localizations + computed OG image).
|
|
1510
|
+
*
|
|
1511
|
+
* **Endpoint:** `GET /pages/{id}/detail`
|
|
1512
|
+
*
|
|
1513
|
+
* @param id - The page's UUID.
|
|
1514
|
+
* @param params - Optional locale resolver (ADR 0002).
|
|
1515
|
+
* @returns The page detail, or `null` if not found.
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* ```ts
|
|
1519
|
+
* // Every localization (admin/editor use case)
|
|
1520
|
+
* const detail = await forja.pages.getDetail('page-uuid');
|
|
1521
|
+
*
|
|
1522
|
+
* // Server-side rendering — single locale
|
|
1523
|
+
* const en = await forja.pages.getDetail('page-uuid', { locale: 'en' });
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1526
|
+
getDetail(id: string, params?: PageDetailParams): Promise<PageDetailResponse | null>;
|
|
1340
1527
|
/**
|
|
1341
1528
|
* Fetch all sections for a page.
|
|
1342
1529
|
*
|
|
@@ -1438,7 +1625,7 @@ declare class ProjectsResource {
|
|
|
1438
1625
|
* }
|
|
1439
1626
|
* ```
|
|
1440
1627
|
*/
|
|
1441
|
-
get(id: string): Promise<ProjectDetailResponse | null>;
|
|
1628
|
+
get(id: string, params?: ProjectDetailParams): Promise<ProjectDetailResponse | null>;
|
|
1442
1629
|
/**
|
|
1443
1630
|
* Fetch a project by its URL slug.
|
|
1444
1631
|
*
|
|
@@ -1452,7 +1639,7 @@ declare class ProjectsResource {
|
|
|
1452
1639
|
* const project = await forja.projects.getBySlug('forja-cms');
|
|
1453
1640
|
* ```
|
|
1454
1641
|
*/
|
|
1455
|
-
getBySlug(slug: string): Promise<ProjectResponse | null>;
|
|
1642
|
+
getBySlug(slug: string, params?: ProjectDetailParams): Promise<ProjectResponse | null>;
|
|
1456
1643
|
}
|
|
1457
1644
|
//#endregion
|
|
1458
1645
|
//#region src/resources/redirects.d.ts
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./client-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./client-DVY5u6LJ.cjs`);function t(e){return{head:e.code_injection_head,footer:e.code_injection_footer}}exports.ForjaAuthError=e.r,exports.ForjaClient=e.t,exports.ForjaError=e.i,exports.ForjaNetworkError=e.a,exports.ForjaNotFoundError=e.o,exports.ForjaPermissionError=e.s,exports.ForjaRateLimitError=e.c,exports.ForjaServerError=e.l,exports.ForjaValidationError=e.u,exports.renderCodeInjection=t,exports.validateSubmission=e.n;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as NavigationTree, A as CvEntryResponse, At as TranslationStatus, B as LegalGroupResponse, C as BlogResponse, Ct as SkillCategory, D as CodeInjection, Dt as TopContentItem, E as CategoryWithCountResponse, Et as TagResponse, F as LegalDocType, G as LocalizationResponse, H as LegalItemResponse, I as LegalDocumentDetailResponse, J as MediaResponse, K as MediaListItem, L as LegalDocumentFullDetailResponse, M as DocumentLocalizationResponse, N as ForjaClientConfig, O as ContentStatus, Ot as TrackPageviewRequest, P as LegalDocLocalizationResponse, Q as NavigationMenuResponse, R as LegalDocumentResponse, S as BlogListItem, St as SiteResponse, T as CategoryTree, Tt as SocialLinkResponse, U as LegalVersionResponse, V as LegalGroupWithItems, W as LocaleFilterParams, X as NavigationItemLocalizationResponse, Y as MediaVariantResponse, Z as NavigationItemResponse, _ as AnalyticsPageParams, _t as ReferrerItem, a as FormFieldValidation, at as Paginated, b as BlogDetailResponse, bt as SectionType, c as PublicFormDefinition, ct as ProjectDetailResponse, d as SubmitFormOptions, dt as ProjectListParams, et as PageDetailResponse, f as ValidationErrorMap, ft as ProjectLocalizationResponse, g as AnalyticsPageDetailResponse, gt as RedirectResponse, h as PaginatedResult, ht as RedirectLookupResponse, i as FormFieldType, it as PageType, j as CvEntryType, jt as TrendDataPoint, k as CvEntryParams, kt as TrackPageviewResponse, l as SelfServiceLookup, lt as ProjectLinkResponse, m as HttpClient, mt as ProjectResponse, n as FormBotProtection, nt as PageResponse, o as FormSubmitData, ot as PaginationMeta, p as validateSubmission, pt as ProjectMediaResponse, q as MediaListParams, r as FormFieldDefinition, rt as PageSectionResponse, s as FormSubmitResponse, st as PaginationParams, t as ForjaClient, tt as PageListItem, u as SelfServiceSubmission, ut as ProjectLinkType, v as AnalyticsReportParams, vt as SearchablePaginationParams, w as CategoryResponse, wt as SkillResponse, x as BlogDocumentResponse, xt as SiteLocaleResponse, y as AnalyticsReportResponse, yt as SectionLocalizationResponse, z as LegalDocumentWithGroups } from "./client-
|
|
1
|
+
import { $ as NavigationTree, A as CvEntryResponse, At as TranslationStatus, B as LegalGroupResponse, C as BlogResponse, Ct as SkillCategory, D as CodeInjection, Dt as TopContentItem, E as CategoryWithCountResponse, Et as TagResponse, F as LegalDocType, G as LocalizationResponse, H as LegalItemResponse, I as LegalDocumentDetailResponse, J as MediaResponse, K as MediaListItem, L as LegalDocumentFullDetailResponse, M as DocumentLocalizationResponse, N as ForjaClientConfig, O as ContentStatus, Ot as TrackPageviewRequest, P as LegalDocLocalizationResponse, Q as NavigationMenuResponse, R as LegalDocumentResponse, S as BlogListItem, St as SiteResponse, T as CategoryTree, Tt as SocialLinkResponse, U as LegalVersionResponse, V as LegalGroupWithItems, W as LocaleFilterParams, X as NavigationItemLocalizationResponse, Y as MediaVariantResponse, Z as NavigationItemResponse, _ as AnalyticsPageParams, _t as ReferrerItem, a as FormFieldValidation, at as Paginated, b as BlogDetailResponse, bt as SectionType, c as PublicFormDefinition, ct as ProjectDetailResponse, d as SubmitFormOptions, dt as ProjectListParams, et as PageDetailResponse, f as ValidationErrorMap, ft as ProjectLocalizationResponse, g as AnalyticsPageDetailResponse, gt as RedirectResponse, h as PaginatedResult, ht as RedirectLookupResponse, i as FormFieldType, it as PageType, j as CvEntryType, jt as TrendDataPoint, k as CvEntryParams, kt as TrackPageviewResponse, l as SelfServiceLookup, lt as ProjectLinkResponse, m as HttpClient, mt as ProjectResponse, n as FormBotProtection, nt as PageResponse, o as FormSubmitData, ot as PaginationMeta, p as validateSubmission, pt as ProjectMediaResponse, q as MediaListParams, r as FormFieldDefinition, rt as PageSectionResponse, s as FormSubmitResponse, st as PaginationParams, t as ForjaClient, tt as PageListItem, u as SelfServiceSubmission, ut as ProjectLinkType, v as AnalyticsReportParams, vt as SearchablePaginationParams, w as CategoryResponse, wt as SkillResponse, x as BlogDocumentResponse, xt as SiteLocaleResponse, y as AnalyticsReportResponse, yt as SectionLocalizationResponse, z as LegalDocumentWithGroups } from "./client-CUbs1rkJ.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/code-injection.d.ts
|
|
4
4
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as NavigationTree, A as CvEntryResponse, At as TranslationStatus, B as LegalGroupResponse, C as BlogResponse, Ct as SkillCategory, D as CodeInjection, Dt as TopContentItem, E as CategoryWithCountResponse, Et as TagResponse, F as LegalDocType, G as LocalizationResponse, H as LegalItemResponse, I as LegalDocumentDetailResponse, J as MediaResponse, K as MediaListItem, L as LegalDocumentFullDetailResponse, M as DocumentLocalizationResponse, N as ForjaClientConfig, O as ContentStatus, Ot as TrackPageviewRequest, P as LegalDocLocalizationResponse, Q as NavigationMenuResponse, R as LegalDocumentResponse, S as BlogListItem, St as SiteResponse, T as CategoryTree, Tt as SocialLinkResponse, U as LegalVersionResponse, V as LegalGroupWithItems, W as LocaleFilterParams, X as NavigationItemLocalizationResponse, Y as MediaVariantResponse, Z as NavigationItemResponse, _ as AnalyticsPageParams, _t as ReferrerItem, a as FormFieldValidation, at as Paginated, b as BlogDetailResponse, bt as SectionType, c as PublicFormDefinition, ct as ProjectDetailResponse, d as SubmitFormOptions, dt as ProjectListParams, et as PageDetailResponse, f as ValidationErrorMap, ft as ProjectLocalizationResponse, g as AnalyticsPageDetailResponse, gt as RedirectResponse, h as PaginatedResult, ht as RedirectLookupResponse, i as FormFieldType, it as PageType, j as CvEntryType, jt as TrendDataPoint, k as CvEntryParams, kt as TrackPageviewResponse, l as SelfServiceLookup, lt as ProjectLinkResponse, m as HttpClient, mt as ProjectResponse, n as FormBotProtection, nt as PageResponse, o as FormSubmitData, ot as PaginationMeta, p as validateSubmission, pt as ProjectMediaResponse, q as MediaListParams, r as FormFieldDefinition, rt as PageSectionResponse, s as FormSubmitResponse, st as PaginationParams, t as ForjaClient, tt as PageListItem, u as SelfServiceSubmission, ut as ProjectLinkType, v as AnalyticsReportParams, vt as SearchablePaginationParams, w as CategoryResponse, wt as SkillResponse, x as BlogDocumentResponse, xt as SiteLocaleResponse, y as AnalyticsReportResponse, yt as SectionLocalizationResponse, z as LegalDocumentWithGroups } from "./client-
|
|
1
|
+
import { $ as NavigationTree, A as CvEntryResponse, At as TranslationStatus, B as LegalGroupResponse, C as BlogResponse, Ct as SkillCategory, D as CodeInjection, Dt as TopContentItem, E as CategoryWithCountResponse, Et as TagResponse, F as LegalDocType, G as LocalizationResponse, H as LegalItemResponse, I as LegalDocumentDetailResponse, J as MediaResponse, K as MediaListItem, L as LegalDocumentFullDetailResponse, M as DocumentLocalizationResponse, N as ForjaClientConfig, O as ContentStatus, Ot as TrackPageviewRequest, P as LegalDocLocalizationResponse, Q as NavigationMenuResponse, R as LegalDocumentResponse, S as BlogListItem, St as SiteResponse, T as CategoryTree, Tt as SocialLinkResponse, U as LegalVersionResponse, V as LegalGroupWithItems, W as LocaleFilterParams, X as NavigationItemLocalizationResponse, Y as MediaVariantResponse, Z as NavigationItemResponse, _ as AnalyticsPageParams, _t as ReferrerItem, a as FormFieldValidation, at as Paginated, b as BlogDetailResponse, bt as SectionType, c as PublicFormDefinition, ct as ProjectDetailResponse, d as SubmitFormOptions, dt as ProjectListParams, et as PageDetailResponse, f as ValidationErrorMap, ft as ProjectLocalizationResponse, g as AnalyticsPageDetailResponse, gt as RedirectResponse, h as PaginatedResult, ht as RedirectLookupResponse, i as FormFieldType, it as PageType, j as CvEntryType, jt as TrendDataPoint, k as CvEntryParams, kt as TrackPageviewResponse, l as SelfServiceLookup, lt as ProjectLinkResponse, m as HttpClient, mt as ProjectResponse, n as FormBotProtection, nt as PageResponse, o as FormSubmitData, ot as PaginationMeta, p as validateSubmission, pt as ProjectMediaResponse, q as MediaListParams, r as FormFieldDefinition, rt as PageSectionResponse, s as FormSubmitResponse, st as PaginationParams, t as ForjaClient, tt as PageListItem, u as SelfServiceSubmission, ut as ProjectLinkType, v as AnalyticsReportParams, vt as SearchablePaginationParams, w as CategoryResponse, wt as SkillResponse, x as BlogDocumentResponse, xt as SiteLocaleResponse, y as AnalyticsReportResponse, yt as SectionLocalizationResponse, z as LegalDocumentWithGroups } from "./client-HGIKi26O.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/code-injection.d.ts
|
|
4
4
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./client-
|
|
1
|
+
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./client-CWajZ1IX.mjs";function u(e){return{head:e.code_injection_head,footer:e.code_injection_footer}}export{o as ForjaAuthError,c as ForjaClient,n as ForjaError,e as ForjaNetworkError,a as ForjaNotFoundError,s as ForjaPermissionError,t as ForjaRateLimitError,r as ForjaServerError,l as ForjaValidationError,u as renderCodeInjection,i as validateSubmission};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forjacms/client",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "Typed TypeScript SDK for the Forja CMS content API",
|
|
5
5
|
"author": "Dominik Dorfstetter <dominik@dorfstetter.at>",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@angular/core": "^21.2.9",
|
|
67
67
|
"@vitest/coverage-v8": "^4.0.18",
|
|
68
68
|
"rxjs": "^7.8.2",
|
|
69
|
-
"tsdown": "^0.
|
|
69
|
+
"tsdown": "^0.22.0",
|
|
70
70
|
"typescript": "^6.0.2",
|
|
71
71
|
"vitest": "^4.0.18",
|
|
72
72
|
"zone.js": "^0.16.1"
|
package/dist/client-C-2JZF6o.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=class extends Error{constructor(e,t){super(e),this.code=t,this.name=`ForjaError`}},t=class extends e{constructor(e=`Invalid or missing API key`){super(e,`AUTH_ERROR`),this.name=`ForjaAuthError`}},n=class extends e{constructor(e=`Insufficient permissions`){super(e,`PERMISSION_ERROR`),this.name=`ForjaPermissionError`}},r=class extends e{constructor(e=`Resource not found`){super(e,`NOT_FOUND`),this.name=`ForjaNotFoundError`}},i=class extends e{constructor(e=`Rate limit exceeded`,t){super(e,`RATE_LIMIT`),this.retryAfter=t,this.name=`ForjaRateLimitError`}},a=class extends e{constructor(e=`Validation error`,t){super(e,`VALIDATION_ERROR`),this.details=t,this.name=`ForjaValidationError`}},o=class extends e{constructor(e=`Internal server error`,t=500){super(e,`SERVER_ERROR`),this.status=t,this.name=`ForjaServerError`}},s=class extends e{constructor(e=`Network error`,t){super(e,`NETWORK_ERROR`),this.cause=t,this.name=`ForjaNetworkError`}};function c(e,t,n){let r=e.replace(/\/+$/,``),i=t.startsWith(`/`)?t:`/${t}`,a=new URL(`${r}${i}`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&a.searchParams.set(e,t);return a.toString()}function l(e){let t={};for(let[n,r]of Object.entries(e))r!=null&&(t[u(n)]=String(r));return t}function u(e){return e.replace(/[A-Z]/g,e=>`_${e.toLowerCase()}`)}async function d(e){let s;try{let t=await e.json();s=t.detail||t.message||t.title||e.statusText}catch{s=e.statusText}switch(e.status){case 401:throw new t(s);case 403:throw new n(s);case 404:throw new r(s);case 422:throw new a(s);case 429:{let t=e.headers.get(`retry-after`);throw new i(s,t?parseInt(t,10):void 0)}default:throw e.status,new o(s,e.status)}}function f(e){let t=e.fetch??globalThis.fetch,n=e.baseUrl.replace(/\/+$/,``),r={"X-API-Key":e.apiKey,"Content-Type":`application/json`};e.siteDomain&&(r[`X-Site-Domain`]=e.siteDomain);async function i(e,i,a,o){let l=c(n,i,a),u;try{u=await t(l,{method:e,headers:r,body:o===void 0?void 0:JSON.stringify(o)})}catch(e){throw new s(`Failed to connect to the Forja API`,e instanceof Error?e:void 0)}return u.ok?u:d(u)}return{get:(e,t)=>i(`GET`,e,t).then(e=>e.json()),getText:(e,t)=>i(`GET`,e,t).then(e=>e.text()),post:(e,t)=>i(`POST`,e,void 0,t).then(e=>e.json()),delete:e=>i(`DELETE`,e).then(()=>void 0)}}function p(e,t,n){return{data:e,meta:t,async fetchNext(){if(t.page>=t.total_pages)return null;let e=await n(t.page+1);return p(e.data,e.meta,n)},async fetchAll(){let r=[...e],i=t.page;for(;i<t.total_pages;){i++;let e=await n(i);r.push(...e.data)}return r},async*[Symbol.asyncIterator](){yield{data:e,meta:t};let r=t.page;for(;r<t.total_pages;)r++,yield await n(r)}}}var m=class{constructor(e,t){this.http=e,this.siteId=t}async trackPageview(e){return this.http.post(`/sites/${this.siteId}/analytics/pageview`,e)}async getReport(e){let t=e?l({days:e.days,top_n:e.topN,start_date:e.startDate,end_date:e.endDate}):void 0;return this.http.get(`/sites/${this.siteId}/analytics/report`,t)}async getPageAnalytics(e){let t=l({path:e.path,days:e.days,start_date:e.startDate,end_date:e.endDate});return this.http.get(`/sites/${this.siteId}/analytics/report/page`,t)}},h=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=e?.localeId?{locale_id:e.localeId}:{},r=async e=>this.http.get(`/sites/${this.siteId}/blogs/published`,{...t,...n,page:String(e)}),i=await r(e?.page??1);return p(i.data,i.meta,r)}async listByCategory(e,t){let n=t?l(t):void 0,r=t?.localeId?{locale_id:t.localeId}:{},i=async t=>this.http.get(`/sites/${this.siteId}/blogs/published/category/${encodeURIComponent(e)}`,{...n,...r,page:String(t)}),a=await i(t?.page??1);return p(a.data,a.meta,i)}async listFeatured(e){return this.http.get(`/sites/${this.siteId}/blogs/featured`,e?.limit===void 0?void 0:{limit:String(e.limit)})}async listSimilar(e,t){return this.http.get(`/sites/${this.siteId}/blogs/${encodeURIComponent(e)}/similar`,t?.limit===void 0?void 0:{limit:String(t.limit)})}async getBySlug(e){try{let t=await this.http.get(`/sites/${this.siteId}/blogs/by-slug/${encodeURIComponent(e)}`);return await this.http.get(`/blogs/${t.id}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async get(e){try{return await this.http.get(`/blogs/${encodeURIComponent(e)}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async rss(){return this.http.getText(`/sites/${this.siteId}/feed.rss`)}},g=class{constructor(e,t){this.http=e,this.siteId=t}async listSkills(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/skills`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getSkill(e){try{return await this.http.get(`/skills/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getSkillBySlug(e){try{return await this.http.get(`/skills/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async listEntries(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/cv`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}},_=class{constructor(e){this.http=e}async getForm(e,t){let n=t?.locale?{locale:t.locale}:void 0;return this.http.get(`/public/forms/${encodeURIComponent(e)}`,n)}async submitForm(e,t,n={}){return this.http.post(`/public/forms/${encodeURIComponent(e)}/submit`,{data:t,consent_given:n.consentGiven??!1,bot_protection_token:n.botProtectionToken})}async lookupSubmission(e){return this.http.post(`/public/submissions/lookup`,{reference_code:e})}async getSubmission(e){return this.http.get(`/public/submissions/${encodeURIComponent(e)}`)}async deleteSubmission(e){return this.http.delete(`/public/submissions/${encodeURIComponent(e)}`)}};const v=/^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;function y(e,t){let n={};for(let r of e.fields){let e=t[r.label],i=b(r,e);i&&(n[r.label]=i)}return n}function b(e,t){let n=t,r=n==null||typeof n==`string`&&n===``||Array.isArray(n)&&n.length===0;if((e.is_required||e.validation.required)&&r)return`${e.label} is required`;if(r)return null;switch(e.field_type){case`text`:case`textarea`:case`custom`:if(typeof n!=`string`)return`Must be a string`;if(e.validation.min_length!==void 0&&n.length<e.validation.min_length)return`Must be at least ${e.validation.min_length} characters`;if(e.validation.max_length!==void 0&&n.length>e.validation.max_length)return`Must be at most ${e.validation.max_length} characters`;if(e.validation.pattern)try{if(!new RegExp(e.validation.pattern).test(n))return`Value does not match the required pattern`}catch{return`Field has an invalid validation pattern`}return null;case`email`:return typeof n==`string`?v.test(n)?null:`Invalid email format`:`Must be a string`;case`number`:{let t=typeof n==`number`?n:Number(n);return Number.isNaN(t)?`Must be a number`:e.validation.min!==void 0&&t<e.validation.min?`Must be at least ${e.validation.min}`:e.validation.max!==void 0&&t>e.validation.max?`Must be at most ${e.validation.max}`:null}case`date`:return typeof n!=`string`||Number.isNaN(Date.parse(n))&&!/^\d{4}-\d{2}-\d{2}$/.test(n)?`Invalid date format`:null;case`select`:case`radio`:case`checkbox`:return null}}var x=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/legal`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/legal/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCookieConsent(){try{return await this.http.get(`/sites/${this.siteId}/legal/cookie-consent`)}catch(e){if(e instanceof r)return null;throw e}}async getGroups(e){return this.http.get(`/legal/${encodeURIComponent(e)}/groups`)}async getGroupItems(e){return this.http.get(`/legal/groups/${encodeURIComponent(e)}/items`)}async getDetail(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async listVersions(e){return this.http.get(`/legal/${encodeURIComponent(e)}/versions`)}},S=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/media`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/media/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},C=class{constructor(e,t){this.http=e,this.siteId=t}async listMenus(){return this.http.get(`/sites/${this.siteId}/menus`)}async getMenu(e){try{return await this.http.get(`/menus/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getMenuBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/menus/slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTree(e,t){return this.http.get(`/menus/${encodeURIComponent(e)}/tree`,t?.locale?{locale:t.locale}:void 0)}async listItems(e){return this.http.get(`/menus/${encodeURIComponent(e)}/items`)}async getItem(e){try{return await this.http.get(`/navigation/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},w=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/pages`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getByRoute(e){let t=e.startsWith(`/`)?e.slice(1):e;try{return await this.http.get(`/sites/${this.siteId}/pages/by-route/${encodeURIComponent(t)}`)}catch(e){if(e instanceof r)return null;throw e}}async getSections(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections`)}async getSectionLocalizations(e){return this.http.get(`/pages/sections/${encodeURIComponent(e)}/localizations`)}async getPageSectionLocalizations(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections/localizations`)}},T=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/projects/public`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/projects/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/projects/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},E=class{constructor(e,t){this.http=e,this.siteId=t}async lookup(e){try{return await this.http.get(`/sites/${this.siteId}/redirects/lookup`,{path:e})}catch(e){if(e instanceof r)return null;throw e}}},D=class{constructor(e,t){this.http=e,this.siteId=t}async get(){return this.http.get(`/sites/${this.siteId}`)}async listLocales(){return this.http.get(`/sites/${this.siteId}/locales`)}async getCodeInjection(){let e=await this.http.get(`/sites/${this.siteId}/settings`);return{code_injection_head:e.code_injection_head??``,code_injection_footer:e.code_injection_footer??``}}},O=class{constructor(e,t){this.http=e,this.siteId=t}async list(){return this.http.get(`/sites/${this.siteId}/social`)}},k=class{constructor(e,t){this.http=e,this.siteId=t}async listTags(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/tags`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async listCategories(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/categories`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getCategoriesWithBlogCounts(){return this.http.get(`/sites/${this.siteId}/categories/blog-counts`)}async getContentTags(e){return this.http.get(`/content/${encodeURIComponent(e)}/tags`)}async getContentCategories(e){return this.http.get(`/content/${encodeURIComponent(e)}/categories`)}async getTag(e){try{return await this.http.get(`/tags/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTagBySlug(e){try{return await this.http.get(`/tags/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategory(e){try{return await this.http.get(`/categories/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategoryChildren(e){return this.http.get(`/categories/${encodeURIComponent(e)}/children`)}},A=class{constructor(e){let t=f(e);this.blogs=new h(t,e.siteId),this.pages=new w(t,e.siteId),this.navigation=new C(t,e.siteId),this.taxonomy=new k(t,e.siteId),this.analytics=new m(t,e.siteId),this.cv=new g(t,e.siteId),this.legal=new x(t,e.siteId),this.projects=new T(t,e.siteId),this.redirects=new E(t,e.siteId),this.site=new D(t,e.siteId),this.media=new S(t,e.siteId),this.social=new O(t,e.siteId),this.forms=new _(t)}};export{s as a,i as c,e as i,o as l,y as n,r as o,t as r,n as s,A as t,a as u};
|
package/dist/client-FailsuXv.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=class extends Error{constructor(e,t){super(e),this.code=t,this.name=`ForjaError`}},t=class extends e{constructor(e=`Invalid or missing API key`){super(e,`AUTH_ERROR`),this.name=`ForjaAuthError`}},n=class extends e{constructor(e=`Insufficient permissions`){super(e,`PERMISSION_ERROR`),this.name=`ForjaPermissionError`}},r=class extends e{constructor(e=`Resource not found`){super(e,`NOT_FOUND`),this.name=`ForjaNotFoundError`}},i=class extends e{constructor(e=`Rate limit exceeded`,t){super(e,`RATE_LIMIT`),this.retryAfter=t,this.name=`ForjaRateLimitError`}},a=class extends e{constructor(e=`Validation error`,t){super(e,`VALIDATION_ERROR`),this.details=t,this.name=`ForjaValidationError`}},o=class extends e{constructor(e=`Internal server error`,t=500){super(e,`SERVER_ERROR`),this.status=t,this.name=`ForjaServerError`}},s=class extends e{constructor(e=`Network error`,t){super(e,`NETWORK_ERROR`),this.cause=t,this.name=`ForjaNetworkError`}};function c(e,t,n){let r=e.replace(/\/+$/,``),i=t.startsWith(`/`)?t:`/${t}`,a=new URL(`${r}${i}`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&a.searchParams.set(e,t);return a.toString()}function l(e){let t={};for(let[n,r]of Object.entries(e))r!=null&&(t[u(n)]=String(r));return t}function u(e){return e.replace(/[A-Z]/g,e=>`_${e.toLowerCase()}`)}async function d(e){let s;try{let t=await e.json();s=t.detail||t.message||t.title||e.statusText}catch{s=e.statusText}switch(e.status){case 401:throw new t(s);case 403:throw new n(s);case 404:throw new r(s);case 422:throw new a(s);case 429:{let t=e.headers.get(`retry-after`);throw new i(s,t?parseInt(t,10):void 0)}default:throw e.status,new o(s,e.status)}}function f(e){let t=e.fetch??globalThis.fetch,n=e.baseUrl.replace(/\/+$/,``),r={"X-API-Key":e.apiKey,"Content-Type":`application/json`};e.siteDomain&&(r[`X-Site-Domain`]=e.siteDomain);async function i(e,i,a,o){let l=c(n,i,a),u;try{u=await t(l,{method:e,headers:r,body:o===void 0?void 0:JSON.stringify(o)})}catch(e){throw new s(`Failed to connect to the Forja API`,e instanceof Error?e:void 0)}return u.ok?u:d(u)}return{get:(e,t)=>i(`GET`,e,t).then(e=>e.json()),getText:(e,t)=>i(`GET`,e,t).then(e=>e.text()),post:(e,t)=>i(`POST`,e,void 0,t).then(e=>e.json()),delete:e=>i(`DELETE`,e).then(()=>void 0)}}function p(e,t,n){return{data:e,meta:t,async fetchNext(){if(t.page>=t.total_pages)return null;let e=await n(t.page+1);return p(e.data,e.meta,n)},async fetchAll(){let r=[...e],i=t.page;for(;i<t.total_pages;){i++;let e=await n(i);r.push(...e.data)}return r},async*[Symbol.asyncIterator](){yield{data:e,meta:t};let r=t.page;for(;r<t.total_pages;)r++,yield await n(r)}}}var m=class{constructor(e,t){this.http=e,this.siteId=t}async trackPageview(e){return this.http.post(`/sites/${this.siteId}/analytics/pageview`,e)}async getReport(e){let t=e?l({days:e.days,top_n:e.topN,start_date:e.startDate,end_date:e.endDate}):void 0;return this.http.get(`/sites/${this.siteId}/analytics/report`,t)}async getPageAnalytics(e){let t=l({path:e.path,days:e.days,start_date:e.startDate,end_date:e.endDate});return this.http.get(`/sites/${this.siteId}/analytics/report/page`,t)}},h=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=e?.localeId?{locale_id:e.localeId}:{},r=async e=>this.http.get(`/sites/${this.siteId}/blogs/published`,{...t,...n,page:String(e)}),i=await r(e?.page??1);return p(i.data,i.meta,r)}async listByCategory(e,t){let n=t?l(t):void 0,r=t?.localeId?{locale_id:t.localeId}:{},i=async t=>this.http.get(`/sites/${this.siteId}/blogs/published/category/${encodeURIComponent(e)}`,{...n,...r,page:String(t)}),a=await i(t?.page??1);return p(a.data,a.meta,i)}async listFeatured(e){return this.http.get(`/sites/${this.siteId}/blogs/featured`,e?.limit===void 0?void 0:{limit:String(e.limit)})}async listSimilar(e,t){return this.http.get(`/sites/${this.siteId}/blogs/${encodeURIComponent(e)}/similar`,t?.limit===void 0?void 0:{limit:String(t.limit)})}async getBySlug(e){try{let t=await this.http.get(`/sites/${this.siteId}/blogs/by-slug/${encodeURIComponent(e)}`);return await this.http.get(`/blogs/${t.id}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async get(e){try{return await this.http.get(`/blogs/${encodeURIComponent(e)}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async rss(){return this.http.getText(`/sites/${this.siteId}/feed.rss`)}},g=class{constructor(e,t){this.http=e,this.siteId=t}async listSkills(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/skills`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getSkill(e){try{return await this.http.get(`/skills/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getSkillBySlug(e){try{return await this.http.get(`/skills/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async listEntries(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/cv`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}},_=class{constructor(e){this.http=e}async getForm(e,t){let n=t?.locale?{locale:t.locale}:void 0;return this.http.get(`/public/forms/${encodeURIComponent(e)}`,n)}async submitForm(e,t,n={}){return this.http.post(`/public/forms/${encodeURIComponent(e)}/submit`,{data:t,consent_given:n.consentGiven??!1,bot_protection_token:n.botProtectionToken})}async lookupSubmission(e){return this.http.post(`/public/submissions/lookup`,{reference_code:e})}async getSubmission(e){return this.http.get(`/public/submissions/${encodeURIComponent(e)}`)}async deleteSubmission(e){return this.http.delete(`/public/submissions/${encodeURIComponent(e)}`)}};const v=/^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;function y(e,t){let n={};for(let r of e.fields){let e=t[r.label],i=b(r,e);i&&(n[r.label]=i)}return n}function b(e,t){let n=t,r=n==null||typeof n==`string`&&n===``||Array.isArray(n)&&n.length===0;if((e.is_required||e.validation.required)&&r)return`${e.label} is required`;if(r)return null;switch(e.field_type){case`text`:case`textarea`:case`custom`:if(typeof n!=`string`)return`Must be a string`;if(e.validation.min_length!==void 0&&n.length<e.validation.min_length)return`Must be at least ${e.validation.min_length} characters`;if(e.validation.max_length!==void 0&&n.length>e.validation.max_length)return`Must be at most ${e.validation.max_length} characters`;if(e.validation.pattern)try{if(!new RegExp(e.validation.pattern).test(n))return`Value does not match the required pattern`}catch{return`Field has an invalid validation pattern`}return null;case`email`:return typeof n==`string`?v.test(n)?null:`Invalid email format`:`Must be a string`;case`number`:{let t=typeof n==`number`?n:Number(n);return Number.isNaN(t)?`Must be a number`:e.validation.min!==void 0&&t<e.validation.min?`Must be at least ${e.validation.min}`:e.validation.max!==void 0&&t>e.validation.max?`Must be at most ${e.validation.max}`:null}case`date`:return typeof n!=`string`||Number.isNaN(Date.parse(n))&&!/^\d{4}-\d{2}-\d{2}$/.test(n)?`Invalid date format`:null;case`select`:case`radio`:case`checkbox`:return null}}var x=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/legal`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/legal/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCookieConsent(){try{return await this.http.get(`/sites/${this.siteId}/legal/cookie-consent`)}catch(e){if(e instanceof r)return null;throw e}}async getGroups(e){return this.http.get(`/legal/${encodeURIComponent(e)}/groups`)}async getGroupItems(e){return this.http.get(`/legal/groups/${encodeURIComponent(e)}/items`)}async getDetail(e){try{return await this.http.get(`/legal/${encodeURIComponent(e)}/detail`)}catch(e){if(e instanceof r)return null;throw e}}async listVersions(e){return this.http.get(`/legal/${encodeURIComponent(e)}/versions`)}},S=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/media`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/media/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},C=class{constructor(e,t){this.http=e,this.siteId=t}async listMenus(){return this.http.get(`/sites/${this.siteId}/menus`)}async getMenu(e){try{return await this.http.get(`/menus/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getMenuBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/menus/slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTree(e,t){return this.http.get(`/menus/${encodeURIComponent(e)}/tree`,t?.locale?{locale:t.locale}:void 0)}async listItems(e){return this.http.get(`/menus/${encodeURIComponent(e)}/items`)}async getItem(e){try{return await this.http.get(`/navigation/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},w=class{constructor(e,t){this.http=e,this.siteId=t}async list(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/pages`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getByRoute(e){let t=e.startsWith(`/`)?e.slice(1):e;try{return await this.http.get(`/sites/${this.siteId}/pages/by-route/${encodeURIComponent(t)}`)}catch(e){if(e instanceof r)return null;throw e}}async getSections(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections`)}async getSectionLocalizations(e){return this.http.get(`/pages/sections/${encodeURIComponent(e)}/localizations`)}async getPageSectionLocalizations(e){return this.http.get(`/pages/${encodeURIComponent(e)}/sections/localizations`)}},T=class{constructor(e,t){this.http=e,this.siteId=t}async listPublished(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/projects/public`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async get(e){try{return await this.http.get(`/projects/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getBySlug(e){try{return await this.http.get(`/sites/${this.siteId}/projects/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}},E=class{constructor(e,t){this.http=e,this.siteId=t}async lookup(e){try{return await this.http.get(`/sites/${this.siteId}/redirects/lookup`,{path:e})}catch(e){if(e instanceof r)return null;throw e}}},D=class{constructor(e,t){this.http=e,this.siteId=t}async get(){return this.http.get(`/sites/${this.siteId}`)}async listLocales(){return this.http.get(`/sites/${this.siteId}/locales`)}async getCodeInjection(){let e=await this.http.get(`/sites/${this.siteId}/settings`);return{code_injection_head:e.code_injection_head??``,code_injection_footer:e.code_injection_footer??``}}},O=class{constructor(e,t){this.http=e,this.siteId=t}async list(){return this.http.get(`/sites/${this.siteId}/social`)}},k=class{constructor(e,t){this.http=e,this.siteId=t}async listTags(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/tags`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async listCategories(e){let t=e?l(e):void 0,n=async e=>this.http.get(`/sites/${this.siteId}/categories`,{...t,page:String(e)}),r=await n(e?.page??1);return p(r.data,r.meta,n)}async getCategoriesWithBlogCounts(){return this.http.get(`/sites/${this.siteId}/categories/blog-counts`)}async getContentTags(e){return this.http.get(`/content/${encodeURIComponent(e)}/tags`)}async getContentCategories(e){return this.http.get(`/content/${encodeURIComponent(e)}/categories`)}async getTag(e){try{return await this.http.get(`/tags/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getTagBySlug(e){try{return await this.http.get(`/tags/by-slug/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategory(e){try{return await this.http.get(`/categories/${encodeURIComponent(e)}`)}catch(e){if(e instanceof r)return null;throw e}}async getCategoryChildren(e){return this.http.get(`/categories/${encodeURIComponent(e)}/children`)}},A=class{constructor(e){let t=f(e);this.blogs=new h(t,e.siteId),this.pages=new w(t,e.siteId),this.navigation=new C(t,e.siteId),this.taxonomy=new k(t,e.siteId),this.analytics=new m(t,e.siteId),this.cv=new g(t,e.siteId),this.legal=new x(t,e.siteId),this.projects=new T(t,e.siteId),this.redirects=new E(t,e.siteId),this.site=new D(t,e.siteId),this.media=new S(t,e.siteId),this.social=new O(t,e.siteId),this.forms=new _(t)}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return a}});
|