lynkow 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1384 @@
1
+ /**
2
+ * Configuration interne normalisee
3
+ */
4
+ interface InternalConfig {
5
+ siteId: string;
6
+ baseUrl: string;
7
+ locale?: string;
8
+ fetchOptions: RequestInit;
9
+ }
10
+ /**
11
+ * Service de base dont heritent tous les services specifiques
12
+ */
13
+ declare abstract class BaseService {
14
+ protected config: InternalConfig;
15
+ constructor(config: InternalConfig);
16
+ /**
17
+ * Construit l'URL complete pour un endpoint
18
+ */
19
+ protected buildEndpointUrl(path: string, query?: Record<string, unknown>): string;
20
+ /**
21
+ * Effectue une requete GET
22
+ */
23
+ protected get<T>(path: string, query?: Record<string, unknown>, options?: BaseRequestOptions): Promise<T>;
24
+ /**
25
+ * Effectue une requete POST
26
+ */
27
+ protected post<T>(path: string, body: Record<string, unknown>, options?: BaseRequestOptions): Promise<T>;
28
+ /**
29
+ * Effectue une requete GET qui retourne du texte brut (XML, txt)
30
+ */
31
+ protected getText(path: string, options?: BaseRequestOptions): Promise<string>;
32
+ /**
33
+ * Fusionne les options fetch locales avec celles globales
34
+ */
35
+ private mergeFetchOptions;
36
+ }
37
+
38
+ /**
39
+ * Service pour les contenus (articles de blog)
40
+ */
41
+ declare class ContentsService extends BaseService {
42
+ /**
43
+ * Recupere une liste paginee de contenus publies
44
+ *
45
+ * @param filters - Filtres optionnels (pagination, categorie, tag, recherche)
46
+ * @param options - Options de requete
47
+ * @returns Liste paginee de contenus
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const { data, meta } = await lynkow.contents.list({
52
+ * page: 1,
53
+ * perPage: 10,
54
+ * category: 'tech'
55
+ * })
56
+ * ```
57
+ */
58
+ list(filters?: ContentsFilters, options?: BaseRequestOptions): Promise<ContentsListResponse>;
59
+ /**
60
+ * Recupere un contenu par son slug
61
+ *
62
+ * @param slug - Slug du contenu
63
+ * @param options - Options de requete (locale)
64
+ * @returns Contenu complet
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const content = await lynkow.contents.getBySlug('my-article')
69
+ * ```
70
+ */
71
+ getBySlug(slug: string, options?: BaseRequestOptions): Promise<Content>;
72
+ }
73
+
74
+ /**
75
+ * Service pour les categories
76
+ */
77
+ declare class CategoriesService extends BaseService {
78
+ /**
79
+ * Recupere la liste des categories
80
+ *
81
+ * @param options - Options de requete (locale)
82
+ * @returns Liste des categories avec compteurs
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const { data, blogUrlMode } = await lynkow.categories.list()
87
+ * ```
88
+ */
89
+ list(options?: BaseRequestOptions): Promise<CategoriesListResponse>;
90
+ /**
91
+ * Recupere l'arborescence des categories
92
+ *
93
+ * @param options - Options de requete (locale)
94
+ * @returns Arborescence complete
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const { data } = await lynkow.categories.tree()
99
+ * // data[0].children contient les sous-categories
100
+ * ```
101
+ */
102
+ tree(options?: BaseRequestOptions): Promise<CategoryTreeResponse>;
103
+ /**
104
+ * Recupere une categorie avec ses contenus pagines
105
+ *
106
+ * @param slug - Slug de la categorie
107
+ * @param options - Options (locale, pagination)
108
+ * @returns Categorie avec contenus
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const { category, contents } = await lynkow.categories.getBySlug('tech', {
113
+ * page: 1,
114
+ * perPage: 10
115
+ * })
116
+ * ```
117
+ */
118
+ getBySlug(slug: string, options?: CategoryOptions & BaseRequestOptions): Promise<CategoryDetailResponse>;
119
+ }
120
+
121
+ /**
122
+ * Service pour les tags
123
+ */
124
+ declare class TagsService extends BaseService {
125
+ /**
126
+ * Recupere la liste des tags
127
+ *
128
+ * @param options - Options de requete (locale)
129
+ * @returns Liste des tags
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const { data } = await lynkow.tags.list()
134
+ * ```
135
+ */
136
+ list(options?: BaseRequestOptions): Promise<TagsListResponse>;
137
+ }
138
+
139
+ /**
140
+ * Service pour les pages (Site Blocks de type "page")
141
+ */
142
+ declare class PagesService extends BaseService {
143
+ /**
144
+ * Recupere la liste des pages publiees
145
+ *
146
+ * @param options - Options de requete (locale)
147
+ * @returns Liste des pages
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const { data } = await lynkow.pages.list()
152
+ * ```
153
+ */
154
+ list(options?: BaseRequestOptions): Promise<PagesListResponse>;
155
+ /**
156
+ * Recupere une page par son slug
157
+ *
158
+ * @param slug - Slug de la page
159
+ * @param options - Options de requete (locale)
160
+ * @returns Page complete avec donnees resolues
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * const page = await lynkow.pages.getBySlug('about')
165
+ * ```
166
+ */
167
+ getBySlug(slug: string, options?: BaseRequestOptions): Promise<Page>;
168
+ /**
169
+ * Recupere une page par son chemin
170
+ *
171
+ * @param path - Chemin de la page (ex: /services/consulting)
172
+ * @param options - Options de requete (locale)
173
+ * @returns Page complete avec donnees resolues
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const page = await lynkow.pages.getByPath('/services/consulting')
178
+ * ```
179
+ */
180
+ getByPath(path: string, options?: BaseRequestOptions): Promise<Page>;
181
+ /**
182
+ * Recupere les donnees JSON-LD pour une page
183
+ *
184
+ * @param slug - Slug de la page
185
+ * @param options - Options de requete (locale)
186
+ * @returns Donnees JSON-LD (Schema.org)
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * const jsonLd = await lynkow.pages.getJsonLd('about')
191
+ * // Utiliser dans <script type="application/ld+json">
192
+ * ```
193
+ */
194
+ getJsonLd(slug: string, options?: BaseRequestOptions): Promise<Record<string, unknown>>;
195
+ }
196
+
197
+ /**
198
+ * Service pour les blocs globaux (header, footer, etc.)
199
+ */
200
+ declare class BlocksService extends BaseService {
201
+ /**
202
+ * Recupere la configuration du site avec tous les blocs globaux
203
+ *
204
+ * @param options - Options de requete (locale)
205
+ * @returns Configuration et blocs globaux
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const { data } = await lynkow.blocks.siteConfig()
210
+ * const header = data.globals['header']
211
+ * const footer = data.globals['footer']
212
+ * ```
213
+ */
214
+ siteConfig(options?: BaseRequestOptions): Promise<SiteConfigResponse>;
215
+ /**
216
+ * Recupere un bloc global specifique par son slug
217
+ *
218
+ * @param slug - Slug du bloc (ex: 'header', 'footer')
219
+ * @param options - Options de requete (locale)
220
+ * @returns Bloc global avec donnees resolues
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const { data } = await lynkow.blocks.global('header')
225
+ * // data.data contient les donnees du bloc
226
+ * ```
227
+ */
228
+ global(slug: string, options?: BaseRequestOptions): Promise<GlobalBlockResponse>;
229
+ }
230
+
231
+ /**
232
+ * Service pour les formulaires
233
+ */
234
+ declare class FormsService extends BaseService {
235
+ /**
236
+ * Timestamp de creation du client (pour anti-spam)
237
+ */
238
+ private sessionStartTime;
239
+ constructor(config: InternalConfig);
240
+ /**
241
+ * Recupere un formulaire par son slug
242
+ *
243
+ * @param slug - Slug du formulaire
244
+ * @returns Schema du formulaire
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * const form = await lynkow.forms.getBySlug('contact')
249
+ * // Utiliser form.schema pour generer le formulaire
250
+ * ```
251
+ */
252
+ getBySlug(slug: string): Promise<Form>;
253
+ /**
254
+ * Soumet un formulaire
255
+ *
256
+ * Les champs anti-spam (_hp, _ts) sont ajoutes automatiquement.
257
+ *
258
+ * @param slug - Slug du formulaire
259
+ * @param data - Donnees du formulaire
260
+ * @param options - Options (token reCAPTCHA si active)
261
+ * @returns Reponse de soumission
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const result = await lynkow.forms.submit('contact', {
266
+ * name: 'John Doe',
267
+ * email: 'john@example.com',
268
+ * message: 'Hello!'
269
+ * })
270
+ * ```
271
+ */
272
+ submit(slug: string, data: FormSubmitData, options?: SubmitOptions & BaseRequestOptions): Promise<FormSubmitResponse>;
273
+ }
274
+
275
+ /**
276
+ * Service pour les avis clients
277
+ */
278
+ declare class ReviewsService extends BaseService {
279
+ /**
280
+ * Timestamp de creation du client (pour anti-spam)
281
+ */
282
+ private sessionStartTime;
283
+ constructor(config: InternalConfig);
284
+ /**
285
+ * Recupere la liste des avis approuves
286
+ *
287
+ * @param filters - Filtres (pagination, note)
288
+ * @param options - Options de requete
289
+ * @returns Liste paginee des avis
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const { data, meta } = await lynkow.reviews.list({
294
+ * minRating: 4,
295
+ * perPage: 10
296
+ * })
297
+ * ```
298
+ */
299
+ list(filters?: ReviewsFilters, options?: BaseRequestOptions): Promise<ReviewsListResponse>;
300
+ /**
301
+ * Recupere un avis par son slug ou ID
302
+ *
303
+ * @param slugOrId - Slug ou ID de l'avis
304
+ * @returns Avis complet
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const review = await lynkow.reviews.getBySlug('excellent-service')
309
+ * ```
310
+ */
311
+ getBySlug(slugOrId: string): Promise<Review>;
312
+ /**
313
+ * Recupere les parametres publics des avis
314
+ *
315
+ * @returns Parametres (champs requis, echelle de notes, etc.)
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * const settings = await lynkow.reviews.settings()
320
+ * if (settings.fields.email.required) {
321
+ * // Afficher le champ email comme requis
322
+ * }
323
+ * ```
324
+ */
325
+ settings(): Promise<ReviewSettings>;
326
+ /**
327
+ * Soumet un nouvel avis
328
+ *
329
+ * Les champs anti-spam (_hp, _ts) sont ajoutes automatiquement.
330
+ *
331
+ * @param data - Donnees de l'avis
332
+ * @param options - Options (token reCAPTCHA si active)
333
+ * @returns Reponse de soumission
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * const result = await lynkow.reviews.submit({
338
+ * authorName: 'Alice',
339
+ * rating: 5,
340
+ * content: 'Excellent service !'
341
+ * })
342
+ * ```
343
+ */
344
+ submit(data: ReviewSubmitData, options?: SubmitOptions & BaseRequestOptions): Promise<ReviewSubmitResponse>;
345
+ }
346
+
347
+ /**
348
+ * Service pour la configuration du site
349
+ */
350
+ declare class SiteService extends BaseService {
351
+ /**
352
+ * Recupere la configuration publique du site
353
+ *
354
+ * @returns Configuration du site
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * const config = await lynkow.site.getConfig()
359
+ * console.log(config.enabledLocales) // ['fr', 'en']
360
+ * ```
361
+ */
362
+ getConfig(): Promise<SiteConfig>;
363
+ }
364
+
365
+ /**
366
+ * Service pour les documents legaux
367
+ */
368
+ declare class LegalService extends BaseService {
369
+ /**
370
+ * Recupere la liste des documents legaux
371
+ *
372
+ * @param options - Options de requete (locale)
373
+ * @returns Liste des documents disponibles
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * const { data } = await lynkow.legal.list()
378
+ * ```
379
+ */
380
+ list(options?: BaseRequestOptions): Promise<LegalListResponse>;
381
+ /**
382
+ * Recupere un document legal par son type
383
+ *
384
+ * @param type - Type de document ('terms', 'privacy', etc.)
385
+ * @param options - Options de requete (locale)
386
+ * @returns Document legal complet
387
+ *
388
+ * @example
389
+ * ```typescript
390
+ * const privacy = await lynkow.legal.getByType('privacy')
391
+ * // privacy.content contient le HTML
392
+ * ```
393
+ */
394
+ getByType(type: LegalDocumentType, options?: BaseRequestOptions): Promise<LegalDocument>;
395
+ }
396
+
397
+ /**
398
+ * Service pour le consentement cookies
399
+ */
400
+ declare class CookiesService extends BaseService {
401
+ /**
402
+ * Recupere la configuration du bandeau de cookies
403
+ *
404
+ * @returns Configuration du bandeau
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * const config = await lynkow.cookies.getConfig()
409
+ * if (config.enabled) {
410
+ * // Afficher le bandeau
411
+ * }
412
+ * ```
413
+ */
414
+ getConfig(): Promise<CookieConfig>;
415
+ /**
416
+ * Enregistre le consentement de l'utilisateur
417
+ *
418
+ * @param preferences - Preferences par categorie
419
+ * @returns Confirmation avec ID du consentement
420
+ *
421
+ * @example
422
+ * ```typescript
423
+ * await lynkow.cookies.logConsent({
424
+ * necessary: true,
425
+ * analytics: true,
426
+ * marketing: false
427
+ * })
428
+ * ```
429
+ */
430
+ logConsent(preferences: CookiePreferences, options?: BaseRequestOptions): Promise<ConsentLogResponse>;
431
+ }
432
+
433
+ /**
434
+ * Service pour les fichiers SEO
435
+ */
436
+ declare class SeoService extends BaseService {
437
+ /**
438
+ * Recupere le sitemap XML
439
+ *
440
+ * @returns Contenu XML du sitemap
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * // Dans une route API Next.js
445
+ * export async function GET() {
446
+ * const xml = await lynkow.seo.sitemap()
447
+ * return new Response(xml, {
448
+ * headers: { 'Content-Type': 'application/xml' }
449
+ * })
450
+ * }
451
+ * ```
452
+ */
453
+ sitemap(options?: BaseRequestOptions): Promise<string>;
454
+ /**
455
+ * Recupere le fichier robots.txt
456
+ *
457
+ * @returns Contenu du robots.txt
458
+ *
459
+ * @example
460
+ * ```typescript
461
+ * // Dans une route API Next.js
462
+ * export async function GET() {
463
+ * const txt = await lynkow.seo.robots()
464
+ * return new Response(txt, {
465
+ * headers: { 'Content-Type': 'text/plain' }
466
+ * })
467
+ * }
468
+ * ```
469
+ */
470
+ robots(options?: BaseRequestOptions): Promise<string>;
471
+ }
472
+
473
+ /**
474
+ * Service pour les chemins (SSG, resolution)
475
+ */
476
+ declare class PathsService extends BaseService {
477
+ /**
478
+ * Recupere tous les chemins pour la generation statique
479
+ *
480
+ * @param options - Options de requete (locale)
481
+ * @returns Liste des chemins
482
+ *
483
+ * @example
484
+ * ```typescript
485
+ * // Dans generateStaticParams() de Next.js
486
+ * export async function generateStaticParams() {
487
+ * const { paths } = await lynkow.paths.list()
488
+ * return paths.map(p => ({
489
+ * slug: p.segments
490
+ * }))
491
+ * }
492
+ * ```
493
+ */
494
+ list(options?: BaseRequestOptions): Promise<PathsListResponse>;
495
+ /**
496
+ * Resout un chemin vers son contenu ou categorie
497
+ *
498
+ * @param path - Chemin a resoudre
499
+ * @param options - Options de requete
500
+ * @returns Contenu ou categorie correspondant
501
+ *
502
+ * @example
503
+ * ```typescript
504
+ * const result = await lynkow.paths.resolve('/blog/tech/my-article')
505
+ *
506
+ * if (result.type === 'content') {
507
+ * // Afficher l'article
508
+ * } else {
509
+ * // Afficher la categorie avec ses articles
510
+ * }
511
+ * ```
512
+ */
513
+ resolve(path: string, options?: BaseRequestOptions): Promise<ResolveResponse>;
514
+ /**
515
+ * Verifie si un chemin a une redirection configuree
516
+ *
517
+ * @param path - Chemin a verifier
518
+ * @returns Redirection ou null
519
+ *
520
+ * @example
521
+ * ```typescript
522
+ * // Dans un middleware Next.js
523
+ * const redirect = await lynkow.paths.matchRedirect(pathname)
524
+ * if (redirect) {
525
+ * return NextResponse.redirect(redirect.target, redirect.statusCode)
526
+ * }
527
+ * ```
528
+ */
529
+ matchRedirect(path: string, options?: BaseRequestOptions): Promise<Redirect | null>;
530
+ }
531
+
532
+ /**
533
+ * Configuration pour creer une instance du client Lynkow
534
+ */
535
+ interface LynkowConfig {
536
+ /**
537
+ * UUID du site Lynkow (requis)
538
+ * @example "550e8400-e29b-41d4-a716-446655440000"
539
+ */
540
+ siteId: string;
541
+ /**
542
+ * URL de base de l'API
543
+ * @default "https://api.lynkow.com"
544
+ */
545
+ baseUrl?: string;
546
+ /**
547
+ * Locale par defaut pour les requetes
548
+ * Sera utilisee si non specifiee dans les options de requete
549
+ * @example "fr"
550
+ */
551
+ locale?: string;
552
+ /**
553
+ * Options passees a toutes les requetes fetch()
554
+ * Permet d'integrer avec le cache Next.js, etc.
555
+ */
556
+ fetchOptions?: RequestInit;
557
+ }
558
+ /**
559
+ * Client Lynkow - Point d'entree principal du SDK
560
+ */
561
+ interface LynkowClient {
562
+ /** Service pour les contenus (articles de blog) */
563
+ contents: ContentsService;
564
+ /** Service pour les categories */
565
+ categories: CategoriesService;
566
+ /** Service pour les tags */
567
+ tags: TagsService;
568
+ /** Service pour les pages (Site Blocks) */
569
+ pages: PagesService;
570
+ /** Service pour les blocs globaux (header, footer) */
571
+ blocks: BlocksService;
572
+ /** Service pour les formulaires */
573
+ forms: FormsService;
574
+ /** Service pour les avis clients */
575
+ reviews: ReviewsService;
576
+ /** Service pour la configuration du site */
577
+ site: SiteService;
578
+ /** Service pour les documents legaux */
579
+ legal: LegalService;
580
+ /** Service pour le consentement cookies */
581
+ cookies: CookiesService;
582
+ /** Service pour les fichiers SEO */
583
+ seo: SeoService;
584
+ /** Service pour les chemins (SSG) */
585
+ paths: PathsService;
586
+ }
587
+
588
+ /**
589
+ * Categorie de contenu
590
+ */
591
+ interface Category {
592
+ /** ID unique */
593
+ id: number;
594
+ /** Nom de la categorie */
595
+ name: string;
596
+ /** Slug URL-friendly */
597
+ slug: string;
598
+ /** Locale */
599
+ locale: string;
600
+ }
601
+ /**
602
+ * Categorie avec chemin et compteur
603
+ */
604
+ interface CategoryWithCount extends Category {
605
+ /** Chemin complet */
606
+ path: string;
607
+ /** Description */
608
+ description: string | null;
609
+ /** URL de l'image */
610
+ image: string | null;
611
+ /** Nombre de contenus dans cette categorie */
612
+ contentCount: number;
613
+ }
614
+ /**
615
+ * Categorie detaillee (avec toutes les infos)
616
+ */
617
+ interface CategoryDetail extends CategoryWithCount {
618
+ /** ID de la categorie parente */
619
+ parentId: number | null;
620
+ }
621
+ /**
622
+ * Noeud de l'arborescence des categories
623
+ */
624
+ interface CategoryTreeNode extends CategoryWithCount {
625
+ /** Sous-categories */
626
+ children: CategoryTreeNode[];
627
+ }
628
+
629
+ /**
630
+ * Tag de contenu
631
+ */
632
+ interface Tag {
633
+ /** ID unique */
634
+ id: number;
635
+ /** Nom du tag */
636
+ name: string;
637
+ /** Slug URL-friendly */
638
+ slug: string;
639
+ /** Locale */
640
+ locale: string;
641
+ }
642
+
643
+ /**
644
+ * Auteur d'un contenu
645
+ */
646
+ interface Author {
647
+ /** ID unique */
648
+ id: number;
649
+ /** Nom complet */
650
+ fullName: string;
651
+ /** URL de l'avatar */
652
+ avatarUrl: string | null;
653
+ }
654
+ /**
655
+ * Bloc de contenu individuel
656
+ */
657
+ interface ContentBlock {
658
+ /** Type de bloc */
659
+ type: 'paragraph' | 'heading' | 'image' | 'list' | 'quote' | 'code' | 'embed' | 'table' | 'divider' | string;
660
+ /** Donnees specifiques au type */
661
+ data: Record<string, unknown>;
662
+ /** ID unique du bloc */
663
+ id?: string;
664
+ }
665
+ /**
666
+ * Corps du contenu (blocs editeur)
667
+ */
668
+ type ContentBody = ContentBlock[];
669
+ /**
670
+ * Resume d'un contenu (pour les listes)
671
+ */
672
+ interface ContentSummary {
673
+ id: number;
674
+ title: string;
675
+ slug: string;
676
+ path: string;
677
+ excerpt: string | null;
678
+ featuredImage: string | null;
679
+ locale: string;
680
+ publishedAt: string;
681
+ createdAt: string;
682
+ }
683
+ /**
684
+ * Contenu complet (article de blog)
685
+ */
686
+ interface Content extends ContentSummary {
687
+ /** Corps de l'article (blocs de contenu) */
688
+ body: ContentBody;
689
+ /** Statut (toujours 'published' via API publique) */
690
+ status: 'published';
691
+ /** Date de derniere modification */
692
+ updatedAt: string;
693
+ /** Meta title personnalise */
694
+ metaTitle: string | null;
695
+ /** Meta description */
696
+ metaDescription: string | null;
697
+ /** Mots-cles SEO */
698
+ keywords: string | null;
699
+ /** URL canonique */
700
+ canonicalUrl: string | null;
701
+ /** Image Open Graph */
702
+ ogImage: string | null;
703
+ /** Donnees structurees JSON-LD */
704
+ structuredData: Record<string, unknown> | null;
705
+ /** Auteur de l'article */
706
+ author: Author | null;
707
+ /** Categories associees */
708
+ categories: Category[];
709
+ /** Tags associes */
710
+ tags: Tag[];
711
+ }
712
+
713
+ /**
714
+ * Parametres SEO d'une page
715
+ */
716
+ interface PageSeo {
717
+ /** Meta title */
718
+ title: string | null;
719
+ /** Meta description */
720
+ description: string | null;
721
+ /** Mots-cles */
722
+ keywords: string | null;
723
+ /** Image Open Graph */
724
+ ogImage: string | null;
725
+ /** URL canonique */
726
+ canonicalUrl: string | null;
727
+ /** Directive noindex */
728
+ noIndex: boolean;
729
+ /** Directive nofollow */
730
+ noFollow: boolean;
731
+ }
732
+ /**
733
+ * Version alternative (autre locale)
734
+ */
735
+ interface Alternate {
736
+ /** Locale de cette version */
737
+ locale: string;
738
+ /** Chemin de cette version */
739
+ path: string;
740
+ /** Est-ce la version actuelle */
741
+ current: boolean;
742
+ }
743
+ /**
744
+ * Resume d'une page
745
+ */
746
+ interface PageSummary {
747
+ /** ID unique */
748
+ id: number;
749
+ /** Slug URL-friendly */
750
+ slug: string;
751
+ /** Nom de la page */
752
+ name: string;
753
+ /** Chemin URL */
754
+ path: string | null;
755
+ /** Locale */
756
+ locale: string;
757
+ /** Date de derniere modification */
758
+ updatedAt: string | null;
759
+ }
760
+ /**
761
+ * Page complete avec donnees resolues
762
+ */
763
+ interface Page extends PageSummary {
764
+ /** Donnees du bloc (resolues depuis les DataSources) */
765
+ data: Record<string, unknown>;
766
+ /** Parametres SEO */
767
+ seo: PageSeo | null;
768
+ /** Versions dans d'autres locales */
769
+ alternates: Alternate[];
770
+ /** Avertissements de resolution (si des DataSources ont echoue) */
771
+ _warnings?: string[];
772
+ }
773
+
774
+ /**
775
+ * Bloc global
776
+ */
777
+ interface GlobalBlock {
778
+ /** Slug du bloc */
779
+ slug: string;
780
+ /** Nom du bloc */
781
+ name: string;
782
+ /** Donnees du bloc (resolues) */
783
+ data: Record<string, unknown>;
784
+ /** Avertissements de resolution */
785
+ _warnings?: string[];
786
+ }
787
+
788
+ /**
789
+ * Types de champs supportes
790
+ */
791
+ type FormFieldType = 'text' | 'email' | 'tel' | 'url' | 'textarea' | 'number' | 'date' | 'datetime' | 'time' | 'select' | 'radio' | 'checkbox' | 'file' | 'hidden';
792
+ /**
793
+ * Option pour les champs select/radio/checkbox
794
+ */
795
+ interface FormFieldOption {
796
+ /** Valeur envoyee */
797
+ value: string;
798
+ /** Label affiche */
799
+ label: string;
800
+ }
801
+ /**
802
+ * Regles de validation
803
+ */
804
+ interface FormFieldValidation {
805
+ /** Longueur minimum */
806
+ minLength?: number;
807
+ /** Longueur maximum */
808
+ maxLength?: number;
809
+ /** Valeur minimum (pour number) */
810
+ min?: number;
811
+ /** Valeur maximum (pour number) */
812
+ max?: number;
813
+ /** Pattern regex */
814
+ pattern?: string;
815
+ /** Message d'erreur personnalise */
816
+ message?: string;
817
+ }
818
+ /**
819
+ * Champ de formulaire
820
+ */
821
+ interface FormField {
822
+ /** Nom du champ (cle dans les donnees) */
823
+ name: string;
824
+ /** Type de champ */
825
+ type: FormFieldType;
826
+ /** Label affiche */
827
+ label: string;
828
+ /** Placeholder */
829
+ placeholder?: string;
830
+ /** Champ requis */
831
+ required: boolean;
832
+ /** Options (pour select, radio, checkbox) */
833
+ options?: FormFieldOption[];
834
+ /** Regles de validation */
835
+ validation?: FormFieldValidation;
836
+ /** Valeur par defaut */
837
+ defaultValue?: string | number | boolean;
838
+ /** Texte d'aide */
839
+ helpText?: string;
840
+ /** Largeur (pour le layout) */
841
+ width?: 'full' | 'half' | 'third';
842
+ }
843
+ /**
844
+ * Parametres du formulaire
845
+ */
846
+ interface FormSettings {
847
+ /** Texte du bouton de soumission */
848
+ submitLabel: string;
849
+ /** Message de succes */
850
+ successMessage: string;
851
+ /** URL de redirection apres soumission */
852
+ redirectUrl?: string;
853
+ /** Activer la double confirmation email */
854
+ doubleOptIn?: boolean;
855
+ }
856
+ /**
857
+ * Formulaire
858
+ */
859
+ interface Form {
860
+ /** ID unique */
861
+ id: number;
862
+ /** Nom du formulaire */
863
+ name: string;
864
+ /** Slug URL-friendly */
865
+ slug: string;
866
+ /** Description */
867
+ description: string | null;
868
+ /** Schema des champs */
869
+ schema: FormField[];
870
+ /** Parametres du formulaire */
871
+ settings: FormSettings;
872
+ /** Statut */
873
+ status: 'active';
874
+ }
875
+ /**
876
+ * Donnees de soumission de formulaire
877
+ */
878
+ type FormSubmitData = Record<string, string | number | boolean | File>;
879
+
880
+ /**
881
+ * Reponse a un avis
882
+ */
883
+ interface ReviewResponse {
884
+ /** Contenu de la reponse */
885
+ content: string;
886
+ /** Date de la reponse */
887
+ respondedAt: string;
888
+ }
889
+ /**
890
+ * Avis client
891
+ */
892
+ interface Review {
893
+ /** ID unique */
894
+ id: number;
895
+ /** Slug URL-friendly */
896
+ slug: string | null;
897
+ /** Nom de l'auteur */
898
+ authorName: string;
899
+ /** Email de l'auteur (peut etre masque) */
900
+ authorEmail?: string;
901
+ /** Note (1-5) */
902
+ rating: number;
903
+ /** Titre de l'avis */
904
+ title: string | null;
905
+ /** Contenu de l'avis */
906
+ content: string;
907
+ /** Locale */
908
+ locale: string;
909
+ /** Statut (toujours 'approved' via API publique) */
910
+ status: 'approved';
911
+ /** Date de creation */
912
+ createdAt: string;
913
+ /** Reponse du site (si presente) */
914
+ response?: ReviewResponse;
915
+ }
916
+ /**
917
+ * Parametres publics des avis
918
+ */
919
+ interface ReviewSettings {
920
+ /** Avis actives pour ce site */
921
+ enabled: boolean;
922
+ /** Moderation requise avant publication */
923
+ requireApproval: boolean;
924
+ /** Autoriser les avis anonymes */
925
+ allowAnonymous: boolean;
926
+ /** Note minimum */
927
+ minRating: number;
928
+ /** Note maximum */
929
+ maxRating: number;
930
+ /** Configuration des champs */
931
+ fields: {
932
+ title: {
933
+ enabled: boolean;
934
+ required: boolean;
935
+ };
936
+ email: {
937
+ enabled: boolean;
938
+ required: boolean;
939
+ };
940
+ };
941
+ }
942
+ /**
943
+ * Donnees pour soumettre un avis
944
+ */
945
+ interface ReviewSubmitData {
946
+ /** Nom de l'auteur */
947
+ authorName: string;
948
+ /** Email de l'auteur */
949
+ authorEmail?: string;
950
+ /** Note (1-5) */
951
+ rating: number;
952
+ /** Titre (optionnel selon settings) */
953
+ title?: string;
954
+ /** Contenu de l'avis */
955
+ content: string;
956
+ }
957
+
958
+ /**
959
+ * Configuration publique du site
960
+ */
961
+ interface SiteConfig {
962
+ /** UUID du site */
963
+ id: string;
964
+ /** Nom du site */
965
+ name: string;
966
+ /** Domaine principal */
967
+ domain: string;
968
+ /** Description du site */
969
+ description: string | null;
970
+ /** URL du logo */
971
+ logoUrl: string | null;
972
+ /** URL du favicon */
973
+ faviconUrl: string | null;
974
+ /** Fuseau horaire */
975
+ timezone: string;
976
+ /** Locale par defaut */
977
+ defaultLocale: string;
978
+ /** Multi-langue active */
979
+ multiLanguageEnabled: boolean;
980
+ /** Locales disponibles */
981
+ enabledLocales: string[];
982
+ /** Parametres additionnels */
983
+ settings: Record<string, unknown>;
984
+ }
985
+
986
+ /**
987
+ * Types de documents legaux
988
+ */
989
+ type LegalDocumentType = 'terms' | 'privacy' | 'cookies' | 'legal-notice' | 'refund' | 'shipping';
990
+ /**
991
+ * Resume d'un document legal
992
+ */
993
+ interface LegalDocumentSummary {
994
+ /** Type de document */
995
+ type: LegalDocumentType;
996
+ /** Titre */
997
+ title: string;
998
+ /** Date de mise a jour */
999
+ updatedAt: string;
1000
+ }
1001
+ /**
1002
+ * Document legal complet
1003
+ */
1004
+ interface LegalDocument extends LegalDocumentSummary {
1005
+ /** Contenu HTML */
1006
+ content: string;
1007
+ /** Locale */
1008
+ locale: string;
1009
+ /** Version du document */
1010
+ version: string;
1011
+ /** Date d'effet */
1012
+ effectiveDate: string;
1013
+ }
1014
+
1015
+ /**
1016
+ * Categorie de cookies
1017
+ */
1018
+ interface CookieCategory {
1019
+ /** ID de la categorie */
1020
+ id: string;
1021
+ /** Nom affiche */
1022
+ name: string;
1023
+ /** Description */
1024
+ description: string;
1025
+ /** Categorie obligatoire (ne peut pas etre desactivee) */
1026
+ required: boolean;
1027
+ }
1028
+ /**
1029
+ * Textes du bandeau de cookies
1030
+ */
1031
+ interface CookieTexts {
1032
+ /** Titre */
1033
+ title: string;
1034
+ /** Description/message */
1035
+ description: string;
1036
+ /** Bouton "Tout accepter" */
1037
+ acceptAll: string;
1038
+ /** Bouton "Tout refuser" */
1039
+ rejectAll: string;
1040
+ /** Bouton "Personnaliser" */
1041
+ customize: string;
1042
+ /** Bouton "Enregistrer" */
1043
+ save: string;
1044
+ }
1045
+ /**
1046
+ * Configuration du bandeau de cookies
1047
+ */
1048
+ interface CookieConfig {
1049
+ /** Bandeau active */
1050
+ enabled: boolean;
1051
+ /** Position du bandeau */
1052
+ position: 'bottom' | 'top' | 'bottom-left' | 'bottom-right';
1053
+ /** Style du bandeau */
1054
+ layout: 'bar' | 'box' | 'popup';
1055
+ /** Theme */
1056
+ theme: 'light' | 'dark' | 'auto';
1057
+ /** Categories de cookies */
1058
+ categories: CookieCategory[];
1059
+ /** Textes du bandeau */
1060
+ texts: CookieTexts;
1061
+ }
1062
+ /**
1063
+ * Preferences de consentement
1064
+ */
1065
+ type CookiePreferences = Record<string, boolean>;
1066
+
1067
+ /**
1068
+ * Chemin pour generation statique
1069
+ */
1070
+ interface Path {
1071
+ /** Chemin complet (ex: /blog/tech/my-article) */
1072
+ path: string;
1073
+ /** Segments du chemin */
1074
+ segments: string[];
1075
+ /** Type de ressource */
1076
+ type: 'content' | 'category';
1077
+ /** Locale */
1078
+ locale: string;
1079
+ /** Date de derniere modification */
1080
+ lastModified: string;
1081
+ }
1082
+ /**
1083
+ * Redirection
1084
+ */
1085
+ interface Redirect {
1086
+ /** Chemin source */
1087
+ source: string;
1088
+ /** Chemin cible */
1089
+ target: string;
1090
+ /** Code HTTP */
1091
+ statusCode: 301 | 302 | 307 | 308;
1092
+ /** Preserver la query string */
1093
+ preserveQueryString: boolean;
1094
+ }
1095
+
1096
+ /**
1097
+ * Metadonnees de pagination
1098
+ */
1099
+ interface PaginationMeta {
1100
+ /** Nombre total d'elements */
1101
+ total: number;
1102
+ /** Elements par page */
1103
+ perPage: number;
1104
+ /** Page actuelle */
1105
+ currentPage: number;
1106
+ /** Derniere page */
1107
+ lastPage: number;
1108
+ /** Premiere page */
1109
+ firstPage: number;
1110
+ /** Y a-t-il plus de pages */
1111
+ hasMorePages: boolean;
1112
+ /** Y a-t-il des pages precedentes */
1113
+ hasPreviousPages: boolean;
1114
+ }
1115
+ /**
1116
+ * Reponse paginee generique
1117
+ */
1118
+ interface PaginatedResponse<T> {
1119
+ data: T[];
1120
+ meta: PaginationMeta;
1121
+ }
1122
+ /**
1123
+ * Reponse de liste des contenus
1124
+ */
1125
+ interface ContentsListResponse {
1126
+ data: ContentSummary[];
1127
+ meta: PaginationMeta;
1128
+ }
1129
+ /**
1130
+ * Reponse de liste des categories
1131
+ */
1132
+ interface CategoriesListResponse {
1133
+ data: CategoryWithCount[];
1134
+ blogUrlMode: string;
1135
+ locale: string | null;
1136
+ }
1137
+ /**
1138
+ * Reponse de l'arborescence des categories
1139
+ */
1140
+ interface CategoryTreeResponse {
1141
+ data: CategoryTreeNode[];
1142
+ blogUrlMode: string;
1143
+ locale: string | null;
1144
+ }
1145
+ /**
1146
+ * Reponse de detail d'une categorie
1147
+ */
1148
+ interface CategoryDetailResponse {
1149
+ category: CategoryDetail;
1150
+ contents: {
1151
+ data: ContentSummary[];
1152
+ meta: PaginationMeta;
1153
+ };
1154
+ locale: string | null;
1155
+ }
1156
+ /**
1157
+ * Reponse de liste des tags
1158
+ */
1159
+ interface TagsListResponse {
1160
+ data: Tag[];
1161
+ }
1162
+ /**
1163
+ * Reponse de liste des pages
1164
+ */
1165
+ interface PagesListResponse {
1166
+ data: PageSummary[];
1167
+ }
1168
+ /**
1169
+ * Reponse de configuration du site avec blocs globaux
1170
+ */
1171
+ interface SiteConfigResponse {
1172
+ data: {
1173
+ site: {
1174
+ name: string;
1175
+ domain: string;
1176
+ logo: string | null;
1177
+ favicon: string | null;
1178
+ };
1179
+ locale: string;
1180
+ globals: Record<string, GlobalBlock>;
1181
+ };
1182
+ }
1183
+ /**
1184
+ * Reponse d'un bloc global
1185
+ */
1186
+ interface GlobalBlockResponse {
1187
+ data: GlobalBlock;
1188
+ }
1189
+ /**
1190
+ * Reponse de liste des avis
1191
+ */
1192
+ interface ReviewsListResponse {
1193
+ data: Review[];
1194
+ meta: PaginationMeta;
1195
+ }
1196
+ /**
1197
+ * Reponse de soumission de formulaire
1198
+ */
1199
+ interface FormSubmitResponse {
1200
+ message: string;
1201
+ status: 'success' | 'pending';
1202
+ submissionId?: number;
1203
+ }
1204
+ /**
1205
+ * Reponse de soumission d'avis
1206
+ */
1207
+ interface ReviewSubmitResponse {
1208
+ message: string;
1209
+ status: 'success' | 'pending';
1210
+ reviewId?: number;
1211
+ }
1212
+ /**
1213
+ * Reponse de liste des documents legaux
1214
+ */
1215
+ interface LegalListResponse {
1216
+ data: LegalDocumentSummary[];
1217
+ }
1218
+ /**
1219
+ * Reponse d'enregistrement de consentement
1220
+ */
1221
+ interface ConsentLogResponse {
1222
+ message: string;
1223
+ consentId: string;
1224
+ }
1225
+ /**
1226
+ * Reponse de liste des chemins
1227
+ */
1228
+ interface PathsListResponse {
1229
+ paths: Path[];
1230
+ blogUrlMode: string;
1231
+ locale: string | null;
1232
+ }
1233
+ /**
1234
+ * Reponse de resolution d'un chemin vers un contenu
1235
+ */
1236
+ interface ContentResolveResponse {
1237
+ type: 'content';
1238
+ locale: string;
1239
+ blogUrlMode: string;
1240
+ content: Content;
1241
+ }
1242
+ /**
1243
+ * Reponse de resolution d'un chemin vers une categorie
1244
+ */
1245
+ interface CategoryResolveResponse {
1246
+ type: 'category';
1247
+ locale: string;
1248
+ blogUrlMode: string;
1249
+ category: CategoryDetail;
1250
+ contents: {
1251
+ data: ContentSummary[];
1252
+ meta: PaginationMeta;
1253
+ };
1254
+ }
1255
+ /**
1256
+ * Reponse de resolution de chemin (union)
1257
+ */
1258
+ type ResolveResponse = ContentResolveResponse | CategoryResolveResponse;
1259
+
1260
+ /**
1261
+ * Options de base pour les requetes
1262
+ */
1263
+ interface BaseRequestOptions {
1264
+ /** Override de la locale */
1265
+ locale?: string;
1266
+ /** Override des options fetch */
1267
+ fetchOptions?: RequestInit;
1268
+ }
1269
+ /**
1270
+ * Options de pagination
1271
+ */
1272
+ interface PaginationOptions {
1273
+ /** Numero de page */
1274
+ page?: number;
1275
+ /** Elements par page */
1276
+ perPage?: number;
1277
+ }
1278
+ /**
1279
+ * Options de tri
1280
+ */
1281
+ interface SortOptions {
1282
+ /** Champ de tri */
1283
+ sort?: string;
1284
+ /** Ordre de tri */
1285
+ order?: 'asc' | 'desc';
1286
+ }
1287
+ /**
1288
+ * Filtres pour les contenus
1289
+ */
1290
+ interface ContentsFilters extends PaginationOptions, SortOptions {
1291
+ /** Filtrer par categorie (slug) */
1292
+ category?: string;
1293
+ /** Filtrer par tag (slug) */
1294
+ tag?: string;
1295
+ /** Recherche textuelle */
1296
+ search?: string;
1297
+ /** Locale */
1298
+ locale?: string;
1299
+ }
1300
+ /**
1301
+ * Options pour recuperer une categorie
1302
+ */
1303
+ interface CategoryOptions extends PaginationOptions {
1304
+ /** Locale */
1305
+ locale?: string;
1306
+ }
1307
+ /**
1308
+ * Filtres pour les avis
1309
+ */
1310
+ interface ReviewsFilters extends PaginationOptions, SortOptions {
1311
+ /** Note minimum */
1312
+ minRating?: number;
1313
+ /** Note maximum */
1314
+ maxRating?: number;
1315
+ }
1316
+ /**
1317
+ * Options de soumission avec reCAPTCHA
1318
+ */
1319
+ interface SubmitOptions {
1320
+ /** Token reCAPTCHA (si active sur le site) */
1321
+ recaptchaToken?: string;
1322
+ }
1323
+
1324
+ /**
1325
+ * Codes d'erreur
1326
+ */
1327
+ type ErrorCode = 'BAD_REQUEST' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'VALIDATION_ERROR' | 'TOO_MANY_REQUESTS' | 'INTERNAL_ERROR' | 'SERVICE_UNAVAILABLE' | 'NETWORK_ERROR';
1328
+ /**
1329
+ * Detail d'une erreur
1330
+ */
1331
+ interface ApiErrorDetail {
1332
+ /** Message d'erreur */
1333
+ message: string;
1334
+ /** Champ concerne (pour les erreurs de validation) */
1335
+ field?: string;
1336
+ /** Code d'erreur specifique */
1337
+ code?: string;
1338
+ }
1339
+
1340
+ /**
1341
+ * Erreur specifique au SDK Lynkow
1342
+ */
1343
+ declare class LynkowError extends Error {
1344
+ /** Code HTTP */
1345
+ status: number;
1346
+ /** Code d'erreur */
1347
+ code: ErrorCode;
1348
+ /** Liste des erreurs detaillees */
1349
+ errors: ApiErrorDetail[];
1350
+ constructor(status: number, code: ErrorCode, message: string, errors?: ApiErrorDetail[]);
1351
+ }
1352
+
1353
+ /**
1354
+ * Verifie si une reponse de resolution est un contenu
1355
+ */
1356
+ declare function isContentResolve(response: ResolveResponse): response is ContentResolveResponse;
1357
+ /**
1358
+ * Verifie si une reponse de resolution est une categorie
1359
+ */
1360
+ declare function isCategoryResolve(response: ResolveResponse): response is CategoryResolveResponse;
1361
+ /**
1362
+ * Verifie si une erreur est une erreur Lynkow
1363
+ */
1364
+ declare function isLynkowError(error: unknown): error is LynkowError;
1365
+
1366
+ /**
1367
+ * Cree une instance du client Lynkow
1368
+ *
1369
+ * @param config - Configuration du client
1370
+ * @returns Instance du client avec tous les services
1371
+ *
1372
+ * @example
1373
+ * ```typescript
1374
+ * const lynkow = createLynkowClient({
1375
+ * siteId: 'your-site-uuid',
1376
+ * locale: 'fr'
1377
+ * })
1378
+ *
1379
+ * const posts = await lynkow.contents.list()
1380
+ * ```
1381
+ */
1382
+ declare function createLynkowClient(config: LynkowConfig): LynkowClient;
1383
+
1384
+ export { type Alternate, type ApiErrorDetail, type Author, type BaseRequestOptions, type CategoriesListResponse, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type ConsentLogResponse, type Content, type ContentBlock, type ContentBody, type ContentResolveResponse, type ContentSummary, type ContentsFilters, type ContentsListResponse, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, type ErrorCode, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, type GlobalBlock, type GlobalBlockResponse, type LegalDocument, type LegalDocumentSummary, type LegalDocumentType, type LegalListResponse, type LynkowClient, type LynkowConfig, LynkowError, type Page, type PageSeo, type PageSummary, type PagesListResponse, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, type SiteConfig, type SiteConfigResponse, type SortOptions, type SubmitOptions, type Tag, type TagsListResponse, createLynkowClient, isCategoryResolve, isContentResolve, isLynkowError };