@easy-cookie/policy 0.0.0-stage → 0.1.1

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,49 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { EasyCookieConfig } from '@easy-cookie/core/shared';
4
+ import { B as BuildPolicyOptions, R as RenderPolicyOptions } from './render-DYrvn1cT.cjs';
5
+ export { d as PolicyModel, h as buildPolicyModel } from './render-DYrvn1cT.cjs';
6
+ import { FetchLegalDocumentOptions, PublishedLegalDocument } from './client.cjs';
7
+ export { fetchLegalDocument } from './client.cjs';
8
+
9
+ interface LegalDocumentProps extends Omit<FetchLegalDocumentOptions, 'init'> {
10
+ className?: string;
11
+ /** Shown while loading. */
12
+ loading?: ReactNode;
13
+ /** Shown when nothing is published or the request fails. */
14
+ fallback?: ReactNode;
15
+ }
16
+ /**
17
+ * Fetch a published legal document in the browser and render it. For
18
+ * server-rendered, indexable pages prefer `getLegalDocument()` (Next.js) or
19
+ * `fetchLegalDocument()` + `<LegalDocumentHtml>`.
20
+ */
21
+ declare function LegalDocument({ endpoint, siteKey, kind, lang, fetch: fetchImpl, className, loading, fallback, }: LegalDocumentProps): react.JSX.Element;
22
+
23
+ interface CookiePolicyProps extends BuildPolicyOptions, RenderPolicyOptions {
24
+ config: EasyCookieConfig;
25
+ lang: string;
26
+ className?: string;
27
+ }
28
+ /**
29
+ * The cookie section of a policy page, generated from the config.
30
+ * No hooks and no browser APIs: works as a React Server Component.
31
+ * Same markup and class names as `renderPolicyHtml()`.
32
+ */
33
+ declare function CookiePolicy({ config, lang, date, labels, headingLevel, idPrefix, meta, hideEmpty, className, }: CookiePolicyProps): react.JSX.Element;
34
+
35
+ interface LegalDocumentHtmlProps {
36
+ /** A document from `fetchLegalDocument()` / `getLegalDocument()` (or anything with `html`). */
37
+ doc: Pick<PublishedLegalDocument, 'html'> | null | undefined;
38
+ className?: string;
39
+ /** Shown when `doc` is null (nothing published yet). */
40
+ fallback?: ReactNode;
41
+ }
42
+ /**
43
+ * Render a legal document fetched on the server. The HTML comes from the
44
+ * consent server's renderer (raw HTML disabled, safe links only), so it is
45
+ * inserted as-is. Works as a React Server Component.
46
+ */
47
+ declare function LegalDocumentHtml({ doc, className, fallback }: LegalDocumentHtmlProps): react.JSX.Element;
48
+
49
+ export { CookiePolicy, type CookiePolicyProps, FetchLegalDocumentOptions, LegalDocument, LegalDocumentHtml, type LegalDocumentHtmlProps, type LegalDocumentProps, PublishedLegalDocument };
@@ -0,0 +1,49 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { EasyCookieConfig } from '@easy-cookie/core/shared';
4
+ import { B as BuildPolicyOptions, R as RenderPolicyOptions } from './render-DYrvn1cT.js';
5
+ export { d as PolicyModel, h as buildPolicyModel } from './render-DYrvn1cT.js';
6
+ import { FetchLegalDocumentOptions, PublishedLegalDocument } from './client.js';
7
+ export { fetchLegalDocument } from './client.js';
8
+
9
+ interface LegalDocumentProps extends Omit<FetchLegalDocumentOptions, 'init'> {
10
+ className?: string;
11
+ /** Shown while loading. */
12
+ loading?: ReactNode;
13
+ /** Shown when nothing is published or the request fails. */
14
+ fallback?: ReactNode;
15
+ }
16
+ /**
17
+ * Fetch a published legal document in the browser and render it. For
18
+ * server-rendered, indexable pages prefer `getLegalDocument()` (Next.js) or
19
+ * `fetchLegalDocument()` + `<LegalDocumentHtml>`.
20
+ */
21
+ declare function LegalDocument({ endpoint, siteKey, kind, lang, fetch: fetchImpl, className, loading, fallback, }: LegalDocumentProps): react.JSX.Element;
22
+
23
+ interface CookiePolicyProps extends BuildPolicyOptions, RenderPolicyOptions {
24
+ config: EasyCookieConfig;
25
+ lang: string;
26
+ className?: string;
27
+ }
28
+ /**
29
+ * The cookie section of a policy page, generated from the config.
30
+ * No hooks and no browser APIs: works as a React Server Component.
31
+ * Same markup and class names as `renderPolicyHtml()`.
32
+ */
33
+ declare function CookiePolicy({ config, lang, date, labels, headingLevel, idPrefix, meta, hideEmpty, className, }: CookiePolicyProps): react.JSX.Element;
34
+
35
+ interface LegalDocumentHtmlProps {
36
+ /** A document from `fetchLegalDocument()` / `getLegalDocument()` (or anything with `html`). */
37
+ doc: Pick<PublishedLegalDocument, 'html'> | null | undefined;
38
+ className?: string;
39
+ /** Shown when `doc` is null (nothing published yet). */
40
+ fallback?: ReactNode;
41
+ }
42
+ /**
43
+ * Render a legal document fetched on the server. The HTML comes from the
44
+ * consent server's renderer (raw HTML disabled, safe links only), so it is
45
+ * inserted as-is. Works as a React Server Component.
46
+ */
47
+ declare function LegalDocumentHtml({ doc, className, fallback }: LegalDocumentHtmlProps): react.JSX.Element;
48
+
49
+ export { CookiePolicy, type CookiePolicyProps, FetchLegalDocumentOptions, LegalDocument, LegalDocumentHtml, type LegalDocumentHtmlProps, type LegalDocumentProps, PublishedLegalDocument };
package/dist/react.js ADDED
@@ -0,0 +1,80 @@
1
+ import {
2
+ buildPolicyModel,
3
+ formatPolicyDate,
4
+ policyRows
5
+ } from "./chunk-P3F5NQPR.js";
6
+ import {
7
+ fetchLegalDocument
8
+ } from "./chunk-HDY2VYU4.js";
9
+
10
+ // src/react.tsx
11
+ import { LegalDocument } from "./legal-document.js";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ function CookiePolicy({
14
+ config,
15
+ lang,
16
+ date,
17
+ labels,
18
+ headingLevel = 2,
19
+ idPrefix = "ec-policy-",
20
+ meta = true,
21
+ hideEmpty = false,
22
+ className
23
+ }) {
24
+ const model = buildPolicyModel(config, lang, { date, labels });
25
+ const L = model.labels;
26
+ const H = `h${headingLevel}`;
27
+ const displayDate = formatPolicyDate(model);
28
+ const categories = hideEmpty ? model.categories.filter((c) => c.services.length > 0) : model.categories;
29
+ return /* @__PURE__ */ jsxs("div", { className: ["ec-policy", className].filter(Boolean).join(" "), lang: model.lang, children: [
30
+ meta && /* @__PURE__ */ jsxs("p", { className: "ec-policy__meta", children: [
31
+ displayDate && /* @__PURE__ */ jsxs(Fragment, { children: [
32
+ L.updated,
33
+ ": ",
34
+ /* @__PURE__ */ jsx("time", { dateTime: model.date, children: displayDate }),
35
+ " \xB7 "
36
+ ] }),
37
+ L.revision,
38
+ ": ",
39
+ /* @__PURE__ */ jsx("span", { className: "ec-policy__revision", children: model.revision })
40
+ ] }),
41
+ categories.map((cat) => {
42
+ const id = `${idPrefix}${cat.id}`;
43
+ const rows = policyRows(cat);
44
+ return /* @__PURE__ */ jsxs("section", { className: "ec-policy__category", id, "data-category": cat.id, "aria-labelledby": `${id}-title`, children: [
45
+ /* @__PURE__ */ jsx(H, { className: "ec-policy__title", id: `${id}-title`, children: cat.title }),
46
+ cat.readOnly && /* @__PURE__ */ jsx("p", { className: "ec-policy__badge", children: L.alwaysOn }),
47
+ cat.description && /* @__PURE__ */ jsx("p", { className: "ec-policy__description", children: cat.description }),
48
+ rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "ec-policy__empty", children: L.noCookies }) : /* @__PURE__ */ jsx("div", { className: "ec-policy__table-wrap", children: /* @__PURE__ */ jsxs("table", { className: "ec-policy__table", children: [
49
+ /* @__PURE__ */ jsx("caption", { className: "ec-policy__caption", children: L.caption.replace("{category}", cat.title) }),
50
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: [L.cookie, L.service, L.provider, L.duration, L.purpose].map((t) => /* @__PURE__ */ jsx("th", { scope: "col", children: t }, t)) }) }),
51
+ /* @__PURE__ */ jsx("tbody", { children: rows.map(({ service, cookie }) => /* @__PURE__ */ jsxs("tr", { "data-service": service.id, children: [
52
+ /* @__PURE__ */ jsx("th", { scope: "row", children: cookie ? /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsx("code", { className: "ec-policy__cookie", title: cookie.pattern ? cookie.name : void 0, children: cookie.displayName }),
54
+ cookie.domain && /* @__PURE__ */ jsxs(Fragment, { children: [
55
+ " ",
56
+ /* @__PURE__ */ jsx("span", { className: "ec-policy__domain", children: cookie.domain })
57
+ ] })
58
+ ] }) : /* @__PURE__ */ jsx("span", { className: "ec-policy__none", children: L.noCookie }) }),
59
+ /* @__PURE__ */ jsx("td", { className: "ec-policy__service", children: service.label }),
60
+ /* @__PURE__ */ jsx("td", { className: "ec-policy__provider", children: service.privacyUrl && /^(https?:|mailto:|\/|#)/i.test(service.privacyUrl.trim()) ? /* @__PURE__ */ jsx("a", { className: "ec-policy__link", href: service.privacyUrl, rel: "noopener noreferrer", target: "_blank", children: service.provider || L.privacyPolicy }) : service.provider }),
61
+ /* @__PURE__ */ jsx("td", { className: "ec-policy__duration", children: cookie?.duration ?? "" }),
62
+ /* @__PURE__ */ jsx("td", { className: "ec-policy__purpose", children: cookie?.description || service.purpose })
63
+ ] }, `${service.id}:${cookie?.name ?? ""}`)) })
64
+ ] }) })
65
+ ] }, cat.id);
66
+ })
67
+ ] });
68
+ }
69
+ function LegalDocumentHtml({ doc, className, fallback = null }) {
70
+ if (!doc?.html) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
71
+ return /* @__PURE__ */ jsx("div", { className, dangerouslySetInnerHTML: { __html: doc.html } });
72
+ }
73
+ export {
74
+ CookiePolicy,
75
+ LegalDocument,
76
+ LegalDocumentHtml,
77
+ buildPolicyModel,
78
+ fetchLegalDocument
79
+ };
80
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import type { EasyCookieConfig } from '@easy-cookie/core/shared';\nimport { buildPolicyModel, formatPolicyDate, type BuildPolicyOptions } from './model';\nimport { policyRows, type RenderPolicyOptions } from './render';\nimport type { ReactNode } from 'react';\nimport type { PublishedLegalDocument } from './legal-client';\n\nexport interface CookiePolicyProps extends BuildPolicyOptions, RenderPolicyOptions {\n config: EasyCookieConfig;\n lang: string;\n className?: string;\n}\n\n/**\n * The cookie section of a policy page, generated from the config.\n * No hooks and no browser APIs: works as a React Server Component.\n * Same markup and class names as `renderPolicyHtml()`.\n */\nexport function CookiePolicy({\n config,\n lang,\n date,\n labels,\n headingLevel = 2,\n idPrefix = 'ec-policy-',\n meta = true,\n hideEmpty = false,\n className,\n}: CookiePolicyProps) {\n const model = buildPolicyModel(config, lang, { date, labels });\n const L = model.labels;\n const H = `h${headingLevel}` as 'h2';\n const displayDate = formatPolicyDate(model);\n const categories = hideEmpty ? model.categories.filter((c) => c.services.length > 0) : model.categories;\n\n return (\n <div className={['ec-policy', className].filter(Boolean).join(' ')} lang={model.lang}>\n {meta && (\n <p className=\"ec-policy__meta\">\n {displayDate && (\n <>\n {L.updated}: <time dateTime={model.date}>{displayDate}</time>\n {' · '}\n </>\n )}\n {L.revision}: <span className=\"ec-policy__revision\">{model.revision}</span>\n </p>\n )}\n {categories.map((cat) => {\n const id = `${idPrefix}${cat.id}`;\n const rows = policyRows(cat);\n return (\n <section key={cat.id} className=\"ec-policy__category\" id={id} data-category={cat.id} aria-labelledby={`${id}-title`}>\n <H className=\"ec-policy__title\" id={`${id}-title`}>\n {cat.title}\n </H>\n {cat.readOnly && <p className=\"ec-policy__badge\">{L.alwaysOn}</p>}\n {cat.description && <p className=\"ec-policy__description\">{cat.description}</p>}\n {rows.length === 0 ? (\n <p className=\"ec-policy__empty\">{L.noCookies}</p>\n ) : (\n <div className=\"ec-policy__table-wrap\">\n <table className=\"ec-policy__table\">\n <caption className=\"ec-policy__caption\">{L.caption.replace('{category}', cat.title)}</caption>\n <thead>\n <tr>\n {[L.cookie, L.service, L.provider, L.duration, L.purpose].map((t) => (\n <th key={t} scope=\"col\">\n {t}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map(({ service, cookie }) => (\n <tr key={`${service.id}:${cookie?.name ?? ''}`} data-service={service.id}>\n <th scope=\"row\">\n {cookie ? (\n <>\n <code className=\"ec-policy__cookie\" title={cookie.pattern ? cookie.name : undefined}>\n {cookie.displayName}\n </code>\n {cookie.domain && (\n <>\n {' '}\n <span className=\"ec-policy__domain\">{cookie.domain}</span>\n </>\n )}\n </>\n ) : (\n <span className=\"ec-policy__none\">{L.noCookie}</span>\n )}\n </th>\n <td className=\"ec-policy__service\">{service.label}</td>\n <td className=\"ec-policy__provider\">\n {service.privacyUrl && /^(https?:|mailto:|\\/|#)/i.test(service.privacyUrl.trim()) ? (\n <a className=\"ec-policy__link\" href={service.privacyUrl} rel=\"noopener noreferrer\" target=\"_blank\">\n {service.provider || L.privacyPolicy}\n </a>\n ) : (\n service.provider\n )}\n </td>\n <td className=\"ec-policy__duration\">{cookie?.duration ?? ''}</td>\n <td className=\"ec-policy__purpose\">{cookie?.description || service.purpose}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n })}\n </div>\n );\n}\n\nexport { buildPolicyModel, type PolicyModel } from './model';\n\nexport interface LegalDocumentHtmlProps {\n /** A document from `fetchLegalDocument()` / `getLegalDocument()` (or anything with `html`). */\n doc: Pick<PublishedLegalDocument, 'html'> | null | undefined;\n className?: string;\n /** Shown when `doc` is null (nothing published yet). */\n fallback?: ReactNode;\n}\n\n/**\n * Render a legal document fetched on the server. The HTML comes from the\n * consent server's renderer (raw HTML disabled, safe links only), so it is\n * inserted as-is. Works as a React Server Component.\n */\nexport function LegalDocumentHtml({ doc, className, fallback = null }: LegalDocumentHtmlProps) {\n if (!doc?.html) return <>{fallback}</>;\n return <div className={className} dangerouslySetInnerHTML={{ __html: doc.html }} />;\n}\n\n// Client component: built as its own file with a \"use client\" banner (see tsup.config.ts).\nexport { LegalDocument, type LegalDocumentProps } from './legal-document';\nexport { fetchLegalDocument, type FetchLegalDocumentOptions, type PublishedLegalDocument } from './legal-client';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,115 @@
1
+ import { EasyCookieConfig } from '@easy-cookie/core/shared';
2
+
3
+ interface PolicyLabels {
4
+ cookie: string;
5
+ service: string;
6
+ provider: string;
7
+ duration: string;
8
+ purpose: string;
9
+ /** Prefix of the "last updated" line. */
10
+ updated: string;
11
+ revision: string;
12
+ alwaysOn: string;
13
+ privacyPolicy: string;
14
+ /** Shown in a category without services. */
15
+ noCookies: string;
16
+ /** Shown in the cookie column for a service that sets no cookies. */
17
+ noCookie: string;
18
+ /** Table caption: `{category}` is replaced with the category title. */
19
+ caption: string;
20
+ }
21
+ /** Built-in table headers and labels. Unknown languages fall back to English. */
22
+ declare const POLICY_LABELS: Record<'it' | 'en', PolicyLabels>;
23
+ interface PolicyCookie {
24
+ /** Name as declared (a regular expression source when `pattern` is true). */
25
+ name: string;
26
+ /** Human-friendly name: anchors stripped, `.*` shown as `*` for patterns. */
27
+ displayName: string;
28
+ pattern: boolean;
29
+ duration: string;
30
+ description: string;
31
+ domain?: string;
32
+ }
33
+ interface PolicyService {
34
+ id: string;
35
+ label: string;
36
+ provider: string;
37
+ privacyUrl?: string;
38
+ purpose: string;
39
+ cookies: PolicyCookie[];
40
+ }
41
+ interface PolicyCategory {
42
+ id: string;
43
+ title: string;
44
+ description: string;
45
+ readOnly: boolean;
46
+ color: string;
47
+ services: PolicyService[];
48
+ }
49
+ interface PolicyModel {
50
+ lang: string;
51
+ revision: string;
52
+ /** ISO date (YYYY-MM-DD) of the revision, when known. */
53
+ date?: string;
54
+ policyUrl?: string;
55
+ labels: PolicyLabels;
56
+ categories: PolicyCategory[];
57
+ }
58
+ interface BuildPolicyOptions {
59
+ /** Date of this revision (ISO). Defaults to the revision itself when it starts with YYYY-MM-DD. */
60
+ date?: string | Date;
61
+ /** Override some labels. */
62
+ labels?: Partial<PolicyLabels>;
63
+ }
64
+ /** Make a cookie-name regular expression readable: `^_ga_.*$` → `_ga_*`. */
65
+ declare function prettyCookiePattern(source: string): string;
66
+ /**
67
+ * Turn the config into a localized, render-agnostic cookie policy model:
68
+ * categories → services → cookies. Pure and DOM-free.
69
+ */
70
+ declare function buildPolicyModel(config: EasyCookieConfig, lang: string, opts?: BuildPolicyOptions): PolicyModel;
71
+ /** Format the model date for display, e.g. "13 novembre 2026" / "November 13, 2026". */
72
+ declare function formatPolicyDate(model: Pick<PolicyModel, 'date' | 'lang'>): string | undefined;
73
+ interface AutoClearRule {
74
+ /** Cookie name, or a regular expression source when `pattern` is true. */
75
+ name: string;
76
+ pattern: boolean;
77
+ domain?: string;
78
+ service: string;
79
+ }
80
+ /**
81
+ * Cookies to delete when a category is withdrawn, per category id.
82
+ * Read-only (necessary) categories are omitted: they cannot be withdrawn.
83
+ */
84
+ declare function autoClearRules(config: EasyCookieConfig): Record<string, AutoClearRule[]>;
85
+ /** True when `cookieName` matches the rule. */
86
+ declare function matchesRule(rule: Pick<AutoClearRule, 'name' | 'pattern'>, cookieName: string): boolean;
87
+
88
+ interface RenderPolicyOptions {
89
+ /** Heading level of category titles (2 → `<h2>`). Default 2. */
90
+ headingLevel?: 2 | 3 | 4 | 5 | 6;
91
+ /** Prefix for section ids (`#ec-policy-measurement`). Default `ec-policy-`. */
92
+ idPrefix?: string;
93
+ /** Show the "last updated / revision" line. Default true. */
94
+ meta?: boolean;
95
+ /** Omit categories without services. Default false. */
96
+ hideEmpty?: boolean;
97
+ }
98
+ declare function escapeHtml(value: string): string;
99
+ interface PolicyRow {
100
+ service: PolicyService;
101
+ cookie?: PolicyService['cookies'][number];
102
+ /** First row of this service (for grouping). */
103
+ first: boolean;
104
+ }
105
+ /** Flatten a category to table rows: one per cookie, or one per service without cookies. */
106
+ declare function policyRows(cat: PolicyCategory): PolicyRow[];
107
+ /**
108
+ * Semantic HTML for the cookie section of a policy: one `<section>` and one
109
+ * `<table>` per category. Class names only (`ec-policy*`), no inline styles.
110
+ */
111
+ declare function renderPolicyHtml(model: PolicyModel, opts?: RenderPolicyOptions): string;
112
+ /** GitHub-flavoured Markdown version of the policy (one table per category). */
113
+ declare function renderPolicyMarkdown(model: PolicyModel, opts?: Pick<RenderPolicyOptions, 'headingLevel' | 'meta' | 'hideEmpty'>): string;
114
+
115
+ export { type AutoClearRule as A, type BuildPolicyOptions as B, POLICY_LABELS as P, type RenderPolicyOptions as R, type PolicyCategory as a, type PolicyCookie as b, type PolicyLabels as c, type PolicyModel as d, type PolicyRow as e, type PolicyService as f, autoClearRules as g, buildPolicyModel as h, escapeHtml as i, formatPolicyDate as j, prettyCookiePattern as k, renderPolicyMarkdown as l, matchesRule as m, policyRows as p, renderPolicyHtml as r };
@@ -0,0 +1,115 @@
1
+ import { EasyCookieConfig } from '@easy-cookie/core/shared';
2
+
3
+ interface PolicyLabels {
4
+ cookie: string;
5
+ service: string;
6
+ provider: string;
7
+ duration: string;
8
+ purpose: string;
9
+ /** Prefix of the "last updated" line. */
10
+ updated: string;
11
+ revision: string;
12
+ alwaysOn: string;
13
+ privacyPolicy: string;
14
+ /** Shown in a category without services. */
15
+ noCookies: string;
16
+ /** Shown in the cookie column for a service that sets no cookies. */
17
+ noCookie: string;
18
+ /** Table caption: `{category}` is replaced with the category title. */
19
+ caption: string;
20
+ }
21
+ /** Built-in table headers and labels. Unknown languages fall back to English. */
22
+ declare const POLICY_LABELS: Record<'it' | 'en', PolicyLabels>;
23
+ interface PolicyCookie {
24
+ /** Name as declared (a regular expression source when `pattern` is true). */
25
+ name: string;
26
+ /** Human-friendly name: anchors stripped, `.*` shown as `*` for patterns. */
27
+ displayName: string;
28
+ pattern: boolean;
29
+ duration: string;
30
+ description: string;
31
+ domain?: string;
32
+ }
33
+ interface PolicyService {
34
+ id: string;
35
+ label: string;
36
+ provider: string;
37
+ privacyUrl?: string;
38
+ purpose: string;
39
+ cookies: PolicyCookie[];
40
+ }
41
+ interface PolicyCategory {
42
+ id: string;
43
+ title: string;
44
+ description: string;
45
+ readOnly: boolean;
46
+ color: string;
47
+ services: PolicyService[];
48
+ }
49
+ interface PolicyModel {
50
+ lang: string;
51
+ revision: string;
52
+ /** ISO date (YYYY-MM-DD) of the revision, when known. */
53
+ date?: string;
54
+ policyUrl?: string;
55
+ labels: PolicyLabels;
56
+ categories: PolicyCategory[];
57
+ }
58
+ interface BuildPolicyOptions {
59
+ /** Date of this revision (ISO). Defaults to the revision itself when it starts with YYYY-MM-DD. */
60
+ date?: string | Date;
61
+ /** Override some labels. */
62
+ labels?: Partial<PolicyLabels>;
63
+ }
64
+ /** Make a cookie-name regular expression readable: `^_ga_.*$` → `_ga_*`. */
65
+ declare function prettyCookiePattern(source: string): string;
66
+ /**
67
+ * Turn the config into a localized, render-agnostic cookie policy model:
68
+ * categories → services → cookies. Pure and DOM-free.
69
+ */
70
+ declare function buildPolicyModel(config: EasyCookieConfig, lang: string, opts?: BuildPolicyOptions): PolicyModel;
71
+ /** Format the model date for display, e.g. "13 novembre 2026" / "November 13, 2026". */
72
+ declare function formatPolicyDate(model: Pick<PolicyModel, 'date' | 'lang'>): string | undefined;
73
+ interface AutoClearRule {
74
+ /** Cookie name, or a regular expression source when `pattern` is true. */
75
+ name: string;
76
+ pattern: boolean;
77
+ domain?: string;
78
+ service: string;
79
+ }
80
+ /**
81
+ * Cookies to delete when a category is withdrawn, per category id.
82
+ * Read-only (necessary) categories are omitted: they cannot be withdrawn.
83
+ */
84
+ declare function autoClearRules(config: EasyCookieConfig): Record<string, AutoClearRule[]>;
85
+ /** True when `cookieName` matches the rule. */
86
+ declare function matchesRule(rule: Pick<AutoClearRule, 'name' | 'pattern'>, cookieName: string): boolean;
87
+
88
+ interface RenderPolicyOptions {
89
+ /** Heading level of category titles (2 → `<h2>`). Default 2. */
90
+ headingLevel?: 2 | 3 | 4 | 5 | 6;
91
+ /** Prefix for section ids (`#ec-policy-measurement`). Default `ec-policy-`. */
92
+ idPrefix?: string;
93
+ /** Show the "last updated / revision" line. Default true. */
94
+ meta?: boolean;
95
+ /** Omit categories without services. Default false. */
96
+ hideEmpty?: boolean;
97
+ }
98
+ declare function escapeHtml(value: string): string;
99
+ interface PolicyRow {
100
+ service: PolicyService;
101
+ cookie?: PolicyService['cookies'][number];
102
+ /** First row of this service (for grouping). */
103
+ first: boolean;
104
+ }
105
+ /** Flatten a category to table rows: one per cookie, or one per service without cookies. */
106
+ declare function policyRows(cat: PolicyCategory): PolicyRow[];
107
+ /**
108
+ * Semantic HTML for the cookie section of a policy: one `<section>` and one
109
+ * `<table>` per category. Class names only (`ec-policy*`), no inline styles.
110
+ */
111
+ declare function renderPolicyHtml(model: PolicyModel, opts?: RenderPolicyOptions): string;
112
+ /** GitHub-flavoured Markdown version of the policy (one table per category). */
113
+ declare function renderPolicyMarkdown(model: PolicyModel, opts?: Pick<RenderPolicyOptions, 'headingLevel' | 'meta' | 'hideEmpty'>): string;
114
+
115
+ export { type AutoClearRule as A, type BuildPolicyOptions as B, POLICY_LABELS as P, type RenderPolicyOptions as R, type PolicyCategory as a, type PolicyCookie as b, type PolicyLabels as c, type PolicyModel as d, type PolicyRow as e, type PolicyService as f, autoClearRules as g, buildPolicyModel as h, escapeHtml as i, formatPolicyDate as j, prettyCookiePattern as k, renderPolicyMarkdown as l, matchesRule as m, policyRows as p, renderPolicyHtml as r };
package/package.json CHANGED
@@ -1,6 +1,78 @@
1
1
  {
2
2
  "name": "@easy-cookie/policy",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "description": "Generate the cookie policy (HTML, Markdown, React) and autoClear rules from an easy-cookie config.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Aleloca/easy-cookie.git",
9
+ "directory": "packages/policy"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/Aleloca/easy-cookie/issues"
13
+ },
14
+ "type": "module",
15
+ "sideEffects": [
16
+ "*.css"
17
+ ],
18
+ "main": "./dist/index.cjs",
19
+ "module": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js",
25
+ "require": "./dist/index.cjs"
26
+ },
27
+ "./react": {
28
+ "types": "./dist/react.d.ts",
29
+ "import": "./dist/react.js",
30
+ "require": "./dist/react.cjs"
31
+ },
32
+ "./client": {
33
+ "types": "./dist/client.d.ts",
34
+ "import": "./dist/client.js",
35
+ "require": "./dist/client.cjs"
36
+ },
37
+ "./legal.css": "./dist/easy-cookie-legal.css",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist"
42
+ ],
43
+ "dependencies": {
44
+ "markdown-it": "^14.3.3",
45
+ "@easy-cookie/core": "^0.1.1"
46
+ },
47
+ "peerDependencies": {
48
+ "react": ">=18"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "react": {
52
+ "optional": true
53
+ }
54
+ },
55
+ "devDependencies": {
56
+ "@types/markdown-it": "^14.2.0",
57
+ "@types/react": "^19.1.0",
58
+ "@types/react-dom": "^19.1.0",
59
+ "react": "^19.1.0",
60
+ "react-dom": "^19.1.0"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "homepage": "https://consent.aleloca.dev",
66
+ "keywords": [
67
+ "cookie",
68
+ "consent",
69
+ "gdpr",
70
+ "cookie-banner",
71
+ "consent-mode"
72
+ ],
73
+ "scripts": {
74
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsup && node -e \"require('fs').copyFileSync('src/legal.css','dist/easy-cookie-legal.css')\"",
75
+ "test": "vitest run",
76
+ "typecheck": "tsc --noEmit"
77
+ }
6
78
  }