@tantainnovative/ndpr-toolkit 3.7.0 → 3.10.2

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +218 -0
  2. package/README.md +158 -11
  3. package/dist/{chunk-SJRIOZ4K.mjs → chunk-EFIWANHF.mjs} +1 -1
  4. package/dist/chunk-GQYBS3A7.mjs +0 -0
  5. package/dist/chunk-OZCNFB5C.js +1 -0
  6. package/dist/{chunk-RXZFYBUJ.js → chunk-XS3Z4UT7.js} +1 -1
  7. package/dist/core.js +1 -1
  8. package/dist/core.mjs +1 -1
  9. package/dist/cross-border-lite.d.mts +141 -0
  10. package/dist/cross-border-lite.d.ts +141 -0
  11. package/dist/cross-border-lite.js +2 -0
  12. package/dist/cross-border-lite.mjs +2 -0
  13. package/dist/dsr.js +1 -1
  14. package/dist/dsr.mjs +1 -1
  15. package/dist/headless.d.mts +2391 -0
  16. package/dist/headless.d.ts +2391 -0
  17. package/dist/headless.js +2 -0
  18. package/dist/headless.mjs +2 -0
  19. package/dist/hooks.js +1 -1
  20. package/dist/hooks.mjs +1 -1
  21. package/dist/index.d.mts +123 -0
  22. package/dist/index.d.ts +123 -0
  23. package/dist/index.js +1 -1
  24. package/dist/index.mjs +1 -1
  25. package/dist/lawful-basis-lite.d.mts +153 -0
  26. package/dist/lawful-basis-lite.d.ts +153 -0
  27. package/dist/lawful-basis-lite.js +2 -0
  28. package/dist/lawful-basis-lite.mjs +2 -0
  29. package/dist/presets-dsr.d.mts +25 -0
  30. package/dist/presets-dsr.d.ts +25 -0
  31. package/dist/presets-dsr.js +1 -1
  32. package/dist/presets-dsr.mjs +1 -1
  33. package/dist/presets.d.mts +25 -0
  34. package/dist/presets.d.ts +25 -0
  35. package/dist/presets.js +1 -1
  36. package/dist/presets.mjs +1 -1
  37. package/dist/ropa-lite.d.mts +218 -0
  38. package/dist/ropa-lite.d.ts +218 -0
  39. package/dist/ropa-lite.js +2 -0
  40. package/dist/ropa-lite.mjs +2 -0
  41. package/dist/server.js +1 -1
  42. package/dist/server.mjs +1 -1
  43. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,224 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [3.10.2](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.10.1...v3.10.2) (2026-05-25)
