dpdpstack-js-sdk 0.1.0 → 0.2.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/README.md +4 -26
- package/dist/dpdpstack.global.js +1 -1
- package/dist/dpdpstack.global.js.map +1 -1
- package/dist/index.cjs +22 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -1
- package/dist/index.d.ts +76 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ consent, erasure, audit, DSR/breach workflows, and verifiable Certificates of
|
|
|
5
5
|
Erasure. Zero runtime dependencies; works in Node 18+ and the browser.
|
|
6
6
|
|
|
7
7
|
> This is the SDK for the **hosted platform** API. The open-source erasure
|
|
8
|
-
> engine is the Python package [`dpdpstack`](https://pypi.org/project/dpdpstack/).
|
|
8
|
+
> engine is the Python package [`dpdpstack`](https://pypi.org/project/dpdpstack-python-sdk/).
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -95,9 +95,9 @@ The SDK mirrors the HTTP API; field names match the wire format exactly.
|
|
|
95
95
|
|---|---|
|
|
96
96
|
| **Consent** | `listPurposes()` · `createPurpose()` · `grantConsent()` · `withdrawConsent()` · `consentStatus(ref)` · `listConsentRecords()` · `recordActivity()` |
|
|
97
97
|
| **Erasure** | `requestErasure()` · `confirmErasure(token)` |
|
|
98
|
-
| **Audit** | `getAuditLog({ principal_ref? })` |
|
|
99
|
-
| **Retention** | `retention.list()` · `retention.upsert()` · `retention.run({ dry_run? })` |
|
|
100
|
-
| **Certificates** | `certificates.issue()` · `certificates.verify(jwt)` · `certificates.publicKey()` · `certificates.registry(fp)` · `certificates.issueFromEvidence()` |
|
|
98
|
+
| **Audit** | `getAuditLog({ principal_ref? })` · `verifyAuditChain()` · `createAuditCheckpoint({ through_sequence? })` |
|
|
99
|
+
| **Retention** | `retention.list()` · `retention.upsert()` · `retention.run({ dry_run? })` · `readiness()` · `stats()` |
|
|
100
|
+
| **Certificates** | `certificates.issue()` · `certificates.issueConsent()` · `certificates.verify(jwt)` · `certificates.publicKey()` · `certificates.registry(fp)` · `certificates.issueFromEvidence()` |
|
|
101
101
|
| **Evidence** | `evidence.ingest()` · `evidence.list({ source?, subject? })` |
|
|
102
102
|
| **DSR** | `dsr.list()` · `dsr.create()` · `dsr.get(id)` · `dsr.act(id, { action })` |
|
|
103
103
|
| **Breaches** | `breaches.list()` · `breaches.report()` · `breaches.get(id)` · `breaches.act(id, { action })` · `breaches.notifications(id)` |
|
|
@@ -115,28 +115,6 @@ npm run build # → dist/ (ESM, CJS, IIFE, .d.ts)
|
|
|
115
115
|
npm run typecheck
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
## Releasing (CI/CD)
|
|
119
|
-
|
|
120
|
-
Publishing is automated by GitHub Actions ([.github/workflows/publish.yml](.github/workflows/publish.yml)).
|
|
121
|
-
|
|
122
|
-
**One-time setup:** add an npm **automation** token as a repo secret named `NPM_TOKEN`
|
|
123
|
-
(npm → Access Tokens → Generate → *Automation* → copy → GitHub repo → Settings →
|
|
124
|
-
Secrets and variables → Actions → New repository secret).
|
|
125
|
-
|
|
126
|
-
**To cut a release:**
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
npm version patch # bump package.json + create tag vX.Y.Z (minor/major as needed)
|
|
130
|
-
git push --follow-tags # pushing the tag triggers the publish workflow
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
The workflow runs typecheck + build, checks the tag matches `package.json`, then
|
|
134
|
-
publishes to npm with provenance. The CDN (jsDelivr / unpkg) updates automatically.
|
|
135
|
-
`.github/workflows/ci.yml` runs typecheck + build on every push/PR.
|
|
136
|
-
|
|
137
|
-
> Provenance needs a **public** repo. On a private repo, remove `--provenance`
|
|
138
|
-
> from the publish step.
|
|
139
|
-
|
|
140
118
|
## License
|
|
141
119
|
|
|
142
120
|
MIT
|
package/dist/dpdpstack.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var dpdpstack=(()=>{var E=Object.defineProperty;var
|
|
1
|
+
"use strict";var dpdpstack=(()=>{var E=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var x=(s,e)=>{for(var t in e)E(s,t,{get:e[t],enumerable:!0})},q=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of S(e))!I.call(s,r)&&r!==t&&E(s,r,{get:()=>e[r],enumerable:!(i=v(e,r))||i.enumerable});return s};var k=s=>q(E({},"__esModule",{value:!0}),s);var B={};x(B,{DEFAULT_API_BASE:()=>R,DPDPConsent:()=>O,DPDPError:()=>m,DPDPStack:()=>h,mountConsentWidget:()=>b});var R="https://getdpdp.net/api/v1",m=class extends Error{constructor(e,t,i){super(`DPDP API error ${e}: ${t}`),this.name="DPDPError",this.status=e,this.detail=t,this.body=i}};function L(s){if(!s)return"";let e=Object.entries(s).filter(([,t])=>t!=null&&t!=="").map(([t,i])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(i))}`);return e.length?`?${e.join("&")}`:""}var h=class{constructor(e={}){this.retention={list:()=>this.request("GET","/retention/policies"),upsert:e=>this.request("POST","/retention/policies",{body:e}),run:(e={})=>this.request("POST","/retention/run",{body:e})};this.certificates={issue:e=>this.request("POST","/certificate",{body:e}),issueConsent:e=>this.request("POST","/consent/certificate",{body:e}),verify:e=>this.request("POST","/certificate/verify",{body:{certificate_jwt:e}}),publicKey:()=>this.request("GET","/certificate/public-key"),registry:e=>this.request("GET",`/certificate/registry/${encodeURIComponent(e)}`),issueFromEvidence:e=>this.request("POST","/evidence/certificate",{body:e})};this.evidence={ingest:e=>this.request("POST","/evidence",{body:e}),list:(e={})=>this.request("GET","/evidence",{query:e})};this.dsr={list:(e={})=>this.request("GET","/dsr",{query:e}),create:e=>this.request("POST","/dsr",{body:e}),get:e=>this.request("GET",`/dsr/${e}`),act:(e,t)=>this.request("POST",`/dsr/${e}`,{body:t})};this.breaches={list:(e={})=>this.request("GET","/breaches",{query:e}),report:e=>this.request("POST","/breaches",{body:e}),get:e=>this.request("GET",`/breaches/${e}`),act:(e,t)=>this.request("POST",`/breaches/${e}`,{body:t}),notifications:e=>this.request("GET",`/breaches/${e}/notification`)};this.targets={list:()=>this.request("GET","/targets"),create:e=>this.request("POST","/targets",{body:e}),get:e=>this.request("GET",`/targets/${e}`),update:(e,t)=>this.request("POST",`/targets/${e}`,{body:t}),remove:e=>this.request("DELETE",`/targets/${e}`)};this.erasureTasks={list:(e={})=>this.request("GET","/erasure/tasks",{query:e}),retry:e=>this.request("POST",`/erasure/tasks/${e}/retry`)};this.apiBase=(e.apiBase??R).replace(/\/+$/,""),this.apiKey=e.apiKey,this.defaultHeaders=e.headers??{},this.credentials=e.credentials;let t=e.fetch??globalThis.fetch;if(typeof t!="function")throw new Error("No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.");this.fetchImpl=t.bind(globalThis)}async request(e,t,i={}){let r=`${this.apiBase}${t}${L(i.query)}`,n={...this.defaultHeaders};this.apiKey&&(n["X-API-Key"]=this.apiKey);let f=i.body!==void 0;f&&(n["Content-Type"]="application/json");let u=await this.fetchImpl(r,{method:e,headers:n,body:f?JSON.stringify(i.body):void 0,...this.credentials?{credentials:this.credentials}:{}}),p=await u.text(),o;if(p)try{o=JSON.parse(p)}catch{o=p}if(!u.ok){let P=(o&&typeof o=="object"&&"detail"in o?String(o.detail):void 0)??u.statusText??"Request failed";throw new m(u.status,P,o)}return o}listPurposes(){return this.request("GET","/purposes")}createPurpose(e){return this.request("POST","/purposes",{body:e})}grantConsent(e){return this.request("POST","/consent",{body:e})}withdrawConsent(e){return this.request("POST","/consent/withdraw",{body:e})}consentStatus(e){return this.request("GET","/consent/status",{query:{principal_ref:e}})}listConsentRecords(){return this.request("GET","/consent/records")}recordActivity(e){return this.request("POST","/activity",{body:e})}requestErasure(e){return this.request("POST","/erasure",{body:e})}confirmErasure(e){return this.request("POST","/erasure/confirm",{body:{token:e}})}getAuditLog(e={}){return this.request("GET","/audit",{query:e})}verifyAuditChain(){return this.request("GET","/audit/verify")}createAuditCheckpoint(e={}){return this.request("POST","/audit/checkpoint",{body:e})}readiness(){return this.request("GET","/readiness")}stats(){return this.request("GET","/stats")}};var w={heading:"We value your privacy",subheading:"Choose what you consent to. You can withdraw anytime (DPDP Act).",save:"Save consent preferences",saving:"Saving\u2026",saved:"Preferences saved.",loading:"Loading\u2026",error:"Could not save your preferences. Please try again."};function c(s,e={},t=[]){let i=document.createElement(s);for(let[r,n]of Object.entries(e))r==="style"&&typeof n=="string"?i.style.cssText=n:r==="class"&&typeof n=="string"?i.className=n:r.startsWith("on")&&typeof n=="function"?i.addEventListener(r.slice(2),n):typeof n=="string"&&i.setAttribute(r,n);for(let r of t)i.appendChild(typeof r=="string"?document.createTextNode(r):r);return i}function A(s,e){let t=s.translations?.[e]??{};return{name:t.name||s.name,description:t.description||s.description}}var D="border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);";function b(s,e){let t=typeof s=="string"?document.querySelector(s):s;if(!t)throw new Error(`mountConsentWidget: container not found: ${String(s)}`);let i=e.client??new h({apiBase:e.apiBase,apiKey:e.apiKey}),r={...w,...e.texts},n=new Set(e.defaultChecked??[]),f=e.locale??"en",u=e.purposes??null;function p(a,C){return c("div",{style:`margin-top:12px;font-size:13px;color:${C};`},[a])}function o(){t.innerHTML="";let a=c("div",{style:D},[c("div",{style:"font-weight:600;font-size:15px;margin-bottom:4px;"},[r.heading]),c("div",{style:"font-size:13px;color:#666;margin-bottom:12px;"},[r.subheading])]);if(!u){a.appendChild(p(r.loading,"#666")),t.appendChild(a);return}let C={};for(let l of u){let d=A(l,f),g=c("input",{type:"checkbox",id:`dpdp_${l.code}`});n.has(l.code)&&(g.checked=!0),C[l.code]=g,a.appendChild(c("label",{style:"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;",for:`dpdp_${l.code}`},[g,c("span",{},[c("strong",{},[d.name]),c("div",{style:"font-size:12px;color:#777;margin-top:2px;"},[d.description])])]))}let T=c("div",{}),y=c("button",{type:"button",style:"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;"},[r.save]);y.addEventListener("click",async()=>{let l=u.filter(d=>C[d.code]?.checked);y.disabled=!0,y.textContent=r.saving,T.innerHTML="";try{let d=await Promise.all(l.map(g=>i.grantConsent({principal_ref:e.principalRef,purpose:g.code,locale:f})));T.appendChild(p(r.saved,"#16a34a")),e.onSave?.(d)}catch(d){T.appendChild(p(r.error,"#dc2626")),e.onError?.(d)}finally{y.disabled=!1,y.textContent=r.save}}),a.appendChild(y),a.appendChild(T),t.appendChild(a)}async function P(){if(!e.purposes){o();try{u=await i.listPurposes()}catch(a){u=[],e.onError?.(a)}}o()}return P(),{setLocale(a){f=a,o()},refresh:P,destroy(){t.innerHTML=""}}}var O={init(s){let{el:e,...t}=s;return b(e,t)}};return k(B);})();
|
|
2
2
|
//# sourceMappingURL=dpdpstack.global.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/widget.ts"],"sourcesContent":["export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n","import type {\n ActivityInput,\n ActivityResult,\n AuditLog,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n"],"mappings":"6bAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,gBAAAC,EAAA,cAAAC,EAAA,cAAAC,EAAA,uBAAAC,IC6CO,IAAMC,EAAmB,6BAqBnBC,EAAN,cAAwB,KAAM,CAKnC,YAAYC,EAAgBC,EAAgBC,EAAe,CACzD,MAAM,kBAAkBF,CAAM,KAAKC,CAAM,EAAE,EAC3C,KAAK,KAAO,YACZ,KAAK,OAASD,EACd,KAAK,OAASC,EACd,KAAK,KAAOC,CACd,CACF,EAEA,SAASC,EAAWC,EAAwB,CAC1C,GAAI,CAACA,EAAO,MAAO,GACnB,IAAMC,EAAQ,OAAO,QAAQD,CAAgC,EAC1D,OAAO,CAAC,CAAC,CAAEE,CAAC,IAAyBA,GAAM,MAAQA,IAAM,EAAE,EAC3D,IAAI,CAAC,CAACC,EAAGD,CAAC,IAAM,GAAG,mBAAmBC,CAAC,CAAC,IAAI,mBAAmB,OAAOD,CAAC,CAAC,CAAC,EAAE,EAC9E,OAAOD,EAAM,OAAS,IAAIA,EAAM,KAAK,GAAG,CAAC,GAAK,EAChD,CAUO,IAAMG,EAAN,KAAgB,CAOrB,YAAYC,EAA4B,CAAC,EAAG,CAkH5C,KAAS,UAAY,CAEnB,KAAM,IAAkC,KAAK,QAAQ,MAAO,qBAAqB,EAEjF,OAASC,GACP,KAAK,QAAQ,OAAQ,sBAAuB,CAAE,KAAMA,CAAM,CAAC,EAE7D,IAAK,CAACA,EAA+B,CAAC,IACpC,KAAK,QAAQ,OAAQ,iBAAkB,CAAE,KAAMA,CAAM,CAAC,CAC1D,EAIA,KAAS,aAAe,CAEtB,MAAQA,GACN,KAAK,QAAQ,OAAQ,eAAgB,CAAE,KAAMA,CAAM,CAAC,EAEtD,OAASC,GACP,KAAK,QAAQ,OAAQ,sBAAuB,CAAE,KAAM,CAAE,gBAAiBA,CAAe,CAAE,CAAC,EAE3F,UAAW,IACT,KAAK,QAAQ,MAAO,yBAAyB,EAE/C,SAAWC,GACT,KAAK,QAAQ,MAAO,yBAAyB,mBAAmBA,CAAW,CAAC,EAAE,EAEhF,kBAAoBF,GAClB,KAAK,QAAQ,OAAQ,wBAAyB,CAAE,KAAMA,CAAM,CAAC,CACjE,EAIA,KAAS,SAAW,CAElB,OAASA,GACP,KAAK,QAAQ,OAAQ,YAAa,CAAE,KAAMA,CAAM,CAAC,EAEnD,KAAM,CAACN,EAA2B,CAAC,IACjC,KAAK,QAAQ,MAAO,YAAa,CAAE,MAAAA,CAAM,CAAC,CAC9C,EAIA,KAAS,IAAM,CAEb,KAAM,CAACA,EAAsB,CAAC,IAAsB,KAAK,QAAQ,MAAO,OAAQ,CAAE,MAAAA,CAAM,CAAC,EAEzF,OAASM,GAAwC,KAAK,QAAQ,OAAQ,OAAQ,CAAE,KAAMA,CAAM,CAAC,EAE7F,IAAMG,GAA6B,KAAK,QAAQ,MAAO,QAAQA,CAAE,EAAE,EAEnE,IAAK,CAACA,EAAYH,IAChB,KAAK,QAAQ,OAAQ,QAAQG,CAAE,GAAI,CAAE,KAAMH,CAAM,CAAC,CACtD,EAIA,KAAS,SAAW,CAElB,KAAM,CAACN,EAAyB,CAAC,IAC/B,KAAK,QAAQ,MAAO,YAAa,CAAE,MAAAA,CAAM,CAAC,EAE5C,OAASM,GACP,KAAK,QAAQ,OAAQ,YAAa,CAAE,KAAMA,CAAM,CAAC,EAEnD,IAAMG,GAAgC,KAAK,QAAQ,MAAO,aAAaA,CAAE,EAAE,EAE3E,IAAK,CAACA,EAAYH,IAChB,KAAK,QAAQ,OAAQ,aAAaG,CAAE,GAAI,CAAE,KAAMH,CAAM,CAAC,EAEzD,cAAgBG,GACd,KAAK,QAAQ,MAAO,aAAaA,CAAE,eAAe,CACtD,EAIA,KAAS,QAAU,CAEjB,KAAM,IAAyB,KAAK,QAAQ,MAAO,UAAU,EAE7D,OAASH,GACP,KAAK,QAAQ,OAAQ,WAAY,CAAE,KAAMA,CAAM,CAAC,EAElD,IAAMG,GAAgC,KAAK,QAAQ,MAAO,YAAYA,CAAE,EAAE,EAE1E,OAAQ,CAACA,EAAYH,IACnB,KAAK,QAAQ,OAAQ,YAAYG,CAAE,GAAI,CAAE,KAAMH,CAAM,CAAC,EAExD,OAASG,GAA8B,KAAK,QAAQ,SAAU,YAAYA,CAAE,EAAE,CAChF,EAEA,KAAS,aAAe,CAEtB,KAAM,CAACT,EAA8B,CAAC,IACpC,KAAK,QAAQ,MAAO,iBAAkB,CAAE,MAAAA,CAAM,CAAC,EAEjD,MAAQS,GACN,KAAK,QAAQ,OAAQ,kBAAkBA,CAAE,QAAQ,CACrD,EApNE,KAAK,SAAWJ,EAAQ,SAAWX,GAAkB,QAAQ,OAAQ,EAAE,EACvE,KAAK,OAASW,EAAQ,OACtB,KAAK,eAAiBA,EAAQ,SAAW,CAAC,EAC1C,KAAK,YAAcA,EAAQ,YAE3B,IAAMK,EAAIL,EAAQ,OAAS,WAAW,MACtC,GAAI,OAAOK,GAAM,WACf,MAAM,IAAI,MACR,qFACF,EAEF,KAAK,UAAYA,EAAE,KAAK,UAAU,CACpC,CAGA,MAAM,QACJC,EACAC,EACAC,EAA2C,CAAC,EAChC,CACZ,IAAMC,EAAM,GAAG,KAAK,OAAO,GAAGF,CAAI,GAAGb,EAAWc,EAAK,KAAK,CAAC,GACrDE,EAAkC,CAAE,GAAG,KAAK,cAAe,EAC7D,KAAK,SAAQA,EAAQ,WAAW,EAAI,KAAK,QAE7C,IAAMC,EAAUH,EAAK,OAAS,OAC1BG,IAASD,EAAQ,cAAc,EAAI,oBAEvC,IAAME,EAAM,MAAM,KAAK,UAAUH,EAAK,CACpC,OAAAH,EACA,QAAAI,EACA,KAAMC,EAAU,KAAK,UAAUH,EAAK,IAAI,EAAI,OAC5C,GAAI,KAAK,YAAc,CAAE,YAAa,KAAK,WAAY,EAAI,CAAC,CAC9D,CAAC,EAEKK,EAAO,MAAMD,EAAI,KAAK,EACxBE,EACJ,GAAID,EACF,GAAI,CACFC,EAAO,KAAK,MAAMD,CAAI,CACxB,MAAQ,CACNC,EAAOD,CACT,CAGF,GAAI,CAACD,EAAI,GAAI,CACX,IAAMpB,GACHsB,GAAQ,OAAOA,GAAS,UAAY,WAAYA,EAC7C,OAAQA,EAA6B,MAAM,EAC3C,SAAcF,EAAI,YAAc,iBACtC,MAAM,IAAItB,EAAUsB,EAAI,OAAQpB,EAAQsB,CAAI,CAC9C,CAEA,OAAOA,CACT,CAKA,cAAmC,CACjC,OAAO,KAAK,QAAQ,MAAO,WAAW,CACxC,CAGA,cAAcb,EAAuC,CACnD,OAAO,KAAK,QAAQ,OAAQ,YAAa,CAAE,KAAMA,CAAM,CAAC,CAC1D,CAGA,aAAaA,EAAmD,CAC9D,OAAO,KAAK,QAAQ,OAAQ,WAAY,CAAE,KAAMA,CAAM,CAAC,CACzD,CAGA,gBAAgBA,EAA6D,CAC3E,OAAO,KAAK,QAAQ,OAAQ,oBAAqB,CAAE,KAAMA,CAAM,CAAC,CAClE,CAGA,cAAcc,EAA8C,CAC1D,OAAO,KAAK,QAAQ,MAAO,kBAAmB,CAAE,MAAO,CAAE,cAAeA,CAAa,CAAE,CAAC,CAC1F,CAGA,oBAAsD,CACpD,OAAO,KAAK,QAAQ,MAAO,kBAAkB,CAC/C,CAGA,eAAed,EAA+C,CAC5D,OAAO,KAAK,QAAQ,OAAQ,YAAa,CAAE,KAAMA,CAAM,CAAC,CAC1D,CAKA,eAAeA,EAA6C,CAC1D,OAAO,KAAK,QAAQ,OAAQ,WAAY,CAAE,KAAMA,CAAM,CAAC,CACzD,CAGA,eAAee,EAA8C,CAC3D,OAAO,KAAK,QAAQ,OAAQ,mBAAoB,CAAE,KAAM,CAAE,MAAAA,CAAM,CAAE,CAAC,CACrE,CAKA,YAAYrB,EAAoC,CAAC,EAAsB,CACrE,OAAO,KAAK,QAAQ,MAAO,SAAU,CAAE,MAAAA,CAAM,CAAC,CAChD,CAwGF,EChTA,IAAMsB,EAAoC,CACxC,QAAS,wBACT,WAAY,mEACZ,KAAM,2BACN,OAAQ,eACR,MAAO,qBACP,QAAS,gBACT,MAAO,oDACT,EAoCA,SAASC,EACPC,EACAC,EAAe,CAAC,EAChBC,EAAiC,CAAC,EACR,CAC1B,IAAMC,EAAO,SAAS,cAAcH,CAAG,EACvC,OAAW,CAACI,EAAGC,CAAC,IAAK,OAAO,QAAQJ,CAAK,EACnCG,IAAM,SAAW,OAAOC,GAAM,SAAUF,EAAK,MAAM,QAAUE,EACxDD,IAAM,SAAW,OAAOC,GAAM,SAAUF,EAAK,UAAYE,EACzDD,EAAE,WAAW,IAAI,GAAK,OAAOC,GAAM,WAAYF,EAAK,iBAAiBC,EAAE,MAAM,CAAC,EAAGC,CAAC,EAClF,OAAOA,GAAM,UAAUF,EAAK,aAAaC,EAAGC,CAAC,EAExD,QAAWC,KAAKJ,EAAUC,EAAK,YAAY,OAAOG,GAAM,SAAW,SAAS,eAAeA,CAAC,EAAIA,CAAC,EACjG,OAAOH,CACT,CAEA,SAASI,EAAUC,EAAkBC,EAA2C,CAC9E,IAAM,EAAqBD,EAAQ,eAAeC,CAAM,GAAK,CAAC,EAC9D,MAAO,CACL,KAAM,EAAE,MAAQD,EAAQ,KACxB,YAAa,EAAE,aAAeA,EAAQ,WACxC,CACF,CAEA,IAAME,EACJ,2MAcK,SAASC,EACdC,EACAC,EACyB,CACzB,IAAMC,EACJ,OAAOF,GAAW,SAAW,SAAS,cAA2BA,CAAM,EAAIA,EAC7E,GAAI,CAACE,EAAW,MAAM,IAAI,MAAM,4CAA4C,OAAOF,CAAM,CAAC,EAAE,EAE5F,IAAMG,EACJF,EAAQ,QAAU,IAAIG,EAAU,CAAE,QAASH,EAAQ,QAAS,OAAQA,EAAQ,MAAO,CAAC,EAChFI,EAA4B,CAAE,GAAGnB,EAAe,GAAGe,EAAQ,KAAM,EACjEK,EAAiB,IAAI,IAAIL,EAAQ,gBAAkB,CAAC,CAAC,EAEvDJ,EAASI,EAAQ,QAAU,KAC3BM,EAA6BN,EAAQ,UAAY,KAErD,SAASO,EAAQC,EAAcC,EAA4B,CACzD,OAAOvB,EAAG,MAAO,CAAE,MAAO,wCAAwCuB,CAAK,GAAI,EAAG,CAACD,CAAI,CAAC,CACtF,CAEA,SAASE,GAAe,CACtBT,EAAW,UAAY,GACvB,IAAMU,EAAOzB,EAAG,MAAO,CAAE,MAAOW,CAAK,EAAG,CACtCX,EAAG,MAAO,CAAE,MAAO,mDAAoD,EAAG,CAACkB,EAAM,OAAO,CAAC,EACzFlB,EAAG,MAAO,CAAE,MAAO,+CAAgD,EAAG,CAACkB,EAAM,UAAU,CAAC,CAC1F,CAAC,EAED,GAAI,CAACE,EAAU,CACbK,EAAK,YAAYJ,EAAQH,EAAM,QAAS,MAAM,CAAC,EAC/CH,EAAW,YAAYU,CAAI,EAC3B,MACF,CAEA,IAAMC,EAA2C,CAAC,EAClD,QAAWC,KAAKP,EAAU,CACxB,IAAMQ,EAAIpB,EAAUmB,EAAGjB,CAAM,EACvBmB,EAAM7B,EAAG,QAAS,CAAE,KAAM,WAAY,GAAI,QAAQ2B,EAAE,IAAI,EAAG,CAAC,EAC9DR,EAAe,IAAIQ,EAAE,IAAI,IAAGE,EAAI,QAAU,IAC9CH,EAAOC,EAAE,IAAI,EAAIE,EACjBJ,EAAK,YACHzB,EACE,QACA,CACE,MACE,2FACF,IAAK,QAAQ2B,EAAE,IAAI,EACrB,EACA,CACEE,EACA7B,EAAG,OAAQ,CAAC,EAAG,CACbA,EAAG,SAAU,CAAC,EAAG,CAAC4B,EAAE,IAAI,CAAC,EACzB5B,EAAG,MAAO,CAAE,MAAO,2CAA4C,EAAG,CAAC4B,EAAE,WAAW,CAAC,CACnF,CAAC,CACH,CACF,CACF,CACF,CAEA,IAAME,EAAS9B,EAAG,MAAO,CAAC,CAAC,EACrB+B,EAAU/B,EACd,SACA,CACE,KAAM,SACN,MACE,yIACJ,EACA,CAACkB,EAAM,IAAI,CACb,EAEAa,EAAQ,iBAAiB,QAAS,SAAY,CAC5C,IAAMC,EAAWZ,EAAU,OAAQO,GAAMD,EAAOC,EAAE,IAAI,GAAG,OAAO,EAChEI,EAAQ,SAAW,GACnBA,EAAQ,YAAcb,EAAM,OAC5BY,EAAO,UAAY,GACnB,GAAI,CACF,IAAMG,EAAW,MAAM,QAAQ,IAC7BD,EAAS,IAAKL,GACZX,EAAO,aAAa,CAAE,cAAeF,EAAQ,aAAc,QAASa,EAAE,KAAM,OAAAjB,CAAO,CAAC,CACtF,CACF,EACAoB,EAAO,YAAYT,EAAQH,EAAM,MAAO,SAAS,CAAC,EAClDJ,EAAQ,SAASmB,CAAQ,CAC3B,OAASC,EAAK,CACZJ,EAAO,YAAYT,EAAQH,EAAM,MAAO,SAAS,CAAC,EAClDJ,EAAQ,UAAUoB,CAAG,CACvB,QAAE,CACAH,EAAQ,SAAW,GACnBA,EAAQ,YAAcb,EAAM,IAC9B,CACF,CAAC,EAEDO,EAAK,YAAYM,CAAO,EACxBN,EAAK,YAAYK,CAAM,EACvBf,EAAW,YAAYU,CAAI,CAC7B,CAEA,eAAeU,GAAyB,CACtC,GAAI,CAACrB,EAAQ,SAAU,CACrBU,EAAO,EACP,GAAI,CACFJ,EAAW,MAAMJ,EAAO,aAAa,CACvC,OAASkB,EAAK,CACZd,EAAW,CAAC,EACZN,EAAQ,UAAUoB,CAAG,CACvB,CACF,CACAV,EAAO,CACT,CAEA,OAAKW,EAAQ,EAEN,CACL,UAAUC,EAAc,CACtB1B,EAAS0B,EACTZ,EAAO,CACT,EACA,QAAAW,EACA,SAAU,CACRpB,EAAW,UAAY,EACzB,CACF,CACF,CFtMO,IAAMsB,EAAc,CACzB,KAAKC,EAQuB,CAC1B,GAAM,CAAE,GAAAC,EAAI,GAAGC,CAAK,EAAIF,EACxB,OAAOG,EAAmBF,EAAIC,CAAI,CACpC,CACF","names":["src_exports","__export","DEFAULT_API_BASE","DPDPConsent","DPDPError","DPDPStack","mountConsentWidget","DEFAULT_API_BASE","DPDPError","status","detail","body","buildQuery","query","parts","v","k","DPDPStack","options","input","certificateJwt","fingerprint","id","f","method","path","opts","url","headers","hasBody","res","text","data","principalRef","token","DEFAULT_TEXTS","el","tag","attrs","children","node","k","v","c","noticeFor","purpose","locale","CARD","mountConsentWidget","target","options","container","client","DPDPStack","texts","defaultChecked","purposes","message","text","color","render","card","checks","p","n","box","status","saveBtn","selected","receipts","err","refresh","next","DPDPConsent","config","el","rest","mountConsentWidget"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/widget.ts"],"sourcesContent":["export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n","import type {\n ActivityInput,\n ActivityResult,\n AuditCheckpoint,\n AuditCheckpointInput,\n AuditLog,\n AuditVerifyResult,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n Readiness,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Stats,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n /** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint\n * it anchored to for a pruned/retained chain. Requires a secret key. */\n verifyAuditChain(): Promise<AuditVerifyResult> {\n return this.request(\"GET\", \"/audit/verify\");\n }\n\n /** Snapshot the chain into an immutable checkpoint so it can be pruned under\n * retention and still verify. Requires a secret key. */\n createAuditCheckpoint(input: AuditCheckpointInput = {}): Promise<AuditCheckpoint> {\n return this.request(\"POST\", \"/audit/checkpoint\", { body: input });\n }\n\n // --- Readiness & stats --------------------------------------------------\n\n /** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */\n readiness(): Promise<Readiness> {\n return this.request(\"GET\", \"/readiness\");\n }\n\n /** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */\n stats(): Promise<Stats> {\n return this.request(\"GET\", \"/stats\");\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Issue a counter-signed Certificate of Consent (what was consented to + the\n * notice fingerprint) for a principal. Requires a secret key. */\n issueConsent: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/consent/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n"],"mappings":"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","names":["src_exports","__export","DEFAULT_API_BASE","DPDPConsent","DPDPError","DPDPStack","mountConsentWidget","DEFAULT_API_BASE","DPDPError","status","detail","body","buildQuery","query","parts","v","k","DPDPStack","options","input","certificateJwt","fingerprint","id","f","method","path","opts","url","headers","hasBody","res","text","data","principalRef","token","DEFAULT_TEXTS","el","tag","attrs","children","node","k","v","c","noticeFor","purpose","locale","CARD","mountConsentWidget","target","options","container","client","DPDPStack","texts","defaultChecked","purposes","message","text","color","render","card","checks","p","n","box","status","saveBtn","selected","receipts","err","refresh","next","DPDPConsent","config","el","rest","mountConsentWidget"]}
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,9 @@ var DPDPStack = class {
|
|
|
31
31
|
this.certificates = {
|
|
32
32
|
/** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */
|
|
33
33
|
issue: (input) => this.request("POST", "/certificate", { body: input }),
|
|
34
|
+
/** Issue a counter-signed Certificate of Consent (what was consented to + the
|
|
35
|
+
* notice fingerprint) for a principal. Requires a secret key. */
|
|
36
|
+
issueConsent: (input) => this.request("POST", "/consent/certificate", { body: input }),
|
|
34
37
|
/** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */
|
|
35
38
|
verify: (certificateJwt) => this.request("POST", "/certificate/verify", { body: { certificate_jwt: certificateJwt } }),
|
|
36
39
|
/** Fetch the issuer public key. Public — no key needed. */
|
|
@@ -173,6 +176,25 @@ var DPDPStack = class {
|
|
|
173
176
|
getAuditLog(query = {}) {
|
|
174
177
|
return this.request("GET", "/audit", { query });
|
|
175
178
|
}
|
|
179
|
+
/** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint
|
|
180
|
+
* it anchored to for a pruned/retained chain. Requires a secret key. */
|
|
181
|
+
verifyAuditChain() {
|
|
182
|
+
return this.request("GET", "/audit/verify");
|
|
183
|
+
}
|
|
184
|
+
/** Snapshot the chain into an immutable checkpoint so it can be pruned under
|
|
185
|
+
* retention and still verify. Requires a secret key. */
|
|
186
|
+
createAuditCheckpoint(input = {}) {
|
|
187
|
+
return this.request("POST", "/audit/checkpoint", { body: input });
|
|
188
|
+
}
|
|
189
|
+
// --- Readiness & stats --------------------------------------------------
|
|
190
|
+
/** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */
|
|
191
|
+
readiness() {
|
|
192
|
+
return this.request("GET", "/readiness");
|
|
193
|
+
}
|
|
194
|
+
/** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */
|
|
195
|
+
stats() {
|
|
196
|
+
return this.request("GET", "/stats");
|
|
197
|
+
}
|
|
176
198
|
};
|
|
177
199
|
|
|
178
200
|
// src/widget.ts
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/widget.ts","../src/index.ts"],"names":["el"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ActivityInput,\n ActivityResult,\n AuditLog,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n","export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/widget.ts","../src/index.ts"],"names":["el"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ActivityInput,\n ActivityResult,\n AuditCheckpoint,\n AuditCheckpointInput,\n AuditLog,\n AuditVerifyResult,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n Readiness,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Stats,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n /** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint\n * it anchored to for a pruned/retained chain. Requires a secret key. */\n verifyAuditChain(): Promise<AuditVerifyResult> {\n return this.request(\"GET\", \"/audit/verify\");\n }\n\n /** Snapshot the chain into an immutable checkpoint so it can be pruned under\n * retention and still verify. Requires a secret key. */\n createAuditCheckpoint(input: AuditCheckpointInput = {}): Promise<AuditCheckpoint> {\n return this.request(\"POST\", \"/audit/checkpoint\", { body: input });\n }\n\n // --- Readiness & stats --------------------------------------------------\n\n /** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */\n readiness(): Promise<Readiness> {\n return this.request(\"GET\", \"/readiness\");\n }\n\n /** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */\n stats(): Promise<Stats> {\n return this.request(\"GET\", \"/stats\");\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Issue a counter-signed Certificate of Consent (what was consented to + the\n * notice fingerprint) for a principal. Requires a secret key. */\n issueConsent: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/consent/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n","export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -112,6 +112,32 @@ interface AuditLog {
|
|
|
112
112
|
count: number;
|
|
113
113
|
entries: AuditEntry[];
|
|
114
114
|
}
|
|
115
|
+
/** Richer verification: whether the chain is intact, where it breaks, and which
|
|
116
|
+
* checkpoint it anchored to (for a pruned/retained chain). */
|
|
117
|
+
interface AuditVerifyResult {
|
|
118
|
+
ok: boolean;
|
|
119
|
+
checked: number;
|
|
120
|
+
count: number;
|
|
121
|
+
first_error_sequence: Nullable<number>;
|
|
122
|
+
anchored_at: Nullable<number>;
|
|
123
|
+
message?: string;
|
|
124
|
+
}
|
|
125
|
+
interface AuditCheckpointInput {
|
|
126
|
+
/** Snapshot up to this sequence (default: the whole current chain). */
|
|
127
|
+
through_sequence?: number;
|
|
128
|
+
}
|
|
129
|
+
/** An immutable checkpoint so the chain can be pruned under retention and still verify. */
|
|
130
|
+
interface AuditCheckpoint {
|
|
131
|
+
from_sequence: number;
|
|
132
|
+
to_sequence: number;
|
|
133
|
+
anchor_prev_hash: string;
|
|
134
|
+
to_hash: string;
|
|
135
|
+
count: number;
|
|
136
|
+
from_time: string;
|
|
137
|
+
to_time: string;
|
|
138
|
+
checkpoint_hash: string;
|
|
139
|
+
created_at: Nullable<Timestamp>;
|
|
140
|
+
}
|
|
115
141
|
type RetentionTrigger = "consent_withdrawn" | "inactivity" | "fixed_period" | string;
|
|
116
142
|
type ErasureAction = "delete" | "anonymize";
|
|
117
143
|
interface RetentionPolicy {
|
|
@@ -146,6 +172,42 @@ interface ActivityResult {
|
|
|
146
172
|
updated: number;
|
|
147
173
|
last_activity_at: Timestamp;
|
|
148
174
|
}
|
|
175
|
+
type ReadinessTier = "exemplary" | "strong" | "moderate" | "at_risk" | "critical";
|
|
176
|
+
/** A graded DPDP retention-readiness score over the org's configured policies. */
|
|
177
|
+
interface Readiness {
|
|
178
|
+
score: number;
|
|
179
|
+
grade: string;
|
|
180
|
+
tier: ReadinessTier;
|
|
181
|
+
policies_scored: number;
|
|
182
|
+
findings: {
|
|
183
|
+
error: number;
|
|
184
|
+
warning: number;
|
|
185
|
+
info: number;
|
|
186
|
+
};
|
|
187
|
+
by_policy: Array<{
|
|
188
|
+
purpose: string;
|
|
189
|
+
score: number;
|
|
190
|
+
findings: string[];
|
|
191
|
+
}>;
|
|
192
|
+
summary: string;
|
|
193
|
+
}
|
|
194
|
+
/** Aggregate dashboard counts for the organization. */
|
|
195
|
+
interface Stats {
|
|
196
|
+
chain_verified: boolean;
|
|
197
|
+
audit_entries: number;
|
|
198
|
+
records: {
|
|
199
|
+
total: number;
|
|
200
|
+
granted: number;
|
|
201
|
+
withdrawn: number;
|
|
202
|
+
expired: number;
|
|
203
|
+
};
|
|
204
|
+
dsr_open: number;
|
|
205
|
+
breaches_open: number;
|
|
206
|
+
certificates: {
|
|
207
|
+
total: number;
|
|
208
|
+
active: number;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
149
211
|
/** The certificate payload (subject, status, action, legal_basis, chain_verified, …). */
|
|
150
212
|
type CertificatePayload = Record<string, unknown>;
|
|
151
213
|
interface IssueCertificateInput {
|
|
@@ -397,6 +459,16 @@ declare class DPDPStack {
|
|
|
397
459
|
getAuditLog(query?: {
|
|
398
460
|
principal_ref?: string;
|
|
399
461
|
}): Promise<AuditLog>;
|
|
462
|
+
/** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint
|
|
463
|
+
* it anchored to for a pruned/retained chain. Requires a secret key. */
|
|
464
|
+
verifyAuditChain(): Promise<AuditVerifyResult>;
|
|
465
|
+
/** Snapshot the chain into an immutable checkpoint so it can be pruned under
|
|
466
|
+
* retention and still verify. Requires a secret key. */
|
|
467
|
+
createAuditCheckpoint(input?: AuditCheckpointInput): Promise<AuditCheckpoint>;
|
|
468
|
+
/** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */
|
|
469
|
+
readiness(): Promise<Readiness>;
|
|
470
|
+
/** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */
|
|
471
|
+
stats(): Promise<Stats>;
|
|
400
472
|
readonly retention: {
|
|
401
473
|
/** List retention policies. Requires a secret key. */
|
|
402
474
|
list: () => Promise<RetentionPolicy[]>;
|
|
@@ -410,6 +482,9 @@ declare class DPDPStack {
|
|
|
410
482
|
readonly certificates: {
|
|
411
483
|
/** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */
|
|
412
484
|
issue: (input: IssueCertificateInput) => Promise<IssuedCertificate>;
|
|
485
|
+
/** Issue a counter-signed Certificate of Consent (what was consented to + the
|
|
486
|
+
* notice fingerprint) for a principal. Requires a secret key. */
|
|
487
|
+
issueConsent: (input: IssueCertificateInput) => Promise<IssuedCertificate>;
|
|
413
488
|
/** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */
|
|
414
489
|
verify: (certificateJwt: string) => Promise<CertificateVerifyResult>;
|
|
415
490
|
/** Fetch the issuer public key. Public — no key needed. */
|
|
@@ -536,4 +611,4 @@ declare const DPDPConsent: {
|
|
|
536
611
|
}): ConsentWidgetController;
|
|
537
612
|
};
|
|
538
613
|
|
|
539
|
-
export { type ActivityInput, type ActivityResult, type AuditEntry, type AuditLog, type Breach, type BreachAction, type BreachActionInput, type BreachListQuery, type BreachNotifications, type BreachReportInput, type BreachSeverity, type BreachStatus, type CertificatePayload, type CertificatePublicKey, type CertificateRegistryResult, type CertificateVerifyResult, type ConsentGrantInput, type ConsentReceipt, type ConsentRecordSummary, type ConsentStatus, type ConsentStatusEntry, type ConsentWidgetController, type ConsentWidgetOptions, type ConsentWidgetTexts, type ConsentWithdrawInput, type ConsentWithdrawResult, DEFAULT_API_BASE, DPDPConsent, DPDPError, DPDPStack, type DPDPStackOptions, type DSR, type DSRAction, type DSRActionInput, type DSRCreateInput, type DSRListQuery, type DSRRequestType, type DSRStatus, type ErasureAction, type ErasureConfirmResult, type ErasureInput, type ErasureOutcome, type ErasureResult, type ErasureTask, type ErasureTaskListQuery, type EvidenceEntry, type EvidenceIngestInput, type EvidenceIngestResult, type EvidenceListQuery, type EvidenceListResult, type IssueCertificateInput, type IssueEvidenceCertificateInput, type IssuedCertificate, type LocalizedNotice, type Nullable, type Purpose, type PurposeInput, type RetentionPolicy, type RetentionPolicyInput, type RetentionRunResult, type RetentionTrigger, type Target, type TargetCreateInput, type TargetUpdateInput, type TargetWithSecret, type Timestamp, mountConsentWidget };
|
|
614
|
+
export { type ActivityInput, type ActivityResult, type AuditCheckpoint, type AuditCheckpointInput, type AuditEntry, type AuditLog, type AuditVerifyResult, type Breach, type BreachAction, type BreachActionInput, type BreachListQuery, type BreachNotifications, type BreachReportInput, type BreachSeverity, type BreachStatus, type CertificatePayload, type CertificatePublicKey, type CertificateRegistryResult, type CertificateVerifyResult, type ConsentGrantInput, type ConsentReceipt, type ConsentRecordSummary, type ConsentStatus, type ConsentStatusEntry, type ConsentWidgetController, type ConsentWidgetOptions, type ConsentWidgetTexts, type ConsentWithdrawInput, type ConsentWithdrawResult, DEFAULT_API_BASE, DPDPConsent, DPDPError, DPDPStack, type DPDPStackOptions, type DSR, type DSRAction, type DSRActionInput, type DSRCreateInput, type DSRListQuery, type DSRRequestType, type DSRStatus, type ErasureAction, type ErasureConfirmResult, type ErasureInput, type ErasureOutcome, type ErasureResult, type ErasureTask, type ErasureTaskListQuery, type EvidenceEntry, type EvidenceIngestInput, type EvidenceIngestResult, type EvidenceListQuery, type EvidenceListResult, type IssueCertificateInput, type IssueEvidenceCertificateInput, type IssuedCertificate, type LocalizedNotice, type Nullable, type Purpose, type PurposeInput, type Readiness, type ReadinessTier, type RetentionPolicy, type RetentionPolicyInput, type RetentionRunResult, type RetentionTrigger, type Stats, type Target, type TargetCreateInput, type TargetUpdateInput, type TargetWithSecret, type Timestamp, mountConsentWidget };
|
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,32 @@ interface AuditLog {
|
|
|
112
112
|
count: number;
|
|
113
113
|
entries: AuditEntry[];
|
|
114
114
|
}
|
|
115
|
+
/** Richer verification: whether the chain is intact, where it breaks, and which
|
|
116
|
+
* checkpoint it anchored to (for a pruned/retained chain). */
|
|
117
|
+
interface AuditVerifyResult {
|
|
118
|
+
ok: boolean;
|
|
119
|
+
checked: number;
|
|
120
|
+
count: number;
|
|
121
|
+
first_error_sequence: Nullable<number>;
|
|
122
|
+
anchored_at: Nullable<number>;
|
|
123
|
+
message?: string;
|
|
124
|
+
}
|
|
125
|
+
interface AuditCheckpointInput {
|
|
126
|
+
/** Snapshot up to this sequence (default: the whole current chain). */
|
|
127
|
+
through_sequence?: number;
|
|
128
|
+
}
|
|
129
|
+
/** An immutable checkpoint so the chain can be pruned under retention and still verify. */
|
|
130
|
+
interface AuditCheckpoint {
|
|
131
|
+
from_sequence: number;
|
|
132
|
+
to_sequence: number;
|
|
133
|
+
anchor_prev_hash: string;
|
|
134
|
+
to_hash: string;
|
|
135
|
+
count: number;
|
|
136
|
+
from_time: string;
|
|
137
|
+
to_time: string;
|
|
138
|
+
checkpoint_hash: string;
|
|
139
|
+
created_at: Nullable<Timestamp>;
|
|
140
|
+
}
|
|
115
141
|
type RetentionTrigger = "consent_withdrawn" | "inactivity" | "fixed_period" | string;
|
|
116
142
|
type ErasureAction = "delete" | "anonymize";
|
|
117
143
|
interface RetentionPolicy {
|
|
@@ -146,6 +172,42 @@ interface ActivityResult {
|
|
|
146
172
|
updated: number;
|
|
147
173
|
last_activity_at: Timestamp;
|
|
148
174
|
}
|
|
175
|
+
type ReadinessTier = "exemplary" | "strong" | "moderate" | "at_risk" | "critical";
|
|
176
|
+
/** A graded DPDP retention-readiness score over the org's configured policies. */
|
|
177
|
+
interface Readiness {
|
|
178
|
+
score: number;
|
|
179
|
+
grade: string;
|
|
180
|
+
tier: ReadinessTier;
|
|
181
|
+
policies_scored: number;
|
|
182
|
+
findings: {
|
|
183
|
+
error: number;
|
|
184
|
+
warning: number;
|
|
185
|
+
info: number;
|
|
186
|
+
};
|
|
187
|
+
by_policy: Array<{
|
|
188
|
+
purpose: string;
|
|
189
|
+
score: number;
|
|
190
|
+
findings: string[];
|
|
191
|
+
}>;
|
|
192
|
+
summary: string;
|
|
193
|
+
}
|
|
194
|
+
/** Aggregate dashboard counts for the organization. */
|
|
195
|
+
interface Stats {
|
|
196
|
+
chain_verified: boolean;
|
|
197
|
+
audit_entries: number;
|
|
198
|
+
records: {
|
|
199
|
+
total: number;
|
|
200
|
+
granted: number;
|
|
201
|
+
withdrawn: number;
|
|
202
|
+
expired: number;
|
|
203
|
+
};
|
|
204
|
+
dsr_open: number;
|
|
205
|
+
breaches_open: number;
|
|
206
|
+
certificates: {
|
|
207
|
+
total: number;
|
|
208
|
+
active: number;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
149
211
|
/** The certificate payload (subject, status, action, legal_basis, chain_verified, …). */
|
|
150
212
|
type CertificatePayload = Record<string, unknown>;
|
|
151
213
|
interface IssueCertificateInput {
|
|
@@ -397,6 +459,16 @@ declare class DPDPStack {
|
|
|
397
459
|
getAuditLog(query?: {
|
|
398
460
|
principal_ref?: string;
|
|
399
461
|
}): Promise<AuditLog>;
|
|
462
|
+
/** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint
|
|
463
|
+
* it anchored to for a pruned/retained chain. Requires a secret key. */
|
|
464
|
+
verifyAuditChain(): Promise<AuditVerifyResult>;
|
|
465
|
+
/** Snapshot the chain into an immutable checkpoint so it can be pruned under
|
|
466
|
+
* retention and still verify. Requires a secret key. */
|
|
467
|
+
createAuditCheckpoint(input?: AuditCheckpointInput): Promise<AuditCheckpoint>;
|
|
468
|
+
/** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */
|
|
469
|
+
readiness(): Promise<Readiness>;
|
|
470
|
+
/** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */
|
|
471
|
+
stats(): Promise<Stats>;
|
|
400
472
|
readonly retention: {
|
|
401
473
|
/** List retention policies. Requires a secret key. */
|
|
402
474
|
list: () => Promise<RetentionPolicy[]>;
|
|
@@ -410,6 +482,9 @@ declare class DPDPStack {
|
|
|
410
482
|
readonly certificates: {
|
|
411
483
|
/** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */
|
|
412
484
|
issue: (input: IssueCertificateInput) => Promise<IssuedCertificate>;
|
|
485
|
+
/** Issue a counter-signed Certificate of Consent (what was consented to + the
|
|
486
|
+
* notice fingerprint) for a principal. Requires a secret key. */
|
|
487
|
+
issueConsent: (input: IssueCertificateInput) => Promise<IssuedCertificate>;
|
|
413
488
|
/** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */
|
|
414
489
|
verify: (certificateJwt: string) => Promise<CertificateVerifyResult>;
|
|
415
490
|
/** Fetch the issuer public key. Public — no key needed. */
|
|
@@ -536,4 +611,4 @@ declare const DPDPConsent: {
|
|
|
536
611
|
}): ConsentWidgetController;
|
|
537
612
|
};
|
|
538
613
|
|
|
539
|
-
export { type ActivityInput, type ActivityResult, type AuditEntry, type AuditLog, type Breach, type BreachAction, type BreachActionInput, type BreachListQuery, type BreachNotifications, type BreachReportInput, type BreachSeverity, type BreachStatus, type CertificatePayload, type CertificatePublicKey, type CertificateRegistryResult, type CertificateVerifyResult, type ConsentGrantInput, type ConsentReceipt, type ConsentRecordSummary, type ConsentStatus, type ConsentStatusEntry, type ConsentWidgetController, type ConsentWidgetOptions, type ConsentWidgetTexts, type ConsentWithdrawInput, type ConsentWithdrawResult, DEFAULT_API_BASE, DPDPConsent, DPDPError, DPDPStack, type DPDPStackOptions, type DSR, type DSRAction, type DSRActionInput, type DSRCreateInput, type DSRListQuery, type DSRRequestType, type DSRStatus, type ErasureAction, type ErasureConfirmResult, type ErasureInput, type ErasureOutcome, type ErasureResult, type ErasureTask, type ErasureTaskListQuery, type EvidenceEntry, type EvidenceIngestInput, type EvidenceIngestResult, type EvidenceListQuery, type EvidenceListResult, type IssueCertificateInput, type IssueEvidenceCertificateInput, type IssuedCertificate, type LocalizedNotice, type Nullable, type Purpose, type PurposeInput, type RetentionPolicy, type RetentionPolicyInput, type RetentionRunResult, type RetentionTrigger, type Target, type TargetCreateInput, type TargetUpdateInput, type TargetWithSecret, type Timestamp, mountConsentWidget };
|
|
614
|
+
export { type ActivityInput, type ActivityResult, type AuditCheckpoint, type AuditCheckpointInput, type AuditEntry, type AuditLog, type AuditVerifyResult, type Breach, type BreachAction, type BreachActionInput, type BreachListQuery, type BreachNotifications, type BreachReportInput, type BreachSeverity, type BreachStatus, type CertificatePayload, type CertificatePublicKey, type CertificateRegistryResult, type CertificateVerifyResult, type ConsentGrantInput, type ConsentReceipt, type ConsentRecordSummary, type ConsentStatus, type ConsentStatusEntry, type ConsentWidgetController, type ConsentWidgetOptions, type ConsentWidgetTexts, type ConsentWithdrawInput, type ConsentWithdrawResult, DEFAULT_API_BASE, DPDPConsent, DPDPError, DPDPStack, type DPDPStackOptions, type DSR, type DSRAction, type DSRActionInput, type DSRCreateInput, type DSRListQuery, type DSRRequestType, type DSRStatus, type ErasureAction, type ErasureConfirmResult, type ErasureInput, type ErasureOutcome, type ErasureResult, type ErasureTask, type ErasureTaskListQuery, type EvidenceEntry, type EvidenceIngestInput, type EvidenceIngestResult, type EvidenceListQuery, type EvidenceListResult, type IssueCertificateInput, type IssueEvidenceCertificateInput, type IssuedCertificate, type LocalizedNotice, type Nullable, type Purpose, type PurposeInput, type Readiness, type ReadinessTier, type RetentionPolicy, type RetentionPolicyInput, type RetentionRunResult, type RetentionTrigger, type Stats, type Target, type TargetCreateInput, type TargetUpdateInput, type TargetWithSecret, type Timestamp, mountConsentWidget };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,9 @@ var DPDPStack = class {
|
|
|
29
29
|
this.certificates = {
|
|
30
30
|
/** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */
|
|
31
31
|
issue: (input) => this.request("POST", "/certificate", { body: input }),
|
|
32
|
+
/** Issue a counter-signed Certificate of Consent (what was consented to + the
|
|
33
|
+
* notice fingerprint) for a principal. Requires a secret key. */
|
|
34
|
+
issueConsent: (input) => this.request("POST", "/consent/certificate", { body: input }),
|
|
32
35
|
/** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */
|
|
33
36
|
verify: (certificateJwt) => this.request("POST", "/certificate/verify", { body: { certificate_jwt: certificateJwt } }),
|
|
34
37
|
/** Fetch the issuer public key. Public — no key needed. */
|
|
@@ -171,6 +174,25 @@ var DPDPStack = class {
|
|
|
171
174
|
getAuditLog(query = {}) {
|
|
172
175
|
return this.request("GET", "/audit", { query });
|
|
173
176
|
}
|
|
177
|
+
/** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint
|
|
178
|
+
* it anchored to for a pruned/retained chain. Requires a secret key. */
|
|
179
|
+
verifyAuditChain() {
|
|
180
|
+
return this.request("GET", "/audit/verify");
|
|
181
|
+
}
|
|
182
|
+
/** Snapshot the chain into an immutable checkpoint so it can be pruned under
|
|
183
|
+
* retention and still verify. Requires a secret key. */
|
|
184
|
+
createAuditCheckpoint(input = {}) {
|
|
185
|
+
return this.request("POST", "/audit/checkpoint", { body: input });
|
|
186
|
+
}
|
|
187
|
+
// --- Readiness & stats --------------------------------------------------
|
|
188
|
+
/** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */
|
|
189
|
+
readiness() {
|
|
190
|
+
return this.request("GET", "/readiness");
|
|
191
|
+
}
|
|
192
|
+
/** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */
|
|
193
|
+
stats() {
|
|
194
|
+
return this.request("GET", "/stats");
|
|
195
|
+
}
|
|
174
196
|
};
|
|
175
197
|
|
|
176
198
|
// src/widget.ts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/widget.ts","../src/index.ts"],"names":["el"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ActivityInput,\n ActivityResult,\n AuditLog,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n","export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/widget.ts","../src/index.ts"],"names":["el"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ActivityInput,\n ActivityResult,\n AuditCheckpoint,\n AuditCheckpointInput,\n AuditLog,\n AuditVerifyResult,\n Breach,\n BreachActionInput,\n BreachListQuery,\n BreachNotifications,\n BreachReportInput,\n CertificatePublicKey,\n CertificateRegistryResult,\n CertificateVerifyResult,\n ConsentGrantInput,\n ConsentReceipt,\n ConsentRecordSummary,\n ConsentStatus,\n ConsentWithdrawInput,\n ConsentWithdrawResult,\n DSR,\n DSRActionInput,\n DSRCreateInput,\n DSRListQuery,\n ErasureConfirmResult,\n ErasureInput,\n ErasureResult,\n ErasureTask,\n ErasureTaskListQuery,\n EvidenceIngestInput,\n EvidenceIngestResult,\n EvidenceListQuery,\n EvidenceListResult,\n IssueCertificateInput,\n IssueEvidenceCertificateInput,\n IssuedCertificate,\n Purpose,\n PurposeInput,\n Readiness,\n RetentionPolicy,\n RetentionPolicyInput,\n RetentionRunResult,\n Stats,\n Target,\n TargetCreateInput,\n TargetUpdateInput,\n TargetWithSecret,\n} from \"./types.js\";\n\nexport const DEFAULT_API_BASE = \"https://getdpdp.net/api/v1\";\n\nexport interface DPDPStackOptions {\n /**\n * API key. A **secret** key (`dpdp_sk_…`) for server-side use, or a\n * **publishable** key (`dpdp_pk_…`) — the only kind safe to ship to a browser,\n * limited to reading purposes and recording consent. Omit for public-only\n * calls (certificate verify/registry/public-key).\n */\n apiKey?: string;\n /** API base URL. Default `https://getdpdp.net/api/v1`. Use a relative path (e.g. `/api/v1`) to call a same-origin proxy. */\n apiBase?: string;\n /** Custom fetch implementation (for Node < 18, testing, or proxies). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Extra headers sent with every request. */\n headers?: Record<string, string>;\n /** `fetch` credentials mode (e.g. `\"include\"` to send cookies). Default: unset. */\n credentials?: RequestCredentials;\n}\n\n/** Thrown for any non-2xx API response. */\nexport class DPDPError extends Error {\n readonly status: number;\n readonly detail: string;\n readonly body: unknown;\n\n constructor(status: number, detail: string, body: unknown) {\n super(`DPDP API error ${status}: ${detail}`);\n this.name = \"DPDPError\";\n this.status = status;\n this.detail = detail;\n this.body = body;\n }\n}\n\nfunction buildQuery(query?: object): string {\n if (!query) return \"\";\n const parts = Object.entries(query as Record<string, unknown>)\n .filter(([, v]) => v !== undefined && v !== null && v !== \"\")\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return parts.length ? `?${parts.join(\"&\")}` : \"\";\n}\n\n/**\n * Thin, typed client for the DPDPStack API.\n *\n * ```ts\n * const dpdp = new DPDPStack({ apiKey: \"dpdp_sk_…\" });\n * await dpdp.grantConsent({ principal_ref: \"user_42\", purpose: \"marketing\" });\n * ```\n */\nexport class DPDPStack {\n private readonly apiBase: string;\n private readonly apiKey?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly credentials?: RequestCredentials;\n\n constructor(options: DPDPStackOptions = {}) {\n this.apiBase = (options.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.defaultHeaders = options.headers ?? {};\n this.credentials = options.credentials;\n\n const f = options.fetch ?? globalThis.fetch;\n if (typeof f !== \"function\") {\n throw new Error(\n \"No fetch implementation found. Use Node 18+, a browser, or pass `fetch` in options.\",\n );\n }\n this.fetchImpl = f.bind(globalThis);\n }\n\n /** Low-level request. Most callers use the typed methods below. */\n async request<T>(\n method: string,\n path: string,\n opts: { query?: object; body?: unknown } = {},\n ): Promise<T> {\n const url = `${this.apiBase}${path}${buildQuery(opts.query)}`;\n const headers: Record<string, string> = { ...this.defaultHeaders };\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const hasBody = opts.body !== undefined;\n if (hasBody) headers[\"Content-Type\"] = \"application/json\";\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: hasBody ? JSON.stringify(opts.body) : undefined,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n\n const text = await res.text();\n let data: unknown = undefined;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n (data && typeof data === \"object\" && \"detail\" in data\n ? String((data as { detail: unknown }).detail)\n : undefined) ?? res.statusText ?? \"Request failed\";\n throw new DPDPError(res.status, detail, data);\n }\n\n return data as T;\n }\n\n // --- Purposes & consent -------------------------------------------------\n\n /** List consent purposes (with multilingual notices). Publishable-key safe. */\n listPurposes(): Promise<Purpose[]> {\n return this.request(\"GET\", \"/purposes\");\n }\n\n /** Create a consent purpose. Requires a secret key. */\n createPurpose(input: PurposeInput): Promise<Purpose> {\n return this.request(\"POST\", \"/purposes\", { body: input });\n }\n\n /** Record purpose-level consent and get an immutable receipt. Publishable-key safe. */\n grantConsent(input: ConsentGrantInput): Promise<ConsentReceipt> {\n return this.request(\"POST\", \"/consent\", { body: input });\n }\n\n /** Withdraw consent for a purpose (triggers erasure/deferral). Requires a secret key. */\n withdrawConsent(input: ConsentWithdrawInput): Promise<ConsentWithdrawResult> {\n return this.request(\"POST\", \"/consent/withdraw\", { body: input });\n }\n\n /** Current consent state for a principal. Requires a secret key. */\n consentStatus(principalRef: string): Promise<ConsentStatus> {\n return this.request(\"GET\", \"/consent/status\", { query: { principal_ref: principalRef } });\n }\n\n /** List the organization's consent records (latest first). Requires a secret key. */\n listConsentRecords(): Promise<ConsentRecordSummary[]> {\n return this.request(\"GET\", \"/consent/records\");\n }\n\n /** Record principal activity, resetting inactivity-based retention. Requires a secret key. */\n recordActivity(input: ActivityInput): Promise<ActivityResult> {\n return this.request(\"POST\", \"/activity\", { body: input });\n }\n\n // --- Erasure ------------------------------------------------------------\n\n /** Right to erasure: resolve erasure across the principal's purposes. Requires a secret key. */\n requestErasure(input: ErasureInput): Promise<ErasureResult> {\n return this.request(\"POST\", \"/erasure\", { body: input });\n }\n\n /** Confirm a downstream erasure with the token delivered to that system. No API key needed. */\n confirmErasure(token: string): Promise<ErasureConfirmResult> {\n return this.request(\"POST\", \"/erasure/confirm\", { body: { token } });\n }\n\n // --- Audit --------------------------------------------------------------\n\n /** Hash-chained audit trail (optionally filtered by principal), plus chain status. Requires a secret key. */\n getAuditLog(query: { principal_ref?: string } = {}): Promise<AuditLog> {\n return this.request(\"GET\", \"/audit\", { query });\n }\n\n /** Verify the chain and report where (if anywhere) it breaks, plus the checkpoint\n * it anchored to for a pruned/retained chain. Requires a secret key. */\n verifyAuditChain(): Promise<AuditVerifyResult> {\n return this.request(\"GET\", \"/audit/verify\");\n }\n\n /** Snapshot the chain into an immutable checkpoint so it can be pruned under\n * retention and still verify. Requires a secret key. */\n createAuditCheckpoint(input: AuditCheckpointInput = {}): Promise<AuditCheckpoint> {\n return this.request(\"POST\", \"/audit/checkpoint\", { body: input });\n }\n\n // --- Readiness & stats --------------------------------------------------\n\n /** A graded DPDP retention-readiness score over your configured policies. Requires a secret key. */\n readiness(): Promise<Readiness> {\n return this.request(\"GET\", \"/readiness\");\n }\n\n /** Aggregate dashboard counts (records, audit entries, open DSRs/breaches, certificates). Requires a secret key. */\n stats(): Promise<Stats> {\n return this.request(\"GET\", \"/stats\");\n }\n\n // --- Retention ----------------------------------------------------------\n\n readonly retention = {\n /** List retention policies. Requires a secret key. */\n list: (): Promise<RetentionPolicy[]> => this.request(\"GET\", \"/retention/policies\"),\n /** Create or update a retention policy. Requires a secret key. */\n upsert: (input: RetentionPolicyInput): Promise<RetentionPolicy> =>\n this.request(\"POST\", \"/retention/policies\", { body: input }),\n /** Run the retention sweep now (`{ dry_run: true }` to preview). Requires a secret key. */\n run: (input: { dry_run?: boolean } = {}): Promise<RetentionRunResult> =>\n this.request(\"POST\", \"/retention/run\", { body: input }),\n };\n\n // --- Certificates -------------------------------------------------------\n\n readonly certificates = {\n /** Issue a counter-signed Certificate of Erasure for a principal. Requires a secret key. */\n issue: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/certificate\", { body: input }),\n /** Issue a counter-signed Certificate of Consent (what was consented to + the\n * notice fingerprint) for a principal. Requires a secret key. */\n issueConsent: (input: IssueCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/consent/certificate\", { body: input }),\n /** Verify a Certificate of Erasure (JWT) against the public key. Public — no key needed. */\n verify: (certificateJwt: string): Promise<CertificateVerifyResult> =>\n this.request(\"POST\", \"/certificate/verify\", { body: { certificate_jwt: certificateJwt } }),\n /** Fetch the issuer public key. Public — no key needed. */\n publicKey: (): Promise<CertificatePublicKey> =>\n this.request(\"GET\", \"/certificate/public-key\"),\n /** Look up a certificate in the public registry by fingerprint. Public — no key needed. */\n registry: (fingerprint: string): Promise<CertificateRegistryResult> =>\n this.request(\"GET\", `/certificate/registry/${encodeURIComponent(fingerprint)}`),\n /** Issue a certificate from SDK-pushed evidence. Requires a secret key. */\n issueFromEvidence: (input: IssueEvidenceCertificateInput): Promise<IssuedCertificate> =>\n this.request(\"POST\", \"/evidence/certificate\", { body: input }),\n };\n\n // --- Evidence -----------------------------------------------------------\n\n readonly evidence = {\n /** Push tamper-evident audit evidence (hash chain) for server-timestamping. Requires a secret key. */\n ingest: (input: EvidenceIngestInput): Promise<EvidenceIngestResult> =>\n this.request(\"POST\", \"/evidence\", { body: input }),\n /** List stored evidence for a source/subject, with chain status. Requires a secret key. */\n list: (query: EvidenceListQuery = {}): Promise<EvidenceListResult> =>\n this.request(\"GET\", \"/evidence\", { query }),\n };\n\n // --- Data-subject requests (DSR) ----------------------------------------\n\n readonly dsr = {\n /** List rights requests (filter by status/type/principal/overdue). Requires a secret key. */\n list: (query: DSRListQuery = {}): Promise<DSR[]> => this.request(\"GET\", \"/dsr\", { query }),\n /** Create a rights request. Requires a secret key. */\n create: (input: DSRCreateInput): Promise<DSR> => this.request(\"POST\", \"/dsr\", { body: input }),\n /** Get a single rights request. Requires a secret key. */\n get: (id: number): Promise<DSR> => this.request(\"GET\", `/dsr/${id}`),\n /** Advance a rights request (acknowledge/start/complete/reject/extend). Requires a secret key. */\n act: (id: number, input: DSRActionInput): Promise<DSR> =>\n this.request(\"POST\", `/dsr/${id}`, { body: input }),\n };\n\n // --- Breaches -----------------------------------------------------------\n\n readonly breaches = {\n /** List breach incidents. Requires a secret key. */\n list: (query: BreachListQuery = {}): Promise<Breach[]> =>\n this.request(\"GET\", \"/breaches\", { query }),\n /** Report a breach incident (metadata only — never PII). Requires a secret key. */\n report: (input: BreachReportInput): Promise<Breach> =>\n this.request(\"POST\", \"/breaches\", { body: input }),\n /** Get a single breach. Requires a secret key. */\n get: (id: number): Promise<Breach> => this.request(\"GET\", `/breaches/${id}`),\n /** Advance a breach (investigate/contain/notify_board/notify_principals/close). Requires a secret key. */\n act: (id: number, input: BreachActionInput): Promise<Breach> =>\n this.request(\"POST\", `/breaches/${id}`, { body: input }),\n /** Generate draft Board + principal breach notices. Requires a secret key. */\n notifications: (id: number): Promise<BreachNotifications> =>\n this.request(\"GET\", `/breaches/${id}/notification`),\n };\n\n // --- Targets & fan-out tasks --------------------------------------------\n\n readonly targets = {\n /** List downstream erasure targets. Requires a secret key. */\n list: (): Promise<Target[]> => this.request(\"GET\", \"/targets\"),\n /** Register a target. The signing `secret` is returned only once. Requires a secret key. */\n create: (input: TargetCreateInput): Promise<TargetWithSecret> =>\n this.request(\"POST\", \"/targets\", { body: input }),\n /** Get a single target. Requires a secret key. */\n get: (id: number): Promise<Target> => this.request(\"GET\", `/targets/${id}`),\n /** Update a target. Requires a secret key. */\n update: (id: number, input: TargetUpdateInput): Promise<Target> =>\n this.request(\"POST\", `/targets/${id}`, { body: input }),\n /** Delete a target. Requires a secret key. */\n remove: (id: number): Promise<void> => this.request(\"DELETE\", `/targets/${id}`),\n };\n\n readonly erasureTasks = {\n /** List per-system erasure fan-out tasks (the propagation evidence). Requires a secret key. */\n list: (query: ErasureTaskListQuery = {}): Promise<ErasureTask[]> =>\n this.request(\"GET\", \"/erasure/tasks\", { query }),\n /** Re-deliver an erasure instruction to a target. Requires a secret key. */\n retry: (id: number): Promise<ErasureTask> =>\n this.request(\"POST\", `/erasure/tasks/${id}/retry`),\n };\n}\n","import { DPDPStack } from \"./client.js\";\nimport type { ConsentReceipt, LocalizedNotice, Purpose } from \"./types.js\";\n\nexport interface ConsentWidgetTexts {\n heading: string;\n subheading: string;\n save: string;\n saving: string;\n saved: string;\n loading: string;\n error: string;\n}\n\nconst DEFAULT_TEXTS: ConsentWidgetTexts = {\n heading: \"We value your privacy\",\n subheading: \"Choose what you consent to. You can withdraw anytime (DPDP Act).\",\n save: \"Save consent preferences\",\n saving: \"Saving…\",\n saved: \"Preferences saved.\",\n loading: \"Loading…\",\n error: \"Could not save your preferences. Please try again.\",\n};\n\nexport interface ConsentWidgetOptions {\n /** Your opaque user id (internal id or hash) — never PII. */\n principalRef: string;\n /** Pre-built client. If omitted, one is built from `apiBase`/`apiKey`. */\n client?: DPDPStack;\n /** Used to build a client when `client` is not supplied. */\n apiBase?: string;\n /** Publishable key (`dpdp_pk_…`). Used to build a client when `client` is not supplied. */\n apiKey?: string;\n /** Purposes to render. If omitted, they're fetched via `client.listPurposes()`. */\n purposes?: Purpose[];\n /** Initial locale for notice text. Default `\"en\"`. */\n locale?: string;\n /** Purpose codes checked on first render. */\n defaultChecked?: string[];\n /** Override any UI strings. */\n texts?: Partial<ConsentWidgetTexts>;\n /** Called with the receipts after a successful save. */\n onSave?: (receipts: ConsentReceipt[]) => void;\n /** Called if loading purposes or saving fails. */\n onError?: (error: unknown) => void;\n}\n\nexport interface ConsentWidgetController {\n /** Switch the notice language and re-render. */\n setLocale(locale: string): void;\n /** Re-fetch purposes (when not passed in) and re-render. */\n refresh(): Promise<void>;\n /** Remove the widget from the DOM. */\n destroy(): void;\n}\n\ntype Attrs = Record<string, string | EventListenerOrEventListenerObject>;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Attrs = {},\n children: Array<Node | string> = [],\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"style\" && typeof v === \"string\") node.style.cssText = v;\n else if (k === \"class\" && typeof v === \"string\") node.className = v;\n else if (k.startsWith(\"on\") && typeof v === \"function\") node.addEventListener(k.slice(2), v);\n else if (typeof v === \"string\") node.setAttribute(k, v);\n }\n for (const c of children) node.appendChild(typeof c === \"string\" ? document.createTextNode(c) : c);\n return node;\n}\n\nfunction noticeFor(purpose: Purpose, locale: string): Required<LocalizedNotice> {\n const t: LocalizedNotice = purpose.translations?.[locale] ?? {};\n return {\n name: t.name || purpose.name,\n description: t.description || purpose.description,\n };\n}\n\nconst CARD =\n \"border:1px solid #e3e3ef;border-radius:12px;padding:20px;background:#fff;max-width:480px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;color:#11113a;box-shadow:0 1px 3px rgba(15,23,42,0.06);\";\n\n/**\n * Mount a drop-in consent capture widget. Returns a controller for switching\n * locale, refreshing, or removing it.\n *\n * ```ts\n * mountConsentWidget(\"#consent\", {\n * apiBase: \"/api/v1\",\n * apiKey: \"dpdp_pk_…\", // publishable key\n * principalRef: \"user_123\",\n * });\n * ```\n */\nexport function mountConsentWidget(\n target: string | HTMLElement,\n options: ConsentWidgetOptions,\n): ConsentWidgetController {\n const container =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`mountConsentWidget: container not found: ${String(target)}`);\n\n const client =\n options.client ?? new DPDPStack({ apiBase: options.apiBase, apiKey: options.apiKey });\n const texts: ConsentWidgetTexts = { ...DEFAULT_TEXTS, ...options.texts };\n const defaultChecked = new Set(options.defaultChecked ?? []);\n\n let locale = options.locale ?? \"en\";\n let purposes: Purpose[] | null = options.purposes ?? null;\n\n function message(text: string, color: string): HTMLElement {\n return el(\"div\", { style: `margin-top:12px;font-size:13px;color:${color};` }, [text]);\n }\n\n function render(): void {\n container!.innerHTML = \"\";\n const card = el(\"div\", { style: CARD }, [\n el(\"div\", { style: \"font-weight:600;font-size:15px;margin-bottom:4px;\" }, [texts.heading]),\n el(\"div\", { style: \"font-size:13px;color:#666;margin-bottom:12px;\" }, [texts.subheading]),\n ]);\n\n if (!purposes) {\n card.appendChild(message(texts.loading, \"#666\"));\n container!.appendChild(card);\n return;\n }\n\n const checks: Record<string, HTMLInputElement> = {};\n for (const p of purposes) {\n const n = noticeFor(p, locale);\n const box = el(\"input\", { type: \"checkbox\", id: `dpdp_${p.code}` }) as HTMLInputElement;\n if (defaultChecked.has(p.code)) box.checked = true;\n checks[p.code] = box;\n card.appendChild(\n el(\n \"label\",\n {\n style:\n \"display:flex;align-items:flex-start;gap:8px;margin:10px 0;font-size:14px;cursor:pointer;\",\n for: `dpdp_${p.code}`,\n },\n [\n box,\n el(\"span\", {}, [\n el(\"strong\", {}, [n.name]),\n el(\"div\", { style: \"font-size:12px;color:#777;margin-top:2px;\" }, [n.description]),\n ]),\n ],\n ),\n );\n }\n\n const status = el(\"div\", {});\n const saveBtn = el(\n \"button\",\n {\n type: \"button\",\n style:\n \"margin-top:14px;background:#4f46e5;color:#fff;border:0;border-radius:8px;padding:10px 16px;font:inherit;font-weight:600;cursor:pointer;\",\n },\n [texts.save],\n ) as HTMLButtonElement;\n\n saveBtn.addEventListener(\"click\", async () => {\n const selected = purposes!.filter((p) => checks[p.code]?.checked);\n saveBtn.disabled = true;\n saveBtn.textContent = texts.saving;\n status.innerHTML = \"\";\n try {\n const receipts = await Promise.all(\n selected.map((p) =>\n client.grantConsent({ principal_ref: options.principalRef, purpose: p.code, locale }),\n ),\n );\n status.appendChild(message(texts.saved, \"#16a34a\"));\n options.onSave?.(receipts);\n } catch (err) {\n status.appendChild(message(texts.error, \"#dc2626\"));\n options.onError?.(err);\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = texts.save;\n }\n });\n\n card.appendChild(saveBtn);\n card.appendChild(status);\n container!.appendChild(card);\n }\n\n async function refresh(): Promise<void> {\n if (!options.purposes) {\n render(); // show loading\n try {\n purposes = await client.listPurposes();\n } catch (err) {\n purposes = [];\n options.onError?.(err);\n }\n }\n render();\n }\n\n void refresh();\n\n return {\n setLocale(next: string) {\n locale = next;\n render();\n },\n refresh,\n destroy() {\n container!.innerHTML = \"\";\n },\n };\n}\n","export { DPDPStack, DPDPError, DEFAULT_API_BASE } from \"./client.js\";\nexport type { DPDPStackOptions } from \"./client.js\";\n\nexport { mountConsentWidget } from \"./widget.js\";\nexport type {\n ConsentWidgetOptions,\n ConsentWidgetController,\n ConsentWidgetTexts,\n} from \"./widget.js\";\n\nexport type * from \"./types.js\";\n\nimport { mountConsentWidget, type ConsentWidgetController } from \"./widget.js\";\nimport type { ConsentReceipt, Purpose } from \"./types.js\";\n\n/**\n * Backward-compatible shim for the original `DPDPConsent.init({ el, … })`\n * script-tag widget. Prefer {@link mountConsentWidget} in new code.\n */\nexport const DPDPConsent = {\n init(config: {\n el: string | HTMLElement;\n apiBase?: string;\n apiKey?: string;\n principalRef: string;\n locale?: string;\n purposes?: Purpose[];\n onSave?: (receipts: ConsentReceipt[]) => void;\n }): ConsentWidgetController {\n const { el, ...rest } = config;\n return mountConsentWidget(el, rest);\n },\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dpdpstack-js-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Official JavaScript/TypeScript SDK for the DPDPStack API (getdpdp.net) — DPDP Act consent, erasure, audit, DSR/breach workflows, and verifiable Certificates of Erasure.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|