lynkow 3.8.73 → 3.8.75
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/dist/index.d.mts +168 -1
- package/dist/index.d.ts +168 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1872,6 +1872,70 @@ interface ContentSchema {
|
|
|
1872
1872
|
fields: SchemaField[];
|
|
1873
1873
|
}
|
|
1874
1874
|
|
|
1875
|
+
/**
|
|
1876
|
+
* JSON-LD cascade types mirroring the Lynkow API schema.
|
|
1877
|
+
*
|
|
1878
|
+
* The Lynkow cascade declares schema.org nodes at four levels:
|
|
1879
|
+
*
|
|
1880
|
+
* 1. Site (SEO settings): shared across every page of the site.
|
|
1881
|
+
* 2. Category: inherited by all contents assigned to the category.
|
|
1882
|
+
* 3. Page (site block): inherited along the page surface.
|
|
1883
|
+
* 4. Content: article-specific overrides.
|
|
1884
|
+
*
|
|
1885
|
+
* Each level stores its own `jsonLdGraph` plus an optional `jsonLdExclusions`
|
|
1886
|
+
* that suppresses a parent node by `@id`. The server resolves the effective
|
|
1887
|
+
* `@graph` at render time and exposes it on the public API response as
|
|
1888
|
+
* `structuredData.graph: object[]`. This SDK only reads that pre-resolved
|
|
1889
|
+
* array; no client-side cascade logic is needed.
|
|
1890
|
+
*
|
|
1891
|
+
* Reserved ids beginning with `auto:` identify the implicit nodes Lynkow
|
|
1892
|
+
* injects automatically (Article, FAQPage, BreadcrumbList, Organization,
|
|
1893
|
+
* WebPage). They may appear in `jsonLdExclusions` to opt out of the
|
|
1894
|
+
* corresponding auto-node, but MUST NOT be used as user-provided ids.
|
|
1895
|
+
*/
|
|
1896
|
+
/**
|
|
1897
|
+
* Source of a JSON-LD node.
|
|
1898
|
+
*
|
|
1899
|
+
* - `preset`: the node was created from a Lynkow typed preset (Organization,
|
|
1900
|
+
* LocalBusiness, Product, etc.). The server fills unspecified fields from
|
|
1901
|
+
* the page context and mapped preset schema.
|
|
1902
|
+
* - `custom`: the node is a raw JSON-LD object supplied verbatim by the
|
|
1903
|
+
* caller. The server only performs basic sanity checks (non-empty `@type`,
|
|
1904
|
+
* prototype-pollution guard).
|
|
1905
|
+
*/
|
|
1906
|
+
type JsonLdNodeSource = 'preset' | 'custom';
|
|
1907
|
+
/**
|
|
1908
|
+
* A single JSON-LD node as stored at one cascade level.
|
|
1909
|
+
*
|
|
1910
|
+
* This is the shape the admin / MCP writes into the cascade columns. The
|
|
1911
|
+
* public API materializes each entry into a fully resolved schema.org object
|
|
1912
|
+
* (adding `@context`, `@id`, and preset-driven fields) before returning it
|
|
1913
|
+
* under `structuredData.graph`.
|
|
1914
|
+
*/
|
|
1915
|
+
interface JsonLdNode {
|
|
1916
|
+
/**
|
|
1917
|
+
* Stable node identifier. Auto-generated when the caller does not provide
|
|
1918
|
+
* one. Never starts with the reserved `auto:` prefix.
|
|
1919
|
+
*/
|
|
1920
|
+
id: string;
|
|
1921
|
+
/** schema.org `@type` string (e.g. "Organization", "LocalBusiness"). */
|
|
1922
|
+
type: string;
|
|
1923
|
+
/** Node payload. For presets, only the preset-documented fields. */
|
|
1924
|
+
data: Record<string, unknown>;
|
|
1925
|
+
/** Whether the node was created from a preset or a raw custom JSON-LD. */
|
|
1926
|
+
source: JsonLdNodeSource;
|
|
1927
|
+
}
|
|
1928
|
+
/**
|
|
1929
|
+
* Cascade configuration stored at any level (site, category, page, content).
|
|
1930
|
+
*
|
|
1931
|
+
* `graph` carries the nodes declared at this level; `exclusions` lists the
|
|
1932
|
+
* parent node ids this level opts out of.
|
|
1933
|
+
*/
|
|
1934
|
+
interface JsonLdGraphConfig {
|
|
1935
|
+
graph: JsonLdNode[];
|
|
1936
|
+
exclusions: string[];
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1875
1939
|
/**
|
|
1876
1940
|
* A content category as returned in content relations and list select projections.
|
|
1877
1941
|
*
|
|
@@ -1997,6 +2061,19 @@ interface CategoryDetail extends CategoryWithCount {
|
|
|
1997
2061
|
* Categories support unlimited nesting depth.
|
|
1998
2062
|
*/
|
|
1999
2063
|
parentId: number | null;
|
|
2064
|
+
/**
|
|
2065
|
+
* Category-level JSON-LD cascade nodes. Inherited by every content
|
|
2066
|
+
* attached to the category. Merged server-side into the content's
|
|
2067
|
+
* final `structuredData.graph`; SDK consumers normally read the
|
|
2068
|
+
* resolved graph on the content and don't need to re-merge.
|
|
2069
|
+
*/
|
|
2070
|
+
jsonLdGraph?: JsonLdNode[];
|
|
2071
|
+
/**
|
|
2072
|
+
* Reserved `@id` values this category opts out of. Typically used to
|
|
2073
|
+
* suppress site-level nodes that should not apply to contents in this
|
|
2074
|
+
* category (e.g. exclude `'auto:organization'` for a sub-brand).
|
|
2075
|
+
*/
|
|
2076
|
+
jsonLdExclusions?: string[];
|
|
2000
2077
|
}
|
|
2001
2078
|
/**
|
|
2002
2079
|
* Recursive category tree node, returned by the tree endpoint (`GET /public/categories/tree`).
|
|
@@ -2194,6 +2271,18 @@ interface StructuredData {
|
|
|
2194
2271
|
*/
|
|
2195
2272
|
jsonLd: JsonLdArticle;
|
|
2196
2273
|
};
|
|
2274
|
+
/**
|
|
2275
|
+
* Resolved JSON-LD `@graph` for this content, produced by the Lynkow
|
|
2276
|
+
* cascade (site + category + content + auto-nodes). Each entry is a
|
|
2277
|
+
* fully-formed schema.org object ready to be serialized inside a
|
|
2278
|
+
* `<script type="application/ld+json">` tag. Use
|
|
2279
|
+
* {@link renderJsonLdGraph} to emit the whole array as a single tag.
|
|
2280
|
+
*
|
|
2281
|
+
* `undefined` or empty on responses from older API versions that do not
|
|
2282
|
+
* populate the cascade. Prefer the individual `faq.jsonLd` / `article.jsonLd`
|
|
2283
|
+
* fields as a fallback.
|
|
2284
|
+
*/
|
|
2285
|
+
graph?: object[];
|
|
2197
2286
|
/**
|
|
2198
2287
|
* Alternate language versions of this content.
|
|
2199
2288
|
* Empty array if the site has only one locale or no translations exist.
|
|
@@ -2504,6 +2593,21 @@ interface Content extends ContentSummary {
|
|
|
2504
2593
|
* ```
|
|
2505
2594
|
*/
|
|
2506
2595
|
customData?: Record<string, any> | null;
|
|
2596
|
+
/**
|
|
2597
|
+
* Content-level cascade nodes declared by the admin or via the MCP
|
|
2598
|
+
* `create_content` / `update_content` tools. Merged with site + category
|
|
2599
|
+
* nodes server-side; consumers should read {@link StructuredData.graph}
|
|
2600
|
+
* instead of re-merging client-side.
|
|
2601
|
+
*
|
|
2602
|
+
* See `/features/json-ld-cascade` in the Lynkow docs for the full model.
|
|
2603
|
+
*/
|
|
2604
|
+
jsonLdGraph?: JsonLdNode[];
|
|
2605
|
+
/**
|
|
2606
|
+
* Reserved `@id` values this content opts out of. Typically used to
|
|
2607
|
+
* suppress auto-generated nodes (e.g. `'auto:article'`) when a custom
|
|
2608
|
+
* replacement has been supplied in `jsonLdGraph`.
|
|
2609
|
+
*/
|
|
2610
|
+
jsonLdExclusions?: string[];
|
|
2507
2611
|
}
|
|
2508
2612
|
|
|
2509
2613
|
/**
|
|
@@ -2747,6 +2851,22 @@ interface Page extends PageSummary {
|
|
|
2747
2851
|
* Useful for debugging during development; avoid displaying these to end users.
|
|
2748
2852
|
*/
|
|
2749
2853
|
_warnings?: string[];
|
|
2854
|
+
/**
|
|
2855
|
+
* Resolved JSON-LD cascade for the page.
|
|
2856
|
+
*
|
|
2857
|
+
* `graph` contains the `@graph` array merged by the server from the site
|
|
2858
|
+
* level plus this page's own nodes plus the auto-nodes (WebPage,
|
|
2859
|
+
* BreadcrumbList, Organization when configured). Use
|
|
2860
|
+
* {@link renderJsonLdGraph} from the helpers to serialize it as a single
|
|
2861
|
+
* `<script type="application/ld+json">` tag.
|
|
2862
|
+
*
|
|
2863
|
+
* `undefined` on responses from older API versions that do not populate
|
|
2864
|
+
* the cascade; in that case, fall back to the dedicated
|
|
2865
|
+
* `/public/:siteId/pages/:slug/json-ld` endpoint.
|
|
2866
|
+
*/
|
|
2867
|
+
structuredData?: {
|
|
2868
|
+
graph: object[];
|
|
2869
|
+
};
|
|
2750
2870
|
}
|
|
2751
2871
|
|
|
2752
2872
|
/**
|
|
@@ -5711,4 +5831,51 @@ declare function detectSiteTheme(): 'dark' | 'light';
|
|
|
5711
5831
|
*/
|
|
5712
5832
|
declare function onSiteThemeChange(callback: (theme: 'dark' | 'light') => void): () => void;
|
|
5713
5833
|
|
|
5714
|
-
|
|
5834
|
+
/**
|
|
5835
|
+
* Render a resolved JSON-LD `@graph` as a single `<script type="application/ld+json">`
|
|
5836
|
+
* tag ready to inject into a page `<head>`.
|
|
5837
|
+
*
|
|
5838
|
+
* The input is the array returned by the Lynkow public API at
|
|
5839
|
+
* `content.structuredData.graph` (for articles) or `page.structuredData.graph`
|
|
5840
|
+
* (for site blocks of type page). Each entry is already a fully-formed
|
|
5841
|
+
* schema.org object with `@context`, `@id`, and `@type`. This helper strips
|
|
5842
|
+
* the per-node `@context` and wraps the array in a top-level `@context` +
|
|
5843
|
+
* `@graph` to keep the emitted script as compact as possible.
|
|
5844
|
+
*
|
|
5845
|
+
* No HTML escaping is performed on the JSON body itself, but `</script>`
|
|
5846
|
+
* sequences that would otherwise break the enclosing tag are guarded against
|
|
5847
|
+
* via a Unicode-safe replacement.
|
|
5848
|
+
*
|
|
5849
|
+
* @param nodes - Array of JSON-LD node objects. `null`, `undefined`, or an
|
|
5850
|
+
* empty array returns an empty string so you can safely
|
|
5851
|
+
* spread the result into server-rendered HTML without
|
|
5852
|
+
* conditional branches.
|
|
5853
|
+
* @returns Serialized `<script>` tag string. Empty string when there are
|
|
5854
|
+
* no nodes to render.
|
|
5855
|
+
*
|
|
5856
|
+
* @example
|
|
5857
|
+
* ```tsx
|
|
5858
|
+
* // Next.js App Router (server component)
|
|
5859
|
+
* import { createClient, renderJsonLdGraph } from 'lynkow'
|
|
5860
|
+
*
|
|
5861
|
+
* const client = createClient({ siteId: process.env.LYNKOW_SITE_ID! })
|
|
5862
|
+
*
|
|
5863
|
+
* export default async function ArticlePage({ params }: { params: { slug: string } }) {
|
|
5864
|
+
* const article = await client.contents.getBySlug(params.slug)
|
|
5865
|
+
* return (
|
|
5866
|
+
* <>
|
|
5867
|
+
* <div
|
|
5868
|
+
* dangerouslySetInnerHTML={{
|
|
5869
|
+
* __html: renderJsonLdGraph(article.structuredData?.graph),
|
|
5870
|
+
* }}
|
|
5871
|
+
* />
|
|
5872
|
+
* <h1>{article.title}</h1>
|
|
5873
|
+
* <article dangerouslySetInnerHTML={{ __html: article.body }} />
|
|
5874
|
+
* </>
|
|
5875
|
+
* )
|
|
5876
|
+
* }
|
|
5877
|
+
* ```
|
|
5878
|
+
*/
|
|
5879
|
+
declare function renderJsonLdGraph(nodes: object[] | null | undefined): string;
|
|
5880
|
+
|
|
5881
|
+
export { type Alternate, AnalyticsService, type ApiErrorDetail, type Author, type BaseRequestOptions, BlocksService, BrandingService, type CategoriesListResponse, CategoriesService, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, ConsentService, type Content, type ContentBody, type ContentResolveResponse, type ContentSchema, type ContentSummary, type ContentsFilters, type ContentsListResponse, ContentsService, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, CookiesService, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, FormsService, type GlobalBlock, type GlobalBlockResponse, type ImageVariants, type JsonLdGraphConfig, type JsonLdNode, type JsonLdNodeSource, type LegalDocument, LegalService, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, MediaHelperService, type Page, type PageSeo, type PageSummary, type PagesListResponse, PagesService, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, PathsService, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, ReviewsService, type SchemaField, type SchemaFieldOption, type SchemaFieldType, type SchemaFieldValidation, type SearchConfig, type SearchHit, type SearchOptions, type SearchResponse, SearchService, SeoService, type SiteConfig, type SiteConfigResponse, SiteService, type SortOptions, type SrcsetOptions, type SubmitOptions, type Tag, type TagsListResponse, TagsService, type TipTapMark, type TipTapNode, type TransformOptions, browserOnly, browserOnlyAsync, createClient, createLynkowClient, detectSiteTheme, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer, onSiteThemeChange, renderJsonLdGraph };
|
package/dist/index.d.ts
CHANGED
|
@@ -1872,6 +1872,70 @@ interface ContentSchema {
|
|
|
1872
1872
|
fields: SchemaField[];
|
|
1873
1873
|
}
|
|
1874
1874
|
|
|
1875
|
+
/**
|
|
1876
|
+
* JSON-LD cascade types mirroring the Lynkow API schema.
|
|
1877
|
+
*
|
|
1878
|
+
* The Lynkow cascade declares schema.org nodes at four levels:
|
|
1879
|
+
*
|
|
1880
|
+
* 1. Site (SEO settings): shared across every page of the site.
|
|
1881
|
+
* 2. Category: inherited by all contents assigned to the category.
|
|
1882
|
+
* 3. Page (site block): inherited along the page surface.
|
|
1883
|
+
* 4. Content: article-specific overrides.
|
|
1884
|
+
*
|
|
1885
|
+
* Each level stores its own `jsonLdGraph` plus an optional `jsonLdExclusions`
|
|
1886
|
+
* that suppresses a parent node by `@id`. The server resolves the effective
|
|
1887
|
+
* `@graph` at render time and exposes it on the public API response as
|
|
1888
|
+
* `structuredData.graph: object[]`. This SDK only reads that pre-resolved
|
|
1889
|
+
* array; no client-side cascade logic is needed.
|
|
1890
|
+
*
|
|
1891
|
+
* Reserved ids beginning with `auto:` identify the implicit nodes Lynkow
|
|
1892
|
+
* injects automatically (Article, FAQPage, BreadcrumbList, Organization,
|
|
1893
|
+
* WebPage). They may appear in `jsonLdExclusions` to opt out of the
|
|
1894
|
+
* corresponding auto-node, but MUST NOT be used as user-provided ids.
|
|
1895
|
+
*/
|
|
1896
|
+
/**
|
|
1897
|
+
* Source of a JSON-LD node.
|
|
1898
|
+
*
|
|
1899
|
+
* - `preset`: the node was created from a Lynkow typed preset (Organization,
|
|
1900
|
+
* LocalBusiness, Product, etc.). The server fills unspecified fields from
|
|
1901
|
+
* the page context and mapped preset schema.
|
|
1902
|
+
* - `custom`: the node is a raw JSON-LD object supplied verbatim by the
|
|
1903
|
+
* caller. The server only performs basic sanity checks (non-empty `@type`,
|
|
1904
|
+
* prototype-pollution guard).
|
|
1905
|
+
*/
|
|
1906
|
+
type JsonLdNodeSource = 'preset' | 'custom';
|
|
1907
|
+
/**
|
|
1908
|
+
* A single JSON-LD node as stored at one cascade level.
|
|
1909
|
+
*
|
|
1910
|
+
* This is the shape the admin / MCP writes into the cascade columns. The
|
|
1911
|
+
* public API materializes each entry into a fully resolved schema.org object
|
|
1912
|
+
* (adding `@context`, `@id`, and preset-driven fields) before returning it
|
|
1913
|
+
* under `structuredData.graph`.
|
|
1914
|
+
*/
|
|
1915
|
+
interface JsonLdNode {
|
|
1916
|
+
/**
|
|
1917
|
+
* Stable node identifier. Auto-generated when the caller does not provide
|
|
1918
|
+
* one. Never starts with the reserved `auto:` prefix.
|
|
1919
|
+
*/
|
|
1920
|
+
id: string;
|
|
1921
|
+
/** schema.org `@type` string (e.g. "Organization", "LocalBusiness"). */
|
|
1922
|
+
type: string;
|
|
1923
|
+
/** Node payload. For presets, only the preset-documented fields. */
|
|
1924
|
+
data: Record<string, unknown>;
|
|
1925
|
+
/** Whether the node was created from a preset or a raw custom JSON-LD. */
|
|
1926
|
+
source: JsonLdNodeSource;
|
|
1927
|
+
}
|
|
1928
|
+
/**
|
|
1929
|
+
* Cascade configuration stored at any level (site, category, page, content).
|
|
1930
|
+
*
|
|
1931
|
+
* `graph` carries the nodes declared at this level; `exclusions` lists the
|
|
1932
|
+
* parent node ids this level opts out of.
|
|
1933
|
+
*/
|
|
1934
|
+
interface JsonLdGraphConfig {
|
|
1935
|
+
graph: JsonLdNode[];
|
|
1936
|
+
exclusions: string[];
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1875
1939
|
/**
|
|
1876
1940
|
* A content category as returned in content relations and list select projections.
|
|
1877
1941
|
*
|
|
@@ -1997,6 +2061,19 @@ interface CategoryDetail extends CategoryWithCount {
|
|
|
1997
2061
|
* Categories support unlimited nesting depth.
|
|
1998
2062
|
*/
|
|
1999
2063
|
parentId: number | null;
|
|
2064
|
+
/**
|
|
2065
|
+
* Category-level JSON-LD cascade nodes. Inherited by every content
|
|
2066
|
+
* attached to the category. Merged server-side into the content's
|
|
2067
|
+
* final `structuredData.graph`; SDK consumers normally read the
|
|
2068
|
+
* resolved graph on the content and don't need to re-merge.
|
|
2069
|
+
*/
|
|
2070
|
+
jsonLdGraph?: JsonLdNode[];
|
|
2071
|
+
/**
|
|
2072
|
+
* Reserved `@id` values this category opts out of. Typically used to
|
|
2073
|
+
* suppress site-level nodes that should not apply to contents in this
|
|
2074
|
+
* category (e.g. exclude `'auto:organization'` for a sub-brand).
|
|
2075
|
+
*/
|
|
2076
|
+
jsonLdExclusions?: string[];
|
|
2000
2077
|
}
|
|
2001
2078
|
/**
|
|
2002
2079
|
* Recursive category tree node, returned by the tree endpoint (`GET /public/categories/tree`).
|
|
@@ -2194,6 +2271,18 @@ interface StructuredData {
|
|
|
2194
2271
|
*/
|
|
2195
2272
|
jsonLd: JsonLdArticle;
|
|
2196
2273
|
};
|
|
2274
|
+
/**
|
|
2275
|
+
* Resolved JSON-LD `@graph` for this content, produced by the Lynkow
|
|
2276
|
+
* cascade (site + category + content + auto-nodes). Each entry is a
|
|
2277
|
+
* fully-formed schema.org object ready to be serialized inside a
|
|
2278
|
+
* `<script type="application/ld+json">` tag. Use
|
|
2279
|
+
* {@link renderJsonLdGraph} to emit the whole array as a single tag.
|
|
2280
|
+
*
|
|
2281
|
+
* `undefined` or empty on responses from older API versions that do not
|
|
2282
|
+
* populate the cascade. Prefer the individual `faq.jsonLd` / `article.jsonLd`
|
|
2283
|
+
* fields as a fallback.
|
|
2284
|
+
*/
|
|
2285
|
+
graph?: object[];
|
|
2197
2286
|
/**
|
|
2198
2287
|
* Alternate language versions of this content.
|
|
2199
2288
|
* Empty array if the site has only one locale or no translations exist.
|
|
@@ -2504,6 +2593,21 @@ interface Content extends ContentSummary {
|
|
|
2504
2593
|
* ```
|
|
2505
2594
|
*/
|
|
2506
2595
|
customData?: Record<string, any> | null;
|
|
2596
|
+
/**
|
|
2597
|
+
* Content-level cascade nodes declared by the admin or via the MCP
|
|
2598
|
+
* `create_content` / `update_content` tools. Merged with site + category
|
|
2599
|
+
* nodes server-side; consumers should read {@link StructuredData.graph}
|
|
2600
|
+
* instead of re-merging client-side.
|
|
2601
|
+
*
|
|
2602
|
+
* See `/features/json-ld-cascade` in the Lynkow docs for the full model.
|
|
2603
|
+
*/
|
|
2604
|
+
jsonLdGraph?: JsonLdNode[];
|
|
2605
|
+
/**
|
|
2606
|
+
* Reserved `@id` values this content opts out of. Typically used to
|
|
2607
|
+
* suppress auto-generated nodes (e.g. `'auto:article'`) when a custom
|
|
2608
|
+
* replacement has been supplied in `jsonLdGraph`.
|
|
2609
|
+
*/
|
|
2610
|
+
jsonLdExclusions?: string[];
|
|
2507
2611
|
}
|
|
2508
2612
|
|
|
2509
2613
|
/**
|
|
@@ -2747,6 +2851,22 @@ interface Page extends PageSummary {
|
|
|
2747
2851
|
* Useful for debugging during development; avoid displaying these to end users.
|
|
2748
2852
|
*/
|
|
2749
2853
|
_warnings?: string[];
|
|
2854
|
+
/**
|
|
2855
|
+
* Resolved JSON-LD cascade for the page.
|
|
2856
|
+
*
|
|
2857
|
+
* `graph` contains the `@graph` array merged by the server from the site
|
|
2858
|
+
* level plus this page's own nodes plus the auto-nodes (WebPage,
|
|
2859
|
+
* BreadcrumbList, Organization when configured). Use
|
|
2860
|
+
* {@link renderJsonLdGraph} from the helpers to serialize it as a single
|
|
2861
|
+
* `<script type="application/ld+json">` tag.
|
|
2862
|
+
*
|
|
2863
|
+
* `undefined` on responses from older API versions that do not populate
|
|
2864
|
+
* the cascade; in that case, fall back to the dedicated
|
|
2865
|
+
* `/public/:siteId/pages/:slug/json-ld` endpoint.
|
|
2866
|
+
*/
|
|
2867
|
+
structuredData?: {
|
|
2868
|
+
graph: object[];
|
|
2869
|
+
};
|
|
2750
2870
|
}
|
|
2751
2871
|
|
|
2752
2872
|
/**
|
|
@@ -5711,4 +5831,51 @@ declare function detectSiteTheme(): 'dark' | 'light';
|
|
|
5711
5831
|
*/
|
|
5712
5832
|
declare function onSiteThemeChange(callback: (theme: 'dark' | 'light') => void): () => void;
|
|
5713
5833
|
|
|
5714
|
-
|
|
5834
|
+
/**
|
|
5835
|
+
* Render a resolved JSON-LD `@graph` as a single `<script type="application/ld+json">`
|
|
5836
|
+
* tag ready to inject into a page `<head>`.
|
|
5837
|
+
*
|
|
5838
|
+
* The input is the array returned by the Lynkow public API at
|
|
5839
|
+
* `content.structuredData.graph` (for articles) or `page.structuredData.graph`
|
|
5840
|
+
* (for site blocks of type page). Each entry is already a fully-formed
|
|
5841
|
+
* schema.org object with `@context`, `@id`, and `@type`. This helper strips
|
|
5842
|
+
* the per-node `@context` and wraps the array in a top-level `@context` +
|
|
5843
|
+
* `@graph` to keep the emitted script as compact as possible.
|
|
5844
|
+
*
|
|
5845
|
+
* No HTML escaping is performed on the JSON body itself, but `</script>`
|
|
5846
|
+
* sequences that would otherwise break the enclosing tag are guarded against
|
|
5847
|
+
* via a Unicode-safe replacement.
|
|
5848
|
+
*
|
|
5849
|
+
* @param nodes - Array of JSON-LD node objects. `null`, `undefined`, or an
|
|
5850
|
+
* empty array returns an empty string so you can safely
|
|
5851
|
+
* spread the result into server-rendered HTML without
|
|
5852
|
+
* conditional branches.
|
|
5853
|
+
* @returns Serialized `<script>` tag string. Empty string when there are
|
|
5854
|
+
* no nodes to render.
|
|
5855
|
+
*
|
|
5856
|
+
* @example
|
|
5857
|
+
* ```tsx
|
|
5858
|
+
* // Next.js App Router (server component)
|
|
5859
|
+
* import { createClient, renderJsonLdGraph } from 'lynkow'
|
|
5860
|
+
*
|
|
5861
|
+
* const client = createClient({ siteId: process.env.LYNKOW_SITE_ID! })
|
|
5862
|
+
*
|
|
5863
|
+
* export default async function ArticlePage({ params }: { params: { slug: string } }) {
|
|
5864
|
+
* const article = await client.contents.getBySlug(params.slug)
|
|
5865
|
+
* return (
|
|
5866
|
+
* <>
|
|
5867
|
+
* <div
|
|
5868
|
+
* dangerouslySetInnerHTML={{
|
|
5869
|
+
* __html: renderJsonLdGraph(article.structuredData?.graph),
|
|
5870
|
+
* }}
|
|
5871
|
+
* />
|
|
5872
|
+
* <h1>{article.title}</h1>
|
|
5873
|
+
* <article dangerouslySetInnerHTML={{ __html: article.body }} />
|
|
5874
|
+
* </>
|
|
5875
|
+
* )
|
|
5876
|
+
* }
|
|
5877
|
+
* ```
|
|
5878
|
+
*/
|
|
5879
|
+
declare function renderJsonLdGraph(nodes: object[] | null | undefined): string;
|
|
5880
|
+
|
|
5881
|
+
export { type Alternate, AnalyticsService, type ApiErrorDetail, type Author, type BaseRequestOptions, BlocksService, BrandingService, type CategoriesListResponse, CategoriesService, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, ConsentService, type Content, type ContentBody, type ContentResolveResponse, type ContentSchema, type ContentSummary, type ContentsFilters, type ContentsListResponse, ContentsService, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, CookiesService, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, FormsService, type GlobalBlock, type GlobalBlockResponse, type ImageVariants, type JsonLdGraphConfig, type JsonLdNode, type JsonLdNodeSource, type LegalDocument, LegalService, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, MediaHelperService, type Page, type PageSeo, type PageSummary, type PagesListResponse, PagesService, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, PathsService, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, ReviewsService, type SchemaField, type SchemaFieldOption, type SchemaFieldType, type SchemaFieldValidation, type SearchConfig, type SearchHit, type SearchOptions, type SearchResponse, SearchService, SeoService, type SiteConfig, type SiteConfigResponse, SiteService, type SortOptions, type SrcsetOptions, type SubmitOptions, type Tag, type TagsListResponse, TagsService, type TipTapMark, type TipTapNode, type TransformOptions, browserOnly, browserOnlyAsync, createClient, createLynkowClient, detectSiteTheme, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer, onSiteThemeChange, renderJsonLdGraph };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var C=class s extends Error{name="LynkowError";code;status;details;cause;constructor(e,t,n,r,o){super(e),this.code=t,this.status=n,this.details=r,this.cause=o,Error.captureStackTrace&&Error.captureStackTrace(this,s);}static async fromResponse(e){let t=e.status,n=`HTTP ${t}`,r;try{let i=await e.json();i.errors&&Array.isArray(i.errors)?(r=i.errors,n=i.errors[0]?.message||n):i.error?n=i.error:i.message&&(n=i.message);}catch{n=e.statusText||n;}let o=s.statusToCode(t);return new s(n,o,t,r)}static fromNetworkError(e){return e.name==="AbortError"?new s("Request timed out","TIMEOUT",void 0,void 0,e):e.name==="TypeError"?new s("Network error - please check your connection","NETWORK_ERROR",void 0,void 0,e):new s(e.message||"Unknown error","UNKNOWN",void 0,void 0,e)}static statusToCode(e){switch(e){case 400:return "VALIDATION_ERROR";case 401:return "UNAUTHORIZED";case 403:return "FORBIDDEN";case 404:return "NOT_FOUND";case 429:return "RATE_LIMITED";default:return "UNKNOWN"}}toJSON(){return {name:this.name,message:this.message,code:this.code,status:this.status,details:this.details}}};function Ce(s){return s instanceof C}function ve(s){switch(s){case 400:return "BAD_REQUEST";case 401:return "UNAUTHORIZED";case 403:return "FORBIDDEN";case 404:return "NOT_FOUND";case 422:return "VALIDATION_ERROR";case 429:return "TOO_MANY_REQUESTS";case 503:return "SERVICE_UNAVAILABLE";default:return "INTERNAL_ERROR"}}async function z(s,e){let t;try{t=await fetch(s,e);}catch(a){throw new C("Network error: Unable to reach the server","NETWORK_ERROR",0,[{message:a instanceof Error?a.message:"Unknown error"}])}if(t.ok)return t.json();let n={};try{n=await t.json();}catch{}let r=ve(t.status),o=n.error||n.message||`HTTP error: ${t.status}`,i=n.errors||[{message:o}];throw new C(o,r,t.status,i)}function re(s){let e=new URLSearchParams;for(let[t,n]of Object.entries(s))n!=null&&n!==""&&e.append(t,String(n));return e.toString()}var d={SHORT:300*1e3,MEDIUM:600*1e3,LONG:1800*1e3},m=class{config;cache;constructor(e){this.config=e,this.cache=e.cache;}buildEndpointUrl(e,t){let n=`${this.config.baseUrl}/public/${this.config.siteId}${e}`;if(t&&Object.keys(t).length>0){let r=re(t);return `${n}?${r}`}return n}async get(e,t,n){let r=n?.locale||this.config.locale,o=r?{...t,locale:r}:t,i=this.buildEndpointUrl(e,o),a=this.mergeFetchOptions(n?.fetchOptions);return z(i,{method:"GET",...a})}async getWithCache(e,t,n,r,o=d.SHORT){return this.cache?this.cache.getOrSet(e,()=>this.get(t,n,r),o):this.get(t,n,r)}invalidateCache(e){this.cache?.invalidate(e);}async post(e,t,n){let r=this.buildEndpointUrl(e),o=this.mergeFetchOptions(n?.fetchOptions);return z(r,{method:"POST",...o,headers:{"Content-Type":"application/json",...o.headers},body:JSON.stringify(t)})}async getText(e,t){let n=this.buildEndpointUrl(e),r=this.mergeFetchOptions(t?.fetchOptions),o=await fetch(n,{method:"GET",...r});if(!o.ok)throw new Error(`HTTP error: ${o.status}`);return o.text()}mergeFetchOptions(e){return {...this.config.fetchOptions,...e,headers:{...this.config.fetchOptions.headers,...e?.headers}}}};var W="contents_",b=class extends m{async list(e,t){let n={};e?.page&&(n.page=e.page),(e?.limit??e?.perPage)&&(n.limit=e?.limit??e?.perPage),e?.category&&(n.category=e.category),e?.tag&&(n.tag=e.tag),e?.search&&(n.search=e.search),e?.sort&&(n.sort=e.sort),e?.order&&(n.order=e.order),e?.locale&&(n.locale=e.locale);let r=`${W}list_${JSON.stringify(e||{})}`;return this.getWithCache(r,"/contents",n,t,d.SHORT)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${W}slug_${e}_${n||"default"}`;return this.getWithCache(r,`/contents/slug/${encodeURIComponent(e)}`,void 0,t,d.SHORT)}clearCache(){this.invalidateCache(W);}};var U="categories_",R=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${U}list_${t||"default"}`;return this.getWithCache(n,"/categories",void 0,e,d.SHORT)}async tree(e){let t=e?.locale||this.config.locale,n=`${U}tree_${t||"default"}`;return this.getWithCache(n,"/categories/tree",void 0,e,d.SHORT)}async getBySlug(e,t){let n={};t?.page&&(n.page=t.page),(t?.limit??t?.perPage)&&(n.limit=t?.limit??t?.perPage);let r=`${U}slug_${e}_${JSON.stringify(t||{})}`;return this.getWithCache(r,`/categories/${encodeURIComponent(e)}`,n,t,d.SHORT)}clearCache(){this.invalidateCache(U);}};var oe="tags_",E=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${oe}list_${t||"default"}`;return this.getWithCache(n,"/tags",void 0,e,d.SHORT)}clearCache(){this.invalidateCache(oe);}};var _="pages_",k=class extends m{async list(e){let t=e?.locale||this.config.locale,n={};e?.tag&&(n.tag=e.tag);let r=`${_}list_${t||"default"}_${e?.tag||"all"}`;return this.getWithCache(r,"/pages",n,e,d.SHORT)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${_}slug_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}`,void 0,t,d.SHORT)).data}async getByPath(e,t){let n=t?.locale||this.config.locale,r=`${_}path_${e}_${n||"default"}`;return (await this.getWithCache(r,"/page-by-path",{path:e},t,d.SHORT)).data}async getJsonLd(e,t){let n=t?.locale||this.config.locale,r=`${_}jsonld_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}/json-ld`,void 0,t,d.SHORT)).data}clearCache(){this.invalidateCache(_);}};var G="globals_",x=class extends m{async siteConfig(e){let t=e?.locale||this.config.locale,n=`${G}siteconfig_${t||"default"}`;return this.getWithCache(n,"/site-config",void 0,e,d.MEDIUM)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${G}${e}_${n||"default"}`;return this.getWithCache(r,`/global/${encodeURIComponent(e)}`,void 0,t,d.MEDIUM)}async global(e,t){return this.getBySlug(e,t)}clearCache(){this.invalidateCache(G);}};function K(s){return {_hp:"",_ts:s}}var se="forms_",S=class extends m{sessionStartTime;constructor(e){super(e),this.sessionStartTime=Date.now();}async getBySlug(e){let t=`${se}${e}`;return (await this.getWithCache(t,`/forms/${encodeURIComponent(e)}`,void 0,void 0,d.MEDIUM)).data}async submit(e,t,n){let r=K(this.sessionStartTime),o={data:t,honeypot:r._hp,...r};return n?.recaptchaToken&&(o.recaptchaToken=n.recaptchaToken),this.post(`/forms/${encodeURIComponent(e)}/submit`,o,n)}clearCache(){this.invalidateCache(se);}};var F="reviews_",T=class extends m{sessionStartTime;constructor(e){super(e),this.sessionStartTime=Date.now();}async list(e,t){let n={};e?.page&&(n.page=e.page),(e?.limit??e?.perPage)&&(n.limit=e?.limit??e?.perPage),e?.minRating&&(n.minRating=e.minRating),e?.maxRating&&(n.maxRating=e.maxRating),e?.sort&&(n.sort=e.sort),e?.order&&(n.order=e.order);let r=`${F}list_${JSON.stringify(e||{})}`;return this.getWithCache(r,"/reviews",n,t,d.SHORT)}async getBySlug(e){let t=`${F}slug_${e}`;return (await this.getWithCache(t,`/reviews/${encodeURIComponent(e)}`,void 0,void 0,d.SHORT)).data}async settings(){let e=`${F}settings`;return this.getWithCache(e,"/reviews/settings",void 0,void 0,d.MEDIUM)}async submit(e,t){let n=K(this.sessionStartTime),r={...e,...n};t?.recaptchaToken&&(r._recaptcha_token=t.recaptchaToken);let o=await this.post("/reviews",r,t);return this.invalidateCache(F),o}clearCache(){this.invalidateCache(F);}};var ie="site_",L=class extends m{async getConfig(){let e=`${ie}config`;return (await this.getWithCache(e,"/site",void 0,void 0,d.MEDIUM)).data}clearCache(){this.invalidateCache(ie);}};var V="legal_",O=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${V}list_${t||"default"}`;return (await this.getWithCache(n,"/pages",{tag:"legal"},e,d.SHORT)).data}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${V}slug_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}`,void 0,t,d.SHORT)).data}clearCache(){this.invalidateCache(V);}};var ae="cookies_",I=class extends m{async getConfig(){let e=`${ae}config`;return (await this.getWithCache(e,"/cookie-consent/config",void 0,void 0,d.MEDIUM)).data}async logConsent(e,t){return this.post("/cookie-consent/log",{preferences:e},t)}clearCache(){this.invalidateCache(ae);}};var P=class extends m{async sitemap(e){return this.getText("/sitemap.xml",e)}async sitemapPart(e,t){return this.getText(`/sitemap-${e}.xml`,t)}async robots(e){return this.getText("/robots.txt",e)}async llmsTxt(e){let t=e?.locale,n=t?`/${t}/llms.txt`:"/llms.txt";return this.getText(n,e)}async llmsFullTxt(e){let t=e?.locale,n=t?`/${t}/llms-full.txt`:"/llms-full.txt";return this.getText(n,e)}async getMarkdown(e,t){let n=e.startsWith("/")?e:`/${e}`;return this.getText(`${n}.md`,t)}};var J="paths_",B=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${J}list_${t||"all"}`;return this.getWithCache(n,"/paths",void 0,e,d.SHORT)}async resolve(e,t){let n=t?.locale||this.config.locale,r=`${J}resolve_${e}_${n||"default"}`;return this.getWithCache(r,"/resolve",{path:e},t,d.SHORT)}async matchRedirect(e,t){try{return (await this.get("/redirects/match",{path:e},t)).data}catch(n){if(n instanceof C&&n.status===404)return null;throw n}}clearCache(){this.invalidateCache(J);}};var c=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",we=!c;function be(s,e){return c?s():e}async function Re(s,e){return c?s():e}var X="lynkow-tracker",D=class{config;enabled=true;initialized=false;loading=false;loadPromise=null;constructor(e){this.config=e;}getTrackerUrl(){return `${this.config.baseUrl}/analytics/tracker.js`}loadTracker(){return !c||window.LynkowAnalytics?Promise.resolve():this.loadPromise?this.loadPromise:(this.loading=true,this.loadPromise=new Promise((e,t)=>{if(document.getElementById(X)){let r=setInterval(()=>{window.LynkowAnalytics&&(clearInterval(r),this.loading=false,e());},50);setTimeout(()=>{clearInterval(r),this.loading=false,t(new Error("Tracker script load timeout"));},1e4);return}let n=document.createElement("script");n.id=X,n.src=this.getTrackerUrl(),n.async=true,n.setAttribute("data-site-id",this.config.siteId),this.config.baseUrl&&n.setAttribute("data-api-url",this.config.baseUrl);try{let r=localStorage.getItem("_lkw_consent_mode");r&&n.setAttribute("data-consent-mode",r);}catch{}n.onload=()=>{this.loading=false,setTimeout(()=>{window.LynkowAnalytics?e():t(new Error("Tracker script loaded but LynkowAnalytics not found"));},0);},n.onerror=()=>{this.loading=false,t(new Error("Failed to load tracker script"));},document.head.appendChild(n);}),this.loadPromise)}async init(){if(!(!c||this.initialized))try{await this.loadTracker(),window.LynkowAnalytics&&!this.initialized&&(this.initialized=!0);}catch(e){console.error("[Lynkow] Failed to initialize analytics:",e);}}async trackEvent(e){!c||!this.enabled||(await this.init(),window.LynkowAnalytics&&window.LynkowAnalytics.track(e));}async trackPageview(e){!c||!this.enabled||(await this.init(),window.LynkowAnalytics&&window.LynkowAnalytics.track({type:"pageview",path:e?.path||window.location.pathname,title:e?.title||document.title,referrer:e?.referrer||document.referrer}));}enable(){this.enabled=true;}disable(){this.enabled=false;}isEnabled(){return this.enabled}isInitialized(){return this.initialized&&!!window.LynkowAnalytics}getTracker(){if(c)return window.LynkowAnalytics}destroy(){if(!c)return;document.getElementById(X)?.remove(),this.initialized=false,this.loadPromise=null;}};function Ee(s){let e=s.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)/);if(!e||(e[4]!==void 0?parseFloat(e[4]):1)===0)return null;let n=parseInt(e[1],10),r=parseInt(e[2],10),o=parseInt(e[3],10);return (.299*n+.587*r+.114*o)/255}function w(){if(!c)return "light";let s=document.documentElement,e=document.body;for(let t of [s,e])for(let n of ["data-theme","data-mode","data-color-scheme"]){let r=t.getAttribute(n)?.toLowerCase();if(r){if(r.includes("dark"))return "dark";if(r.includes("light"))return "light"}}if(s.classList.contains("dark")||e.classList.contains("dark"))return "dark";try{let t=getComputedStyle(s).colorScheme;if(t){let n=t.toLowerCase().trim();if(n.startsWith("dark"))return "dark";if(n.startsWith("light"))return "light"}}catch{}try{let t=getComputedStyle(e).backgroundColor,n=Ee(t);if(n!==null)return n<.5?"dark":"light"}catch{}try{if(window.matchMedia("(prefers-color-scheme: dark)").matches)return "dark"}catch{}return "light"}function $(s){if(!c)return ()=>{};let e=w(),t=[],n=()=>{let i=w();i!==e&&(e=i,s(i));},r=new MutationObserver(n),o={attributes:true,attributeFilter:["data-theme","data-mode","data-color-scheme","class","style"]};r.observe(document.documentElement,o),r.observe(document.body,o),t.push(()=>r.disconnect());try{let i=window.matchMedia("(prefers-color-scheme: dark)"),a=()=>n();i.addEventListener("change",a),t.push(()=>i.removeEventListener("change",a));}catch{}return ()=>t.forEach(i=>i())}var j="_lkw_consent",ke=365*24*60*60*1e3,ce="lkw-script-",Y={necessary:true,analytics:false,marketing:false,preferences:false},q=class{config;events;bannerElement=null;preferencesElement=null;configCache=null;injectedScriptIds=new Set;themeCleanup=null;constructor(e,t){this.config=e,this.events=t;}async getConfig(){if(this.configCache)return this.configCache;let e=`${this.config.baseUrl}/public/${this.config.siteId}/cookie-consent/config`,t=await fetch(e,{method:"GET",headers:{"Content-Type":"application/json"},...this.config.fetchOptions});if(!t.ok)throw new Error(`Failed to fetch consent config: ${t.status}`);let n=await t.json();return this.configCache=n.data,this.configCache}async logConsent(e,t){let n=`${this.config.baseUrl}/public/${this.config.siteId}/cookie-consent/log`;await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visitorId:this.getOrCreateVisitorId(),action:t||this.inferAction(e),consentGiven:e,pageUrl:c?window.location.href:void 0}),...this.config.fetchOptions}).catch(()=>{});}getOrCreateVisitorId(){if(!c)return "server";let e="_lkw_vid";try{let t=localStorage.getItem(e);return t||(t=crypto.randomUUID(),localStorage.setItem(e,t)),t}catch{return crypto.randomUUID()}}inferAction(e){let t=Object.entries(e).filter(([o])=>o!=="necessary"),n=t.every(([,o])=>o===true),r=t.every(([,o])=>o===false);return n?"accept_all":r?"reject_all":"customize"}getStoredConsent(){if(!c)return null;try{let e=localStorage.getItem(j);if(e){let t=JSON.parse(e);return t.choices?t.timestamp&&Date.now()-t.timestamp>ke?(localStorage.removeItem(j),null):t.choices:t}}catch{}return null}saveConsent(e){if(c){try{localStorage.setItem(j,JSON.stringify({choices:e,timestamp:Date.now()}));}catch{}this.events.emit("consent-changed",e),document.dispatchEvent(new CustomEvent("lynkow:consent:update",{detail:e}));}}show(){c&&this.getConfig().then(e=>{if(!e.enabled)return;try{e.consentMode&&localStorage.setItem("_lkw_consent_mode",e.consentMode);}catch{}let t=this.getStoredConsent();if(t){this.activateScripts(t);return}if(this.bannerElement)return;let n=document.createElement("div");n.innerHTML=this.createBannerHTML(e),this.bannerElement=n.firstElementChild,document.body.appendChild(this.bannerElement),this.attachBannerEvents(),e.theme==="auto"&&!this.themeCleanup&&(this.themeCleanup=$(r=>{this.updateConsentTheme(r);}));});}hide(){c&&(this.bannerElement?.remove(),this.bannerElement=null,this.cleanupThemeObserverIfIdle());}showPreferences(){c&&(this.preferencesElement||this.getConfig().then(e=>{let t=this.getCategories(),n=document.createElement("div");n.innerHTML=this.createPreferencesHTML(e,t),this.preferencesElement=n.firstElementChild,document.body.appendChild(this.preferencesElement),this.attachPreferencesEvents(e),e.theme==="auto"&&!this.themeCleanup&&(this.themeCleanup=$(r=>{this.updateConsentTheme(r);}));}));}getCategories(){return c?this.getStoredConsent()||{...Y}:{...Y}}hasConsented(){return c?this.getStoredConsent()!==null:false}acceptAll(){if(!c)return;let e={necessary:true,analytics:true,marketing:true,preferences:true};this.saveConsent(e),this.logConsent(e,"accept_all"),this.activateScripts(e),this.hide();}rejectAll(){if(!c)return;let e={necessary:true,analytics:false,marketing:false,preferences:false};this.saveConsent(e),this.logConsent(e,"reject_all"),this.hide();}setCategories(e){if(!c)return;let n={...this.getCategories(),...e,necessary:true};this.saveConsent(n),this.logConsent(n,"customize"),this.activateScripts(n);}reset(){if(c){this.removeInjectedScripts();try{localStorage.removeItem(j);}catch{}this.events.emit("consent-changed",{...Y}),this.show();}}activateScripts(e){if(this.configCache?.thirdPartyScripts?.length)for(let[t,n]of Object.entries(e))n&&this.injectScriptsForCategory(t,this.configCache.thirdPartyScripts);}injectScriptsForCategory(e,t){for(let n of t){if(n.category!==e||this.injectedScriptIds.has(n.id))continue;this.injectedScriptIds.add(n.id);let r=document.createElement("div");r.innerHTML=n.script;let o=Array.from(r.children);for(let i=0;i<o.length;i++){let a=o[i],p=`${ce}${n.id}-${i}`;if(a.tagName==="SCRIPT"){let g=document.createElement("script");for(let u of Array.from(a.attributes))g.setAttribute(u.name,u.value);a.textContent&&(g.textContent=a.textContent),g.id=p,document.head.appendChild(g);}else a.id=p,document.body.appendChild(a);}}}removeInjectedScripts(){for(let e of this.injectedScriptIds){let t=0,n;for(;n=document.getElementById(`${ce}${e}-${t}`);)n.remove(),t++;}this.injectedScriptIds.clear();}cleanupThemeObserverIfIdle(){!this.bannerElement&&!this.preferencesElement&&(this.themeCleanup?.(),this.themeCleanup=null);}updateConsentTheme(e){let t=this.configCache?this.resolveColors(this.configCache,e):{bgColor:e==="dark"?"#18181b":"#ffffff",textColor:e==="dark"?"#f4f4f5":"#1a1a1a"},{bgColor:n,textColor:r}=t;if(this.bannerElement&&(this.bannerElement.style.background=n,this.bannerElement.style.color=r),this.preferencesElement){let o=this.preferencesElement.querySelector(":scope > div");o&&(o.style.background=n,o.style.color=r);}}resolveTheme(e){return e==="auto"?w():e==="dark"?"dark":"light"}resolveColors(e,t){if(e.themeStyles?.[t])return e.themeStyles[t];let n=t==="dark";return {primaryColor:e.primaryColor||"#0066cc",bgColor:n?"#18181b":"#ffffff",textColor:n?"#f4f4f5":"#1a1a1a"}}contrastColor(e){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return (.299*t+.587*n+.114*r)/255>.5?"#000000":"#ffffff"}createBannerHTML(e){let t=e.position||"bottom-right",n=e.theme||"light",r=e.borderRadius??8,o=e.fontSize??13,i={"bottom-left":`bottom: 20px; left: 20px; max-width: 580px; border-radius: ${r}px;`,"bottom-right":`bottom: 20px; right: 20px; max-width: 580px; border-radius: ${r}px;`},a=i[t]||i["bottom-right"],p=this.resolveTheme(n),g=this.resolveColors(e,p),{primaryColor:u,bgColor:l,textColor:f}=g,h=e.texts||{description:"Ce site utilise des cookies pour ameliorer votre experience.",acceptAll:"Accepter tout",rejectAll:"Refuser",customize:"Personnaliser"};return `
|
|
1
|
+
'use strict';var C=class s extends Error{name="LynkowError";code;status;details;cause;constructor(e,t,n,r,o){super(e),this.code=t,this.status=n,this.details=r,this.cause=o,Error.captureStackTrace&&Error.captureStackTrace(this,s);}static async fromResponse(e){let t=e.status,n=`HTTP ${t}`,r;try{let i=await e.json();i.errors&&Array.isArray(i.errors)?(r=i.errors,n=i.errors[0]?.message||n):i.error?n=i.error:i.message&&(n=i.message);}catch{n=e.statusText||n;}let o=s.statusToCode(t);return new s(n,o,t,r)}static fromNetworkError(e){return e.name==="AbortError"?new s("Request timed out","TIMEOUT",void 0,void 0,e):e.name==="TypeError"?new s("Network error - please check your connection","NETWORK_ERROR",void 0,void 0,e):new s(e.message||"Unknown error","UNKNOWN",void 0,void 0,e)}static statusToCode(e){switch(e){case 400:return "VALIDATION_ERROR";case 401:return "UNAUTHORIZED";case 403:return "FORBIDDEN";case 404:return "NOT_FOUND";case 429:return "RATE_LIMITED";default:return "UNKNOWN"}}toJSON(){return {name:this.name,message:this.message,code:this.code,status:this.status,details:this.details}}};function Ce(s){return s instanceof C}function ve(s){switch(s){case 400:return "BAD_REQUEST";case 401:return "UNAUTHORIZED";case 403:return "FORBIDDEN";case 404:return "NOT_FOUND";case 422:return "VALIDATION_ERROR";case 429:return "TOO_MANY_REQUESTS";case 503:return "SERVICE_UNAVAILABLE";default:return "INTERNAL_ERROR"}}async function z(s,e){let t;try{t=await fetch(s,e);}catch(a){throw new C("Network error: Unable to reach the server","NETWORK_ERROR",0,[{message:a instanceof Error?a.message:"Unknown error"}])}if(t.ok)return t.json();let n={};try{n=await t.json();}catch{}let r=ve(t.status),o=n.error||n.message||`HTTP error: ${t.status}`,i=n.errors||[{message:o}];throw new C(o,r,t.status,i)}function re(s){let e=new URLSearchParams;for(let[t,n]of Object.entries(s))n!=null&&n!==""&&e.append(t,String(n));return e.toString()}var d={SHORT:300*1e3,MEDIUM:600*1e3,LONG:1800*1e3},m=class{config;cache;constructor(e){this.config=e,this.cache=e.cache;}buildEndpointUrl(e,t){let n=`${this.config.baseUrl}/public/${this.config.siteId}${e}`;if(t&&Object.keys(t).length>0){let r=re(t);return `${n}?${r}`}return n}async get(e,t,n){let r=n?.locale||this.config.locale,o=r?{...t,locale:r}:t,i=this.buildEndpointUrl(e,o),a=this.mergeFetchOptions(n?.fetchOptions);return z(i,{method:"GET",...a})}async getWithCache(e,t,n,r,o=d.SHORT){return this.cache?this.cache.getOrSet(e,()=>this.get(t,n,r),o):this.get(t,n,r)}invalidateCache(e){this.cache?.invalidate(e);}async post(e,t,n){let r=this.buildEndpointUrl(e),o=this.mergeFetchOptions(n?.fetchOptions);return z(r,{method:"POST",...o,headers:{"Content-Type":"application/json",...o.headers},body:JSON.stringify(t)})}async getText(e,t){let n=this.buildEndpointUrl(e),r=this.mergeFetchOptions(t?.fetchOptions),o=await fetch(n,{method:"GET",...r});if(!o.ok)throw new Error(`HTTP error: ${o.status}`);return o.text()}mergeFetchOptions(e){return {...this.config.fetchOptions,...e,headers:{...this.config.fetchOptions.headers,...e?.headers}}}};var W="contents_",b=class extends m{async list(e,t){let n={};e?.page&&(n.page=e.page),(e?.limit??e?.perPage)&&(n.limit=e?.limit??e?.perPage),e?.category&&(n.category=e.category),e?.tag&&(n.tag=e.tag),e?.search&&(n.search=e.search),e?.sort&&(n.sort=e.sort),e?.order&&(n.order=e.order),e?.locale&&(n.locale=e.locale);let r=`${W}list_${JSON.stringify(e||{})}`;return this.getWithCache(r,"/contents",n,t,d.SHORT)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${W}slug_${e}_${n||"default"}`;return this.getWithCache(r,`/contents/slug/${encodeURIComponent(e)}`,void 0,t,d.SHORT)}clearCache(){this.invalidateCache(W);}};var U="categories_",R=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${U}list_${t||"default"}`;return this.getWithCache(n,"/categories",void 0,e,d.SHORT)}async tree(e){let t=e?.locale||this.config.locale,n=`${U}tree_${t||"default"}`;return this.getWithCache(n,"/categories/tree",void 0,e,d.SHORT)}async getBySlug(e,t){let n={};t?.page&&(n.page=t.page),(t?.limit??t?.perPage)&&(n.limit=t?.limit??t?.perPage);let r=`${U}slug_${e}_${JSON.stringify(t||{})}`;return this.getWithCache(r,`/categories/${encodeURIComponent(e)}`,n,t,d.SHORT)}clearCache(){this.invalidateCache(U);}};var oe="tags_",E=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${oe}list_${t||"default"}`;return this.getWithCache(n,"/tags",void 0,e,d.SHORT)}clearCache(){this.invalidateCache(oe);}};var _="pages_",k=class extends m{async list(e){let t=e?.locale||this.config.locale,n={};e?.tag&&(n.tag=e.tag);let r=`${_}list_${t||"default"}_${e?.tag||"all"}`;return this.getWithCache(r,"/pages",n,e,d.SHORT)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${_}slug_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}`,void 0,t,d.SHORT)).data}async getByPath(e,t){let n=t?.locale||this.config.locale,r=`${_}path_${e}_${n||"default"}`;return (await this.getWithCache(r,"/page-by-path",{path:e},t,d.SHORT)).data}async getJsonLd(e,t){let n=t?.locale||this.config.locale,r=`${_}jsonld_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}/json-ld`,void 0,t,d.SHORT)).data}clearCache(){this.invalidateCache(_);}};var G="globals_",x=class extends m{async siteConfig(e){let t=e?.locale||this.config.locale,n=`${G}siteconfig_${t||"default"}`;return this.getWithCache(n,"/site-config",void 0,e,d.MEDIUM)}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${G}${e}_${n||"default"}`;return this.getWithCache(r,`/global/${encodeURIComponent(e)}`,void 0,t,d.MEDIUM)}async global(e,t){return this.getBySlug(e,t)}clearCache(){this.invalidateCache(G);}};function K(s){return {_hp:"",_ts:s}}var se="forms_",S=class extends m{sessionStartTime;constructor(e){super(e),this.sessionStartTime=Date.now();}async getBySlug(e){let t=`${se}${e}`;return (await this.getWithCache(t,`/forms/${encodeURIComponent(e)}`,void 0,void 0,d.MEDIUM)).data}async submit(e,t,n){let r=K(this.sessionStartTime),o={data:t,honeypot:r._hp,...r};return n?.recaptchaToken&&(o.recaptchaToken=n.recaptchaToken),this.post(`/forms/${encodeURIComponent(e)}/submit`,o,n)}clearCache(){this.invalidateCache(se);}};var F="reviews_",T=class extends m{sessionStartTime;constructor(e){super(e),this.sessionStartTime=Date.now();}async list(e,t){let n={};e?.page&&(n.page=e.page),(e?.limit??e?.perPage)&&(n.limit=e?.limit??e?.perPage),e?.minRating&&(n.minRating=e.minRating),e?.maxRating&&(n.maxRating=e.maxRating),e?.sort&&(n.sort=e.sort),e?.order&&(n.order=e.order);let r=`${F}list_${JSON.stringify(e||{})}`;return this.getWithCache(r,"/reviews",n,t,d.SHORT)}async getBySlug(e){let t=`${F}slug_${e}`;return (await this.getWithCache(t,`/reviews/${encodeURIComponent(e)}`,void 0,void 0,d.SHORT)).data}async settings(){let e=`${F}settings`;return this.getWithCache(e,"/reviews/settings",void 0,void 0,d.MEDIUM)}async submit(e,t){let n=K(this.sessionStartTime),r={...e,...n};t?.recaptchaToken&&(r._recaptcha_token=t.recaptchaToken);let o=await this.post("/reviews",r,t);return this.invalidateCache(F),o}clearCache(){this.invalidateCache(F);}};var ie="site_",L=class extends m{async getConfig(){let e=`${ie}config`;return (await this.getWithCache(e,"/site",void 0,void 0,d.MEDIUM)).data}clearCache(){this.invalidateCache(ie);}};var J="legal_",O=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${J}list_${t||"default"}`;return (await this.getWithCache(n,"/pages",{tag:"legal"},e,d.SHORT)).data}async getBySlug(e,t){let n=t?.locale||this.config.locale,r=`${J}slug_${e}_${n||"default"}`;return (await this.getWithCache(r,`/pages/${encodeURIComponent(e)}`,void 0,t,d.SHORT)).data}clearCache(){this.invalidateCache(J);}};var ae="cookies_",I=class extends m{async getConfig(){let e=`${ae}config`;return (await this.getWithCache(e,"/cookie-consent/config",void 0,void 0,d.MEDIUM)).data}async logConsent(e,t){return this.post("/cookie-consent/log",{preferences:e},t)}clearCache(){this.invalidateCache(ae);}};var P=class extends m{async sitemap(e){return this.getText("/sitemap.xml",e)}async sitemapPart(e,t){return this.getText(`/sitemap-${e}.xml`,t)}async robots(e){return this.getText("/robots.txt",e)}async llmsTxt(e){let t=e?.locale,n=t?`/${t}/llms.txt`:"/llms.txt";return this.getText(n,e)}async llmsFullTxt(e){let t=e?.locale,n=t?`/${t}/llms-full.txt`:"/llms-full.txt";return this.getText(n,e)}async getMarkdown(e,t){let n=e.startsWith("/")?e:`/${e}`;return this.getText(`${n}.md`,t)}};var V="paths_",B=class extends m{async list(e){let t=e?.locale||this.config.locale,n=`${V}list_${t||"all"}`;return this.getWithCache(n,"/paths",void 0,e,d.SHORT)}async resolve(e,t){let n=t?.locale||this.config.locale,r=`${V}resolve_${e}_${n||"default"}`;return this.getWithCache(r,"/resolve",{path:e},t,d.SHORT)}async matchRedirect(e,t){try{return (await this.get("/redirects/match",{path:e},t)).data}catch(n){if(n instanceof C&&n.status===404)return null;throw n}}clearCache(){this.invalidateCache(V);}};var c=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",we=!c;function be(s,e){return c?s():e}async function Re(s,e){return c?s():e}var X="lynkow-tracker",D=class{config;enabled=true;initialized=false;loading=false;loadPromise=null;constructor(e){this.config=e;}getTrackerUrl(){return `${this.config.baseUrl}/analytics/tracker.js`}loadTracker(){return !c||window.LynkowAnalytics?Promise.resolve():this.loadPromise?this.loadPromise:(this.loading=true,this.loadPromise=new Promise((e,t)=>{if(document.getElementById(X)){let r=setInterval(()=>{window.LynkowAnalytics&&(clearInterval(r),this.loading=false,e());},50);setTimeout(()=>{clearInterval(r),this.loading=false,t(new Error("Tracker script load timeout"));},1e4);return}let n=document.createElement("script");n.id=X,n.src=this.getTrackerUrl(),n.async=true,n.setAttribute("data-site-id",this.config.siteId),this.config.baseUrl&&n.setAttribute("data-api-url",this.config.baseUrl);try{let r=localStorage.getItem("_lkw_consent_mode");r&&n.setAttribute("data-consent-mode",r);}catch{}n.onload=()=>{this.loading=false,setTimeout(()=>{window.LynkowAnalytics?e():t(new Error("Tracker script loaded but LynkowAnalytics not found"));},0);},n.onerror=()=>{this.loading=false,t(new Error("Failed to load tracker script"));},document.head.appendChild(n);}),this.loadPromise)}async init(){if(!(!c||this.initialized))try{await this.loadTracker(),window.LynkowAnalytics&&!this.initialized&&(this.initialized=!0);}catch(e){console.error("[Lynkow] Failed to initialize analytics:",e);}}async trackEvent(e){!c||!this.enabled||(await this.init(),window.LynkowAnalytics&&window.LynkowAnalytics.track(e));}async trackPageview(e){!c||!this.enabled||(await this.init(),window.LynkowAnalytics&&window.LynkowAnalytics.track({type:"pageview",path:e?.path||window.location.pathname,title:e?.title||document.title,referrer:e?.referrer||document.referrer}));}enable(){this.enabled=true;}disable(){this.enabled=false;}isEnabled(){return this.enabled}isInitialized(){return this.initialized&&!!window.LynkowAnalytics}getTracker(){if(c)return window.LynkowAnalytics}destroy(){if(!c)return;document.getElementById(X)?.remove(),this.initialized=false,this.loadPromise=null;}};function Ee(s){let e=s.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)/);if(!e||(e[4]!==void 0?parseFloat(e[4]):1)===0)return null;let n=parseInt(e[1],10),r=parseInt(e[2],10),o=parseInt(e[3],10);return (.299*n+.587*r+.114*o)/255}function w(){if(!c)return "light";let s=document.documentElement,e=document.body;for(let t of [s,e])for(let n of ["data-theme","data-mode","data-color-scheme"]){let r=t.getAttribute(n)?.toLowerCase();if(r){if(r.includes("dark"))return "dark";if(r.includes("light"))return "light"}}if(s.classList.contains("dark")||e.classList.contains("dark"))return "dark";try{let t=getComputedStyle(s).colorScheme;if(t){let n=t.toLowerCase().trim();if(n.startsWith("dark"))return "dark";if(n.startsWith("light"))return "light"}}catch{}try{let t=getComputedStyle(e).backgroundColor,n=Ee(t);if(n!==null)return n<.5?"dark":"light"}catch{}try{if(window.matchMedia("(prefers-color-scheme: dark)").matches)return "dark"}catch{}return "light"}function $(s){if(!c)return ()=>{};let e=w(),t=[],n=()=>{let i=w();i!==e&&(e=i,s(i));},r=new MutationObserver(n),o={attributes:true,attributeFilter:["data-theme","data-mode","data-color-scheme","class","style"]};r.observe(document.documentElement,o),r.observe(document.body,o),t.push(()=>r.disconnect());try{let i=window.matchMedia("(prefers-color-scheme: dark)"),a=()=>n();i.addEventListener("change",a),t.push(()=>i.removeEventListener("change",a));}catch{}return ()=>t.forEach(i=>i())}var j="_lkw_consent",ke=365*24*60*60*1e3,ce="lkw-script-",Y={necessary:true,analytics:false,marketing:false,preferences:false},q=class{config;events;bannerElement=null;preferencesElement=null;configCache=null;injectedScriptIds=new Set;themeCleanup=null;constructor(e,t){this.config=e,this.events=t;}async getConfig(){if(this.configCache)return this.configCache;let e=`${this.config.baseUrl}/public/${this.config.siteId}/cookie-consent/config`,t=await fetch(e,{method:"GET",headers:{"Content-Type":"application/json"},...this.config.fetchOptions});if(!t.ok)throw new Error(`Failed to fetch consent config: ${t.status}`);let n=await t.json();return this.configCache=n.data,this.configCache}async logConsent(e,t){let n=`${this.config.baseUrl}/public/${this.config.siteId}/cookie-consent/log`;await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visitorId:this.getOrCreateVisitorId(),action:t||this.inferAction(e),consentGiven:e,pageUrl:c?window.location.href:void 0}),...this.config.fetchOptions}).catch(()=>{});}getOrCreateVisitorId(){if(!c)return "server";let e="_lkw_vid";try{let t=localStorage.getItem(e);return t||(t=crypto.randomUUID(),localStorage.setItem(e,t)),t}catch{return crypto.randomUUID()}}inferAction(e){let t=Object.entries(e).filter(([o])=>o!=="necessary"),n=t.every(([,o])=>o===true),r=t.every(([,o])=>o===false);return n?"accept_all":r?"reject_all":"customize"}getStoredConsent(){if(!c)return null;try{let e=localStorage.getItem(j);if(e){let t=JSON.parse(e);return t.choices?t.timestamp&&Date.now()-t.timestamp>ke?(localStorage.removeItem(j),null):t.choices:t}}catch{}return null}saveConsent(e){if(c){try{localStorage.setItem(j,JSON.stringify({choices:e,timestamp:Date.now()}));}catch{}this.events.emit("consent-changed",e),document.dispatchEvent(new CustomEvent("lynkow:consent:update",{detail:e}));}}show(){c&&this.getConfig().then(e=>{if(!e.enabled)return;try{e.consentMode&&localStorage.setItem("_lkw_consent_mode",e.consentMode);}catch{}let t=this.getStoredConsent();if(t){this.activateScripts(t);return}if(this.bannerElement)return;let n=document.createElement("div");n.innerHTML=this.createBannerHTML(e),this.bannerElement=n.firstElementChild,document.body.appendChild(this.bannerElement),this.attachBannerEvents(),e.theme==="auto"&&!this.themeCleanup&&(this.themeCleanup=$(r=>{this.updateConsentTheme(r);}));});}hide(){c&&(this.bannerElement?.remove(),this.bannerElement=null,this.cleanupThemeObserverIfIdle());}showPreferences(){c&&(this.preferencesElement||this.getConfig().then(e=>{let t=this.getCategories(),n=document.createElement("div");n.innerHTML=this.createPreferencesHTML(e,t),this.preferencesElement=n.firstElementChild,document.body.appendChild(this.preferencesElement),this.attachPreferencesEvents(e),e.theme==="auto"&&!this.themeCleanup&&(this.themeCleanup=$(r=>{this.updateConsentTheme(r);}));}));}getCategories(){return c?this.getStoredConsent()||{...Y}:{...Y}}hasConsented(){return c?this.getStoredConsent()!==null:false}acceptAll(){if(!c)return;let e={necessary:true,analytics:true,marketing:true,preferences:true};this.saveConsent(e),this.logConsent(e,"accept_all"),this.activateScripts(e),this.hide();}rejectAll(){if(!c)return;let e={necessary:true,analytics:false,marketing:false,preferences:false};this.saveConsent(e),this.logConsent(e,"reject_all"),this.hide();}setCategories(e){if(!c)return;let n={...this.getCategories(),...e,necessary:true};this.saveConsent(n),this.logConsent(n,"customize"),this.activateScripts(n);}reset(){if(c){this.removeInjectedScripts();try{localStorage.removeItem(j);}catch{}this.events.emit("consent-changed",{...Y}),this.show();}}activateScripts(e){if(this.configCache?.thirdPartyScripts?.length)for(let[t,n]of Object.entries(e))n&&this.injectScriptsForCategory(t,this.configCache.thirdPartyScripts);}injectScriptsForCategory(e,t){for(let n of t){if(n.category!==e||this.injectedScriptIds.has(n.id))continue;this.injectedScriptIds.add(n.id);let r=document.createElement("div");r.innerHTML=n.script;let o=Array.from(r.children);for(let i=0;i<o.length;i++){let a=o[i],p=`${ce}${n.id}-${i}`;if(a.tagName==="SCRIPT"){let g=document.createElement("script");for(let u of Array.from(a.attributes))g.setAttribute(u.name,u.value);a.textContent&&(g.textContent=a.textContent),g.id=p,document.head.appendChild(g);}else a.id=p,document.body.appendChild(a);}}}removeInjectedScripts(){for(let e of this.injectedScriptIds){let t=0,n;for(;n=document.getElementById(`${ce}${e}-${t}`);)n.remove(),t++;}this.injectedScriptIds.clear();}cleanupThemeObserverIfIdle(){!this.bannerElement&&!this.preferencesElement&&(this.themeCleanup?.(),this.themeCleanup=null);}updateConsentTheme(e){let t=this.configCache?this.resolveColors(this.configCache,e):{bgColor:e==="dark"?"#18181b":"#ffffff",textColor:e==="dark"?"#f4f4f5":"#1a1a1a"},{bgColor:n,textColor:r}=t;if(this.bannerElement&&(this.bannerElement.style.background=n,this.bannerElement.style.color=r),this.preferencesElement){let o=this.preferencesElement.querySelector(":scope > div");o&&(o.style.background=n,o.style.color=r);}}resolveTheme(e){return e==="auto"?w():e==="dark"?"dark":"light"}resolveColors(e,t){if(e.themeStyles?.[t])return e.themeStyles[t];let n=t==="dark";return {primaryColor:e.primaryColor||"#0066cc",bgColor:n?"#18181b":"#ffffff",textColor:n?"#f4f4f5":"#1a1a1a"}}contrastColor(e){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return (.299*t+.587*n+.114*r)/255>.5?"#000000":"#ffffff"}createBannerHTML(e){let t=e.position||"bottom-right",n=e.theme||"light",r=e.borderRadius??8,o=e.fontSize??13,i={"bottom-left":`bottom: 20px; left: 20px; max-width: 580px; border-radius: ${r}px;`,"bottom-right":`bottom: 20px; right: 20px; max-width: 580px; border-radius: ${r}px;`},a=i[t]||i["bottom-right"],p=this.resolveTheme(n),g=this.resolveColors(e,p),{primaryColor:u,bgColor:l,textColor:f}=g,h=e.texts||{description:"Ce site utilise des cookies pour ameliorer votre experience.",acceptAll:"Accepter tout",rejectAll:"Refuser",customize:"Personnaliser"};return `
|
|
2
2
|
<div id="lynkow-consent-banner" style="
|
|
3
3
|
position: fixed;
|
|
4
4
|
${a}
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
</form>
|
|
117
117
|
</div>
|
|
118
118
|
</div>
|
|
119
|
-
`}attachBannerEvents(){let e=document.getElementById("lynkow-consent-accept"),t=document.getElementById("lynkow-consent-reject"),n=document.getElementById("lynkow-consent-preferences");e?.addEventListener("click",()=>{this.acceptAll();}),t?.addEventListener("click",()=>{this.rejectAll();}),n?.addEventListener("click",()=>{this.showPreferences();});}attachPreferencesEvents(e){let t=document.getElementById("lynkow-consent-form"),n=document.getElementById("lynkow-consent-close"),r=document.getElementById("lynkow-consent-preferences-modal");t?.addEventListener("submit",o=>{o.preventDefault();let i=new FormData(t),a={necessary:true,analytics:i.has("analytics"),marketing:i.has("marketing"),preferences:i.has("preferences")};this.setCategories(a),this.hide(),this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle();}),n?.addEventListener("click",()=>{this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle();}),r?.addEventListener("click",o=>{o.target===r&&(this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle());});}destroy(){this.themeCleanup?.(),this.themeCleanup=null,this.hide(),this.preferencesElement?.remove(),this.preferencesElement=null,this.removeInjectedScripts();}};var Q="lynkow-badge-container",Z="lynkow-badge-styles",
|
|
119
|
+
`}attachBannerEvents(){let e=document.getElementById("lynkow-consent-accept"),t=document.getElementById("lynkow-consent-reject"),n=document.getElementById("lynkow-consent-preferences");e?.addEventListener("click",()=>{this.acceptAll();}),t?.addEventListener("click",()=>{this.rejectAll();}),n?.addEventListener("click",()=>{this.showPreferences();});}attachPreferencesEvents(e){let t=document.getElementById("lynkow-consent-form"),n=document.getElementById("lynkow-consent-close"),r=document.getElementById("lynkow-consent-preferences-modal");t?.addEventListener("submit",o=>{o.preventDefault();let i=new FormData(t),a={necessary:true,analytics:i.has("analytics"),marketing:i.has("marketing"),preferences:i.has("preferences")};this.setCategories(a),this.hide(),this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle();}),n?.addEventListener("click",()=>{this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle();}),r?.addEventListener("click",o=>{o.target===r&&(this.preferencesElement?.remove(),this.preferencesElement=null,this.cleanupThemeObserverIfIdle());});}destroy(){this.themeCleanup?.(),this.themeCleanup=null,this.hide(),this.preferencesElement?.remove(),this.preferencesElement=null,this.removeInjectedScripts();}};var Q="lynkow-badge-container",Z="lynkow-badge-styles",N=class extends m{containerElement=null;themeCleanup=null;async inject(){if(c&&!document.getElementById(Q))try{let{data:e}=await this.getWithCache("branding:badge","/branding/badge",void 0,void 0,d.LONG);if(!document.getElementById(Z)){let n=document.createElement("style");n.id=Z,n.textContent=e.css,document.head.appendChild(n);}let t=document.createElement("div");t.id=Q,t.innerHTML=e.html,w()==="light"&&t.classList.add("lynkow-badge-light"),document.body.appendChild(t),this.containerElement=t,this.themeCleanup=$(n=>{this.containerElement&&this.containerElement.classList.toggle("lynkow-badge-light",n==="light");});}catch{}}remove(){c&&(this.themeCleanup?.(),this.themeCleanup=null,this.containerElement?.remove(),this.containerElement=null,document.getElementById(Z)?.remove());}isVisible(){return c?document.getElementById(Q)!==null:false}destroy(){this.remove();}};var ee="lynkow-enhancements-styles",te="data-lynkow-clone",xe=new Set(["","module","text/plain","text/javascript","application/javascript","application/ecmascript","text/ecmascript","application/x-javascript","application/x-ecmascript"]),Se='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>',Te='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',Le=`
|
|
120
120
|
/*
|
|
121
121
|
* Lynkow Content Enhancements
|
|
122
122
|
* These styles ensure that content from the Lynkow API is displayed correctly,
|
|
@@ -232,6 +232,6 @@
|
|
|
232
232
|
color: #1a1a1a;
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
-
`,
|
|
236
|
-
exports.AnalyticsService=D;exports.BlocksService=x;exports.BrandingService=
|
|
235
|
+
`,H=class{initialized=false;observer=null;pendingFrame=null;handleWidgetResize=e=>{if(!e.data||e.data.type!=="lynkow-widget-resize")return;document.querySelectorAll('iframe[src*="/widgets/calendar/"]').forEach(n=>{n.contentWindow===e.source&&(n.style.height=e.data.height+"px");});};injectStyles(){if(!c||document.getElementById(ee))return;let e=document.createElement("style");e.id=ee,e.textContent=Le,document.head.appendChild(e);}async handleCopyClick(e){let t=e.closest(".code-block");if(!t)return;let n=t.querySelector("code");if(!n)return;let r=n.textContent||"";try{await navigator.clipboard.writeText(r),e.classList.add("copied"),e.innerHTML=Te,setTimeout(()=>{e.classList.remove("copied"),e.innerHTML=Se;},2e3);}catch(o){console.error("Lynkow SDK: Failed to copy code",o);}}bindCodeBlockCopy(){if(!c)return;document.querySelectorAll("[data-copy-code]").forEach(t=>{t.dataset.lynkowBound||(t.dataset.lynkowBound="true",t.addEventListener("click",n=>{n.preventDefault(),this.handleCopyClick(t);}));});}activateScripts(e){if(!c)return;let n=(e instanceof HTMLElement?e:document.body).querySelectorAll("script:not([data-lynkow-activated])"),r=Array.from(n).filter(o=>!o.src&&o.isConnected&&xe.has(o.type.toLowerCase()));r.length!==0&&(document.head.querySelectorAll(`script[${te}]`).forEach(o=>o.remove()),r.forEach(o=>{o.setAttribute("data-lynkow-activated","true");let i=document.createElement("script"),a=o.attributes;for(let p=0;p<a.length;p++){let g=a[p];g&&(g.name==="type"&&g.value==="text/plain"||g.name!=="data-lynkow-activated"&&i.setAttribute(g.name,g.value));}i.textContent=o.textContent,i.setAttribute(te,""),document.head.appendChild(i);}));}init(){!c||this.initialized||(this.injectStyles(),this.bindCodeBlockCopy(),this.activateScripts(),window.addEventListener("message",this.handleWidgetResize),this.observer||(this.observer=new MutationObserver(()=>{this.pendingFrame===null&&(this.pendingFrame=requestAnimationFrame(()=>{this.pendingFrame=null,this.activateScripts(),this.bindCodeBlockCopy();}));}),this.observer.observe(document.body,{childList:true,subtree:true})),this.initialized=true);}isInitialized(){return this.initialized}destroy(){c&&(window.removeEventListener("message",this.handleWidgetResize),this.pendingFrame!==null&&(cancelAnimationFrame(this.pendingFrame),this.pendingFrame=null),this.observer&&(this.observer.disconnect(),this.observer=null),document.getElementById(ee)?.remove(),document.head.querySelectorAll(`script[${te}]`).forEach(e=>e.remove()),this.initialized=false);}};var M=class{srcset(e,t={}){if(!e)return "";let{widths:n=[400,800,1200,1920],fit:r="scale-down",quality:o=80,gravity:i}=t,a=this.parseImageUrl(e);return a?n.map(p=>{let g=[`w=${p}`,`fit=${r}`,"format=auto",`quality=${o}`,i&&`gravity=${i}`].filter(Boolean).join(",");return `${a.cdnBase}/cdn-cgi/image/${g}/${a.relativePath} ${p}w`}).join(", "):""}transform(e,t={}){if(!e)return "";let n=this.parseImageUrl(e);if(!n)return e||"";let r=[t.w&&`w=${t.w}`,t.h&&`h=${t.h}`,`fit=${t.fit||"scale-down"}`,`format=${t.format||"auto"}`,`quality=${t.quality||80}`,t.gravity&&`gravity=${t.gravity}`,t.dpr&&`dpr=${t.dpr}`].filter(Boolean).join(",");return `${n.cdnBase}/cdn-cgi/image/${r}/${n.relativePath}`}parseImageUrl(e){let t=e.indexOf("/cdn-cgi/image/");if(t!==-1){let o=e.substring(0,t),i=e.substring(t+15),a=i.indexOf("/");if(a===-1)return null;let p=i.substring(a+1);return {cdnBase:o,relativePath:p}}let n=e.indexOf("/sites/");if(n!==-1){let o=e.substring(0,n),i=e.substring(n+1);return {cdnBase:o,relativePath:i}}let r=e.indexOf("/avatars/");if(r!==-1){let o=e.substring(0,r),i=e.substring(r+1);return {cdnBase:o,relativePath:i}}return null}};var A=class extends m{async search(e,t){return this.get("/search",{q:e,locale:t?.locale,category:t?.category,tag:t?.tag,page:t?.page,limit:t?.limit},t)}async getConfig(e){return this.getWithCache("search-config","/search/config",void 0,e,d.MEDIUM)}};var Oe=300*1e3,Ie="lynkow_cache_",v=new Map;function le(s={}){let e=s.defaultTtl??Oe,t=s.prefix??Ie;function n(u){return `${t}${u}`}function r(u){return Date.now()>u.expiresAt}function o(u){let l=n(u);if(c)try{let h=localStorage.getItem(l);if(!h)return null;let y=JSON.parse(h);return r(y)?(localStorage.removeItem(l),null):y.value}catch{return null}let f=v.get(l);return f?r(f)?(v.delete(l),null):f.value:null}function i(u,l,f=e){let h=n(u),y={value:l,expiresAt:Date.now()+f};if(c){try{localStorage.setItem(h,JSON.stringify(y));}catch{}return}v.set(h,y);}function a(u){let l=n(u);if(c){try{localStorage.removeItem(l);}catch{}return}v.delete(l);}function p(u){if(c){try{let l=[];for(let f=0;f<localStorage.length;f++){let h=localStorage.key(f);h&&h.startsWith(t)&&(!u||h.includes(u))&&l.push(h);}l.forEach(f=>localStorage.removeItem(f));}catch{}return}if(u)for(let l of v.keys())l.startsWith(t)&&l.includes(u)&&v.delete(l);else for(let l of v.keys())l.startsWith(t)&&v.delete(l);}async function g(u,l,f=e){let h=o(u);if(h!==null)return h;let y=await l();return i(u,y,f),y}return {get:o,set:i,remove:a,invalidate:p,getOrSet:g}}function de(s){let e=s.prefix||"[Lynkow]";return {debug(...t){s.debug&&console.debug(e,...t);},info(...t){console.info(e,...t);},warn(...t){console.warn(e,...t);},error(...t){console.error(e,...t);},log(t,...n){switch(t){case "debug":this.debug(...n);break;case "info":this.info(...n);break;case "warn":this.warn(...n);break;case "error":this.error(...n);break}}}}function pe(){let s=new Map;function e(i,a){return s.has(i)||s.set(i,new Set),s.get(i).add(a),()=>t(i,a)}function t(i,a){let p=s.get(i);p&&p.delete(a);}function n(i,a){let p=s.get(i);if(p)for(let g of p)try{g(a);}catch(u){console.error(`[Lynkow] Error in event listener for "${i}":`,u);}}function r(i,a){let p=(g=>{t(i,p),a(g);});return e(i,p)}function o(i){i?s.delete(i):s.clear();}return {on:e,off:t,emit:n,once:r,removeAllListeners:o}}var me="lynkow_locale";function ne(s,e){let t=s.toLowerCase();return e.find(n=>n.toLowerCase()===t)??null}function ue(s,e){if(!c)return e;let t=Pe();if(t&&s.includes(t))return t;let n=Be(s);if(n)return n;let r=document.documentElement.lang;if(r){let o=ne(r,s);if(o)return o;let i=r.split("-")[0]?.toLowerCase();if(i){let a=ne(i,s);if(a)return a}}return e}function Pe(){if(!c)return null;try{return localStorage.getItem(me)}catch{return null}}function ge(s){if(c)try{localStorage.setItem(me,s);}catch{}}function Be(s){if(!c)return null;let t=window.location.pathname.split("/").filter(Boolean);if(t.length>0){let n=t[0];if(n){let r=ne(n,s);if(r)return r}}return null}function he(s,e){return e.includes(s)}var fe="https://api.lynkow.com";function $e(s){if(!s.siteId)throw new Error("Lynkow SDK: siteId is required");let e=s.cache===true?le():void 0,t=de({debug:s.debug??false}),n=pe(),r=(s.baseUrl||fe).replace(/\/$/,""),o={siteId:s.siteId,baseUrl:r,locale:s.locale,fetchOptions:s.fetchOptions||{},...e?{cache:e}:{}},i={locale:s.locale||"fr",availableLocales:["fr"],siteConfig:null,initialized:false},a={contents:new b(o),categories:new R(o),tags:new E(o),pages:new k(o),blocks:new x(o),forms:new S(o),reviews:new T(o),site:new L(o),legal:new O(o),cookies:new I(o),seo:new P(o),paths:new B(o),analytics:new D(o),consent:new q(o,n),branding:new N(o),enhancements:new H,media:new M,search:new A(o)};function p(l){o.locale=l;}async function g(){if(!i.initialized)try{let l=await a.site.getConfig();i.siteConfig=l;let f=l.defaultLocale||"fr";if(i.availableLocales=l.enabledLocales||[f],c&&!s.locale){let h=ue(i.availableLocales,f);i.locale=h,p(h);}i.initialized=!0,t.debug("Client initialized",{locale:i.locale,availableLocales:i.availableLocales}),c&&(a.analytics.init(),a.consent.hasConsented()||a.consent.show(),l.showBranding&&await a.branding.inject(),a.enhancements.init()),n.emit("ready",void 0);}catch(l){t.error("Failed to initialize client",l),n.emit("error",l);}}return c&&setTimeout(()=>{a.enhancements.init(),g();},0),{...a,globals:a.blocks,config:Object.freeze({siteId:s.siteId,baseUrl:r,debug:s.debug??false,cache:s.cache===true}),get locale(){return i.locale},get availableLocales(){return [...i.availableLocales]},setLocale(l){if(!he(l,i.availableLocales)){t.warn(`Locale "${l}" is not available. Available: ${i.availableLocales.join(", ")}`);return}l!==i.locale&&(i.locale=l,p(l),c&&ge(l),e?.invalidate(),n.emit("locale-changed",l),t.debug("Locale changed to",l));},clearCache(){e?.invalidate(),t.debug("Cache cleared");},destroy(){a.analytics.destroy(),a.consent.destroy(),a.branding.destroy(),a.enhancements.destroy(),e?.invalidate(),n.removeAllListeners(),t.debug("Client destroyed");},on(l,f){return n.on(l,f)}}}function Ae(s){if(!s.siteId)throw new Error("Lynkow SDK: siteId is required");let e={siteId:s.siteId,baseUrl:(s.baseUrl||fe).replace(/\/$/,""),locale:s.locale,fetchOptions:s.fetchOptions||{}};return {contents:new b(e),categories:new R(e),tags:new E(e),pages:new k(e),blocks:new x(e),forms:new S(e),reviews:new T(e),site:new L(e),legal:new O(e),cookies:new I(e),seo:new P(e),paths:new B(e),search:new A(e)}}function _e(s){return s.type==="content"}function Fe(s){return s.type==="category"}function De(s){if(!s||s.length===0)return "";let e=s.map(r=>{let{["@context"]:o,...i}=r;return i});return `<script type="application/ld+json">${JSON.stringify({"@context":"https://schema.org","@graph":e}).replace(/<\/(script)/gi,"<\\/$1")}</script>`}
|
|
236
|
+
exports.AnalyticsService=D;exports.BlocksService=x;exports.BrandingService=N;exports.CategoriesService=R;exports.ConsentService=q;exports.ContentsService=b;exports.CookiesService=I;exports.EnhancementsService=H;exports.FormsService=S;exports.LegalService=O;exports.LynkowError=C;exports.MediaHelperService=M;exports.PagesService=k;exports.PathsService=B;exports.ReviewsService=T;exports.SearchService=A;exports.SeoService=P;exports.SiteService=L;exports.TagsService=E;exports.browserOnly=be;exports.browserOnlyAsync=Re;exports.createClient=$e;exports.createLynkowClient=Ae;exports.detectSiteTheme=w;exports.isBrowser=c;exports.isCategoryResolve=Fe;exports.isContentResolve=_e;exports.isLynkowError=Ce;exports.isServer=we;exports.onSiteThemeChange=$;exports.renderJsonLdGraph=De;//# sourceMappingURL=index.js.map
|
|
237
237
|
//# sourceMappingURL=index.js.map
|