6
+
7
+ README-only patch — runtime is byte-identical to 3.10.1. Fixes the npm-rendered README so it reflects the current state of the toolkit.
8
+
9
+ ### What was wrong
10
+
11
+ The npm publish workflow runs `npm publish` from `working-directory: .` (the repo root), so the README that lands on the npm package page is **`/README.md`**, not `packages/ndpr-toolkit/README.md`. Three earlier releases (3.8.1, 3.9.0, 3.10.0) updated the inner README — wrong file — leaving the npm-visible header stuck at the v3.4.0 "What's new" notice with the v3.4.0 release link and the `1098 passing` tests badge.
12
+
13
+ ### What changed in this patch
14
+
15
+ - "What's new" notice — v3.4.0 paragraph → consolidated 3.5 → 3.10.x highlights (NDPRThemeProvider, `/headless`, production DSR backend example, ecommerce starter, SSR-safe templates, Bun quickstart, typed DSR callbacks, Lite manager variants, focus management).
16
+ - Header release link — `v3.4.0 Release` → `v3.10.1 Release`.
17
+ - Tests badge — `1098 passing` → `1192 passing`.
18
+ - StackBlitz / CodeSandbox "Open in" links — `examples/nextjs-app` (no longer exists) → `examples/ecommerce-starter`.
19
+ - Screenshot image URLs — pinned tag `v3.5.2` → `v3.10.1` so the images come from the current release tree.
20
+
21
+ The body of the README already had the correct content for everything below the header (Bun quickstart, Choose Your Layer, Adapters, Live Demos table, etc.).
22
+
23
+ ## [3.10.1](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.10.0...v3.10.1) (2026-05-25)
24
+
25
+ Hotfix release. Code and runtime are identical to 3.10.0 — this patch fixes the build/publish pipeline that silently failed every release from 3.8.0 onward, so 3.10.1 is the first version since 3.7.0 to actually reach npm.
26
+
27
+ ### Root cause
28
+
29
+ The dts-rollup post-build step (`scripts/rollup-dts.mjs`) deletes "leftover" hash-suffixed declaration files that tsup emits alongside each rolled-up entry. The 3.8.0 release added new entry names with two hyphens (`lawful-basis-lite`, `cross-border-lite`) — and the hash-suffix regex `/-[A-Za-z0-9_-]{8,}\.d\.m?ts$/` matched those legitimate entries because the trailing `basis-lite` / `border-lite` segments fall inside the 8-char dash-inclusive window. The sweep then deleted `dist/lawful-basis-lite.d.ts` and `dist/cross-border-lite.d.ts` right after rollup, the workflow's entry-points check then failed, and `npm publish` never ran. The git tags / GitHub releases for 3.8.0, 3.8.1, 3.9.0, and 3.10.0 existed; only npm was stuck on 3.7.0.
30
+
31
+ ### Fix
32
+
33
+ - Replaced the regex-based sweep with an explicit allowlist (`new Set([...ENTRIES, 'styles'])`). Any `.d.ts` / `.d.mts` whose basename isn't in the allowed entries gets swept. No more pattern matching against names.
34
+ - Wired the 3.10.0 `/headless` entry into the root `tsup.config.ts` (it had only been wired in `packages/ndpr-toolkit/tsup.config.ts`, which the publish workflow doesn't use) and added it to `CLIENT_ENTRIES` so the `"use client"` banner is injected.
35
+ - Workflow's `Verify entry points` step now covers 22 entries (was 21) — added `headless`.
36
+
37
+ ### Recovery
38
+
39
+ After this patch lands and 3.10.1 publishes successfully, the failed tags (v3.8.0, v3.8.1, v3.9.0, v3.10.0) will be backfilled to npm by cherry-picking this fix onto each tagged commit and re-running the workflow.
40
+
41
+ ## [3.10.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.9.0...v3.10.0) (2026-05-25)
42
+
43
+ Phase J of the feedback work — new API surface (theme provider + headless alias) and a production-grade DSR backend reference. Fully additive — no breaking changes.
44
+
45
+ ### `NDPRThemeProvider` — typed theme object → CSS variables
46
+
47
+ A small React Context provider that takes a TypeScript theme object and injects matching `--ndpr-*` CSS custom properties on a wrapping `div`. Syntactic sugar over the existing CSS-variable theming model — unset fields fall through to stylesheet defaults.
48
+
49
+ ```tsx
50
+ import { NDPRThemeProvider, type NDPRTheme } from '@tantainnovative/ndpr-toolkit';
51
+
52
+ const theme: NDPRTheme = {
53
+ colors: { primary: '22 163 74', primaryHover: '21 128 61' }, // RGB triplets
54
+ radius: { base: '0.75rem' },
55
+ font: { sans: '"Inter", system-ui, sans-serif' },
56
+ };
57
+
58
+ <NDPRThemeProvider theme={theme}>
59
+ <App />
60
+ </NDPRThemeProvider>
61
+ ```
62
+
63
+ The `NDPRTheme` interface keys are derived 1:1 from the variables actually defined in `styles.css` — no inventing tokens. Setting `mode: 'dark'` stamps `data-theme="dark"` on the wrapper to activate the stylesheet's dark-mode block. **6 new tests** cover variable injection, key isolation, dark-mode wiring, and className passthrough. Exported from the default entry only (not `/core`) to keep the RSC-safe surface clean.
64
+
65
+ ### `/headless` subpath — alias of `/hooks` for discoverability
66
+
67
+ A pure rename of the existing `/hooks` entry under a more discoverable name. Same exports, same source, same identifiers — `export *` from `hooks-entry.ts`. Useful when consumers grep for "headless" looking for a hooks-only API.
68
+
69
+ ```tsx
70
+ import { useConsent, useDSR, useFocusTrap } from '@tantainnovative/ndpr-toolkit/headless';
71
+ ```
72
+
73
+ **12 new tests** verify that `/headless` and `/hooks` export identical keys and identity-equal values (so the alias can never silently drift). Wired into `package.json` exports, `typesVersions`, and `tsup.config.ts`.
74
+
75
+ ### `examples/dsr-backend-prod/` — production-grade DSR backend
76
+
77
+ A 14-file Next.js 15 / React 19 reference implementation that wires `NDPRSubjectRights` to a real backend pipeline:
78
+
79
+ 1. **Validate** via `validateDsrSubmission` from `/server` — 400 with `{ error, fields }` on invalid payloads.
80
+ 2. **Defense-in-depth** disposable-email blocklist (configurable via `DSR_BLOCKED_EMAIL_DOMAINS`).
81
+ 3. **Persist** to a Prisma `DSRRequest` model with a 30-day `estimatedCompletionAt` (NDPA Part IV §29-36).
82
+ 4. **Confirm** by sending a Resend transactional email — best-effort: the request still succeeds if email fails.
83
+
84
+ Both Prisma and Resend are wrapped in **dual-mode shims**: real clients when `DATABASE_URL` / `RESEND_API_KEY` are set, otherwise a Map-backed mock and a stdout logger. The example runs out of the box with no infrastructure.
85
+
86
+ The 201 response is exactly `{ referenceId, status, estimatedCompletionAt }` — the shape `NDPRSubjectRights.onSubmitSuccess` consumers read from `body` per the 3.8.1 contract.
87
+
88
+ ### Three new docs guides
89
+
90
+ Wired into the Implementation Guides sidebar:
91
+
92
+ - `/docs/guides/theming` — `NDPRThemeProvider`, the full `NDPRTheme` reference, RGB-triplet convention, dark mode, when not to use the provider
93
+ - `/docs/guides/headless` — `/headless` quickstart, the 10 hooks it exposes, adapter wiring, bundle-size note, the relationship to `/hooks`
94
+ - `/docs/guides/production-dsr-backend` — walks through the `examples/dsr-backend-prod` pipeline, response contract, and how to swap in your own database/email stack
95
+
96
+ ### Verification
97
+
98
+ - `tsc --noEmit` clean for the docs site
99
+ - **Full Jest suite: 1192/1192 passing** (was 1173 — +19: 6 ThemeProvider + 12 headless-parity + 1 default-entry exports check)
100
+ - No changes to existing prop types, hook signatures, or storage adapters
101
+
102
+ ## [3.9.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.8.1...v3.9.0) (2026-05-25)
103
+
104
+ Examples expansion + Bun quickstart + SSR-safe storage docs. Fully additive — no breaking changes.
105
+
106
+ ### Runnable example apps
107
+
108
+ - **`examples/ecommerce-starter`** — multi-page Next.js 15 / React 19 storefront ("Zuri Market") wiring the toolkit into a realistic Nigerian ecommerce flow: home page, checkout, privacy notice, data-subject rights portal (with `submitTo` + `onSubmitSuccess` rendering a server-issued reference), and an editable cookie preferences page using `useConsent`. Demonstrates the `/presets/consent`, `/presets/dsr`, `/presets/policy`, and `/hooks` subpaths together.
109
+ - **`examples/ssr/nextjs-app-router`** — SSR-safe consent on Next.js 15. Layout reads the consent cookie via `next/headers`, parses it with a small typed helper, and passes the result to a client `ConsentRoot` so the banner hydrates already-resolved (no flash, no hydration warning).
110
+ - **`examples/ssr/remix`** — the same cookie-bridge pattern wired from a Remix `loader` and Vite's `?url` asset import for the stylesheet.
111
+ - **`examples/ssr/astro`** — `Astro.cookies.get` in the page frontmatter, then `<ConsentRoot client:load>` as a React island.
112
+
113
+ Each example is self-contained (own `package.json`, `tsconfig.json`, `next.config.mjs` / `vite.config.ts` / `astro.config.mjs`) so you can copy a directory and `bun install && bun dev` to run it.
114
+
115
+ ### Bun quickstart in the README
116
+
117
+ Root README now includes copy-pasteable Bun + Vite + React and Bun + Next.js 15 (App Router) recipes that go from zero to a working banner in three commands. The npm-published README also gets a one-line Bun install command alongside pnpm/npm.
118
+
119
+ ### SSR-safe storage guide
120
+
121
+ New docs page at **`/docs/guides/server-side-storage`** documenting the cookie-bridge pattern in detail: why `localStorageAdapter` flashes on SSR, how `cookieAdapter` solves it, and worked examples for Next.js App Router, Remix, Astro, and SvelteKit. Wired into the docs sidebar under Implementation Guides.
122
+
123
+ ### npm-published README brought current (3.4.0 → 3.9.0)
124
+
125
+ The README that ships to npm was stale at the 3.4.0 highlights. It now leads with a 3.9.0 "what's new", references back to 3.8.1 (`onSubmitSuccess`), 3.8.0 (Lite Manager variants), 3.6.0 (`onSubmitError`), and 3.5.x (focus management + reduced motion). Adds a "Runnable Examples" section, a typed DSR callbacks snippet in the Presets section, and a Bun install command. Screenshot URLs bumped from `v3.5.2` → `v3.9.0`. Tests badge bumped to 1173.
126
+
127
+ ### Verification
128
+
129
+ - `tsc --noEmit` clean for the docs site
130
+ - **Full Jest suite: 1173/1173 passing** (unchanged from 3.8.1 — no logic changes in the published package)
131
+ - No changes to runtime exports, prop types, or storage adapters
132
+
133
+ ## [3.8.1](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.8.0...v3.8.1) (2026-05-25)
134
+
135
+ Documentation + small API addition patch. Fully additive — no breaking changes.
136
+
137
+ ### `NDPRSubjectRights` — typed `onSubmitSuccess` callback
138
+
139
+ Counterpart to the existing `onSubmitError`. Fires when the `submitTo` POST returns a 2xx response. Receives the `Response`, the submitted `DSRFormSubmission` payload, and the parsed JSON body (or `undefined` if the response had no body or was not valid JSON).
140
+
141
+ ```tsx
142
+ <NDPRSubjectRights
143
+ submitTo="/api/dsr"
144
+ onSubmitSuccess={({ response, data, body }) => {
145
+ const ref = (body as { referenceId?: string })?.referenceId;
146
+ if (ref) router.push(`/dsr-confirmation?ref=${ref}`);
147
+ }}
148
+ onSubmitError={({ error, response }) => {
149
+ console.error('DSR submit failed', error, response?.status);
150
+ }}
151
+ />
152
+ ```
153
+
154
+ The `body` field is `unknown` to force consumers to narrow it themselves before reading fields. **4 new tests** cover both success and failure paths.
155
+
156
+ ### Documentation
157
+
158
+ - **DSR submission payload contract** documented on the Data Subject Rights component page (`/docs/components/data-subject-rights#submission-payload`). Includes the canonical `DSRFormSubmission` TypeScript interface, a concrete JSON example, the recommended response shape, and a working Next.js App Router backend handler.
159
+ - **Accessibility sections** added to ConsentBanner and DSRRequestForm docs pages. Each lists CONCRETE a11y features verified against the source — `useFocusTrap`, escape-to-dismiss, `prefers-reduced-motion` block in the BEM stylesheet, `role="alert"` on errors, `aria-required` + `aria-invalid` wiring on form fields, etc. Features that aren't implemented (e.g. auto-focusing the first invalid field) are NOT claimed — they're suggested as consumer-side recipes instead.
160
+ - **Migration guide 3.5 → 3.8** at `/docs/guides/migrating-3-5-to-3-8`. Covers every minor and patch from 3.5.4 through 3.8.1 with a "what changed / action required" breakdown, a net migration diff for the most common upgrade path (adapter → submitTo + onSubmitSuccess), and a verify checklist. Sidebar entry added under Implementation Guides.
161
+
162
+ ### Verification
163
+
164
+ - `tsc --noEmit` clean for both the library and the docs site
165
+ - **Full Jest suite: 1173/1173 passing** (was 1169 — +4 new submit-callback tests)
166
+ - No changes to the existing `onSubmitError`, `submitTo`, or `submitOptions` props (backward compatible)
167
+
168
+ ## [3.8.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.6.2...v3.8.0) (2026-05-24)
169
+
170
+ ### Lite (read-only) variants of the heavy Manager components
171
+
172
+ Three new components — `LawfulBasisTrackerLite`, `ROPAManagerLite`, `CrossBorderTransferManagerLite` — that render the same list-and-summary view as their Full counterparts without the form, validation, write callbacks, or CSV-export utilities. Built for dashboards, audit pages, embedded compliance widgets, and customer-facing transparency pages where users only need to *see* the records.
173
+
174
+ Exposed at new subpath entries:
175
+
176
+ ```ts
177
+ import { LawfulBasisTrackerLite } from '@tantainnovative/ndpr-toolkit/lawful-basis/lite';
178
+ import { ROPAManagerLite } from '@tantainnovative/ndpr-toolkit/ropa/lite';
179
+ import { CrossBorderTransferManagerLite } from '@tantainnovative/ndpr-toolkit/cross-border/lite';
180
+ ```
181
+
182
+ Bundle deltas (minified + tree-shaken, pre-gzip; **transitive closure** of each subpath):
183
+
184
+ | Module | Full | Lite | Saved |
185
+ |---|---|---|---|
186
+ | `/lawful-basis` → `/lawful-basis/lite` | 36.7 KB | 12.7 KB | **65%** |
187
+ | `/cross-border` → `/cross-border/lite` | 53.3 KB | 5.6 KB | **89%** |
188
+ | `/ropa` → `/ropa/lite` | 36.9 KB | 13.2 KB | **64%** |
189
+
190
+ The cross-border Lite saves the most because it does NOT import the 624-row country-adequacy dataset — Lite displays `adequacyStatus` from each transfer record directly instead of recomputing it.
191
+
192
+ Each Lite component accepts an optional `onActivityClick` / `onRecordClick` / `onTransferClick` callback so consumers can render their own detail view on row click. All other props (`title`, `description`, `unstyled`, `classNames`, `showSummary`, `showComplianceGaps`/`showRiskAlerts`) carry the same names and semantics as the Full versions.
193
+
194
+ Existing `/lawful-basis`, `/cross-border`, and `/ropa` entries are unchanged. This release is fully additive — no consumers need to migrate.
195
+
196
+ See the new guide: [Lite vs Full managers](https://ndprtoolkit.com.ng/docs/guides/lite-vs-full).
197
+
198
+ ### Other
199
+
200
+ - Added `lawful-basis-lite`, `cross-border-lite`, `ropa-lite` to the publish workflow's entry-point verification loop. Total verified entries: 21.
201
+
202
+ ## [3.6.2](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.7.0...v3.6.2) (2026-05-24)
203
+
204
+ Compressed Phase D + E + F patch — companion-CLI templates, per-module StackBlitz scaffolds, and a real backend for the `/score` lead-magnet. Main `@tantainnovative/ndpr-toolkit` library has no code changes; the bump is for changelog alignment.
205
+
206
+ ### Companion packages
207
+
208
+ - **`@tantainnovative/create-ndpr@0.3.0`** — the 9 remaining route templates now support all three ORM choices via `{{#if ORM=prisma|drizzle|none}}` conditional blocks. Picking `ORM=none` now scaffolds a fully working in-memory app for every endpoint, not just consent:
209
+ - Next.js routes: dsr, breach, dpia, lawful-basis, cross-border
210
+ - Express routes: consent, dpia, lawful-basis, cross-border
211
+ - **`create-ndpr@1.0.0` (unscoped alias)** — `packages/create-ndpr-unscoped/PUBLISHING.md` documents the one-time manual publish + Trusted Publisher setup so future updates flow through CI.
212
+
213
+ ### Docs
214
+
215
+ - **8 per-module StackBlitz scaffolds** under `examples/stackblitz/{consent,dsr,dpia,breach,policy,lawful-basis,cross-border,ropa}/`. Each is a minimal Next.js 15 + React 19 app that demonstrates ONE preset. Boot any of them in StackBlitz / CodeSandbox with one click — no clone, no install. README has a per-module badge table.
216
+ - **Each recipe page** (`/docs/recipes/*`) now has "Open in StackBlitz" + "Open in CodeSandbox" badges pointing at the matching module's scaffold.
217
+ - **`/score` email capture** now uses a real backend (Web3Forms) when `NEXT_PUBLIC_WEB3FORMS_KEY` is set, with the mailto: path preserved as a graceful fallback when the env var is missing or the request fails. Lead emails arrive as structured fields (name, email, org, score, top recommendations) instead of free-form mail-client output.
218
+
219
+ ### No library code changes
220
+
221
+ `@tantainnovative/ndpr-toolkit` package is unchanged; consumers don't need to upgrade. The version bump keeps the repo, npm, and CHANGELOG in lockstep so the next library feature (3.8.0 with manager-component bundle splitting) lands cleanly.
222
+
5
223
  ## [3.7.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v3.6.1...v3.7.0) (2026-05-24)
6
224
 
7
225
  Phase B — Template + Recipe Library. Closes the dev-feedback content gap (feedback items #7 and #9). New API additions are all backward-compatible — 3.6.x consumers upgrade without changes.
package/README.md CHANGED
@@ -6,20 +6,22 @@
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@tantainnovative/ndpr-toolkit.svg)](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-5%2B-3178C6.svg)](https://www.typescriptlang.org/)
9
- [![Tests](https://img.shields.io/badge/tests-1098%20passing-brightgreen.svg)](#)
9
+ [![Tests](https://img.shields.io/badge/tests-1192%20passing-brightgreen.svg)](#)
10
10
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@tantainnovative/ndpr-toolkit)](https://bundlephobia.com/package/@tantainnovative/ndpr-toolkit)
11
11
 
12
12
  v3 ships **zero-config presets**, **pluggable storage adapters**, **compound components**, and a **compliance score engine** — eight production-ready modules covering consent, data subject rights, DPIA, breach notification, privacy policies, lawful basis, cross-border transfers, and ROPA.
13
13
 
14
- **[Documentation](https://ndprtoolkit.com.ng)** | **[Live Demos](https://ndprtoolkit.com.ng/ndpr-demos)** | **[npm](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)** | **[Blog](https://ndprtoolkit.com.ng/blog)** | **[v3.4.0 Release](https://github.com/mr-tanta/ndpr-toolkit/releases/tag/v3.4.0)**
14
+ **[Documentation](https://ndprtoolkit.com.ng)** | **[Live Demos](https://ndprtoolkit.com.ng/ndpr-demos)** | **[npm](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)** | **[Blog](https://ndprtoolkit.com.ng/blog)** | **[v3.10.1 Release](https://github.com/mr-tanta/ndpr-toolkit/releases/tag/v3.10.1)**
15
15
 
16
- [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/nextjs-app)
17
- [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/nextjs-app)
16
+ [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/ecommerce-starter)
17
+ [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/ecommerce-starter)
18
18
 
19
- > **What's new in 3.4.0:** components now ship styled defaults via a real stylesheet Tailwind is no longer required. Add `import "@tantainnovative/ndpr-toolkit/styles";` once in your app entry. Plus a new `/server` subpath for RSC-safe pure-logic imports (validators, generators, scoring) with zero React in the import graph. Backward-compatible at the component API level. Full notes on the [release page](https://github.com/mr-tanta/ndpr-toolkit/releases/tag/v3.4.0).
19
+ > **What's new in 3.10.x:** `NDPRThemeProvider` a typed React Context that turns a JavaScript theme object into the `--ndpr-*` CSS variables the stylesheet already consumes. `/headless` subpath ships every hook with zero UI in the import graph (an alias of `/hooks` under a more discoverable name). A new production-grade DSR backend reference at `examples/dsr-backend-prod/` wires `NDPRSubjectRights` to Prisma persistence + Resend email confirmation behind dual-mode shims (no infra required to run). Three new docs guides: [theming](https://ndprtoolkit.com.ng/docs/guides/theming), [headless](https://ndprtoolkit.com.ng/docs/guides/headless), [production-dsr-backend](https://ndprtoolkit.com.ng/docs/guides/production-dsr-backend).
20
+ >
21
+ > **3.9.0** shipped runnable example apps — `examples/ecommerce-starter` (Nigerian multi-page storefront) and SSR-safe cookie-bridge templates for Next.js App Router, Remix, and Astro under `examples/ssr/*`. Plus Bun + Vite and Bun + Next.js quickstarts in this README. **3.8.1** added a typed `onSubmitSuccess` callback to `NDPRSubjectRights`, a documented DSR submission payload contract, accessibility notes, and a 3.5 → 3.8 migration guide. **3.8.0** shipped Lite (read-only) variants of the heavy Manager components (`/lawful-basis/lite`, `/cross-border/lite`, `/ropa/lite`). **3.6.0** added a typed `onSubmitError({ error, response })` callback. **3.5.x** added focus management (`useFocusTrap`), escape-to-dismiss, and `prefers-reduced-motion` support. Full notes on the [release page](https://github.com/mr-tanta/ndpr-toolkit/releases/tag/v3.10.1).
20
22
 
21
23
  <p align="center">
22
- <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.5.2/public/screenshots/hero.png" alt="NDPA Toolkit — NDPA Compliance Made Beautiful" width="800" />
24
+ <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.10.1/public/screenshots/hero.png" alt="NDPA Toolkit — NDPA Compliance Made Beautiful" width="800" />
23
25
  </p>
24
26
 
25
27
  ---
@@ -68,7 +70,7 @@ import { apiAdapter } from '@tantainnovative/ndpr-toolkit/adapters';
68
70
  That's it. NDPA-compliant consent with server-side persistence in under 20 lines.
69
71
 
70
72
  <p align="center">
71
- <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.5.2/public/screenshots/consent-demo.png" alt="Consent Management Demo — interactive consent banner with state inspector" width="800" />
73
+ <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.10.1/public/screenshots/consent-demo.png" alt="Consent Management Demo — interactive consent banner with state inspector" width="800" />
72
74
  <br />
73
75
  <em>Interactive consent demo with configurable position, theme, storage, and real-time state inspector</em>
74
76
  </p>
@@ -127,6 +129,101 @@ bun create ndpr
127
129
 
128
130
  ---
129
131
 
132
+ ## Bun quickstart
133
+
134
+ Bun is a first-class runtime for the toolkit. Both common React app shapes work without extra config.
135
+
136
+ ### Bun + Vite + React
137
+
138
+ ```bash
139
+ bun create vite@latest my-ndpr-app --template react-ts
140
+ cd my-ndpr-app
141
+ bun install
142
+ bun add @tantainnovative/ndpr-toolkit
143
+ ```
144
+
145
+ ```tsx
146
+ // src/App.tsx
147
+ import { NDPRConsent } from '@tantainnovative/ndpr-toolkit/presets/consent';
148
+ import '@tantainnovative/ndpr-toolkit/styles';
149
+
150
+ export default function App() {
151
+ return (
152
+ <>
153
+ <NDPRConsent
154
+ options={[
155
+ { id: 'essential', label: 'Essential', description: 'Required for the site to function', required: true, purpose: 'Site operation' },
156
+ { id: 'analytics', label: 'Analytics', description: 'Anonymous usage measurement', required: false, purpose: 'Product analytics' },
157
+ { id: 'marketing', label: 'Marketing', description: 'Personalised offers and ads', required: false, purpose: 'Marketing communications' },
158
+ ]}
159
+ />
160
+ <main className="p-6">
161
+ <h1 className="text-3xl font-semibold">My NDPA-compliant app</h1>
162
+ </main>
163
+ </>
164
+ );
165
+ }
166
+ ```
167
+
168
+ ```bash
169
+ bun dev
170
+ ```
171
+
172
+ Vite is client-only by default — no extra wiring needed. The toolkit's preset components ship with the `"use client"` directive already injected.
173
+
174
+ ### Bun + Next.js 15 (App Router)
175
+
176
+ ```bash
177
+ bun create next-app@latest my-ndpr-app --typescript --app --tailwind
178
+ cd my-ndpr-app
179
+ bun add @tantainnovative/ndpr-toolkit
180
+ ```
181
+
182
+ The consent banner is a stateful client component. Mount it from a small client wrapper so the rest of your layout can stay in RSC:
183
+
184
+ ```tsx
185
+ // app/ConsentRoot.tsx
186
+ 'use client';
187
+ import { NDPRConsent } from '@tantainnovative/ndpr-toolkit/presets/consent';
188
+
189
+ export function ConsentRoot() {
190
+ return (
191
+ <NDPRConsent
192
+ options={[
193
+ { id: 'essential', label: 'Essential', description: 'Required for the site to function', required: true, purpose: 'Site operation' },
194
+ { id: 'analytics', label: 'Analytics', description: 'Anonymous usage measurement', required: false, purpose: 'Product analytics' },
195
+ { id: 'marketing', label: 'Marketing', description: 'Personalised offers and ads', required: false, purpose: 'Marketing communications' },
196
+ ]}
197
+ />
198
+ );
199
+ }
200
+ ```
201
+
202
+ ```tsx
203
+ // app/layout.tsx
204
+ import '@tantainnovative/ndpr-toolkit/styles';
205
+ import { ConsentRoot } from './ConsentRoot';
206
+
207
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
208
+ return (
209
+ <html lang="en">
210
+ <body>
211
+ <ConsentRoot />
212
+ {children}
213
+ </body>
214
+ </html>
215
+ );
216
+ }
217
+ ```
218
+
219
+ ```bash
220
+ bun dev
221
+ ```
222
+
223
+ You don't need to manually mark the import with `"use client"` from `app/layout.tsx` — the preset module already ships the directive in its bundled output, so React Server Components import it cleanly via the client wrapper. For RSC-safe, zero-React imports use `/server` or `/core` instead.
224
+
225
+ ---
226
+
130
227
  ## Choose Your Layer
131
228
 
132
229
  Pick exactly what your project needs.
@@ -337,19 +434,47 @@ Every module has an interactive demo. No signup, no setup — try them instantly
337
434
 
338
435
  <p align="center">
339
436
  <a href="https://ndprtoolkit.com.ng/ndpr-demos">
340
- <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.5.2/public/screenshots/demos-overview.png" alt="8 interactive live demos — zero setup required" width="800" />
437
+ <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.10.1/public/screenshots/demos-overview.png" alt="8 interactive live demos — zero setup required" width="800" />
341
438
  </a>
342
439
  </p>
343
440
 
344
441
  <p align="center">
345
- <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.5.2/public/screenshots/dsr-demo.png" alt="Data Subject Rights — 8 rights with request tracking" width="400" />
346
- <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.5.2/public/screenshots/breach-demo.png" alt="Breach Notification — 72-hour countdown with step-by-step workflow" width="400" />
442
+ <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.10.1/public/screenshots/dsr-demo.png" alt="Data Subject Rights — 8 rights with request tracking" width="400" />
443
+ <img src="https://raw.githubusercontent.com/mr-tanta/ndpr-toolkit/v3.10.1/public/screenshots/breach-demo.png" alt="Breach Notification — 72-hour countdown with step-by-step workflow" width="400" />
347
444
  </p>
348
445
 
349
446
  <p align="center">
350
447
  <em>Left: Data Subject Rights portal with 8 NDPA rights. Right: Breach notification with 72-hour NDPC deadline countdown.</em>
351
448
  </p>
352
449
 
450
+ ### Open any module in your browser (zero install)
451
+
452
+ Each module ships a minimal Next.js scaffold you can fork in StackBlitz or CodeSandbox. One click → working app demonstrating just that module:
453
+
454
+ | Module | NDPA | Open in StackBlitz | Open in CodeSandbox |
455
+ |---|---|---|---|
456
+ | **Ecommerce starter (full app)** | §25–27, §34–38 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/ecommerce-starter) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/ecommerce-starter) |
457
+ | Consent | §26 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/consent) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/consent) |
458
+ | DSR | §34 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/dsr) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/dsr) |
459
+ | DPIA | §28 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/dpia) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/dpia) |
460
+ | Breach | §40 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/breach) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/breach) |
461
+ | Policy | §27 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/policy) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/policy) |
462
+ | Lawful Basis | §25 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/lawful-basis) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/lawful-basis) |
463
+ | Cross-Border | §41–43 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/cross-border) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/cross-border) |
464
+ | RoPA | §29 | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/stackblitz/ropa) | [![Open](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/mr-tanta/ndpr-toolkit/main/examples/stackblitz/ropa) |
465
+
466
+ Or open the [all-in-one example](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/nextjs-app) that demos every module in a single app.
467
+
468
+ ### SSR-safe consent scaffolds
469
+
470
+ Cookie-bridged consent that hydrates without a flash. Each scaffold reads the `ndpr-consent` cookie on the server, seeds the banner's `show` prop, then lets the browser `cookieAdapter` take over. See the [Server-Side Storage guide](https://ndprtoolkit.com.ng/docs/guides/server-side-storage) for the pattern.
471
+
472
+ | Framework | Path | Open in StackBlitz |
473
+ |---|---|---|
474
+ | Next.js App Router | [`examples/ssr/nextjs-app-router`](./examples/ssr/nextjs-app-router) | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/ssr/nextjs-app-router) |
475
+ | Remix | [`examples/ssr/remix`](./examples/ssr/remix) | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/ssr/remix) |
476
+ | Astro | [`examples/ssr/astro`](./examples/ssr/astro) | [![Open](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mr-tanta/ndpr-toolkit/tree/main/examples/ssr/astro) |
477
+
353
478
  ---
354
479
 
355
480
  ## All 8 Modules
@@ -390,7 +515,23 @@ import "@tantainnovative/ndpr-toolkit/styles";
390
515
  }
