@splitin/verification-react 0.1.0-beta.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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +32 -0
  3. package/README.md +14 -0
  4. package/dist/appeal.cjs +63 -0
  5. package/dist/appeal.cjs.map +1 -0
  6. package/dist/appeal.d.cts +21 -0
  7. package/dist/appeal.d.ts +21 -0
  8. package/dist/appeal.d.ts.map +1 -0
  9. package/dist/appeal.js +61 -0
  10. package/dist/appeal.js.map +1 -0
  11. package/dist/index.cjs +126 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.d.cts +49 -0
  14. package/dist/index.d.ts +49 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +118 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/launcher.cjs +501 -0
  19. package/dist/launcher.cjs.map +1 -0
  20. package/dist/launcher.d.cts +39 -0
  21. package/dist/launcher.d.ts +39 -0
  22. package/dist/launcher.d.ts.map +1 -0
  23. package/dist/launcher.js +499 -0
  24. package/dist/launcher.js.map +1 -0
  25. package/dist/operations.cjs +225 -0
  26. package/dist/operations.cjs.map +1 -0
  27. package/dist/operations.d.cts +37 -0
  28. package/dist/operations.d.ts +37 -0
  29. package/dist/operations.d.ts.map +1 -0
  30. package/dist/operations.js +223 -0
  31. package/dist/operations.js.map +1 -0
  32. package/dist/retry.cjs +16 -0
  33. package/dist/retry.cjs.map +1 -0
  34. package/dist/retry.d.cts +9 -0
  35. package/dist/retry.d.ts +9 -0
  36. package/dist/retry.d.ts.map +1 -0
  37. package/dist/retry.js +14 -0
  38. package/dist/retry.js.map +1 -0
  39. package/dist/status.cjs +27 -0
  40. package/dist/status.cjs.map +1 -0
  41. package/dist/status.d.cts +8 -0
  42. package/dist/status.d.ts +8 -0
  43. package/dist/status.d.ts.map +1 -0
  44. package/dist/status.js +25 -0
  45. package/dist/status.js.map +1 -0
  46. package/dist/support.cjs +12 -0
  47. package/dist/support.cjs.map +1 -0
  48. package/dist/support.d.cts +8 -0
  49. package/dist/support.d.ts +8 -0
  50. package/dist/support.d.ts.map +1 -0
  51. package/dist/support.js +10 -0
  52. package/dist/support.js.map +1 -0
  53. package/package.json +92 -0
  54. package/src/styles.css +71 -0
