@tantainnovative/ndpr-toolkit 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +80 -38
- package/dist/adapters.d.mts +34 -25
- package/dist/adapters.d.ts +34 -25
- package/dist/breach.d.mts +803 -44
- package/dist/breach.d.ts +803 -44
- package/dist/breach.js +2 -1
- package/dist/breach.mjs +2 -1
- package/dist/{chunk-2WH4DLV5.js → chunk-3EGQWLJ6.js} +3 -3
- package/dist/chunk-B4Z5MBUC.mjs +2 -0
- package/dist/{chunk-LSCMXAPY.mjs → chunk-CKGJK4D7.mjs} +3 -3
- package/dist/{chunk-XSEZDQLB.js → chunk-CKJAECGV.js} +2 -2
- package/dist/{chunk-AHSMDPG5.js → chunk-CPK5D5FY.js} +2 -2
- package/dist/{chunk-DCJK5OZT.mjs → chunk-CWHBCQGT.mjs} +2 -2
- package/dist/{chunk-KSERBMXW.mjs → chunk-F5TXUA4O.mjs} +3 -3
- package/dist/{chunk-BN77GP4W.mjs → chunk-GN5C32JB.mjs} +2 -2
- package/dist/{chunk-ZLSWOFAY.mjs → chunk-GRLIPT5V.mjs} +2 -2
- package/dist/{chunk-DUY6F3GT.mjs → chunk-H3EYBSVP.mjs} +3 -3
- package/dist/{chunk-MG73MOZC.mjs → chunk-I557S566.mjs} +2 -2
- package/dist/{chunk-QVULSG6J.mjs → chunk-ID2NYIVE.mjs} +3 -3
- package/dist/chunk-J5WCPZLW.js +2 -0
- package/dist/{chunk-4R42ZNO7.mjs → chunk-JFFOPHU3.mjs} +57 -57
- package/dist/{chunk-P2YV6DR3.js → chunk-LIM64IV2.js} +3 -3
- package/dist/chunk-LU7PKE7Y.mjs +2 -0
- package/dist/{chunk-HQSU7LGM.js → chunk-LWXZMKC2.js} +4 -4
- package/dist/{chunk-XMBSJJ5U.js → chunk-ORFC66EA.js} +3 -3
- package/dist/{chunk-VTITKWGX.mjs → chunk-QSVVAZVT.mjs} +2 -2
- package/dist/chunk-SCWNM4PC.mjs +2 -0
- package/dist/{chunk-EHAZIKDX.js → chunk-SKKOMFXH.js} +2 -2
- package/dist/{chunk-WH6ZMUOS.mjs → chunk-TUNQUVHU.mjs} +2 -2
- package/dist/chunk-TV4U6AIS.js +2 -0
- package/dist/{chunk-ZYLDLGFL.js → chunk-VIQUXWJC.js} +2 -2
- package/dist/{chunk-SUEGUY35.js → chunk-XIM7KMD6.js} +2 -2
- package/dist/{chunk-P6QAFBCV.js → chunk-XNSZ7KUH.js} +2 -2
- package/dist/{chunk-RNTNHVKZ.js → chunk-YPKUHSK4.js} +2 -2
- package/dist/{chunk-UFPSUO52.js → chunk-Z73T6MWY.js} +57 -57
- package/dist/consent.d.mts +648 -84
- package/dist/consent.d.ts +648 -84
- package/dist/consent.js +2 -1
- package/dist/consent.mjs +2 -1
- package/dist/core.d.mts +2049 -23
- package/dist/core.d.ts +2049 -23
- package/dist/core.js +1 -1
- package/dist/core.mjs +1 -1
- package/dist/cross-border.d.mts +470 -99
- package/dist/cross-border.d.ts +470 -99
- package/dist/cross-border.js +1 -0
- package/dist/cross-border.mjs +1 -0
- package/dist/dpia.d.mts +591 -37
- package/dist/dpia.d.ts +591 -37
- package/dist/dpia.js +1 -0
- package/dist/dpia.mjs +1 -0
- package/dist/dsr.d.mts +654 -37
- package/dist/dsr.d.ts +654 -37
- package/dist/dsr.js +2 -1
- package/dist/dsr.mjs +2 -1
- package/dist/hooks.d.mts +2174 -30
- package/dist/hooks.d.ts +2174 -30
- package/dist/hooks.js +2 -1
- package/dist/hooks.mjs +2 -1
- package/dist/index.d.mts +4428 -43
- package/dist/index.d.ts +4428 -43
- package/dist/index.js +2 -1
- package/dist/index.mjs +2 -1
- package/dist/lawful-basis.d.mts +368 -32
- package/dist/lawful-basis.d.ts +368 -32
- package/dist/lawful-basis.js +1 -0
- package/dist/lawful-basis.mjs +1 -0
- package/dist/policy.d.mts +1178 -83
- package/dist/policy.d.ts +1178 -83
- package/dist/policy.js +2 -1
- package/dist/policy.mjs +2 -1
- package/dist/presets.d.mts +1020 -114
- package/dist/presets.d.ts +1020 -114
- package/dist/presets.js +2 -1
- package/dist/presets.mjs +2 -1
- package/dist/ropa.d.mts +396 -31
- package/dist/ropa.d.ts +396 -31
- package/dist/ropa.js +2 -1
- package/dist/ropa.mjs +2 -1
- package/dist/server.d.mts +2133 -24
- package/dist/server.d.ts +2133 -24
- package/dist/server.js +1 -1
- package/dist/server.mjs +1 -1
- package/dist/unstyled.d.mts +523 -55
- package/dist/unstyled.d.ts +523 -55
- package/dist/unstyled.js +2 -1
- package/dist/unstyled.mjs +2 -1
- package/package.json +3 -3
- package/dist/BreachReportForm-DpRrBoxU.d.ts +0 -158
- package/dist/BreachReportForm-yJ2Zl6gz.d.mts +0 -158
- package/dist/ConsentBanner-F5ayys5K.d.mts +0 -156
- package/dist/ConsentBanner-VqIPophc.d.ts +0 -156
- package/dist/ConsentManager-C7I3PDe8.d.mts +0 -105
- package/dist/ConsentManager-CQ2IZtUU.d.ts +0 -105
- package/dist/CrossBorderTransferManager-D5Lc0e46.d.ts +0 -90
- package/dist/CrossBorderTransferManager-DkZhv9vD.d.mts +0 -90
- package/dist/DPIAQuestionnaire-VXBoWFMC.d.ts +0 -123
- package/dist/DPIAQuestionnaire-jkt1Veb6.d.mts +0 -123
- package/dist/DSRRequestForm-D8rPTNmU.d.ts +0 -146
- package/dist/DSRRequestForm-DRouEr9j.d.mts +0 -146
- package/dist/DSRTracker-Bl__d4df.d.ts +0 -163
- package/dist/DSRTracker-CSVDfgQQ.d.mts +0 -163
- package/dist/LawfulBasisTracker-CBqOxX1D.d.mts +0 -85
- package/dist/LawfulBasisTracker-Cg30NbDA.d.ts +0 -85
- package/dist/NDPRDashboard-CLJpEg0X.d.mts +0 -44
- package/dist/NDPRDashboard-DDWNd2Ah.d.ts +0 -44
- package/dist/NDPRProvider-DYFb8xEl.d.ts +0 -68
- package/dist/NDPRProvider-U3QNu6MA.d.mts +0 -68
- package/dist/PolicyExporter-Bgi6nz82.d.mts +0 -291
- package/dist/PolicyExporter-BnvuFncj.d.ts +0 -291
- package/dist/ROPAManager-BS4eB8Hw.d.mts +0 -79
- package/dist/ROPAManager-qxTrXLkD.d.ts +0 -79
- package/dist/RegulatoryReportGenerator-BUYgzTTT.d.ts +0 -282
- package/dist/RegulatoryReportGenerator-DwcHcEFp.d.mts +0 -282
- package/dist/StepIndicator-CgrlokSV.d.ts +0 -171
- package/dist/StepIndicator-W8S_QjgO.d.mts +0 -171
- package/dist/breach-B_-6lDqS.d.mts +0 -17
- package/dist/breach-CzXqSsaY.d.ts +0 -17
- package/dist/breach-Eu9byel8.d.mts +0 -185
- package/dist/breach-Eu9byel8.d.ts +0 -185
- package/dist/chunk-5X32J5IA.mjs +0 -2
- package/dist/chunk-7D2OIPHH.mjs +0 -2
- package/dist/chunk-JKKRPS4P.js +0 -2
- package/dist/chunk-NCOZB2WU.mjs +0 -2
- package/dist/chunk-RGNP45VR.js +0 -2
- package/dist/compliance-score-racQe_E_.d.mts +0 -115
- package/dist/compliance-score-racQe_E_.d.ts +0 -115
- package/dist/consent-CmVzqZUk.d.mts +0 -99
- package/dist/consent-CmVzqZUk.d.ts +0 -99
- package/dist/consent-audit-BdByjYlM.d.mts +0 -65
- package/dist/consent-audit-DhbfMR0n.d.ts +0 -65
- package/dist/cross-border-BBi9rZyO.d.mts +0 -54
- package/dist/cross-border-Dy-U9Hu6.d.ts +0 -54
- package/dist/cross-border-UyT00llA.d.mts +0 -141
- package/dist/cross-border-UyT00llA.d.ts +0 -141
- package/dist/docx-BxKascXN.d.ts +0 -64
- package/dist/docx-CV7Vsry_.d.mts +0 -64
- package/dist/dpia-D82hUrJe.d.ts +0 -15
- package/dist/dpia-DQDFw2_l.d.mts +0 -15
- package/dist/dpia-c9GiiOq0.d.mts +0 -137
- package/dist/dpia-c9GiiOq0.d.ts +0 -137
- package/dist/dsr-CIx5sd7e.d.ts +0 -14
- package/dist/dsr-XZ_HqTlA.d.mts +0 -14
- package/dist/dsr-yKbqX531.d.mts +0 -128
- package/dist/dsr-yKbqX531.d.ts +0 -128
- package/dist/lawful-basis-BEyI0kGg.d.ts +0 -57
- package/dist/lawful-basis-C2eGaoHM.d.mts +0 -57
- package/dist/lawful-basis-Cv1VmDLn.d.mts +0 -112
- package/dist/lawful-basis-Cv1VmDLn.d.ts +0 -112
- package/dist/locale-CxJx2tzn.d.mts +0 -25
- package/dist/locale-DSkrtf-c.d.ts +0 -25
- package/dist/policy-engine-CCUCud2T.d.ts +0 -154
- package/dist/policy-engine-fYSqEqSW.d.mts +0 -154
- package/dist/policy-sections-BYx6fEFk.d.ts +0 -56
- package/dist/policy-sections-Dm97Nq8m.d.mts +0 -56
- package/dist/policy-templates-DhLwq4R-.d.ts +0 -43
- package/dist/policy-templates-DwYl2329.d.mts +0 -43
- package/dist/privacy-Ca6te9Ir.d.mts +0 -138
- package/dist/privacy-Ca6te9Ir.d.ts +0 -138
- package/dist/ropa-BDTM06tr.d.ts +0 -152
- package/dist/ropa-CFHuT7jE.d.mts +0 -152
- package/dist/ropa-CyynscU6.d.ts +0 -51
- package/dist/ropa-NIgxd8uP.d.mts +0 -51
- package/dist/sanitize-CxxwKxAx.d.mts +0 -94
- package/dist/sanitize-CxxwKxAx.d.ts +0 -94
- package/dist/styling-BMDGQDgS.d.mts +0 -64
- package/dist/styling-BaoQtV06.d.ts +0 -64
- package/dist/types-DK2CoKOC.d.mts +0 -10
- package/dist/types-DK2CoKOC.d.ts +0 -10
- package/dist/useAdaptivePolicyWizard-BnjW4OR4.d.mts +0 -52
- package/dist/useAdaptivePolicyWizard-sb3m4-Zk.d.ts +0 -52
- package/dist/useBreach-CPr86Yan.d.mts +0 -115
- package/dist/useBreach-DkVXvtJK.d.ts +0 -115
- package/dist/useConsent-DCNkIJHR.d.mts +0 -75
- package/dist/useConsent-dOcELSfX.d.ts +0 -75
- package/dist/useCrossBorderTransfer-DixjLjN1.d.mts +0 -78
- package/dist/useCrossBorderTransfer-DvSq06lv.d.ts +0 -78
- package/dist/useDPIA-B6180UQn.d.mts +0 -109
- package/dist/useDPIA-CTqbNbww.d.ts +0 -109
- package/dist/useDSR-WvHk8_iu.d.mts +0 -85
- package/dist/useDSR-wH4H6hSM.d.ts +0 -85
- package/dist/useDefaultPrivacyPolicy-Cs2WQSYQ.d.mts +0 -162
- package/dist/useDefaultPrivacyPolicy-DkOqMg2e.d.ts +0 -162
- package/dist/useLawfulBasis-CKJ-kw84.d.mts +0 -79
- package/dist/useLawfulBasis-DFTmu1ca.d.ts +0 -79
- package/dist/useROPA-BSSU1rfx.d.ts +0 -76
- package/dist/useROPA-C2hjaBTz.d.mts +0 -76
package/dist/policy.d.mts
CHANGED
|
@@ -1,83 +1,1178 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
1
|
+
import * as React_2 from 'react';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
|
|
4
|
+
export declare const AdaptivePolicyWizard: React__default.FC<AdaptivePolicyWizardProps>;
|
|
5
|
+
|
|
6
|
+
declare interface AdaptivePolicyWizardProps {
|
|
7
|
+
adapter?: StorageAdapter<PolicyDraft>;
|
|
8
|
+
onComplete?: (policy: PrivacyPolicy) => void;
|
|
9
|
+
classNames?: Record<string, string>;
|
|
10
|
+
unstyled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Assemble an ordered, NDPA-aligned array of privacy-policy sections from
|
|
15
|
+
* a {@link TemplateContext}. This is the canonical "compute the policy"
|
|
16
|
+
* function — it produces structured `PolicySection[]` data that downstream
|
|
17
|
+
* renderers (`exportHTML`, `exportMarkdown`, `exportPDF`, `exportDOCX`,
|
|
18
|
+
* `<PolicyPage />`) consume.
|
|
19
|
+
*
|
|
20
|
+
* Section composition:
|
|
21
|
+
* - **Core sections** (always included): Introduction, Data Collection,
|
|
22
|
+
* Legal Basis, Data Usage, Data Sharing, Data Retention, Data Security,
|
|
23
|
+
* Data Subject Rights, Contact Information.
|
|
24
|
+
* - **Conditional sections** (included based on context flags):
|
|
25
|
+
* - `hasChildrenData` → Children's Data Protection (NDPA §31)
|
|
26
|
+
* - `hasSensitiveData` → Sensitive / Special-Category Data
|
|
27
|
+
* - `hasCrossBorderTransfer` → Cross-Border Transfers (NDPA Part VI)
|
|
28
|
+
* - `hasAutomatedDecisions` → Automated Decision-Making (NDPA §37)
|
|
29
|
+
*
|
|
30
|
+
* Section text uses `«TODO: fieldName»` markers (see {@link UNFILLED_PREFIX})
|
|
31
|
+
* for any required org-info field that's empty in the context. Pair with
|
|
32
|
+
* {@link findUnfilledTokens} to surface those before publishing.
|
|
33
|
+
*
|
|
34
|
+
* @param context - Organisation info, data categories, processing purposes,
|
|
35
|
+
* third-party processors, and feature flags. Build a default
|
|
36
|
+
* context with `createDefaultContext()` then mutate.
|
|
37
|
+
* @returns An ordered array of {@link PolicySection} objects ready to pass
|
|
38
|
+
* to `exportHTML(policy)` or `<PolicyPage policy={...} />`.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { assemblePolicy, createDefaultContext } from '@tantainnovative/ndpr-toolkit/server';
|
|
43
|
+
*
|
|
44
|
+
* const ctx = createDefaultContext();
|
|
45
|
+
* ctx.org.name = 'Acme Nigeria Ltd';
|
|
46
|
+
* ctx.org.privacyEmail = 'privacy@acme.ng';
|
|
47
|
+
* ctx.hasCrossBorderTransfer = true;
|
|
48
|
+
*
|
|
49
|
+
* const sections = assemblePolicy(ctx);
|
|
50
|
+
* // sections is a 10-element array (9 core + 1 cross-border)
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function assemblePolicy(context: TemplateContext): PolicySection[];
|
|
54
|
+
|
|
55
|
+
/** A single gap found during NDPA compliance evaluation. */
|
|
56
|
+
export declare interface ComplianceGap {
|
|
57
|
+
/** Machine-readable requirement identifier. */
|
|
58
|
+
requirementId: string;
|
|
59
|
+
/** Human-readable name of the requirement. */
|
|
60
|
+
requirement: string;
|
|
61
|
+
/** Reference to the relevant NDPA section. */
|
|
62
|
+
ndpaSection: string;
|
|
63
|
+
/** How severe the gap is. */
|
|
64
|
+
severity: 'critical' | 'important' | 'recommended';
|
|
65
|
+
/** Explanation of what is missing. */
|
|
66
|
+
message: string;
|
|
67
|
+
/** Suggested fix type for the UI. */
|
|
68
|
+
fixType: 'add_section' | 'add_content' | 'fill_field';
|
|
69
|
+
/** Label for the fix action button. */
|
|
70
|
+
fixLabel: string;
|
|
71
|
+
/** Pre-written content the user can insert to close the gap. */
|
|
72
|
+
suggestedContent?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Result of evaluating a policy against NDPA requirements. */
|
|
76
|
+
export declare interface ComplianceResult {
|
|
77
|
+
/** Points earned. */
|
|
78
|
+
score: number;
|
|
79
|
+
/** Maximum achievable points (115). */
|
|
80
|
+
maxScore: number;
|
|
81
|
+
/** Percentage score (0-100). */
|
|
82
|
+
percentage: number;
|
|
83
|
+
/** Overall compliance rating. */
|
|
84
|
+
rating: 'compliant' | 'nearly_compliant' | 'not_compliant';
|
|
85
|
+
/** List of identified compliance gaps. */
|
|
86
|
+
gaps: ComplianceGap[];
|
|
87
|
+
/** List of requirement ids that passed. */
|
|
88
|
+
passed: string[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates a complete business privacy policy template with default
|
|
93
|
+
* NDPA-compliant sections and variables.
|
|
94
|
+
*
|
|
95
|
+
* @returns An object containing the default sections and variables.
|
|
96
|
+
*/
|
|
97
|
+
export declare function createBusinessPolicyTemplate(): {
|
|
98
|
+
sections: PolicySection[];
|
|
99
|
+
variables: PolicyVariable[];
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates a default TemplateContext with sensible empty/initial values.
|
|
104
|
+
* Useful for initialising the wizard state before the user begins editing.
|
|
105
|
+
*/
|
|
106
|
+
export declare function createDefaultContext(): TemplateContext;
|
|
107
|
+
|
|
108
|
+
/** A user-defined section added to the policy outside the generated ones. */
|
|
109
|
+
export declare interface CustomSection {
|
|
110
|
+
id: string;
|
|
111
|
+
title: string;
|
|
112
|
+
content: string;
|
|
113
|
+
order: number;
|
|
114
|
+
required: false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** A logical category of personal data the organisation may collect. */
|
|
118
|
+
export declare interface DataCategory {
|
|
119
|
+
/** Machine-readable identifier. */
|
|
120
|
+
id: string;
|
|
121
|
+
/** Human-readable label shown in the wizard. */
|
|
122
|
+
label: string;
|
|
123
|
+
/** Grouping for display and compliance checks. */
|
|
124
|
+
group: 'identity' | 'financial' | 'behavioral' | 'sensitive' | 'children';
|
|
125
|
+
/** Specific data points within this category. */
|
|
126
|
+
dataPoints: string[];
|
|
127
|
+
/** Whether this category is currently selected by the user. */
|
|
128
|
+
selected: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Comprehensive set of 16 data categories spanning identity, financial,
|
|
133
|
+
* behavioral, sensitive, and children groups. Used to populate the wizard
|
|
134
|
+
* and drive adaptive section generation.
|
|
135
|
+
*/
|
|
136
|
+
export declare const DEFAULT_DATA_CATEGORIES: DataCategory[];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Default NDPA-compliant privacy policy sections.
|
|
140
|
+
* Each section uses {{variable}} placeholders that are resolved at generation time.
|
|
141
|
+
*/
|
|
142
|
+
export declare const DEFAULT_POLICY_SECTIONS: PolicySection[];
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Default policy variables for NDPA-compliant privacy policies.
|
|
146
|
+
* These map to the {{variable}} placeholders used in DEFAULT_POLICY_SECTIONS.
|
|
147
|
+
*/
|
|
148
|
+
export declare const DEFAULT_POLICY_VARIABLES: PolicyVariable[];
|
|
149
|
+
|
|
150
|
+
/** Options for DOCX export of the finalised policy. */
|
|
151
|
+
declare interface DOCXExportOptions {
|
|
152
|
+
includeTOC?: boolean;
|
|
153
|
+
filename?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* NDPA policy compliance checker.
|
|
158
|
+
*
|
|
159
|
+
* Evaluates a {@link PrivacyPolicy} against 15 requirements drawn from
|
|
160
|
+
* the Nigeria Data Protection Act (NDPA) 2023, producing a scored
|
|
161
|
+
* {@link ComplianceResult} with actionable gaps.
|
|
162
|
+
*
|
|
163
|
+
* Scoring:
|
|
164
|
+
* 6 critical @ 10 pts = 60
|
|
165
|
+
* 5 important @ 7 pts = 35
|
|
166
|
+
* 4 recommended @ 5 pts = 20
|
|
167
|
+
* Total max = 115
|
|
168
|
+
*
|
|
169
|
+
* Rating thresholds:
|
|
170
|
+
* >= 100 → compliant
|
|
171
|
+
* >= 80 → nearly_compliant
|
|
172
|
+
* < 80 → not_compliant
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Evaluates a privacy policy against 15 NDPA 2023 requirements and
|
|
177
|
+
* returns a scored compliance result with actionable gap information.
|
|
178
|
+
*
|
|
179
|
+
* @param policy - The privacy policy to evaluate.
|
|
180
|
+
* @param context - The template context that was used to generate the policy.
|
|
181
|
+
* @returns A {@link ComplianceResult} with score, rating, gaps, and passed ids.
|
|
182
|
+
*/
|
|
183
|
+
export declare function evaluatePolicyCompliance(policy: PrivacyPolicy, context: TemplateContext): ComplianceResult;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Export a PrivacyPolicy as a Word (.docx) Blob using the `docx` library
|
|
187
|
+
* (optional peer dependency).
|
|
188
|
+
*
|
|
189
|
+
* Features:
|
|
190
|
+
* - Title paragraph with large bold text
|
|
191
|
+
* - Organisation name + version subtitle
|
|
192
|
+
* - Optional table of contents placeholder heading
|
|
193
|
+
* - All included policy sections as Heading 1 + body paragraphs / bullet lists
|
|
194
|
+
* - Running header (org name) and page-number footer on every page
|
|
195
|
+
*
|
|
196
|
+
* @throws {Error} if the `docx` package is not installed
|
|
197
|
+
*/
|
|
198
|
+
export declare function exportDOCX(policy: PrivacyPolicy, options?: DOCXExportOptions): Promise<Blob>;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Export a PrivacyPolicy as a self-contained HTML string.
|
|
202
|
+
*
|
|
203
|
+
* The returned string includes:
|
|
204
|
+
* - An embedded `<style>` block (responsive, dark/light, print-friendly)
|
|
205
|
+
* - An `<article>` wrapper with semantic markup
|
|
206
|
+
* - A `<nav>` table of contents with anchor links
|
|
207
|
+
* - A `<section>` for every included policy section
|
|
208
|
+
* - A metadata footer (org name, effective date, version, generator credit)
|
|
209
|
+
* - Optional custom CSS injection via `options.customCSS`
|
|
210
|
+
*/
|
|
211
|
+
export declare function exportHTML(policy: PrivacyPolicy, options?: HTMLExportOptions): string;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Export a PrivacyPolicy as a clean Markdown string.
|
|
215
|
+
*
|
|
216
|
+
* Structure:
|
|
217
|
+
* ```
|
|
218
|
+
* # Policy Title
|
|
219
|
+
* _Effective: date | Version: X | Org Name_
|
|
220
|
+
*
|
|
221
|
+
* ## Table of Contents
|
|
222
|
+
* - [Section Title](#anchor)
|
|
223
|
+
*
|
|
224
|
+
* ## 1. Section Title
|
|
225
|
+
* Section content...
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export declare function exportMarkdown(policy: PrivacyPolicy): string;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Export a PrivacyPolicy to a PDF Blob using jspdf (optional peer dependency).
|
|
232
|
+
*
|
|
233
|
+
* Features:
|
|
234
|
+
* - Optional cover page with title, organisation, date, version and compliance badge
|
|
235
|
+
* - Optional table of contents page
|
|
236
|
+
* - One section per heading, content reflowed to fit the page
|
|
237
|
+
* - Automatic page breaks
|
|
238
|
+
* - Page header (org name) and footer (page X of Y) on every page
|
|
239
|
+
* - PDF metadata (title, author, subject, keywords)
|
|
240
|
+
*
|
|
241
|
+
* @throws {Error} if the `jspdf` package is not installed
|
|
242
|
+
*/
|
|
243
|
+
export declare function exportPDF(policy: PrivacyPolicy, options?: PDFExportOptions): Promise<Blob>;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Scan rendered policy text for unfilled placeholder tokens.
|
|
247
|
+
*
|
|
248
|
+
* Detects two token forms:
|
|
249
|
+
* - `«TODO: fieldName»` — sentinel emitted by {@link assemblePolicy} when
|
|
250
|
+
* a required org-info field is missing from the context.
|
|
251
|
+
* - `{{fieldName}}` — mustache token that escaped substitution (either
|
|
252
|
+
* because the variable wasn't declared or its value was empty).
|
|
253
|
+
*
|
|
254
|
+
* Returns a deduplicated list of the field names found. An empty array
|
|
255
|
+
* means the rendered text is fully populated.
|
|
256
|
+
*
|
|
257
|
+
* Two recommended uses:
|
|
258
|
+
*
|
|
259
|
+
* 1. **CI guard** — assert your canonical org-info fixture renders without
|
|
260
|
+
* leaving any tokens behind:
|
|
261
|
+
* ```ts
|
|
262
|
+
* const html = exportHTML(policy);
|
|
263
|
+
* expect(findUnfilledTokens(html)).toEqual([]);
|
|
264
|
+
* ```
|
|
265
|
+
*
|
|
266
|
+
* 2. **Runtime guard** — surface a clear error to compliance officers
|
|
267
|
+
* before they publish a policy with `{{orgName}}` visible to visitors:
|
|
268
|
+
* ```ts
|
|
269
|
+
* const missing = findUnfilledTokens(getPolicyText().fullText);
|
|
270
|
+
* if (missing.length) throw new Error(`Policy is missing: ${missing.join(', ')}`);
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* @param rendered - The substituted policy text (from `exportHTML`,
|
|
274
|
+
* `exportMarkdown`, or `usePrivacyPolicy().getPolicyText().fullText`).
|
|
275
|
+
* @returns Deduplicated array of unfilled field names; `[]` if fully filled.
|
|
276
|
+
*/
|
|
277
|
+
export declare function findUnfilledTokens(rendered: string): string[];
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Generates policy text by replacing variables in a template with organization-specific values
|
|
281
|
+
* @param sectionsOrTemplate The policy sections or template string to generate text for
|
|
282
|
+
* @param organizationInfoOrVariables The organization information or variable map to use for replacement
|
|
283
|
+
* @returns The generated policy text or an object with the generated text and metadata
|
|
284
|
+
*/
|
|
285
|
+
export declare function generatePolicyText(sectionsOrTemplate: PolicySection[] | string, organizationInfoOrVariables: OrganizationInfo | Record<string, string>): string | {
|
|
286
|
+
fullText: string;
|
|
287
|
+
sectionTexts: Record<string, string>;
|
|
288
|
+
missingVariables: string[];
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/** Options for HTML export of the finalised policy. */
|
|
292
|
+
declare interface HTMLExportOptions {
|
|
293
|
+
includeStyles?: boolean;
|
|
294
|
+
includePrintCSS?: boolean;
|
|
295
|
+
customCSS?: string;
|
|
296
|
+
/**
|
|
297
|
+
* Theme controlling the embedded design tokens.
|
|
298
|
+
*
|
|
299
|
+
* - `'light'` (default): emits the light token palette only. No
|
|
300
|
+
* `prefers-color-scheme: dark` block is included, so a visitor's OS
|
|
301
|
+
* dark-mode setting will NOT recolour the policy. This is the right
|
|
302
|
+
* default for an embedded compliance widget — most consumer host sites
|
|
303
|
+
* are single-theme and Shadow DOM does not isolate `prefers-color-scheme`.
|
|
304
|
+
* - `'dark'`: emits the dark token palette as the primary style.
|
|
305
|
+
* - `'auto'`: emits light tokens plus a `@media (prefers-color-scheme: dark)`
|
|
306
|
+
* block that swaps to dark on the user's OS preference. Use this when
|
|
307
|
+
* your host site genuinely follows OS dark mode and you want the policy
|
|
308
|
+
* to match.
|
|
309
|
+
*
|
|
310
|
+
* Pre-3.4.1 the export effectively behaved like `'auto'` unconditionally,
|
|
311
|
+
* which leaked dark colours into light-only host sites via Shadow DOM.
|
|
312
|
+
*
|
|
313
|
+
* @default 'light'
|
|
314
|
+
*/
|
|
315
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Policy engine types for the adaptive privacy policy generator.
|
|
320
|
+
* These types power the wizard-driven policy builder, compliance checker,
|
|
321
|
+
* and export functionality — all aligned with the NDPA 2023.
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
/** Industry verticals with sector-specific compliance requirements. */
|
|
325
|
+
export declare type Industry = 'fintech' | 'healthcare' | 'ecommerce' | 'saas' | 'education' | 'government' | 'other';
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Represents organization information for a privacy policy
|
|
329
|
+
*/
|
|
330
|
+
export declare interface OrganizationInfo {
|
|
331
|
+
/** Name of the organization */
|
|
332
|
+
name: string;
|
|
333
|
+
/** Website URL of the organization */
|
|
334
|
+
website: string;
|
|
335
|
+
/** Contact email for privacy inquiries */
|
|
336
|
+
privacyEmail: string;
|
|
337
|
+
/** Physical address of the organization */
|
|
338
|
+
address?: string;
|
|
339
|
+
/** Phone number for privacy inquiries */
|
|
340
|
+
privacyPhone?: string;
|
|
341
|
+
/** Name of the Data Protection Officer */
|
|
342
|
+
dpoName?: string;
|
|
343
|
+
/** Email of the Data Protection Officer */
|
|
344
|
+
dpoEmail?: string;
|
|
345
|
+
/** Industry or sector of the organization */
|
|
346
|
+
industry?: string;
|
|
347
|
+
/** NDPC registration number (if registered) */
|
|
348
|
+
ndpcRegistrationNumber?: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** Organisation size tiers — affects complexity of generated language. */
|
|
352
|
+
export declare type OrgSize = 'startup' | 'midsize' | 'enterprise';
|
|
353
|
+
|
|
354
|
+
/** Options for PDF export of the finalised policy. */
|
|
355
|
+
declare interface PDFExportOptions {
|
|
356
|
+
includeCoverPage?: boolean;
|
|
357
|
+
includeTOC?: boolean;
|
|
358
|
+
includeComplianceBadge?: boolean;
|
|
359
|
+
logoUrl?: string;
|
|
360
|
+
filename?: string;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export declare const Policy: {
|
|
364
|
+
Provider: React_2.FC<PolicyProviderProps>;
|
|
365
|
+
Generator: React_2.FC<PolicyGeneratorProps>;
|
|
366
|
+
Preview: React_2.FC<PolicyPreviewProps>;
|
|
367
|
+
Exporter: React_2.FC<PolicyExporterProps>;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
declare interface PolicyContextValue extends UsePrivacyPolicyReturn {
|
|
371
|
+
templates: PolicyTemplate[];
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** Represents an in-progress policy being built in the wizard. */
|
|
375
|
+
export declare interface PolicyDraft {
|
|
376
|
+
/** Unique identifier for the draft. */
|
|
377
|
+
id: string;
|
|
378
|
+
/** The template context driving section generation. */
|
|
379
|
+
templateContext: TemplateContext;
|
|
380
|
+
/** Custom sections added by the user. */
|
|
381
|
+
customSections: CustomSection[];
|
|
382
|
+
/** Per-section content overrides keyed by section id. */
|
|
383
|
+
sectionOverrides: Record<string, string>;
|
|
384
|
+
/** Ordered list of section ids defining the final order. */
|
|
385
|
+
sectionOrder: string[];
|
|
386
|
+
/** Current wizard step (0-indexed). */
|
|
387
|
+
currentStep: number;
|
|
388
|
+
/** Timestamp of the last save. */
|
|
389
|
+
lastSavedAt: number;
|
|
390
|
+
/** The draft is always in "draft" status until finalised. */
|
|
391
|
+
status: 'draft';
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export declare const PolicyExporter: React__default.FC<PolicyExporterProps>;
|
|
395
|
+
|
|
396
|
+
declare interface PolicyExporterClassNames {
|
|
397
|
+
/** Root container */
|
|
398
|
+
root?: string;
|
|
399
|
+
/** Header area containing title and description */
|
|
400
|
+
header?: string;
|
|
401
|
+
/** Title element */
|
|
402
|
+
title?: string;
|
|
403
|
+
/** Description element */
|
|
404
|
+
description?: string;
|
|
405
|
+
/** Format selector container */
|
|
406
|
+
formatSelector?: string;
|
|
407
|
+
/** Individual format option */
|
|
408
|
+
formatOption?: string;
|
|
409
|
+
/** Export button */
|
|
410
|
+
exportButton?: string;
|
|
411
|
+
/** Alias for exportButton */
|
|
412
|
+
primaryButton?: string;
|
|
413
|
+
/** NDPA compliance / export tips notice */
|
|
414
|
+
complianceNotice?: string;
|
|
415
|
+
/** Preview / export history area */
|
|
416
|
+
preview?: string;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
declare interface PolicyExporterProps {
|
|
420
|
+
/**
|
|
421
|
+
* The policy content to export
|
|
422
|
+
*/
|
|
423
|
+
content: string;
|
|
424
|
+
/**
|
|
425
|
+
* The policy title
|
|
426
|
+
*/
|
|
427
|
+
title?: string;
|
|
428
|
+
/**
|
|
429
|
+
* The organization name to include in the exported policy
|
|
430
|
+
*/
|
|
431
|
+
organizationName?: string;
|
|
432
|
+
/**
|
|
433
|
+
* The last updated date to include in the exported policy
|
|
434
|
+
*/
|
|
435
|
+
lastUpdated?: Date;
|
|
436
|
+
/**
|
|
437
|
+
* Callback function called when the export is complete
|
|
438
|
+
*/
|
|
439
|
+
onExportComplete?: (format: string, url: string) => void;
|
|
440
|
+
/**
|
|
441
|
+
* Title displayed on the exporter
|
|
442
|
+
* @default "Export Privacy Policy"
|
|
443
|
+
*/
|
|
444
|
+
componentTitle?: string;
|
|
445
|
+
/**
|
|
446
|
+
* Description text displayed on the exporter
|
|
447
|
+
* @default "Export your NDPA-compliant privacy policy in various formats."
|
|
448
|
+
*/
|
|
449
|
+
description?: string;
|
|
450
|
+
/**
|
|
451
|
+
* Custom CSS class for the exporter
|
|
452
|
+
*/
|
|
453
|
+
className?: string;
|
|
454
|
+
/**
|
|
455
|
+
* Custom CSS class for the buttons
|
|
456
|
+
*/
|
|
457
|
+
buttonClassName?: string;
|
|
458
|
+
/**
|
|
459
|
+
* Whether to show the export history
|
|
460
|
+
* @default true
|
|
461
|
+
*/
|
|
462
|
+
showExportHistory?: boolean;
|
|
463
|
+
/**
|
|
464
|
+
* Whether to include the NDPA compliance notice in the exported policy
|
|
465
|
+
* @default true
|
|
466
|
+
*/
|
|
467
|
+
includeComplianceNotice?: boolean;
|
|
468
|
+
/**
|
|
469
|
+
* Whether to include the organization logo in the exported policy
|
|
470
|
+
* @default false
|
|
471
|
+
*/
|
|
472
|
+
includeLogo?: boolean;
|
|
473
|
+
/**
|
|
474
|
+
* URL of the organization logo
|
|
475
|
+
*/
|
|
476
|
+
logoUrl?: string;
|
|
477
|
+
/**
|
|
478
|
+
* Custom CSS styles for the exported policy
|
|
479
|
+
*/
|
|
480
|
+
customStyles?: string;
|
|
481
|
+
/**
|
|
482
|
+
* Override class names for internal elements
|
|
483
|
+
*/
|
|
484
|
+
classNames?: PolicyExporterClassNames;
|
|
485
|
+
/**
|
|
486
|
+
* If true, removes all default styles. Use with classNames to apply your own.
|
|
487
|
+
* @default false
|
|
488
|
+
*/
|
|
489
|
+
unstyled?: boolean;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Privacy policy generator component. Implements NDPA Section 24 transparency requirements,
|
|
494
|
+
* helping organizations generate compliant privacy policies that disclose required information.
|
|
495
|
+
*/
|
|
496
|
+
export declare const PolicyGenerator: React__default.FC<PolicyGeneratorProps>;
|
|
497
|
+
|
|
498
|
+
declare interface PolicyGeneratorClassNames {
|
|
499
|
+
/** Root container */
|
|
500
|
+
root?: string;
|
|
501
|
+
/** Header area containing title and description */
|
|
502
|
+
header?: string;
|
|
503
|
+
/** Title element */
|
|
504
|
+
title?: string;
|
|
505
|
+
/** Description element */
|
|
506
|
+
description?: string;
|
|
507
|
+
/** Section list container */
|
|
508
|
+
sectionList?: string;
|
|
509
|
+
/** Individual section item */
|
|
510
|
+
sectionItem?: string;
|
|
511
|
+
/** Variable form container */
|
|
512
|
+
form?: string;
|
|
513
|
+
/** Form input fields */
|
|
514
|
+
input?: string;
|
|
515
|
+
/** Generate button */
|
|
516
|
+
generateButton?: string;
|
|
517
|
+
/** Alias for generateButton */
|
|
518
|
+
primaryButton?: string;
|
|
519
|
+
/** NDPA compliance notice */
|
|
520
|
+
complianceNotice?: string;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
declare interface PolicyGeneratorProps {
|
|
524
|
+
/**
|
|
525
|
+
* List of policy sections
|
|
526
|
+
* @default DEFAULT_POLICY_SECTIONS
|
|
527
|
+
*/
|
|
528
|
+
sections?: PolicySection[];
|
|
529
|
+
/**
|
|
530
|
+
* List of policy variables
|
|
531
|
+
* @default DEFAULT_POLICY_VARIABLES
|
|
532
|
+
*/
|
|
533
|
+
variables?: PolicyVariable[];
|
|
534
|
+
/**
|
|
535
|
+
* Callback function called when the policy is generated
|
|
536
|
+
*/
|
|
537
|
+
onGenerate: (policy: {
|
|
538
|
+
sections: PolicySection[];
|
|
539
|
+
variables: PolicyVariable[];
|
|
540
|
+
content: string;
|
|
541
|
+
}) => void;
|
|
542
|
+
/**
|
|
543
|
+
* Title displayed on the generator
|
|
544
|
+
* @default "NDPA Privacy Policy Generator"
|
|
545
|
+
*/
|
|
546
|
+
title?: string;
|
|
547
|
+
/**
|
|
548
|
+
* Description text displayed on the generator
|
|
549
|
+
* @default "Generate an NDPA-compliant privacy policy for your organization in accordance with NDPA Section 24."
|
|
550
|
+
*/
|
|
551
|
+
description?: string;
|
|
552
|
+
/**
|
|
553
|
+
* Custom CSS class for the generator
|
|
554
|
+
*/
|
|
555
|
+
className?: string;
|
|
556
|
+
/**
|
|
557
|
+
* Custom CSS class for the buttons
|
|
558
|
+
*/
|
|
559
|
+
buttonClassName?: string;
|
|
560
|
+
/**
|
|
561
|
+
* Text for the generate button
|
|
562
|
+
* @default "Generate Policy"
|
|
563
|
+
*/
|
|
564
|
+
generateButtonText?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Whether to show a preview of the generated policy
|
|
567
|
+
* @default true
|
|
568
|
+
*/
|
|
569
|
+
showPreview?: boolean;
|
|
570
|
+
/**
|
|
571
|
+
* Whether to allow editing the policy content
|
|
572
|
+
* @default true
|
|
573
|
+
*/
|
|
574
|
+
allowEditing?: boolean;
|
|
575
|
+
/**
|
|
576
|
+
* Override class names for internal elements
|
|
577
|
+
*/
|
|
578
|
+
classNames?: PolicyGeneratorClassNames;
|
|
579
|
+
/**
|
|
580
|
+
* If true, removes all default styles. Use with classNames to apply your own.
|
|
581
|
+
* @default false
|
|
582
|
+
*/
|
|
583
|
+
unstyled?: boolean;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Renders a full privacy policy from a typed `PrivacyPolicy` object.
|
|
588
|
+
*
|
|
589
|
+
* ## Choosing a mode
|
|
590
|
+
*
|
|
591
|
+
* | mode | renders | SEO | host-CSS isolation | best for |
|
|
592
|
+
* |------|---------|-----|--------------------|----------|
|
|
593
|
+
* | `'shadow'` (default) | Inside a Shadow DOM root, opinionated styles included | ❌ markup is invisible to crawlers (lives in shadow) | ✅ structurally impossible to leak | in-app embeds where you want a polished drop-in widget |
|
|
594
|
+
* | `'inline'` | Directly in the host document body | ✅ crawlable markup | ⚠️ consumer styles the markup themselves | SSR'd `/privacy` pages, public legal pages |
|
|
595
|
+
*
|
|
596
|
+
* Inline mode defaults `includeStyles: false` so bare element selectors
|
|
597
|
+
* (`body`, `article`, `h1`...) don't leak into the host page. The rendered
|
|
598
|
+
* markup is plain semantic HTML — `<article>`, `<section>`, `<h2>`, `<p>`,
|
|
599
|
+
* `<ul>`. Pair it with your own typography to make it look right.
|
|
600
|
+
*
|
|
601
|
+
* @example **Inline mode + Tailwind `@tailwindcss/typography`**
|
|
602
|
+
* ```tsx
|
|
603
|
+
* import { PolicyPage } from '@tantainnovative/ndpr-toolkit';
|
|
604
|
+
*
|
|
605
|
+
* // Wrap with the `prose` class so headings, paragraphs, and lists pick
|
|
606
|
+
* // up Tailwind's typography defaults. dark:prose-invert handles dark mode.
|
|
607
|
+
* <article className="prose prose-slate dark:prose-invert max-w-3xl mx-auto">
|
|
608
|
+
* <PolicyPage policy={policy} mode="inline" />
|
|
609
|
+
* </article>
|
|
610
|
+
* ```
|
|
611
|
+
*
|
|
612
|
+
* @example **Inline mode with shadcn-ui typography**
|
|
613
|
+
* ```tsx
|
|
614
|
+
* <Card>
|
|
615
|
+
* <CardContent className="prose dark:prose-invert">
|
|
616
|
+
* <PolicyPage policy={policy} mode="inline" />
|
|
617
|
+
* </CardContent>
|
|
618
|
+
* </Card>
|
|
619
|
+
* ```
|
|
620
|
+
*
|
|
621
|
+
* @example **Inline mode with raw CSS**
|
|
622
|
+
* ```css
|
|
623
|
+
* .ndpr-policy-page article { font-family: Georgia, serif; line-height: 1.7; }
|
|
624
|
+
* .ndpr-policy-page h2 { font-size: 1.5rem; margin-top: 2rem; }
|
|
625
|
+
* .ndpr-policy-page section { margin-bottom: 1.5rem; }
|
|
626
|
+
* ```
|
|
627
|
+
*
|
|
628
|
+
* @example **Theming the shadow-mode default**
|
|
629
|
+
* ```tsx
|
|
630
|
+
* // Brand the policy without leaving shadow mode — pass theme + customCSS.
|
|
631
|
+
* <PolicyPage
|
|
632
|
+
* policy={policy}
|
|
633
|
+
* options={{
|
|
634
|
+
* theme: 'auto', // or 'light' (default) / 'dark'
|
|
635
|
+
* customCSS: ':root { --color-accent: #1d4ed8; --max-width: 64rem; }',
|
|
636
|
+
* }}
|
|
637
|
+
* />
|
|
638
|
+
* ```
|
|
639
|
+
*
|
|
640
|
+
* HTML is generated internally by `exportHTML` from a typed `PrivacyPolicy`
|
|
641
|
+
* and never contains untrusted user input.
|
|
642
|
+
*/
|
|
643
|
+
export declare const PolicyPage: React__default.FC<PolicyPageProps>;
|
|
644
|
+
|
|
645
|
+
declare type PolicyPageMode = 'shadow' | 'inline';
|
|
646
|
+
|
|
647
|
+
declare interface PolicyPageProps {
|
|
648
|
+
policy: PrivacyPolicy;
|
|
649
|
+
className?: string;
|
|
650
|
+
/**
|
|
651
|
+
* Render mode.
|
|
652
|
+
*
|
|
653
|
+
* - `'shadow'` (default): mounts the rendered policy inside a Shadow DOM
|
|
654
|
+
* root, fully isolating the embedded `<style>` block from the host page.
|
|
655
|
+
* Use this for in-app embeds where you want the rich, opinionated
|
|
656
|
+
* default styling without polluting global CSS. Client-only.
|
|
657
|
+
*
|
|
658
|
+
* - `'inline'`: injects the policy markup directly into the host document.
|
|
659
|
+
* Defaults to `includeStyles: false` so bare element selectors don't
|
|
660
|
+
* leak. Pair with your own CSS / design tokens. SSR-safe.
|
|
661
|
+
*/
|
|
662
|
+
mode?: PolicyPageMode;
|
|
663
|
+
/**
|
|
664
|
+
* Pass-through to {@link exportHTML}. Lets you toggle `includeStyles`,
|
|
665
|
+
* `includePrintCSS`, or inject `customCSS`. Defaults differ by mode:
|
|
666
|
+
* shadow mode includes styles; inline mode omits them.
|
|
667
|
+
*/
|
|
668
|
+
options?: HTMLExportOptions;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export declare const PolicyPreview: React__default.FC<PolicyPreviewProps>;
|
|
672
|
+
|
|
673
|
+
declare interface PolicyPreviewClassNames {
|
|
674
|
+
/** Root container */
|
|
675
|
+
root?: string;
|
|
676
|
+
/** Header area containing title and description */
|
|
677
|
+
header?: string;
|
|
678
|
+
/** Title element */
|
|
679
|
+
title?: string;
|
|
680
|
+
/** Description element */
|
|
681
|
+
description?: string;
|
|
682
|
+
/** Content area wrapping the rendered policy */
|
|
683
|
+
content?: string;
|
|
684
|
+
/** Individual rendered section container */
|
|
685
|
+
section?: string;
|
|
686
|
+
/** Section title within rendered content */
|
|
687
|
+
sectionTitle?: string;
|
|
688
|
+
/** Section content within rendered content */
|
|
689
|
+
sectionContent?: string;
|
|
690
|
+
/** NDPA compliance notice */
|
|
691
|
+
complianceNotice?: string;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
declare interface PolicyPreviewProps {
|
|
695
|
+
/**
|
|
696
|
+
* The policy content to preview
|
|
697
|
+
*/
|
|
698
|
+
content: string;
|
|
699
|
+
/**
|
|
700
|
+
* The policy sections
|
|
701
|
+
*/
|
|
702
|
+
sections?: PolicySection[];
|
|
703
|
+
/**
|
|
704
|
+
* The policy variables
|
|
705
|
+
*/
|
|
706
|
+
variables?: PolicyVariable[];
|
|
707
|
+
/**
|
|
708
|
+
* Callback function called when the policy is exported
|
|
709
|
+
*/
|
|
710
|
+
onExport?: (format: 'pdf' | 'html' | 'markdown' | 'docx') => void;
|
|
711
|
+
/**
|
|
712
|
+
* Callback function called when the policy is edited
|
|
713
|
+
*/
|
|
714
|
+
onEdit?: () => void;
|
|
715
|
+
/**
|
|
716
|
+
* Title displayed on the preview
|
|
717
|
+
* @default "Privacy Policy Preview"
|
|
718
|
+
*/
|
|
719
|
+
title?: string;
|
|
720
|
+
/**
|
|
721
|
+
* Description text displayed on the preview
|
|
722
|
+
* @default "Preview your NDPA-compliant privacy policy before exporting."
|
|
723
|
+
*/
|
|
724
|
+
description?: string;
|
|
725
|
+
/**
|
|
726
|
+
* Custom CSS class for the preview
|
|
727
|
+
*/
|
|
728
|
+
className?: string;
|
|
729
|
+
/**
|
|
730
|
+
* Custom CSS class for the buttons
|
|
731
|
+
*/
|
|
732
|
+
buttonClassName?: string;
|
|
733
|
+
/**
|
|
734
|
+
* Whether to show the export options
|
|
735
|
+
* @default true
|
|
736
|
+
*/
|
|
737
|
+
showExportOptions?: boolean;
|
|
738
|
+
/**
|
|
739
|
+
* Whether to show the edit button
|
|
740
|
+
* @default true
|
|
741
|
+
*/
|
|
742
|
+
showEditButton?: boolean;
|
|
743
|
+
/**
|
|
744
|
+
* Whether to show the table of contents
|
|
745
|
+
* @default true
|
|
746
|
+
*/
|
|
747
|
+
showTableOfContents?: boolean;
|
|
748
|
+
/**
|
|
749
|
+
* Whether to show the policy metadata
|
|
750
|
+
* @default true
|
|
751
|
+
*/
|
|
752
|
+
showMetadata?: boolean;
|
|
753
|
+
/**
|
|
754
|
+
* The organization name to display in the policy
|
|
755
|
+
*/
|
|
756
|
+
organizationName?: string;
|
|
757
|
+
/**
|
|
758
|
+
* The last updated date to display in the policy
|
|
759
|
+
*/
|
|
760
|
+
lastUpdated?: Date;
|
|
761
|
+
/**
|
|
762
|
+
* Override class names for internal elements
|
|
763
|
+
*/
|
|
764
|
+
classNames?: PolicyPreviewClassNames;
|
|
765
|
+
/**
|
|
766
|
+
* If true, removes all default styles. Use with classNames to apply your own.
|
|
767
|
+
* @default false
|
|
768
|
+
*/
|
|
769
|
+
unstyled?: boolean;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export declare const PolicyProvider: React__default.FC<PolicyProviderProps>;
|
|
773
|
+
|
|
774
|
+
export declare interface PolicyProviderProps {
|
|
775
|
+
templates: PolicyTemplate[];
|
|
776
|
+
adapter?: StorageAdapter<PrivacyPolicy>;
|
|
777
|
+
storageKey?: string;
|
|
778
|
+
useLocalStorage?: boolean;
|
|
779
|
+
initialPolicy?: PrivacyPolicy;
|
|
780
|
+
onGenerate?: (policy: PrivacyPolicy) => void;
|
|
781
|
+
children: React__default.ReactNode;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Privacy policy types aligned with NDPA 2023
|
|
786
|
+
* Privacy policies must clearly inform data subjects of their rights under the NDPA
|
|
787
|
+
*/
|
|
788
|
+
/**
|
|
789
|
+
* Represents a section in a privacy policy
|
|
790
|
+
*/
|
|
791
|
+
export declare interface PolicySection {
|
|
792
|
+
/** Unique identifier for the section */
|
|
793
|
+
id: string;
|
|
794
|
+
/** Title of the section */
|
|
795
|
+
title: string;
|
|
796
|
+
/** Description of the section */
|
|
797
|
+
description?: string;
|
|
798
|
+
/** Order of the section in the policy */
|
|
799
|
+
order?: number;
|
|
800
|
+
/** Whether the section is required by NDPA */
|
|
801
|
+
required: boolean;
|
|
802
|
+
/** Template text for the section */
|
|
803
|
+
template: string;
|
|
804
|
+
/**
|
|
805
|
+
* Default content for the section (legacy field)
|
|
806
|
+
* @deprecated Use template instead
|
|
807
|
+
*/
|
|
808
|
+
defaultContent?: string;
|
|
809
|
+
/**
|
|
810
|
+
* Custom content for the section (overrides default content)
|
|
811
|
+
* @deprecated Use template instead
|
|
812
|
+
*/
|
|
813
|
+
customContent?: string;
|
|
814
|
+
/** Whether the section is included in the policy */
|
|
815
|
+
included: boolean;
|
|
816
|
+
/** Variables that can be used in the section content */
|
|
817
|
+
variables?: string[];
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Represents a privacy policy template
|
|
822
|
+
*/
|
|
823
|
+
export declare interface PolicyTemplate {
|
|
824
|
+
/** Unique identifier for the template */
|
|
825
|
+
id: string;
|
|
826
|
+
/** Name of the template */
|
|
827
|
+
name: string;
|
|
828
|
+
/** Description of the template */
|
|
829
|
+
description: string;
|
|
830
|
+
/** Type of organization the template is designed for */
|
|
831
|
+
organizationType: 'business' | 'nonprofit' | 'government' | 'educational';
|
|
832
|
+
/** Sections included in the template */
|
|
833
|
+
sections: PolicySection[];
|
|
834
|
+
/** Variables used across the template */
|
|
835
|
+
variables: Record<string, {
|
|
836
|
+
name: string;
|
|
837
|
+
description: string;
|
|
838
|
+
required: boolean;
|
|
839
|
+
defaultValue?: string;
|
|
840
|
+
}>;
|
|
841
|
+
/** Version of the template */
|
|
842
|
+
version: string;
|
|
843
|
+
/** Last updated date of the template */
|
|
844
|
+
lastUpdated: number;
|
|
845
|
+
/**
|
|
846
|
+
* Whether this template is NDPA 2023 compliant
|
|
847
|
+
*/
|
|
848
|
+
ndpaCompliant: boolean;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Represents a variable in a privacy policy
|
|
853
|
+
*/
|
|
854
|
+
export declare interface PolicyVariable {
|
|
855
|
+
/** Unique identifier for the variable */
|
|
856
|
+
id: string;
|
|
857
|
+
/** Name of the variable as it appears in the template */
|
|
858
|
+
name: string;
|
|
859
|
+
/** Description of the variable */
|
|
860
|
+
description: string;
|
|
861
|
+
/** Default value for the variable */
|
|
862
|
+
defaultValue?: string;
|
|
863
|
+
/** Current value of the variable */
|
|
864
|
+
value: string;
|
|
865
|
+
/** Type of input for the variable */
|
|
866
|
+
inputType: 'text' | 'textarea' | 'email' | 'url' | 'date' | 'select';
|
|
867
|
+
/** Options for select inputs */
|
|
868
|
+
options?: string[];
|
|
869
|
+
/** Whether the variable is required */
|
|
870
|
+
required: boolean;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Represents a generated privacy policy
|
|
875
|
+
*/
|
|
876
|
+
export declare interface PrivacyPolicy {
|
|
877
|
+
/** Unique identifier for the policy */
|
|
878
|
+
id: string;
|
|
879
|
+
/** Title of the policy */
|
|
880
|
+
title: string;
|
|
881
|
+
/** Template used to generate the policy */
|
|
882
|
+
templateId: string;
|
|
883
|
+
/** Organization information */
|
|
884
|
+
organizationInfo: OrganizationInfo;
|
|
885
|
+
/** Sections of the policy */
|
|
886
|
+
sections: PolicySection[];
|
|
887
|
+
/** Values for the variables used in the policy */
|
|
888
|
+
variableValues: Record<string, string>;
|
|
889
|
+
/** Effective date of the policy */
|
|
890
|
+
effectiveDate: number;
|
|
891
|
+
/** Last updated date of the policy */
|
|
892
|
+
lastUpdated: number;
|
|
893
|
+
/** Version of the policy */
|
|
894
|
+
version: string;
|
|
895
|
+
/**
|
|
896
|
+
* Applicable legal frameworks
|
|
897
|
+
*/
|
|
898
|
+
applicableFrameworks?: ('ndpa' | 'ndpr' | 'gdpr' | 'ccpa')[];
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/** Lawful processing purposes recognised under the NDPA. */
|
|
902
|
+
export declare type ProcessingPurpose = 'service_delivery' | 'marketing' | 'analytics' | 'research' | 'legal_compliance' | 'fraud_prevention';
|
|
903
|
+
|
|
904
|
+
export declare interface StorageAdapter<T = unknown> {
|
|
905
|
+
/** Load persisted data. Called once on hook mount. */
|
|
906
|
+
load(): T | null | Promise<T | null>;
|
|
907
|
+
/** Persist data. Called on every state change. */
|
|
908
|
+
save(data: T): void | Promise<void>;
|
|
909
|
+
/** Clear persisted data. Called on reset. */
|
|
910
|
+
remove(): void | Promise<void>;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/** Full context used to generate an adaptive privacy policy. */
|
|
914
|
+
export declare interface TemplateContext {
|
|
915
|
+
/** Organisation details, extended with industry and size. */
|
|
916
|
+
org: OrganizationInfo & {
|
|
917
|
+
industry: Industry;
|
|
918
|
+
orgSize: OrgSize;
|
|
919
|
+
country: string;
|
|
920
|
+
};
|
|
921
|
+
/** Data categories the organisation collects. */
|
|
922
|
+
dataCategories: DataCategory[];
|
|
923
|
+
/** Processing purposes relevant to the organisation. */
|
|
924
|
+
purposes: ProcessingPurpose[];
|
|
925
|
+
/** Whether the organisation processes children's data. */
|
|
926
|
+
hasChildrenData: boolean;
|
|
927
|
+
/** Whether the organisation processes sensitive/special-category data. */
|
|
928
|
+
hasSensitiveData: boolean;
|
|
929
|
+
/** Whether the organisation processes financial data. */
|
|
930
|
+
hasFinancialData: boolean;
|
|
931
|
+
/** Whether data is transferred outside Nigeria. */
|
|
932
|
+
hasCrossBorderTransfer: boolean;
|
|
933
|
+
/** Whether automated decision-making or profiling is used. */
|
|
934
|
+
hasAutomatedDecisions: boolean;
|
|
935
|
+
/** Third-party processors that receive personal data. */
|
|
936
|
+
thirdPartyProcessors: ThirdPartyProcessor[];
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/** A third-party entity that processes data on behalf of the organisation. */
|
|
940
|
+
export declare interface ThirdPartyProcessor {
|
|
941
|
+
/** Name of the third party. */
|
|
942
|
+
name: string;
|
|
943
|
+
/** Purpose of sharing data with this processor. */
|
|
944
|
+
purpose: string;
|
|
945
|
+
/** Country where the processor is located. */
|
|
946
|
+
country: string;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
export declare function useAdaptivePolicyWizard(options?: UseAdaptivePolicyWizardOptions): UseAdaptivePolicyWizardReturn;
|
|
950
|
+
|
|
951
|
+
export declare interface UseAdaptivePolicyWizardOptions {
|
|
952
|
+
adapter?: StorageAdapter<PolicyDraft>;
|
|
953
|
+
onComplete?: (policy: PrivacyPolicy) => void;
|
|
954
|
+
onComplianceChange?: (score: number, gaps: ComplianceGap[]) => void;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
export declare interface UseAdaptivePolicyWizardReturn {
|
|
958
|
+
currentStep: number;
|
|
959
|
+
goToStep: (step: number) => void;
|
|
960
|
+
nextStep: () => void;
|
|
961
|
+
prevStep: () => void;
|
|
962
|
+
canProceed: boolean;
|
|
963
|
+
context: TemplateContext;
|
|
964
|
+
updateContext: (updates: Partial<TemplateContext>) => void;
|
|
965
|
+
updateOrg: (updates: Partial<TemplateContext['org']>) => void;
|
|
966
|
+
toggleDataCategory: (categoryId: string) => void;
|
|
967
|
+
togglePurpose: (purpose: string) => void;
|
|
968
|
+
addProcessor: (processor: {
|
|
969
|
+
name: string;
|
|
970
|
+
purpose: string;
|
|
971
|
+
country: string;
|
|
972
|
+
}) => void;
|
|
973
|
+
removeProcessor: (index: number) => void;
|
|
974
|
+
policy: PrivacyPolicy | null;
|
|
975
|
+
sections: PolicySection[];
|
|
976
|
+
customSections: CustomSection[];
|
|
977
|
+
addCustomSection: (section: Omit<CustomSection, 'id' | 'required'>) => void;
|
|
978
|
+
updateCustomSection: (id: string, updates: Partial<CustomSection>) => void;
|
|
979
|
+
removeCustomSection: (id: string) => void;
|
|
980
|
+
reorderSections: (sectionId: string, direction: 'up' | 'down') => void;
|
|
981
|
+
editSectionContent: (sectionId: string, content: string) => void;
|
|
982
|
+
sectionOverrides: Record<string, string>;
|
|
983
|
+
complianceScore: number;
|
|
984
|
+
complianceResult: ComplianceResult;
|
|
985
|
+
complianceGaps: ComplianceGap[];
|
|
986
|
+
applyFix: (gapId: string) => void;
|
|
987
|
+
handleExportPDF: (options?: PDFExportOptions) => Promise<Blob>;
|
|
988
|
+
handleExportDOCX: (options?: DOCXExportOptions) => Promise<Blob>;
|
|
989
|
+
handleExportHTML: (options?: HTMLExportOptions) => string;
|
|
990
|
+
handleExportMarkdown: () => string;
|
|
991
|
+
isDraftSaved: boolean;
|
|
992
|
+
lastSavedAt: number | null;
|
|
993
|
+
saveDraft: () => Promise<void>;
|
|
994
|
+
discardDraft: () => void;
|
|
995
|
+
isLoading: boolean;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Convenience wrapper around `usePrivacyPolicy`. With `orgInfo` provided
|
|
1000
|
+
* and `autoGenerate` enabled (default), `policy` is non-null on the first
|
|
1001
|
+
* post-load render — no manual `selectTemplate` / `generatePolicy` chaining
|
|
1002
|
+
* required.
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* ```tsx
|
|
1006
|
+
* const { policy } = useDefaultPrivacyPolicy({
|
|
1007
|
+
* orgInfo: { name: 'Acme Ltd', email: 'privacy@acme.ng' }
|
|
1008
|
+
* });
|
|
1009
|
+
* return policy ? <PolicyPage policy={policy} /> : <Spinner />;
|
|
1010
|
+
* ```
|
|
1011
|
+
*/
|
|
1012
|
+
export declare function useDefaultPrivacyPolicy(options?: UseDefaultPrivacyPolicyOptions): UsePrivacyPolicyReturn;
|
|
1013
|
+
|
|
1014
|
+
declare interface UseDefaultPrivacyPolicyOptions {
|
|
1015
|
+
/**
|
|
1016
|
+
* Organisation information to pre-fill into the policy. When provided and
|
|
1017
|
+
* `autoGenerate` is true (the default), the hook will auto-select the
|
|
1018
|
+
* default template and generate a renderable policy on first commit, so
|
|
1019
|
+
* `policy` is non-null on the first useful render.
|
|
1020
|
+
*/
|
|
1021
|
+
orgInfo?: {
|
|
1022
|
+
/** Organisation name (maps to `organizationInfo.name` and `orgName` variable) */
|
|
1023
|
+
name?: string;
|
|
1024
|
+
/** Privacy contact email (maps to `privacyEmail`) */
|
|
1025
|
+
email?: string;
|
|
1026
|
+
/** Organisation website URL */
|
|
1027
|
+
website?: string;
|
|
1028
|
+
/** Physical address */
|
|
1029
|
+
address?: string;
|
|
1030
|
+
/** Industry / sector descriptor */
|
|
1031
|
+
industry?: string;
|
|
1032
|
+
/** Data Protection Officer name */
|
|
1033
|
+
dpoName?: string;
|
|
1034
|
+
/** DPO email address */
|
|
1035
|
+
dpoEmail?: string;
|
|
1036
|
+
};
|
|
1037
|
+
/**
|
|
1038
|
+
* Whether the hook should auto-select the default template and generate
|
|
1039
|
+
* the policy as soon as it's mounted with `orgInfo`. Set to false to
|
|
1040
|
+
* retain manual control via `selectTemplate` / `generatePolicy`.
|
|
1041
|
+
* @default true
|
|
1042
|
+
*/
|
|
1043
|
+
autoGenerate?: boolean;
|
|
1044
|
+
/**
|
|
1045
|
+
* Storage key for policy data.
|
|
1046
|
+
* @default "ndpr_privacy_policy"
|
|
1047
|
+
*/
|
|
1048
|
+
storageKey?: string;
|
|
1049
|
+
/**
|
|
1050
|
+
* Whether to persist policy data in storage. When `false`, the hook
|
|
1051
|
+
* uses an in-memory no-op adapter and nothing survives a page reload.
|
|
1052
|
+
* @default true
|
|
1053
|
+
*/
|
|
1054
|
+
persist?: boolean;
|
|
1055
|
+
/**
|
|
1056
|
+
* @deprecated Renamed to `persist` in v3.5.0 — `useLocalStorage` is
|
|
1057
|
+
* still accepted for backward compatibility and will be removed in
|
|
1058
|
+
* v4.0. Use `persist` (or pass an explicit `adapter`) instead.
|
|
1059
|
+
* @default true
|
|
1060
|
+
*/
|
|
1061
|
+
useLocalStorage?: boolean;
|
|
1062
|
+
/**
|
|
1063
|
+
* Pluggable storage adapter. When provided, takes precedence over
|
|
1064
|
+
* storageKey/persist/useLocalStorage.
|
|
1065
|
+
*/
|
|
1066
|
+
adapter?: StorageAdapter<PrivacyPolicy>;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
export declare function usePolicyCompound(): PolicyContextValue;
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Hook for generating NDPA-compliant privacy policies
|
|
1073
|
+
*/
|
|
1074
|
+
export declare function usePrivacyPolicy({ templates, initialPolicy, adapter, storageKey, persist, useLocalStorage, onGenerate, }: UsePrivacyPolicyOptions): UsePrivacyPolicyReturn;
|
|
1075
|
+
|
|
1076
|
+
declare interface UsePrivacyPolicyOptions {
|
|
1077
|
+
/**
|
|
1078
|
+
* Available policy templates
|
|
1079
|
+
*/
|
|
1080
|
+
templates: PolicyTemplate[];
|
|
1081
|
+
/**
|
|
1082
|
+
* Initial policy data (if editing an existing policy)
|
|
1083
|
+
*/
|
|
1084
|
+
initialPolicy?: PrivacyPolicy;
|
|
1085
|
+
/**
|
|
1086
|
+
* Pluggable storage adapter. When provided, takes precedence over storageKey/useLocalStorage.
|
|
1087
|
+
*/
|
|
1088
|
+
adapter?: StorageAdapter<PrivacyPolicy>;
|
|
1089
|
+
/**
|
|
1090
|
+
* Storage key for policy data
|
|
1091
|
+
* @default "ndpr_privacy_policy"
|
|
1092
|
+
* @deprecated Use adapter instead
|
|
1093
|
+
*/
|
|
1094
|
+
storageKey?: string;
|
|
1095
|
+
/**
|
|
1096
|
+
* Whether to persist policy data in storage. When `false`, the hook
|
|
1097
|
+
* uses an in-memory no-op adapter and nothing survives a page reload.
|
|
1098
|
+
* Prefer `adapter` for richer control (custom backends, async APIs).
|
|
1099
|
+
*
|
|
1100
|
+
* @default true
|
|
1101
|
+
*/
|
|
1102
|
+
persist?: boolean;
|
|
1103
|
+
/**
|
|
1104
|
+
* @deprecated Renamed to `persist` in v3.5.0 — `useLocalStorage` is
|
|
1105
|
+
* still accepted for backward compatibility and will be removed in
|
|
1106
|
+
* v4.0. Use `persist` (or pass an explicit `adapter`) instead.
|
|
1107
|
+
* @default true
|
|
1108
|
+
*/
|
|
1109
|
+
useLocalStorage?: boolean;
|
|
1110
|
+
/**
|
|
1111
|
+
* Callback function called when a policy is generated
|
|
1112
|
+
*/
|
|
1113
|
+
onGenerate?: (policy: PrivacyPolicy) => void;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
declare interface UsePrivacyPolicyReturn {
|
|
1117
|
+
/**
|
|
1118
|
+
* Current policy data
|
|
1119
|
+
*/
|
|
1120
|
+
policy: PrivacyPolicy | null;
|
|
1121
|
+
/**
|
|
1122
|
+
* Selected template
|
|
1123
|
+
*/
|
|
1124
|
+
selectedTemplate: PolicyTemplate | null;
|
|
1125
|
+
/**
|
|
1126
|
+
* Organization information
|
|
1127
|
+
*/
|
|
1128
|
+
organizationInfo: OrganizationInfo;
|
|
1129
|
+
/**
|
|
1130
|
+
* Select a template
|
|
1131
|
+
*/
|
|
1132
|
+
selectTemplate: (templateId: string) => boolean;
|
|
1133
|
+
/**
|
|
1134
|
+
* Update organization information
|
|
1135
|
+
*/
|
|
1136
|
+
updateOrganizationInfo: (updates: Partial<OrganizationInfo>) => void;
|
|
1137
|
+
/**
|
|
1138
|
+
* Toggle whether a section is included in the policy
|
|
1139
|
+
*/
|
|
1140
|
+
toggleSection: (sectionId: string, included: boolean) => void;
|
|
1141
|
+
/**
|
|
1142
|
+
* Update section content
|
|
1143
|
+
*/
|
|
1144
|
+
updateSectionContent: (sectionId: string, content: string) => void;
|
|
1145
|
+
/**
|
|
1146
|
+
* Update variable values
|
|
1147
|
+
*/
|
|
1148
|
+
updateVariableValue: (variable: string, value: string) => void;
|
|
1149
|
+
/**
|
|
1150
|
+
* Generate the policy
|
|
1151
|
+
*/
|
|
1152
|
+
generatePolicy: () => PrivacyPolicy | null;
|
|
1153
|
+
/**
|
|
1154
|
+
* Get the generated policy text
|
|
1155
|
+
*/
|
|
1156
|
+
getPolicyText: () => {
|
|
1157
|
+
fullText: string;
|
|
1158
|
+
sectionTexts: Record<string, string>;
|
|
1159
|
+
missingVariables: string[];
|
|
1160
|
+
};
|
|
1161
|
+
/**
|
|
1162
|
+
* Reset the policy
|
|
1163
|
+
*/
|
|
1164
|
+
resetPolicy: () => void;
|
|
1165
|
+
/**
|
|
1166
|
+
* Check if the policy is valid
|
|
1167
|
+
*/
|
|
1168
|
+
isValid: () => {
|
|
1169
|
+
valid: boolean;
|
|
1170
|
+
errors: string[];
|
|
1171
|
+
};
|
|
1172
|
+
/**
|
|
1173
|
+
* Whether the adapter is still loading data (relevant for async adapters)
|
|
1174
|
+
*/
|
|
1175
|
+
isLoading: boolean;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
export { }
|