391
516
  ```
392
517
 
393
- Light + dark mode auto-switch via `prefers-color-scheme`, plus an explicit opt-in via `data-theme="dark"` or `.dark` on any ancestor.
518
+ **Theme via typed JS object `NDPRThemeProvider` (new in 3.10.0):**
519
+ ```tsx
520
+ import { NDPRThemeProvider, type NDPRTheme } from '@tantainnovative/ndpr-toolkit';
521
+
522
+ const theme: NDPRTheme = {
523
+ colors: { primary: '22 163 74', primaryHover: '21 128 61' },
524
+ radius: { base: '0.75rem' },
525
+ font: { sans: '"Inter", system-ui, sans-serif' },
526
+ };
527
+
528
+ <NDPRThemeProvider theme={theme}>
529
+ <App />
530
+ </NDPRThemeProvider>
531
+ ```
532
+ The provider wraps children in a single `div` with the `--ndpr-*` variables set inline. Every `NDPRTheme` field is optional and maps 1:1 to a CSS variable defined in the stylesheet — unset fields fall through to defaults. Same end result as raw CSS overrides; pick what fits your codebase. Full reference in [the theming guide](https://ndprtoolkit.com.ng/docs/guides/theming).
533
+
534
+ Light + dark mode auto-switch via `prefers-color-scheme`, plus an explicit opt-in via `data-theme="dark"` or `.dark` on any ancestor (or `mode: 'dark'` on `NDPRThemeProvider`).
394
535
 
395
536
  **Per-instance override via slot map:**
396
537
  ```tsx