@@ -0,0 +1,223 @@
1
+ import { useState, useCallback, useEffect, useMemo } from 'react';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ // src/operations/OperationsConsole.tsx
5
+ var TABS = ["health", "routes", "circuits", "attempts", "review", "reconciliation", "redaction", "audit"];
6
+ function OperationsConsole({ client }) {
7
+ const [snapshot, setSnapshot] = useState({ generatedAt: "" });
8
+ const [tab, setTab] = useState("health");
9
+ const [error, setError] = useState(null);
10
+ const [busy, setBusy] = useState(null);
11
+ const headers = useCallback((extra = {}) => {
12
+ const csrf = client.getCsrfToken?.();
13
+ return {
14
+ "Idempotency-Key": client.createIdempotencyKey?.() ?? (globalThis.crypto?.randomUUID?.() ?? `idem_${Date.now()}`),
15
+ ...csrf ? { "X-CSRF-Token": csrf } : {},
16
+ ...extra
17
+ };
18
+ }, [client]);
19
+ const refresh = useCallback(async () => {
20
+ const [health, routes, circuits, attempts, review, audit, reconciliation, redaction] = await Promise.all([
21
+ client.get("/v1/admin/health"),
22
+ client.get("/v1/admin/routes"),
23
+ client.get("/v1/admin/circuits"),
24
+ client.get("/v1/admin/attempts"),
25
+ client.get("/v1/admin/review"),
26
+ client.get("/v1/admin/audit"),
27
+ client.get("/v1/admin/reconciliation"),
28
+ client.get("/v1/admin/redaction")
29
+ ]);
30
+ setSnapshot({
31
+ generatedAt: health.generatedAt,
32
+ runtime: health.runtime,
33
+ health: health.health,
34
+ alerts: health.alerts,
35
+ routes: routes.routes,
36
+ routeChanges: routes.routeChanges,
37
+ circuits: circuits.circuits,
38
+ attempts: attempts.attempts,
39
+ appeals: review.appeals,
40
+ manualExceptions: review.manualExceptions,
41
+ policyVersions: review.policyVersions,
42
+ audit: audit.audit,
43
+ reconciliationJobs: reconciliation.jobs,
44
+ queues: reconciliation.queues,
45
+ privacyRequests: redaction.privacyRequests,
46
+ redactionJobs: redaction.jobs
47
+ });
48
+ }, [client]);
49
+ const mutate = useCallback(async (path, body, key) => {
50
+ setBusy(key);
51
+ try {
52
+ await client.mutate(path, body, headers());
53
+ await refresh();
54
+ setError(null);
55
+ } catch (cause) {
56
+ setError(cause instanceof Error ? cause.message : "The operation could not be completed.");
57
+ } finally {
58
+ setBusy(null);
59
+ }
60
+ }, [client, headers, refresh]);
61
+ useEffect(() => {
62
+ void refresh().catch((cause) => setError(cause instanceof Error ? cause.message : "Operations are unavailable."));
63
+ }, [refresh]);
64
+ const productionEnabled = useMemo(() => (snapshot.runtime ?? []).some((row) => row.provider_environment === "production" && row.enabled === true), [snapshot.runtime]);
65
+ return /* @__PURE__ */ jsxs("main", { className: "siv", children: [
66
+ /* @__PURE__ */ jsxs("header", { className: "siv-header", children: [
67
+ /* @__PURE__ */ jsxs("div", { children: [
68
+ /* @__PURE__ */ jsx("h1", { className: "siv-title", children: "Identity operations" }),
69
+ /* @__PURE__ */ jsx("p", { className: "siv-copy", children: "Provider health, governed routes, reviews, appeals and privacy queues. Identity documents stay in provider dashboards. Routing policy is never shown to end users." })
70
+ ] }),
71
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", onClick: () => void refresh(), children: "Refresh" })
72
+ ] }),
73
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", children: error }) : null,
74
+ productionEnabled ? /* @__PURE__ */ jsx("p", { className: "siv-alert", role: "status", children: "Production routing is active. Review routes, approval expiry and provider health." }) : /* @__PURE__ */ jsx("p", { className: "siv-alert", role: "status", children: "Production is fail-closed until runtime enablement and a separately approved policy are both present." }),
75
+ /* @__PURE__ */ jsx("div", { className: "siv-tabs", role: "tablist", "aria-label": "Operations sections", children: TABS.map((item) => /* @__PURE__ */ jsx("button", { type: "button", role: "tab", className: "siv-button siv-tab", "aria-selected": tab === item, onClick: () => setTab(item), children: item }, item)) }),
76
+ tab === "health" ? /* @__PURE__ */ jsx(RecordList, { title: "Provider health", records: [...snapshot.runtime ?? [], ...snapshot.health ?? [], ...snapshot.alerts ?? []], empty: "No runtime, provider-health or alert records." }) : null,
77
+ tab === "routes" ? /* @__PURE__ */ jsxs("section", { children: [
78
+ /* @__PURE__ */ jsx(RouteChangeForm, { busy, currentActorId: client.currentActorId, changes: snapshot.routeChanges ?? [], onMutate: (body, key) => mutate("/v1/admin/routes", body, key) }),
79
+ /* @__PURE__ */ jsx(RecordList, { title: "Routes", records: snapshot.routes ?? [], empty: "No reviewed route policies." })
80
+ ] }) : null,
81
+ tab === "circuits" ? /* @__PURE__ */ jsx(CircuitForm, { busy, onSubmit: (body) => mutate("/v1/admin/circuits", body, `circuit:${body.provider}`), records: snapshot.circuits ?? [] }) : null,
82
+ tab === "attempts" ? /* @__PURE__ */ jsx("div", { className: "siv-grid", children: (snapshot.attempts ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
83
+ /* @__PURE__ */ jsx("p", { children: String(row.package_code ?? "Verification attempt") }),
84
+ /* @__PURE__ */ jsxs("p", { className: "siv-copy", children: [
85
+ String(row.id),
86
+ " \xB7 ",
87
+ String(row.status)
88
+ ] }),
89
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void mutate("/v1/admin/reconciliation", { attemptId: row.id }, `reconcile:${row.id}`), children: "Reconcile" })
90
+ ] }, String(row.id))) }) : null,
91
+ tab === "review" ? /* @__PURE__ */ jsx(ReviewPanel, { snapshot, busy, currentActorId: client.currentActorId, onMutate: (body, key) => mutate("/v1/admin/review", body, key) }) : null,
92
+ tab === "reconciliation" ? /* @__PURE__ */ jsx(RecordList, { title: "Reconciliation", records: snapshot.reconciliationJobs ?? [], empty: "No reconciliation jobs." }) : null,
93
+ tab === "redaction" ? /* @__PURE__ */ jsx("div", { className: "siv-grid", children: (snapshot.privacyRequests ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
94
+ /* @__PURE__ */ jsxs("p", { children: [
95
+ String(row.request_reference ?? "Privacy request"),
96
+ " \xB7 ",
97
+ String(row.status)
98
+ ] }),
99
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void mutate("/v1/admin/redaction", { privacyRequestId: row.id }, `redact:${row.id}`), children: "Approve redaction" })
100
+ ] }, String(row.id))) }) : null,
101
+ tab === "audit" ? /* @__PURE__ */ jsx(RecordList, { title: "Audit", records: snapshot.audit ?? [], empty: "No immutable operational audit events." }) : null,
102
+ /* @__PURE__ */ jsxs("p", { className: "siv-copy", children: [
103
+ "Last refreshed ",
104
+ snapshot.generatedAt || "not yet",
105
+ ". Raw webhooks, launch secrets and identity documents are never displayed."
106
+ ] })
107
+ ] });
108
+ }
109
+ function RecordList({ title, records, empty }) {
110
+ if (!records.length) return /* @__PURE__ */ jsx("p", { className: "siv-copy", children: empty });
111
+ return /* @__PURE__ */ jsx("section", { "aria-label": title, className: "siv-grid", children: records.map((row, index) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
112
+ /* @__PURE__ */ jsx("p", { children: String(row.alert_code ?? row.provider ?? row.action ?? row.package_code ?? row.id ?? "Operational record") }),
113
+ /* @__PURE__ */ jsx("p", { className: "siv-copy", children: String(row.status ?? row.lifecycle ?? "") })
114
+ ] }, `${row.id ?? index}`)) });
115
+ }
116
+ function RouteChangeForm({ busy, currentActorId, changes, onMutate }) {
117
+ const [targetRoutePolicyId, setTarget] = useState("");
118
+ const [action, setAction] = useState("drain");
119
+ const [reasonCode, setReason] = useState("operator_requested_drain");
120
+ return /* @__PURE__ */ jsxs("div", { className: "siv-grid", children: [
121
+ /* @__PURE__ */ jsxs("form", { className: "siv-record", onSubmit: (event) => {
122
+ event.preventDefault();
123
+ void onMutate({ operation: "propose", targetRoutePolicyId, action, reasonCode }, "propose");
124
+ }, children: [
125
+ /* @__PURE__ */ jsx("h2", { className: "siv-title", children: "Governed route change" }),
126
+ /* @__PURE__ */ jsx("p", { className: "siv-copy", children: "Proposal and approval must be performed by different authorized staff." }),
127
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
128
+ "Route policy ID",
129
+ /* @__PURE__ */ jsx("input", { className: "siv-input", value: targetRoutePolicyId, onChange: (event) => setTarget(event.target.value) })
130
+ ] }),
131
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
132
+ "Action",
133
+ /* @__PURE__ */ jsxs("select", { className: "siv-select", value: action, onChange: (event) => setAction(event.target.value), children: [
134
+ /* @__PURE__ */ jsx("option", { value: "drain", children: "Drain" }),
135
+ /* @__PURE__ */ jsx("option", { value: "activate", children: "Activate" }),
136
+ /* @__PURE__ */ jsx("option", { value: "rollback", children: "Rollback" })
137
+ ] })
138
+ ] }),
139
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
140
+ "Reason code",
141
+ /* @__PURE__ */ jsx("input", { className: "siv-input", value: reasonCode, onChange: (event) => setReason(event.target.value) })
142
+ ] }),
143
+ /* @__PURE__ */ jsx("button", { type: "submit", className: "siv-button", disabled: Boolean(busy) || !targetRoutePolicyId, children: "Propose" })
144
+ ] }),
145
+ changes.map((row) => {
146
+ const sameProposer = currentActorId && row.proposedBy === currentActorId;
147
+ return /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
148
+ /* @__PURE__ */ jsxs("p", { children: [
149
+ String(row.action),
150
+ " \xB7 ",
151
+ String(row.status)
152
+ ] }),
153
+ /* @__PURE__ */ jsxs("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "approve", requestId: row.id }, `approve:${row.id}`), children: [
154
+ "Approve",
155
+ sameProposer ? " (server will enforce separation of duties)" : ""
156
+ ] }),
157
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "apply", requestId: row.id }, `apply:${row.id}`), children: "Apply" })
158
+ ] }, String(row.id));
159
+ })
160
+ ] });
161
+ }
162
+ function CircuitForm({ busy, onSubmit, records }) {
163
+ const [provider, setProvider] = useState("test_fake");
164
+ const [providerEnvironment, setEnv] = useState("sandbox");
165
+ const [status, setStatus] = useState("healthy");
166
+ return /* @__PURE__ */ jsxs("section", { children: [
167
+ /* @__PURE__ */ jsxs("form", { className: "siv-record", onSubmit: (event) => {
168
+ event.preventDefault();
169
+ void onSubmit({ provider, providerEnvironment, status });
170
+ }, children: [
171
+ /* @__PURE__ */ jsx("h2", { className: "siv-title", children: "Provider circuit" }),
172
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
173
+ "Provider",
174
+ /* @__PURE__ */ jsx("input", { className: "siv-input", value: provider, onChange: (event) => setProvider(event.target.value) })
175
+ ] }),
176
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
177
+ "Environment",
178
+ /* @__PURE__ */ jsxs("select", { className: "siv-select", value: providerEnvironment, onChange: (event) => setEnv(event.target.value), children: [
179
+ /* @__PURE__ */ jsx("option", { value: "sandbox", children: "Sandbox" }),
180
+ /* @__PURE__ */ jsx("option", { value: "production", children: "Production" })
181
+ ] })
182
+ ] }),
183
+ /* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
184
+ "State",
185
+ /* @__PURE__ */ jsxs("select", { className: "siv-select", value: status, onChange: (event) => setStatus(event.target.value), children: [
186
+ /* @__PURE__ */ jsx("option", { value: "healthy", children: "Healthy" }),
187
+ /* @__PURE__ */ jsx("option", { value: "degraded", children: "Degraded" }),
188
+ /* @__PURE__ */ jsx("option", { value: "unavailable", children: "Unavailable" }),
189
+ /* @__PURE__ */ jsx("option", { value: "circuit_open", children: "Circuit open" })
190
+ ] })
191
+ ] }),
192
+ /* @__PURE__ */ jsx("button", { type: "submit", className: "siv-button", disabled: Boolean(busy), children: "Update circuit" })
193
+ ] }),
194
+ /* @__PURE__ */ jsx(RecordList, { title: "Circuits", records, empty: "No circuit records." })
195
+ ] });
196
+ }
197
+ function ReviewPanel({ snapshot, busy, currentActorId, onMutate }) {
198
+ return /* @__PURE__ */ jsxs("div", { className: "siv-grid", children: [
199
+ (snapshot.appeals ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
200
+ /* @__PURE__ */ jsxs("p", { children: [
201
+ "Appeal \xB7 ",
202
+ String(row.reason_code ?? "review")
203
+ ] }),
204
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "begin_appeal_review", appealId: row.id }, `review:${row.id}`), children: "Begin review" })
205
+ ] }, `appeal:${row.id}`)),
206
+ (snapshot.manualExceptions ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
207
+ /* @__PURE__ */ jsxs("p", { children: [
208
+ String(row.decision),
209
+ " \xB7 ",
210
+ String(row.status)
211
+ ] }),
212
+ /* @__PURE__ */ jsxs("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "approve_manual_exception", requestId: row.id }, `approve-exc:${row.id}`), children: [
213
+ "Approve",
214
+ currentActorId && row.proposedBy === currentActorId ? " (server will enforce separation of duties)" : ""
215
+ ] }),
216
+ /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "apply_manual_exception", requestId: row.id }, `apply-exc:${row.id}`), children: "Apply decision" })
217
+ ] }, `exc:${row.id}`))
218
+ ] });
219
+ }
220
+
221
+ export { OperationsConsole };
222
+ //# sourceMappingURL=operations.js.map
223
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/operations/OperationsConsole.tsx"],"names":[],"mappings":"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","file":"operations.js","sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nexport interface OperationsRecord {\n id?: string;\n [key: string]: string | number | boolean | null | undefined;\n}\n\nexport interface OperationsSnapshot {\n generatedAt: string;\n runtime?: OperationsRecord[];\n health?: OperationsRecord[];\n alerts?: OperationsRecord[];\n routes?: OperationsRecord[];\n routeChanges?: OperationsRecord[];\n circuits?: OperationsRecord[];\n attempts?: OperationsRecord[];\n appeals?: OperationsRecord[];\n manualExceptions?: OperationsRecord[];\n audit?: OperationsRecord[];\n reconciliationJobs?: OperationsRecord[];\n privacyRequests?: OperationsRecord[];\n redactionJobs?: OperationsRecord[];\n policyVersions?: OperationsRecord[];\n queues?: Record<string, number>;\n jobs?: OperationsRecord[];\n}\n\nexport interface OperationsClient {\n get(path: string): Promise<unknown>;\n mutate(path: string, body: unknown, headers: Record<string, string>): Promise<unknown>;\n createIdempotencyKey?: () => string;\n getCsrfToken?: () => string | null;\n currentActorId?: string;\n}\n\nconst TABS = ['health', 'routes', 'circuits', 'attempts', 'review', 'reconciliation', 'redaction', 'audit'] as const;\n\nexport function OperationsConsole({ client }: { client: OperationsClient }) {\n const [snapshot, setSnapshot] = useState<OperationsSnapshot>({ generatedAt: '' });\n const [tab, setTab] = useState<(typeof TABS)[number]>('health');\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n\n const headers = useCallback((extra: Record<string, string> = {}) => {\n const csrf = client.getCsrfToken?.();\n return {\n 'Idempotency-Key': client.createIdempotencyKey?.() ?? (globalThis.crypto?.randomUUID?.() ?? `idem_${Date.now()}`),\n ...(csrf ? { 'X-CSRF-Token': csrf } : {}),\n ...extra,\n };\n }, [client]);\n\n const refresh = useCallback(async () => {\n const [health, routes, circuits, attempts, review, audit, reconciliation, redaction] = await Promise.all([\n client.get('/v1/admin/health') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/routes') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/circuits') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/attempts') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/review') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/audit') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/reconciliation') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/redaction') as Promise<OperationsSnapshot>,\n ]);\n setSnapshot({\n generatedAt: health.generatedAt,\n runtime: health.runtime,\n health: health.health,\n alerts: health.alerts,\n routes: routes.routes,\n routeChanges: routes.routeChanges,\n circuits: circuits.circuits,\n attempts: attempts.attempts,\n appeals: review.appeals,\n manualExceptions: review.manualExceptions,\n policyVersions: review.policyVersions,\n audit: audit.audit,\n reconciliationJobs: reconciliation.jobs as OperationsRecord[] | undefined,\n queues: reconciliation.queues,\n privacyRequests: redaction.privacyRequests,\n redactionJobs: redaction.jobs as OperationsRecord[] | undefined,\n });\n }, [client]);\n\n const mutate = useCallback(async (path: string, body: unknown, key: string) => {\n setBusy(key);\n try {\n await client.mutate(path, body, headers());\n await refresh();\n setError(null);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : 'The operation could not be completed.');\n } finally {\n setBusy(null);\n }\n }, [client, headers, refresh]);\n\n useEffect(() => { void refresh().catch((cause) => setError(cause instanceof Error ? cause.message : 'Operations are unavailable.')); }, [refresh]);\n\n const productionEnabled = useMemo(() => (snapshot.runtime ?? []).some((row) => row.provider_environment === 'production' && row.enabled === true), [snapshot.runtime]);\n\n return (\n <main className=\"siv\">\n <header className=\"siv-header\">\n <div>\n <h1 className=\"siv-title\">Identity operations</h1>\n <p className=\"siv-copy\">Provider health, governed routes, reviews, appeals and privacy queues. Identity documents stay in provider dashboards. Routing policy is never shown to end users.</p>\n </div>\n <button type=\"button\" className=\"siv-button\" onClick={() => void refresh()}>Refresh</button>\n </header>\n {error ? <p role=\"alert\">{error}</p> : null}\n {productionEnabled\n ? <p className=\"siv-alert\" role=\"status\">Production routing is active. Review routes, approval expiry and provider health.</p>\n : <p className=\"siv-alert\" role=\"status\">Production is fail-closed until runtime enablement and a separately approved policy are both present.</p>}\n\n <div className=\"siv-tabs\" role=\"tablist\" aria-label=\"Operations sections\">\n {TABS.map((item) => (\n <button key={item} type=\"button\" role=\"tab\" className=\"siv-button siv-tab\" aria-selected={tab === item} onClick={() => setTab(item)}>{item}</button>\n ))}\n </div>\n\n {tab === 'health' ? <RecordList title=\"Provider health\" records={[...(snapshot.runtime ?? []), ...(snapshot.health ?? []), ...(snapshot.alerts ?? [])]} empty=\"No runtime, provider-health or alert records.\" /> : null}\n {tab === 'routes' ? (\n <section>\n <RouteChangeForm busy={busy} currentActorId={client.currentActorId} changes={snapshot.routeChanges ?? []} onMutate={(body, key) => mutate('/v1/admin/routes', body, key)} />\n <RecordList title=\"Routes\" records={snapshot.routes ?? []} empty=\"No reviewed route policies.\" />\n </section>\n ) : null}\n {tab === 'circuits' ? <CircuitForm busy={busy} onSubmit={(body) => mutate('/v1/admin/circuits', body, `circuit:${body.provider}`)} records={snapshot.circuits ?? []} /> : null}\n {tab === 'attempts' ? (\n <div className=\"siv-grid\">\n {(snapshot.attempts ?? []).map((row) => (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.package_code ?? 'Verification attempt')}</p>\n <p className=\"siv-copy\">{String(row.id)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void mutate('/v1/admin/reconciliation', { attemptId: row.id }, `reconcile:${row.id}`)}>Reconcile</button>\n </article>\n ))}\n </div>\n ) : null}\n {tab === 'review' ? <ReviewPanel snapshot={snapshot} busy={busy} currentActorId={client.currentActorId} onMutate={(body, key) => mutate('/v1/admin/review', body, key)} /> : null}\n {tab === 'reconciliation' ? <RecordList title=\"Reconciliation\" records={snapshot.reconciliationJobs ?? []} empty=\"No reconciliation jobs.\" /> : null}\n {tab === 'redaction' ? (\n <div className=\"siv-grid\">\n {(snapshot.privacyRequests ?? []).map((row) => (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.request_reference ?? 'Privacy request')} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void mutate('/v1/admin/redaction', { privacyRequestId: row.id }, `redact:${row.id}`)}>Approve redaction</button>\n </article>\n ))}\n </div>\n ) : null}\n {tab === 'audit' ? <RecordList title=\"Audit\" records={snapshot.audit ?? []} empty=\"No immutable operational audit events.\" /> : null}\n <p className=\"siv-copy\">Last refreshed {snapshot.generatedAt || 'not yet'}. Raw webhooks, launch secrets and identity documents are never displayed.</p>\n </main>\n );\n}\n\nfunction RecordList({ title, records, empty }: { title: string; records: OperationsRecord[]; empty: string }) {\n if (!records.length) return <p className=\"siv-copy\">{empty}</p>;\n return (\n <section aria-label={title} className=\"siv-grid\">\n {records.map((row, index) => (\n <article key={`${row.id ?? index}`} className=\"siv-record\">\n <p>{String(row.alert_code ?? row.provider ?? row.action ?? row.package_code ?? row.id ?? 'Operational record')}</p>\n <p className=\"siv-copy\">{String(row.status ?? row.lifecycle ?? '')}</p>\n </article>\n ))}\n </section>\n );\n}\n\nfunction RouteChangeForm({ busy, currentActorId, changes, onMutate }: {\n busy: string | null;\n currentActorId?: string;\n changes: OperationsRecord[];\n onMutate: (body: unknown, key: string) => Promise<void>;\n}) {\n const [targetRoutePolicyId, setTarget] = useState('');\n const [action, setAction] = useState('drain');\n const [reasonCode, setReason] = useState('operator_requested_drain');\n return (\n <div className=\"siv-grid\">\n <form className=\"siv-record\" onSubmit={(event) => { event.preventDefault(); void onMutate({ operation: 'propose', targetRoutePolicyId, action, reasonCode }, 'propose'); }}>\n <h2 className=\"siv-title\">Governed route change</h2>\n <p className=\"siv-copy\">Proposal and approval must be performed by different authorized staff.</p>\n <label className=\"siv-field\">Route policy ID<input className=\"siv-input\" value={targetRoutePolicyId} onChange={(event) => setTarget(event.target.value)} /></label>\n <label className=\"siv-field\">Action\n <select className=\"siv-select\" value={action} onChange={(event) => setAction(event.target.value)}>\n <option value=\"drain\">Drain</option>\n <option value=\"activate\">Activate</option>\n <option value=\"rollback\">Rollback</option>\n </select>\n </label>\n <label className=\"siv-field\">Reason code<input className=\"siv-input\" value={reasonCode} onChange={(event) => setReason(event.target.value)} /></label>\n <button type=\"submit\" className=\"siv-button\" disabled={Boolean(busy) || !targetRoutePolicyId}>Propose</button>\n </form>\n {changes.map((row) => {\n const sameProposer = currentActorId && row.proposedBy === currentActorId;\n return (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.action)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'approve', requestId: row.id }, `approve:${row.id}`)}>\n Approve{sameProposer ? ' (server will enforce separation of duties)' : ''}\n </button>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'apply', requestId: row.id }, `apply:${row.id}`)}>Apply</button>\n </article>\n );\n })}\n </div>\n );\n}\n\nfunction CircuitForm({ busy, onSubmit, records }: {\n busy: string | null;\n records: OperationsRecord[];\n onSubmit: (body: { provider: string; providerEnvironment: string; status: string }) => Promise<void>;\n}) {\n const [provider, setProvider] = useState('test_fake');\n const [providerEnvironment, setEnv] = useState('sandbox');\n const [status, setStatus] = useState('healthy');\n return (\n <section>\n <form className=\"siv-record\" onSubmit={(event) => { event.preventDefault(); void onSubmit({ provider, providerEnvironment, status }); }}>\n <h2 className=\"siv-title\">Provider circuit</h2>\n <label className=\"siv-field\">Provider<input className=\"siv-input\" value={provider} onChange={(event) => setProvider(event.target.value)} /></label>\n <label className=\"siv-field\">Environment\n <select className=\"siv-select\" value={providerEnvironment} onChange={(event) => setEnv(event.target.value)}>\n <option value=\"sandbox\">Sandbox</option>\n <option value=\"production\">Production</option>\n </select>\n </label>\n <label className=\"siv-field\">State\n <select className=\"siv-select\" value={status} onChange={(event) => setStatus(event.target.value)}>\n <option value=\"healthy\">Healthy</option>\n <option value=\"degraded\">Degraded</option>\n <option value=\"unavailable\">Unavailable</option>\n <option value=\"circuit_open\">Circuit open</option>\n </select>\n </label>\n <button type=\"submit\" className=\"siv-button\" disabled={Boolean(busy)}>Update circuit</button>\n </form>\n <RecordList title=\"Circuits\" records={records} empty=\"No circuit records.\" />\n </section>\n );\n}\n\nfunction ReviewPanel({ snapshot, busy, currentActorId, onMutate }: {\n snapshot: OperationsSnapshot;\n busy: string | null;\n currentActorId?: string;\n onMutate: (body: unknown, key: string) => Promise<void>;\n}) {\n return (\n <div className=\"siv-grid\">\n {(snapshot.appeals ?? []).map((row) => (\n <article key={`appeal:${row.id}`} className=\"siv-record\">\n <p>Appeal · {String(row.reason_code ?? 'review')}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'begin_appeal_review', appealId: row.id }, `review:${row.id}`)}>Begin review</button>\n </article>\n ))}\n {(snapshot.manualExceptions ?? []).map((row) => (\n <article key={`exc:${row.id}`} className=\"siv-record\">\n <p>{String(row.decision)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'approve_manual_exception', requestId: row.id }, `approve-exc:${row.id}`)}>\n Approve{currentActorId && row.proposedBy === currentActorId ? ' (server will enforce separation of duties)' : ''}\n </button>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'apply_manual_exception', requestId: row.id }, `apply-exc:${row.id}`)}>Apply decision</button>\n </article>\n ))}\n </div>\n );\n}\n\nexport default OperationsConsole;\n"]}
package/dist/retry.cjs ADDED
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+
5
+ // src/retry/RetryButton.tsx
6
+ function RetryButton({
7
+ disabled,
8
+ busy,
9
+ onClick
10
+ }) {
11
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "siv-button", onClick, disabled: disabled || busy, "aria-busy": busy || void 0, children: busy ? "Retrying\u2026" : "Retry verification" });
12
+ }
13
+
14
+ exports.RetryButton = RetryButton;
15
+ //# sourceMappingURL=retry.cjs.map
16
+ //# sourceMappingURL=retry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/retry/RetryButton.tsx"],"names":["jsx"],"mappings":";;;;;AAAO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,uBACEA,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,YAAA,EAAa,OAAA,EAAkB,QAAA,EAAU,QAAA,IAAY,MAAM,WAAA,EAAW,IAAA,IAAQ,MAAA,EAC3G,QAAA,EAAA,IAAA,GAAO,mBAAc,oBAAA,EACxB,CAAA;AAEJ","file":"retry.cjs","sourcesContent":["export function RetryButton({\n disabled,\n busy,\n onClick,\n}: {\n disabled?: boolean;\n busy?: boolean;\n onClick: () => void;\n}) {\n return (\n <button type=\"button\" className=\"siv-button\" onClick={onClick} disabled={disabled || busy} aria-busy={busy || undefined}>\n {busy ? 'Retrying…' : 'Retry verification'}\n </button>\n );\n}\n\nexport default RetryButton;\n"]}
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+
3
+ declare function RetryButton({ disabled, busy, onClick, }: {
4
+ disabled?: boolean;
5
+ busy?: boolean;
6
+ onClick: () => void;
7
+ }): react.JSX.Element;
8
+
9
+ export { RetryButton };
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+
3
+ declare function RetryButton({ disabled, busy, onClick, }: {
4
+ disabled?: boolean;
5
+ busy?: boolean;
6
+ onClick: () => void;
7
+ }): react.JSX.Element;
8
+
9
+ export { RetryButton };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sources":["retry.d.ts"],"names":[],"mappings":"AAAA"}
package/dist/retry.js ADDED
@@ -0,0 +1,14 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ // src/retry/RetryButton.tsx
4
+ function RetryButton({
5
+ disabled,
6
+ busy,
7
+ onClick
8
+ }) {
9
+ return /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", onClick, disabled: disabled || busy, "aria-busy": busy || void 0, children: busy ? "Retrying\u2026" : "Retry verification" });
10
+ }
11
+
12
+ export { RetryButton };
13
+ //# sourceMappingURL=retry.js.map
14
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/retry/RetryButton.tsx"],"names":[],"mappings":";;;AAAO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,YAAA,EAAa,OAAA,EAAkB,QAAA,EAAU,QAAA,IAAY,MAAM,WAAA,EAAW,IAAA,IAAQ,MAAA,EAC3G,QAAA,EAAA,IAAA,GAAO,mBAAc,oBAAA,EACxB,CAAA;AAEJ","file":"retry.js","sourcesContent":["export function RetryButton({\n disabled,\n busy,\n onClick,\n}: {\n disabled?: boolean;\n busy?: boolean;\n onClick: () => void;\n}) {\n return (\n <button type=\"button\" className=\"siv-button\" onClick={onClick} disabled={disabled || busy} aria-busy={busy || undefined}>\n {busy ? 'Retrying…' : 'Retry verification'}\n </button>\n );\n}\n\nexport default RetryButton;\n"]}
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+
5
+ // src/hooks/status.ts
6
+ function useVerificationStatus(envelope) {
7
+ const blocked = envelope?.status === "processing" || envelope?.status === "manual_review_required";
8
+ const unavailable = envelope?.status === "provider_unavailable";
9
+ const terminal = envelope != null && ["verified", "declined", "failed", "expired", "canceled", "redacted"].includes(envelope.status);
10
+ return { blocked, unavailable, terminal, status: envelope?.status ?? "created", disclosure: envelope?.providerDisclosure ?? null };
11
+ }
12
+ function VerificationStatus({ envelope }) {
13
+ const state = useVerificationStatus(envelope);
14
+ if (!envelope) return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-copy", role: "status", children: "Verification has not started." });
15
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "siv siv-record", "aria-label": "Verification status", children: [
16
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", "aria-live": "polite", children: [
17
+ "Status: ",
18
+ state.status.replace(/_/g, " ")
19
+ ] }),
20
+ state.disclosure ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-disclosure", children: state.disclosure }) : null,
21
+ state.blocked ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-copy", children: "This protected action stays blocked until a server-side decision arrives." }) : null
22
+ ] });
23
+ }
24
+
25
+ exports.VerificationStatus = VerificationStatus;
26
+ //# sourceMappingURL=status.cjs.map
27
+ //# sourceMappingURL=status.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/status.ts","../src/status/VerificationStatus.tsx"],"names":["jsx","jsxs"],"mappings":";;;;;AAEO,SAAS,sBAAsB,QAAA,EAA6C;AACjF,EAAA,MAAM,OAAA,GAAU,QAAA,EAAU,MAAA,KAAW,YAAA,IAAgB,UAAU,MAAA,KAAW,wBAAA;AAC1E,EAAA,MAAM,WAAA,GAAc,UAAU,MAAA,KAAW,sBAAA;AACzC,EAAA,MAAM,QAAA,GAAW,QAAA,IAAY,IAAA,IAAQ,CAAC,UAAA,EAAY,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,SAAS,MAAM,CAAA;AACnI,EAAA,OAAO,EAAE,OAAA,EAAS,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,IAAU,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,kBAAA,IAAsB,IAAA,EAAK;AACnI;ACHO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAS,EAAoD;AAChG,EAAA,MAAM,KAAA,GAAQ,sBAAsB,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,UAAU,uBAAOA,cAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,QAAA,EAAA,+BAAA,EAA6B,CAAA;AACzF,EAAA,uBACEC,eAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,gBAAA,EAAiB,cAAW,qBAAA,EAC7C,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EAAS,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACzB,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,GAAG;AAAA,KAAA,EACzC,CAAA;AAAA,IACC,KAAA,CAAM,6BAAaD,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,CAAM,YAAW,CAAA,GAAO,IAAA;AAAA,IAC1E,MAAM,OAAA,mBAAUA,cAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,uFAAyE,CAAA,GAAO;AAAA,GAAA,EAC3H,CAAA;AAEJ","file":"status.cjs","sourcesContent":["import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nexport function useVerificationStatus(envelope: VerificationStatusEnvelope | null) {\n const blocked = envelope?.status === 'processing' || envelope?.status === 'manual_review_required';\n const unavailable = envelope?.status === 'provider_unavailable';\n const terminal = envelope != null && ['verified', 'declined', 'failed', 'expired', 'canceled', 'redacted'].includes(envelope.status);\n return { blocked, unavailable, terminal, status: envelope?.status ?? 'created', disclosure: envelope?.providerDisclosure ?? null };\n}\n","import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nimport { useVerificationStatus } from '../hooks/status.ts';\n\nexport function VerificationStatus({ envelope }: { envelope: VerificationStatusEnvelope | null }) {\n const state = useVerificationStatus(envelope);\n if (!envelope) return <p className=\"siv-copy\" role=\"status\">Verification has not started.</p>;\n return (\n <section className=\"siv siv-record\" aria-label=\"Verification status\">\n <p role=\"status\" aria-live=\"polite\">\n Status: {state.status.replace(/_/g, ' ')}\n </p>\n {state.disclosure ? <p className=\"siv-disclosure\">{state.disclosure}</p> : null}\n {state.blocked ? <p className=\"siv-copy\">This protected action stays blocked until a server-side decision arrives.</p> : null}\n </section>\n );\n}\n\nexport default VerificationStatus;\n"]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import { VerificationStatusEnvelope } from '@splitin/verification-web';
3
+
4
+ declare function VerificationStatus({ envelope }: {
5
+ envelope: VerificationStatusEnvelope | null;
6
+ }): react.JSX.Element;
7
+
8
+ export { VerificationStatus };
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import { VerificationStatusEnvelope } from '@splitin/verification-web';
3
+
4
+ declare function VerificationStatus({ envelope }: {
5
+ envelope: VerificationStatusEnvelope | null;
6
+ }): react.JSX.Element;
7
+
8
+ export { VerificationStatus };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sources":["status.d.ts"],"names":[],"mappings":"AAAA"}
package/dist/status.js ADDED
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+
3
+ // src/hooks/status.ts
4
+ function useVerificationStatus(envelope) {
5
+ const blocked = envelope?.status === "processing" || envelope?.status === "manual_review_required";
6
+ const unavailable = envelope?.status === "provider_unavailable";
7
+ const terminal = envelope != null && ["verified", "declined", "failed", "expired", "canceled", "redacted"].includes(envelope.status);
8
+ return { blocked, unavailable, terminal, status: envelope?.status ?? "created", disclosure: envelope?.providerDisclosure ?? null };
9
+ }
10
+ function VerificationStatus({ envelope }) {
11
+ const state = useVerificationStatus(envelope);
12
+ if (!envelope) return /* @__PURE__ */ jsx("p", { className: "siv-copy", role: "status", children: "Verification has not started." });
13
+ return /* @__PURE__ */ jsxs("section", { className: "siv siv-record", "aria-label": "Verification status", children: [
14
+ /* @__PURE__ */ jsxs("p", { role: "status", "aria-live": "polite", children: [
15
+ "Status: ",
16
+ state.status.replace(/_/g, " ")
17
+ ] }),
18
+ state.disclosure ? /* @__PURE__ */ jsx("p", { className: "siv-disclosure", children: state.disclosure }) : null,
19
+ state.blocked ? /* @__PURE__ */ jsx("p", { className: "siv-copy", children: "This protected action stays blocked until a server-side decision arrives." }) : null
20
+ ] });
21
+ }
22
+
23
+ export { VerificationStatus };
24
+ //# sourceMappingURL=status.js.map
25
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/status.ts","../src/status/VerificationStatus.tsx"],"names":[],"mappings":";;;AAEO,SAAS,sBAAsB,QAAA,EAA6C;AACjF,EAAA,MAAM,OAAA,GAAU,QAAA,EAAU,MAAA,KAAW,YAAA,IAAgB,UAAU,MAAA,KAAW,wBAAA;AAC1E,EAAA,MAAM,WAAA,GAAc,UAAU,MAAA,KAAW,sBAAA;AACzC,EAAA,MAAM,QAAA,GAAW,QAAA,IAAY,IAAA,IAAQ,CAAC,UAAA,EAAY,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,SAAS,MAAM,CAAA;AACnI,EAAA,OAAO,EAAE,OAAA,EAAS,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,IAAU,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,kBAAA,IAAsB,IAAA,EAAK;AACnI;ACHO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAS,EAAoD;AAChG,EAAA,MAAM,KAAA,GAAQ,sBAAsB,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,UAAU,uBAAO,GAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,QAAA,EAAA,+BAAA,EAA6B,CAAA;AACzF,EAAA,uBACE,IAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,gBAAA,EAAiB,cAAW,qBAAA,EAC7C,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EAAS,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACzB,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,GAAG;AAAA,KAAA,EACzC,CAAA;AAAA,IACC,KAAA,CAAM,6BAAa,GAAA,CAAC,GAAA,EAAA,EAAE,WAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,CAAM,YAAW,CAAA,GAAO,IAAA;AAAA,IAC1E,MAAM,OAAA,mBAAU,GAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,uFAAyE,CAAA,GAAO;AAAA,GAAA,EAC3H,CAAA;AAEJ","file":"status.js","sourcesContent":["import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nexport function useVerificationStatus(envelope: VerificationStatusEnvelope | null) {\n const blocked = envelope?.status === 'processing' || envelope?.status === 'manual_review_required';\n const unavailable = envelope?.status === 'provider_unavailable';\n const terminal = envelope != null && ['verified', 'declined', 'failed', 'expired', 'canceled', 'redacted'].includes(envelope.status);\n return { blocked, unavailable, terminal, status: envelope?.status ?? 'created', disclosure: envelope?.providerDisclosure ?? null };\n}\n","import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nimport { useVerificationStatus } from '../hooks/status.ts';\n\nexport function VerificationStatus({ envelope }: { envelope: VerificationStatusEnvelope | null }) {\n const state = useVerificationStatus(envelope);\n if (!envelope) return <p className=\"siv-copy\" role=\"status\">Verification has not started.</p>;\n return (\n <section className=\"siv siv-record\" aria-label=\"Verification status\">\n <p role=\"status\" aria-live=\"polite\">\n Status: {state.status.replace(/_/g, ' ')}\n </p>\n {state.disclosure ? <p className=\"siv-disclosure\">{state.disclosure}</p> : null}\n {state.blocked ? <p className=\"siv-copy\">This protected action stays blocked until a server-side decision arrives.</p> : null}\n </section>\n );\n}\n\nexport default VerificationStatus;\n"]}
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+
5
+ // src/support/SupportLink.tsx
6
+ function SupportLink({ href = "/support/verification", children = "Contact support" }) {
7
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { className: "siv-link", href, rel: "noopener noreferrer", children });
8
+ }
9
+
10
+ exports.SupportLink = SupportLink;
11
+ //# sourceMappingURL=support.cjs.map
12
+ //# sourceMappingURL=support.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/support/SupportLink.tsx"],"names":[],"mappings":";;;;;AAAO,SAAS,YAAY,EAAE,IAAA,GAAO,uBAAA,EAAyB,QAAA,GAAW,mBAAkB,EAGxF;AACD,EAAA,sCACG,GAAA,EAAA,EAAE,SAAA,EAAU,YAAW,IAAA,EAAY,GAAA,EAAI,uBACrC,QAAA,EACH,CAAA;AAEJ","file":"support.cjs","sourcesContent":["export function SupportLink({ href = '/support/verification', children = 'Contact support' }: {\n href?: string;\n children?: string;\n}) {\n return (\n <a className=\"siv-link\" href={href} rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n}\n\nexport default SupportLink;\n"]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SupportLink({ href, children }: {
4
+ href?: string;
5
+ children?: string;
6
+ }): react.JSX.Element;
7
+
8
+ export { SupportLink };
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SupportLink({ href, children }: {
4
+ href?: string;
5
+ children?: string;
6
+ }): react.JSX.Element;
7
+
8
+ export { SupportLink };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.d.ts","sources":["support.d.ts"],"names":[],"mappings":"AAAA"}
@@ -0,0 +1,10 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ // src/support/SupportLink.tsx
4
+ function SupportLink({ href = "/support/verification", children = "Contact support" }) {
5
+ return /* @__PURE__ */ jsx("a", { className: "siv-link", href, rel: "noopener noreferrer", children });
6
+ }
7
+
8
+ export { SupportLink };
9
+ //# sourceMappingURL=support.js.map
10
+ //# sourceMappingURL=support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/support/SupportLink.tsx"],"names":[],"mappings":";;;AAAO,SAAS,YAAY,EAAE,IAAA,GAAO,uBAAA,EAAyB,QAAA,GAAW,mBAAkB,EAGxF;AACD,EAAA,2BACG,GAAA,EAAA,EAAE,SAAA,EAAU,YAAW,IAAA,EAAY,GAAA,EAAI,uBACrC,QAAA,EACH,CAAA;AAEJ","file":"support.js","sourcesContent":["export function SupportLink({ href = '/support/verification', children = 'Contact support' }: {\n href?: string;\n children?: string;\n}) {\n return (\n <a className=\"siv-link\" href={href} rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n}\n\nexport default SupportLink;\n"]}
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@splitin/verification-react",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "Accessible React hooks and components for verification launch, status, appeals, and operations.",
5
+ "license": "MIT",
6
+ "author": "SplitInTech, @ojchavan",
7
+ "homepage": "https://github.com/splitintech/open-internal-tools/tree/main/verification-adapter-sdk/packages/verification-react#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/splitintech/open-internal-tools.git",
11
+ "directory": "verification-adapter-sdk/packages/verification-react"
12
+ },
13
+ "type": "module",
14
+ "sideEffects": ["./dist/styles.css", "./src/styles.css"],
15
+ "engines": { "node": ">=20" },
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js",
23
+ "require": "./dist/index.cjs"
24
+ },
25
+ "./launcher": {
26
+ "types": "./dist/launcher.d.ts",
27
+ "import": "./dist/launcher.js",
28
+ "require": "./dist/launcher.cjs"
29
+ },
30
+ "./status": {
31
+ "types": "./dist/status.d.ts",
32
+ "import": "./dist/status.js",
33
+ "require": "./dist/status.cjs"
34
+ },
35
+ "./retry": {
36
+ "types": "./dist/retry.d.ts",
37
+ "import": "./dist/retry.js",
38
+ "require": "./dist/retry.cjs"
39
+ },
40
+ "./appeal": {
41
+ "types": "./dist/appeal.d.ts",
42
+ "import": "./dist/appeal.js",
43
+ "require": "./dist/appeal.cjs"
44
+ },
45
+ "./support": {
46
+ "types": "./dist/support.d.ts",
47
+ "import": "./dist/support.js",
48
+ "require": "./dist/support.cjs"
49
+ },
50
+ "./operations": {
51
+ "types": "./dist/operations.d.ts",
52
+ "import": "./dist/operations.js",
53
+ "require": "./dist/operations.cjs"
54
+ },
55
+ "./styles.css": "./src/styles.css"
56
+ },
57
+ "files": ["dist", "src/styles.css", "LICENSE", "NOTICE", "README.md", "package.json"],
58
+ "publishConfig": { "access": "public" },
59
+ "scripts": {
60
+ "build": "tsup",
61
+ "test": "vitest run",
62
+ "typecheck": "tsc --noEmit -p tsconfig.json"
63
+ },
64
+ "dependencies": {
65
+ "@splitin/verification-adapter-sdk": "0.1.0-beta.0",
66
+ "@splitin/verification-web": "0.1.0-beta.0"
67
+ },
68
+ "peerDependencies": {
69
+ "react": "^18.0.0 || ^19.0.0",
70
+ "react-dom": "^18.0.0 || ^19.0.0",
71
+ "@stripe/stripe-js": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
72
+ "persona": ">=4.0.0",
73
+ "react-plaid-link": "^3.5.0 || ^4.0.0"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "@stripe/stripe-js": { "optional": true },
77
+ "persona": { "optional": true },
78
+ "react-plaid-link": { "optional": true }
79
+ },
80
+ "devDependencies": {
81
+ "@testing-library/jest-dom": "^6.6.3",
82
+ "@testing-library/react": "^16.3.0",
83
+ "@types/react": "^19.1.6",
84
+ "@types/react-dom": "^19.1.5",
85
+ "jsdom": "^26.1.0",
86
+ "react": "^19.1.0",
87
+ "react-dom": "^19.1.0",
88
+ "tsup": "^8.5.0",
89
+ "typescript": "^5.8.3",
90
+ "vitest": "^3.2.4"
91
+ }
92
+ }