@@ -425,6 +566,7 @@ Each component exports its `ClassNames` TypeScript interface for autocomplete. F
425
566
  | `/server` | **Pure validators, generators, scoring, locales, adapters, types — zero React** | `tslib` | **Yes** |
426
567
  | `/core` | Types, utility functions, NDPRProvider | `react`[^core] | Partial |
427
568
  | `/hooks` | React hooks for all 8 modules | `react` | No |
569
+ | `/headless` | **Alias of `/hooks`** — identical exports under a more discoverable name (3.10.0) | `react` | No |
428
570
  | `/presets` | All zero-config preset components (barrel) | `react`, Radix peers | No |
429
571
  | `/presets/consent` | **Just `NDPRConsent`** — narrower barrel for bundle size | `react`, Radix peers | No |
430
572
  | `/presets/dsr` | **Just `NDPRSubjectRights`** | `react`, Radix peers | No |
@@ -436,8 +578,11 @@ Each component exports its `ClassNames` TypeScript interface for autocomplete. F
436
578
  | `/breach` | Breach components + hook | `react` | No |
437
579
  | `/policy` | Policy components + hook | `react`, `jspdf`, `docx` (optional) | No |
438
580
  | `/lawful-basis` | Lawful basis component + hook | `react` | No |
581
+ | `/lawful-basis/lite` | Read-only `LawfulBasisTrackerLite` — ~65% smaller than `/lawful-basis` | `react` | No |
439
582
  | `/cross-border` | Cross-border component + hook | `react` | No |
583
+ | `/cross-border/lite` | Read-only `CrossBorderTransferManagerLite` — ~89% smaller (skips the 624-row adequacy dataset) | `react` | No |
440
584
  | `/ropa` | ROPA component + hook | `react` | No |
585
+ | `/ropa/lite` | Read-only `ROPAManagerLite` — ~64% smaller than `/ropa` | `react` | No |
441
586
  | `/unstyled` | All published components with `unstyled` defaulted to `true` | `react` | No |
442
587
  | `/styles` | Default CSS stylesheet — `import "@tantainnovative/ndpr-toolkit/styles"` once in your app entry | none | N/A |
443
588
 
@@ -458,6 +603,8 @@ The toolkit is published with `sideEffects: ["*.css"]`, so a modern bundler (Vit
458
603
 
459
604
  If your app only needs the hook (e.g. you're rendering ROPA records inside your own admin UI), import from `/hooks` instead of the feature subpath — the hook chunk doesn't drag the manager component into your bundle.
460
605
 
606
+ If your page only needs to *display* records (no Add / Edit / Archive / CSV export), reach for the new **Lite** variants from `/lawful-basis/lite`, `/cross-border/lite`, and `/ropa/lite` instead — they save ~65%, 89%, and 64% respectively. See [Lite vs Full managers](https://ndprtoolkit.com.ng/docs/guides/lite-vs-full).
607
+
461
608
  4. **`/server` carries zero React.** For Server Actions, Route Handlers, scheduled jobs, or compliance-score computation in CI, prefer `/server` and you'll pay no React-tree cost.
462
609
 
463
610
  ---
@@ -1 +1 @@
1
- import {a}from'./chunk-XJO4DH3L.mjs';import {d,a as a$1}from'./chunk-ZJYULEER.mjs';import {jsx}from'react/jsx-runtime';var S=[{id:"access",name:"Access My Data",description:"Request a copy of your personal data held by us",ndpaSection:"Section 34(1)(a)\u2013(b)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"rectification",name:"Correct My Data",description:"Request corrections to inaccurate personal data",ndpaSection:"Section 34(1)(c)",estimatedCompletionTime:30,requiresAdditionalInfo:true,additionalFields:[{id:"correction_details",label:"What data needs to be corrected?",type:"textarea",required:true,placeholder:"Please describe the inaccurate data and what the correct information should be"}]},{id:"erasure",name:"Delete My Data",description:"Request deletion of your personal data",ndpaSection:"Section 34(1)(d), Section 34(2)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"portability",name:"Export My Data",description:"Receive your data in a portable format",ndpaSection:"Section 38",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"restrict",name:"Restrict Processing",description:"Request restriction of data processing",ndpaSection:"Section 34(1)(e)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"object",name:"Object to Processing",description:"Object to processing of your personal data",ndpaSection:"Section 36",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"withdraw_consent",name:"Withdraw My Consent",description:"Withdraw consent previously given for processing",ndpaSection:"Section 35",estimatedCompletionTime:30,requiresAdditionalInfo:false}],g=({requestTypes:p=S,adapter:i,classNames:m,unstyled:f,onSubmit:R=()=>{},submitTo:s,submitOptions:e,onSubmitError:t})=>jsx(a,{requestTypes:p,onSubmit:o=>d(null,null,function*(){var n,r;if(s){let y=typeof(e==null?void 0:e.headers)=="function"?e.headers():(n=e==null?void 0:e.headers)!=null?n:{};try{let a=yield fetch(s,{method:"POST",headers:a$1({"Content-Type":"application/json"},y),credentials:(r=e==null?void 0:e.credentials)!=null?r:"same-origin",body:JSON.stringify(o)});a.ok||t==null||t({response:a});}catch(a){t==null||t({error:a});}}else i&&i.save(o);R(o);}),classNames:m,unstyled:f});export{g as a};
1
+ import {a}from'./chunk-XJO4DH3L.mjs';import {d,a as a$1}from'./chunk-ZJYULEER.mjs';import {jsx}from'react/jsx-runtime';var q=[{id:"access",name:"Access My Data",description:"Request a copy of your personal data held by us",ndpaSection:"Section 34(1)(a)\u2013(b)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"rectification",name:"Correct My Data",description:"Request corrections to inaccurate personal data",ndpaSection:"Section 34(1)(c)",estimatedCompletionTime:30,requiresAdditionalInfo:true,additionalFields:[{id:"correction_details",label:"What data needs to be corrected?",type:"textarea",required:true,placeholder:"Please describe the inaccurate data and what the correct information should be"}]},{id:"erasure",name:"Delete My Data",description:"Request deletion of your personal data",ndpaSection:"Section 34(1)(d), Section 34(2)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"portability",name:"Export My Data",description:"Receive your data in a portable format",ndpaSection:"Section 38",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"restrict",name:"Restrict Processing",description:"Request restriction of data processing",ndpaSection:"Section 34(1)(e)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"object",name:"Object to Processing",description:"Object to processing of your personal data",ndpaSection:"Section 36",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"withdraw_consent",name:"Withdraw My Consent",description:"Withdraw consent previously given for processing",ndpaSection:"Section 35",estimatedCompletionTime:30,requiresAdditionalInfo:false}],C=({requestTypes:R=q,adapter:s,classNames:y,unstyled:S,onSubmit:u=()=>{},submitTo:n,submitOptions:e,onSubmitError:t,onSubmitSuccess:r})=>jsx(a,{requestTypes:R,onSubmit:a=>d(null,null,function*(){var d,c;if(n){let h=typeof(e==null?void 0:e.headers)=="function"?e.headers():(d=e==null?void 0:e.headers)!=null?d:{};try{let o=yield fetch(n,{method:"POST",headers:a$1({"Content-Type":"application/json"},h),credentials:(c=e==null?void 0:e.credentials)!=null?c:"same-origin",body:JSON.stringify(a)});if(!o.ok)t==null||t({response:o});else if(r){let l;try{let i=yield o.clone().text();i&&(l=JSON.parse(i));}catch(i){}r({response:o,data:a,body:l});}}catch(o){t==null||t({error:o});}}else s&&s.save(a);u(a);}),classNames:y,unstyled:S});export{C as a};
File without changes
@@ -0,0 +1 @@
1
+ 'use strict';
@@ -1 +1 @@
1
- 'use strict';var chunkW47OSMT6_js=require('./chunk-W47OSMT6.js'),chunkRFPLZDIO_js=require('./chunk-RFPLZDIO.js'),jsxRuntime=require('react/jsx-runtime');var S=[{id:"access",name:"Access My Data",description:"Request a copy of your personal data held by us",ndpaSection:"Section 34(1)(a)\u2013(b)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"rectification",name:"Correct My Data",description:"Request corrections to inaccurate personal data",ndpaSection:"Section 34(1)(c)",estimatedCompletionTime:30,requiresAdditionalInfo:true,additionalFields:[{id:"correction_details",label:"What data needs to be corrected?",type:"textarea",required:true,placeholder:"Please describe the inaccurate data and what the correct information should be"}]},{id:"erasure",name:"Delete My Data",description:"Request deletion of your personal data",ndpaSection:"Section 34(1)(d), Section 34(2)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"portability",name:"Export My Data",description:"Receive your data in a portable format",ndpaSection:"Section 38",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"restrict",name:"Restrict Processing",description:"Request restriction of data processing",ndpaSection:"Section 34(1)(e)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"object",name:"Object to Processing",description:"Object to processing of your personal data",ndpaSection:"Section 36",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"withdraw_consent",name:"Withdraw My Consent",description:"Withdraw consent previously given for processing",ndpaSection:"Section 35",estimatedCompletionTime:30,requiresAdditionalInfo:false}],g=({requestTypes:p=S,adapter:i,classNames:m,unstyled:f,onSubmit:R=()=>{},submitTo:s,submitOptions:e,onSubmitError:t})=>jsxRuntime.jsx(chunkW47OSMT6_js.a,{requestTypes:p,onSubmit:o=>chunkRFPLZDIO_js.d(null,null,function*(){var n,r;if(s){let y=typeof(e==null?void 0:e.headers)=="function"?e.headers():(n=e==null?void 0:e.headers)!=null?n:{};try{let a=yield fetch(s,{method:"POST",headers:chunkRFPLZDIO_js.a({"Content-Type":"application/json"},y),credentials:(r=e==null?void 0:e.credentials)!=null?r:"same-origin",body:JSON.stringify(o)});a.ok||t==null||t({response:a});}catch(a){t==null||t({error:a});}}else i&&i.save(o);R(o);}),classNames:m,unstyled:f});exports.a=g;
1
+ 'use strict';var chunkW47OSMT6_js=require('./chunk-W47OSMT6.js'),chunkRFPLZDIO_js=require('./chunk-RFPLZDIO.js'),jsxRuntime=require('react/jsx-runtime');var q=[{id:"access",name:"Access My Data",description:"Request a copy of your personal data held by us",ndpaSection:"Section 34(1)(a)\u2013(b)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"rectification",name:"Correct My Data",description:"Request corrections to inaccurate personal data",ndpaSection:"Section 34(1)(c)",estimatedCompletionTime:30,requiresAdditionalInfo:true,additionalFields:[{id:"correction_details",label:"What data needs to be corrected?",type:"textarea",required:true,placeholder:"Please describe the inaccurate data and what the correct information should be"}]},{id:"erasure",name:"Delete My Data",description:"Request deletion of your personal data",ndpaSection:"Section 34(1)(d), Section 34(2)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"portability",name:"Export My Data",description:"Receive your data in a portable format",ndpaSection:"Section 38",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"restrict",name:"Restrict Processing",description:"Request restriction of data processing",ndpaSection:"Section 34(1)(e)",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"object",name:"Object to Processing",description:"Object to processing of your personal data",ndpaSection:"Section 36",estimatedCompletionTime:30,requiresAdditionalInfo:false},{id:"withdraw_consent",name:"Withdraw My Consent",description:"Withdraw consent previously given for processing",ndpaSection:"Section 35",estimatedCompletionTime:30,requiresAdditionalInfo:false}],C=({requestTypes:R=q,adapter:s,classNames:y,unstyled:S,onSubmit:u=()=>{},submitTo:n,submitOptions:e,onSubmitError:t,onSubmitSuccess:r})=>jsxRuntime.jsx(chunkW47OSMT6_js.a,{requestTypes:R,onSubmit:a=>chunkRFPLZDIO_js.d(null,null,function*(){var d,c;if(n){let h=typeof(e==null?void 0:e.headers)=="function"?e.headers():(d=e==null?void 0:e.headers)!=null?d:{};try{let o=yield fetch(n,{method:"POST",headers:chunkRFPLZDIO_js.a({"Content-Type":"application/json"},h),credentials:(c=e==null?void 0:e.credentials)!=null?c:"same-origin",body:JSON.stringify(a)});if(!o.ok)t==null||t({response:o});else if(r){let l;try{let i=yield o.clone().text();i&&(l=JSON.parse(i));}catch(i){}r({response:o,data:a,body:l});}}catch(o){t==null||t({error:o});}}else s&&s.save(a);u(a);}),classNames:y,unstyled:S});exports.a=C;
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkUAV7V4EM_js=require('./chunk-UAV7V4EM.js'),chunk4QXTB3L6_js=require('./chunk-4QXTB3L6.js'),chunk3GRGYT3P_js=require('./chunk-3GRGYT3P.js'),chunk7IFSWCQP_js=require('./chunk-7IFSWCQP.js'),chunkLVGT3DLT_js=require('./chunk-LVGT3DLT.js'),chunkQPRYXVH2_js=require('./chunk-QPRYXVH2.js'),chunkQ64735OC_js=require('./chunk-Q64735OC.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkB46SJB5V_js=require('./chunk-B46SJB5V.js'),chunkL2BRFMVS_js=require('./chunk-L2BRFMVS.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkUAV7V4EM_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkUAV7V4EM_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkUAV7V4EM_js.c}});Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunk3GRGYT3P_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunk3GRGYT3P_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunk3GRGYT3P_js.b}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunk7IFSWCQP_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunk7IFSWCQP_js.b}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkLVGT3DLT_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkLVGT3DLT_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkLVGT3DLT_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkLVGT3DLT_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkLVGT3DLT_js.b}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunkQPRYXVH2_js.a}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunkQ64735OC_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunkQ64735OC_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunkQ64735OC_js.f}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsent",{enumerable:true,get:function(){return chunkB46SJB5V_js.a}});Object.defineProperty(exports,"validateConsentOptions",{enumerable:true,get:function(){return chunkB46SJB5V_js.b}});Object.defineProperty(exports,"formatDSRRequest",{enumerable:true,get:function(){return chunkL2BRFMVS_js.b}});Object.defineProperty(exports,"validateDsrSubmission",{enumerable:true,get:function(){return chunkL2BRFMVS_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});
1
+ 'use strict';var chunkUAV7V4EM_js=require('./chunk-UAV7V4EM.js'),chunk4QXTB3L6_js=require('./chunk-4QXTB3L6.js'),chunk3GRGYT3P_js=require('./chunk-3GRGYT3P.js'),chunk7IFSWCQP_js=require('./chunk-7IFSWCQP.js'),chunkQPRYXVH2_js=require('./chunk-QPRYXVH2.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkLVGT3DLT_js=require('./chunk-LVGT3DLT.js'),chunkQ64735OC_js=require('./chunk-Q64735OC.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkB46SJB5V_js=require('./chunk-B46SJB5V.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkL2BRFMVS_js=require('./chunk-L2BRFMVS.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkUAV7V4EM_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkUAV7V4EM_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkUAV7V4EM_js.c}});Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunk4QXTB3L6_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunk3GRGYT3P_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunk3GRGYT3P_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunk3GRGYT3P_js.b}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunk7IFSWCQP_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunk7IFSWCQP_js.b}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunkQPRYXVH2_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkLVGT3DLT_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkLVGT3DLT_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkLVGT3DLT_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkLVGT3DLT_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkLVGT3DLT_js.b}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunkQ64735OC_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunkQ64735OC_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunkQ64735OC_js.f}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsent",{enumerable:true,get:function(){return chunkB46SJB5V_js.a}});Object.defineProperty(exports,"validateConsentOptions",{enumerable:true,get:function(){return chunkB46SJB5V_js.b}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"formatDSRRequest",{enumerable:true,get:function(){return chunkL2BRFMVS_js.b}});Object.defineProperty(exports,"validateDsrSubmission",{enumerable:true,get:function(){return chunkL2BRFMVS_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});
package/dist/core.mjs CHANGED
@@ -1 +1 @@
1
- export{a as NDPRProvider,b as useNDPRConfig,c as useNDPRLocale}from'./chunk-EEQALYOY.mjs';export{c as hausaLocale,b as igboLocale,d as pidginLocale,a as yorubaLocale}from'./chunk-LQTARVPU.mjs';export{a as ORG_POLICY_TEMPLATE_REGISTRY,b as createOrgTemplate,b as templateContextFor}from'./chunk-UKLU6BQF.mjs';export{a as defaultLocale,b as mergeLocale}from'./chunk-HWHBINVN.mjs';export{c as DEFAULT_POLICY_SECTIONS,d as DEFAULT_POLICY_VARIABLES,e as createBusinessPolicyTemplate,a as findUnfilledTokens,b as generatePolicyText}from'./chunk-Y3MKMAFQ.mjs';export{a as getComplianceScore}from'./chunk-EFIBHKQE.mjs';export{c as assemblePolicy,e as createDefaultContext,f as evaluatePolicyCompliance}from'./chunk-RMQ7OLNY.mjs';export{c as assessComplianceGaps,d as generateLawfulBasisSummary,b as getLawfulBasisDescription,a as validateProcessingActivity}from'./chunk-LWIKDDSU.mjs';export{h as assessTransferRisk,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';export{c as exportROPAToCSV,b as generateROPASummary,d as identifyComplianceGaps,a as validateProcessingRecord}from'./chunk-XP5PL6K7.mjs';export{c as appendAuditEntry,a as createAuditEntry,b as getAuditLog}from'./chunk-V7UFP6QU.mjs';export{a as validateConsent,b as validateConsentOptions}from'./chunk-PJNKQPQP.mjs';export{b as formatDSRRequest,a as validateDsrSubmission}from'./chunk-RZ6GC6WN.mjs';export{a as assessDPIARisk}from'./chunk-LRRENTT5.mjs';export{a as calculateBreachSeverity}from'./chunk-WTGKZX7J.mjs';export{a as sanitizeInput}from'./chunk-EWVK45Z3.mjs';export{b as LEGAL_DISCLAIMER_LONG,a as LEGAL_DISCLAIMER_SHORT,c as legalDisclaimerBlock}from'./chunk-ITCY2Z66.mjs';import'./chunk-ZJYULEER.mjs';
1
+ export{a as NDPRProvider,b as useNDPRConfig,c as useNDPRLocale}from'./chunk-EEQALYOY.mjs';export{c as hausaLocale,b as igboLocale,d as pidginLocale,a as yorubaLocale}from'./chunk-LQTARVPU.mjs';export{a as ORG_POLICY_TEMPLATE_REGISTRY,b as createOrgTemplate,b as templateContextFor}from'./chunk-UKLU6BQF.mjs';export{a as defaultLocale,b as mergeLocale}from'./chunk-HWHBINVN.mjs';export{a as getComplianceScore}from'./chunk-EFIBHKQE.mjs';export{a as calculateBreachSeverity}from'./chunk-WTGKZX7J.mjs';export{c as DEFAULT_POLICY_SECTIONS,d as DEFAULT_POLICY_VARIABLES,e as createBusinessPolicyTemplate,a as findUnfilledTokens,b as generatePolicyText}from'./chunk-Y3MKMAFQ.mjs';export{c as assemblePolicy,e as createDefaultContext,f as evaluatePolicyCompliance}from'./chunk-RMQ7OLNY.mjs';export{h as assessTransferRisk,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';export{c as assessComplianceGaps,d as generateLawfulBasisSummary,b as getLawfulBasisDescription,a as validateProcessingActivity}from'./chunk-LWIKDDSU.mjs';export{c as exportROPAToCSV,b as generateROPASummary,d as identifyComplianceGaps,a as validateProcessingRecord}from'./chunk-XP5PL6K7.mjs';export{c as appendAuditEntry,a as createAuditEntry,b as getAuditLog}from'./chunk-V7UFP6QU.mjs';export{a as validateConsent,b as validateConsentOptions}from'./chunk-PJNKQPQP.mjs';export{a as sanitizeInput}from'./chunk-EWVK45Z3.mjs';export{b as formatDSRRequest,a as validateDsrSubmission}from'./chunk-RZ6GC6WN.mjs';export{a as assessDPIARisk}from'./chunk-LRRENTT5.mjs';export{b as LEGAL_DISCLAIMER_LONG,a as LEGAL_DISCLAIMER_SHORT,c as legalDisclaimerBlock}from'./chunk-ITCY2Z66.mjs';import'./chunk-ZJYULEER.mjs';