@everfur/sdk 0.1.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 (89) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +161 -0
  4. package/animations/package.json +8 -0
  5. package/chat/package.json +8 -0
  6. package/client/package.json +8 -0
  7. package/core/package.json +8 -0
  8. package/dist/CameraPort-Cv31Pz7g.d.cts +29 -0
  9. package/dist/CameraPort-Cv31Pz7g.d.ts +29 -0
  10. package/dist/ChatController-CKdBvPj2.d.ts +146 -0
  11. package/dist/ChatController-CpUMvvZf.d.cts +146 -0
  12. package/dist/EverfurResult-D92-uL82.d.cts +240 -0
  13. package/dist/EverfurResult-D92-uL82.d.ts +240 -0
  14. package/dist/FilePort-BabWrv7I.d.cts +22 -0
  15. package/dist/FilePort-BabWrv7I.d.ts +22 -0
  16. package/dist/PhotoController-BItt5M7u.d.cts +43 -0
  17. package/dist/PhotoController-D8zMTdcW.d.ts +43 -0
  18. package/dist/TelemetryPort-BDNr00hu.d.cts +12 -0
  19. package/dist/TelemetryPort-BDNr00hu.d.ts +12 -0
  20. package/dist/animations/index.cjs +1997 -0
  21. package/dist/animations/index.d.cts +517 -0
  22. package/dist/animations/index.d.ts +517 -0
  23. package/dist/animations/index.js +1972 -0
  24. package/dist/cacheEpoch-DknKn3S0.d.cts +36 -0
  25. package/dist/cacheEpoch-DknKn3S0.d.ts +36 -0
  26. package/dist/chat/index.cjs +1170 -0
  27. package/dist/chat/index.d.cts +59 -0
  28. package/dist/chat/index.d.ts +59 -0
  29. package/dist/chat/index.js +1167 -0
  30. package/dist/client/index.cjs +2317 -0
  31. package/dist/client/index.d.cts +65 -0
  32. package/dist/client/index.d.ts +65 -0
  33. package/dist/client/index.js +2217 -0
  34. package/dist/config-BSjBdxrZ.d.cts +501 -0
  35. package/dist/config-CiJ0PVBB.d.ts +501 -0
  36. package/dist/core/index.cjs +3175 -0
  37. package/dist/core/index.d.cts +70 -0
  38. package/dist/core/index.d.ts +70 -0
  39. package/dist/core/index.js +3163 -0
  40. package/dist/identity-Brl-lDd6.d.cts +91 -0
  41. package/dist/identity-DK9zORrG.d.ts +91 -0
  42. package/dist/ids-CJ1S6adf.d.cts +46 -0
  43. package/dist/ids-CJ1S6adf.d.ts +46 -0
  44. package/dist/index.cjs +4488 -0
  45. package/dist/index.d.cts +156 -0
  46. package/dist/index.d.ts +156 -0
  47. package/dist/index.js +4464 -0
  48. package/dist/petsRepository-BEGb97M9.d.cts +326 -0
  49. package/dist/petsRepository-Bu18r2kK.d.ts +326 -0
  50. package/dist/photo/index.cjs +2189 -0
  51. package/dist/photo/index.d.cts +43 -0
  52. package/dist/photo/index.d.ts +43 -0
  53. package/dist/photo/index.js +2186 -0
  54. package/dist/projection-CeIUsbSk.d.cts +8 -0
  55. package/dist/projection-CeIUsbSk.d.ts +8 -0
  56. package/dist/records/index.cjs +2840 -0
  57. package/dist/records/index.d.cts +224 -0
  58. package/dist/records/index.d.ts +224 -0
  59. package/dist/records/index.js +2834 -0
  60. package/dist/requestFunnel-DuUH-kAe.d.cts +28 -0
  61. package/dist/requestFunnel-dio5OmR9.d.ts +28 -0
  62. package/dist/resolve-Dq_4_agU.d.cts +86 -0
  63. package/dist/resolve-Dq_4_agU.d.ts +86 -0
  64. package/dist/runtime-BgQnA594.d.cts +349 -0
  65. package/dist/runtime-CBA-LvdM.d.ts +349 -0
  66. package/dist/server/index.cjs +533 -0
  67. package/dist/server/index.d.cts +48 -0
  68. package/dist/server/index.d.ts +48 -0
  69. package/dist/server/index.js +530 -0
  70. package/dist/testing/index.cjs +825 -0
  71. package/dist/testing/index.d.cts +113 -0
  72. package/dist/testing/index.d.ts +113 -0
  73. package/dist/testing/index.js +822 -0
  74. package/dist/testing/rn/index.cjs +449 -0
  75. package/dist/testing/rn/index.d.cts +49 -0
  76. package/dist/testing/rn/index.d.ts +49 -0
  77. package/dist/testing/rn/index.js +444 -0
  78. package/dist/video/index.cjs +1941 -0
  79. package/dist/video/index.d.cts +66 -0
  80. package/dist/video/index.d.ts +66 -0
  81. package/dist/video/index.js +1938 -0
  82. package/package.json +311 -0
  83. package/photo/package.json +8 -0
  84. package/records/package.json +8 -0
  85. package/server/device-blocked.cjs +15 -0
  86. package/server/package.json +9 -0
  87. package/testing/package.json +8 -0
  88. package/testing/rn/package.json +8 -0
  89. package/video/package.json +8 -0
@@ -0,0 +1,224 @@
1
+ import { f as EverfurError, E as EverfurResult } from '../EverfurResult-D92-uL82.cjs';
2
+ export { g as EverfurErrorCategory, a as EverfurErrorCode } from '../EverfurResult-D92-uL82.cjs';
3
+ import { P as PetRef, R as RecordsRequestId, D as DocumentId } from '../ids-CJ1S6adf.cjs';
4
+ export { B as Brand, _ as __brand } from '../ids-CJ1S6adf.cjs';
5
+ import { F as FileHandle } from '../FilePort-BabWrv7I.cjs';
6
+ import { ReactNode } from 'react';
7
+ import { StyleProp, ViewStyle } from 'react-native';
8
+
9
+ /**
10
+ * The partner-scoped projection of the backend records-request status (records_schemas.py). The internal
11
+ * `dispatching` / `parsing_failed` / `review_email_failed` values are already collapsed by the backend
12
+ * `from_db_status`; the clinic-dispatch statuses are out of partner scope (§0) and never appear here.
13
+ */
14
+ type RecordsRequestStatus = 'awaiting_upload' | 'received' | 'parsing' | 'in_review' | 'published' | 'failed' | 'revoked';
15
+ /** Terminal statuses: polling stops here. */
16
+ declare const RECORDS_TERMINAL: readonly RecordsRequestStatus[];
17
+ declare function isTerminalStatus(status: RecordsRequestStatus): boolean;
18
+ interface RecordsRequestView {
19
+ readonly id: RecordsRequestId;
20
+ readonly petRef: PetRef;
21
+ readonly status: RecordsRequestStatus;
22
+ /** BE-authored copy, rendered verbatim (dumb-renderer rule). */
23
+ readonly statusLabel: string;
24
+ /**
25
+ * DEAD, measured 2026-08-22: no plane sends it and nothing in this SDK reads it. The widget
26
+ * `RecordsRequestResponse` omits it, the consumer `RecordsRequestSummary` has no such field either, and a
27
+ * grep of `src/` finds zero render consumers - so it is always the mapper's `0` default.
28
+ *
29
+ * Deliberately NOT deleted here: removing a non-optional public field is a breaking change that needs a
30
+ * major bump, which is a release decision. Documented so nobody reads a count off it.
31
+ */
32
+ readonly documentCount: number;
33
+ /** facts extracted but awaiting review (badge "N being reviewed"). */
34
+ readonly heldItemCount: number;
35
+ /** ISO; null before first upload. */
36
+ readonly receivedAt: string | null;
37
+ /** drives the timeline "reading your records" step. */
38
+ readonly parsingStartedAt: string | null;
39
+ /** non-null == a parse gap occurred (§5, honest, not silent). */
40
+ readonly reviewStartedAt: string | null;
41
+ readonly createdAt: string;
42
+ readonly updatedAt: string;
43
+ }
44
+ interface UploadedDocument {
45
+ readonly documentId: DocumentId;
46
+ readonly requestId: RecordsRequestId;
47
+ /** uploads NEVER auto-bind / auto-publish. */
48
+ readonly status: 'received';
49
+ }
50
+ /** One redacted identity row (name / species / breed / owner-safe field). Provenance absent. */
51
+ interface RecordIdentityField {
52
+ readonly label: string;
53
+ readonly value: string;
54
+ }
55
+ /**
56
+ * Who produced a reading. `owner_reported` is owner-entered (a home scale, typed into the pet profile);
57
+ * `clinic_document` is extracted from a vet document. The two now share one series, so a clinician reading a
58
+ * weight can tell them apart before dosing from it.
59
+ *
60
+ * A value this build does not know folds to `null` (unlabelled), never to a guess - see `normalizeOrigin`.
61
+ * `null` therefore means "the backend did not say", NOT "clinic".
62
+ */
63
+ type RecordOrigin = 'owner_reported' | 'clinic_document';
64
+ /**
65
+ * One extracted clinical fact. No `raw_value` / `source_span` / `source_bbox` / `source_page` /
66
+ * `source_doc_id` / `value_source` / `extraction_method` / `source_precedence` members - `origin` is the only
67
+ * provenance-adjacent field, and it is a display label (see `RecordOrigin`).
68
+ */
69
+ interface RecordEntity {
70
+ readonly key: string;
71
+ readonly category: string;
72
+ readonly label: string;
73
+ readonly value: string | null;
74
+ readonly unit: string | null;
75
+ readonly observedAt: string | null;
76
+ readonly status: string | null;
77
+ /** Who measured it. `null` when the backend did not label it (an older backend never does). */
78
+ readonly origin: RecordOrigin | null;
79
+ }
80
+ interface RecordSeriesPoint {
81
+ readonly at: string;
82
+ readonly value: number | null;
83
+ readonly display: string | null;
84
+ /** Who measured this reading. `null` when the backend did not label it - never assume `clinic_document`. */
85
+ readonly origin: RecordOrigin | null;
86
+ }
87
+ /** A time series of one entity (e.g. a weight trend). */
88
+ interface RecordSeries {
89
+ readonly key: string;
90
+ readonly label: string;
91
+ readonly points: readonly RecordSeriesPoint[];
92
+ }
93
+ /** A forward-looking item (a due vaccine / follow-up). */
94
+ interface RecordForwardItem {
95
+ readonly title: string;
96
+ readonly detail: string | null;
97
+ readonly dueAt: string | null;
98
+ }
99
+ /** Metadata for one source document, keyed by its id. No raw bytes / provenance. */
100
+ interface RecordDocumentMeta {
101
+ readonly docId: string;
102
+ readonly title: string | null;
103
+ readonly pageCount: number | null;
104
+ readonly receivedAt: string | null;
105
+ }
106
+ /**
107
+ * The parsed record, ALREADY partner-redacted server-side (§5). `isEmpty` is the normal pre-parse render;
108
+ * `withheld` is the §5 fail-closed suppression (redaction could not be proven safe) and renders the WITHHELD
109
+ * state, never empty, never raw.
110
+ */
111
+ interface RecordsView {
112
+ readonly petRef: PetRef;
113
+ readonly schemaVersion: string;
114
+ readonly isEmpty: boolean;
115
+ readonly withheld: boolean;
116
+ readonly generatedAt: string | null;
117
+ readonly identity: readonly RecordIdentityField[];
118
+ readonly entities: readonly RecordEntity[];
119
+ readonly entitySeries: readonly RecordSeries[];
120
+ readonly forwardLooking: readonly RecordForwardItem[];
121
+ readonly documents: Readonly<Record<string, RecordDocumentMeta>>;
122
+ /** BE-authored not-medical-advice notice, rendered verbatim. */
123
+ readonly disclaimer: string;
124
+ }
125
+ interface ConsentState {
126
+ readonly petRef: PetRef;
127
+ readonly granted: boolean;
128
+ /** consent-text version the user agreed to. */
129
+ readonly version: string | null;
130
+ readonly grantedAt: string | null;
131
+ }
132
+ interface CreateUploadRequestInput {
133
+ readonly petRef: PetRef;
134
+ /** /^[A-Za-z0-9._-]{8,128}$/ (§3.1). Idempotent: a replay returns the SAME request. */
135
+ readonly idempotencyKey: string;
136
+ }
137
+ interface GrantConsentInput {
138
+ readonly petRef: PetRef;
139
+ readonly consentVersion: string;
140
+ readonly idempotencyKey: string;
141
+ }
142
+ /**
143
+ * Why a records read/write was access-denied (all fold to `EverfurErrorCode = 'accessDenied'`, §7). The
144
+ * coarse reason selects the recovery affordance: `consent_required` -> consent CTA, `session_required` ->
145
+ * establish-session CTA, `entitlement` -> the CapabilityGate disabled surface.
146
+ */
147
+ type RecordsDenialReason = 'consent_required' | 'session_required' | 'entitlement';
148
+ /** Read the records denial reason off any settled error, defensively (null when absent). */
149
+ declare function recordsDenialReasonOf(error: EverfurError | null): RecordsDenialReason | null;
150
+
151
+ interface UploadDocumentInput {
152
+ readonly requestId: RecordsRequestId;
153
+ readonly file: FileHandle;
154
+ readonly onProgress?: (fraction: number) => void;
155
+ readonly signal?: AbortSignal;
156
+ }
157
+ interface RecordsController {
158
+ /** Create the self-upload request. Idempotent on `idempotencyKey`. Lands `awaiting_upload`. */
159
+ createUploadRequest(input: CreateUploadRequestInput): Promise<EverfurResult<RecordsRequestView>>;
160
+ /** Two-phase presigned upload of ONE document (§3.2). Bytes go DIRECT to S3. Resolves at `received`. */
161
+ uploadDocument(input: UploadDocumentInput): Promise<EverfurResult<UploadedDocument>>;
162
+ /** Poll one request's parse lifecycle. */
163
+ getRequest(id: RecordsRequestId): Promise<EverfurResult<RecordsRequestView>>;
164
+ /** All of this user's requests, newest-first (server-ordered). */
165
+ listRequests(): Promise<EverfurResult<readonly RecordsRequestView[]>>;
166
+ /** The parsed, partner-redacted record. Consent-gated + redaction-fail-closed. */
167
+ getRecord(pet: PetRef): Promise<EverfurResult<RecordsView>>;
168
+ /** Consent read-back. Never a hard failure for an absent row -> `granted:false`. */
169
+ getConsent(pet: PetRef): Promise<EverfurResult<ConsentState>>;
170
+ /** Grant content-exposure consent. Fail-closed audited server-side. Idempotent. */
171
+ grantConsent(input: GrantConsentInput): Promise<EverfurResult<ConsentState>>;
172
+ /** Revoke consent (prospective). Drops any cached record for the pet from memory. Idempotent. */
173
+ revokeConsent(pet: PetRef): Promise<EverfurResult<ConsentState>>;
174
+ /** The last record read for a pet, held in memory only; cleared on revoke. Null when none. */
175
+ peekCachedRecord(pet: PetRef): RecordsView | null;
176
+ /** Emit `records.capability.denied` (the rn CapabilityGate disabled surface calls this once, R12). */
177
+ reportCapabilityDenied(pet: PetRef | null): void;
178
+ }
179
+
180
+ type RecordsStatus = 'loading' | 'empty' | 'error' | 'populated';
181
+ interface UseEverfurRecordsState {
182
+ readonly status: RecordsStatus;
183
+ readonly record: RecordsView | null;
184
+ readonly requests: readonly RecordsRequestView[];
185
+ /** the most-recent request, whose timeline the populated state renders. */
186
+ readonly activeRequest: RecordsRequestView | null;
187
+ readonly consent: ConsentState | null;
188
+ readonly error: EverfurError | null;
189
+ /** drives the recovery affordance: consent CTA / establish-session CTA / disabled. */
190
+ readonly denialReason: RecordsDenialReason | null;
191
+ /** §5.1 fail-closed suppression: render the withheld notice, never empty, never raw. */
192
+ readonly withheld: boolean;
193
+ readonly isUploading: boolean;
194
+ readonly uploadProgress: number | null;
195
+ /** Create a self-upload request the user attaches documents to. */
196
+ createRequest(idempotencyKey: string): Promise<EverfurResult<RecordsRequestView>>;
197
+ /** Two-phase presigned upload of one document to the active request. */
198
+ uploadDocument(requestId: RecordsRequestView['id'], file: FileHandle): Promise<EverfurResult<UploadedDocument>>;
199
+ /** Grant content-exposure consent, then fetch the record. */
200
+ grantConsent(consentVersion: string, idempotencyKey: string): Promise<EverfurResult<ConsentState>>;
201
+ /** Revoke consent (prospective); drops the record from view. */
202
+ revokeConsent(): Promise<EverfurResult<ConsentState>>;
203
+ /** Re-run the surface fetch (error retry). */
204
+ refresh(): void;
205
+ }
206
+ declare function useEverfurRecords(opts: {
207
+ readonly petRef: PetRef;
208
+ /** Host/test seam: inject a controller directly instead of acquiring one from the runtime. */
209
+ readonly controller?: RecordsController;
210
+ }): UseEverfurRecordsState;
211
+
212
+ interface EverfurRecordsProps {
213
+ readonly petRef: PetRef;
214
+ /** Host/test seam: inject a controller instead of acquiring one from the runtime. */
215
+ readonly controller?: RecordsController;
216
+ /** Host file picker: resolves a picked FileHandle (native document picker lives in the host app). */
217
+ readonly onPickDocument?: () => Promise<FileHandle | null>;
218
+ /** The consent-text version the grant CTA records (host/product owned). */
219
+ readonly consentVersion?: string;
220
+ readonly style?: StyleProp<ViewStyle>;
221
+ }
222
+ declare function EverfurRecords(props: EverfurRecordsProps): ReactNode;
223
+
224
+ export { type ConsentState, type CreateUploadRequestInput, DocumentId, EverfurError, EverfurRecords, type EverfurRecordsProps, EverfurResult, FileHandle, type GrantConsentInput, PetRef, RECORDS_TERMINAL, type RecordDocumentMeta, type RecordEntity, type RecordForwardItem, type RecordIdentityField, type RecordOrigin, type RecordSeries, type RecordSeriesPoint, type RecordsController, type RecordsDenialReason, RecordsRequestId, type RecordsRequestStatus, type RecordsRequestView, type RecordsStatus, type RecordsView, type UploadDocumentInput, type UploadedDocument, type UseEverfurRecordsState, isTerminalStatus, recordsDenialReasonOf, useEverfurRecords };
@@ -0,0 +1,224 @@
1
+ import { f as EverfurError, E as EverfurResult } from '../EverfurResult-D92-uL82.js';
2
+ export { g as EverfurErrorCategory, a as EverfurErrorCode } from '../EverfurResult-D92-uL82.js';
3
+ import { P as PetRef, R as RecordsRequestId, D as DocumentId } from '../ids-CJ1S6adf.js';
4
+ export { B as Brand, _ as __brand } from '../ids-CJ1S6adf.js';
5
+ import { F as FileHandle } from '../FilePort-BabWrv7I.js';
6
+ import { ReactNode } from 'react';
7
+ import { StyleProp, ViewStyle } from 'react-native';
8
+
9
+ /**
10
+ * The partner-scoped projection of the backend records-request status (records_schemas.py). The internal
11
+ * `dispatching` / `parsing_failed` / `review_email_failed` values are already collapsed by the backend
12
+ * `from_db_status`; the clinic-dispatch statuses are out of partner scope (§0) and never appear here.
13
+ */
14
+ type RecordsRequestStatus = 'awaiting_upload' | 'received' | 'parsing' | 'in_review' | 'published' | 'failed' | 'revoked';
15
+ /** Terminal statuses: polling stops here. */
16
+ declare const RECORDS_TERMINAL: readonly RecordsRequestStatus[];
17
+ declare function isTerminalStatus(status: RecordsRequestStatus): boolean;
18
+ interface RecordsRequestView {
19
+ readonly id: RecordsRequestId;
20
+ readonly petRef: PetRef;
21
+ readonly status: RecordsRequestStatus;
22
+ /** BE-authored copy, rendered verbatim (dumb-renderer rule). */
23
+ readonly statusLabel: string;
24
+ /**
25
+ * DEAD, measured 2026-08-22: no plane sends it and nothing in this SDK reads it. The widget
26
+ * `RecordsRequestResponse` omits it, the consumer `RecordsRequestSummary` has no such field either, and a
27
+ * grep of `src/` finds zero render consumers - so it is always the mapper's `0` default.
28
+ *
29
+ * Deliberately NOT deleted here: removing a non-optional public field is a breaking change that needs a
30
+ * major bump, which is a release decision. Documented so nobody reads a count off it.
31
+ */
32
+ readonly documentCount: number;
33
+ /** facts extracted but awaiting review (badge "N being reviewed"). */
34
+ readonly heldItemCount: number;
35
+ /** ISO; null before first upload. */
36
+ readonly receivedAt: string | null;
37
+ /** drives the timeline "reading your records" step. */
38
+ readonly parsingStartedAt: string | null;
39
+ /** non-null == a parse gap occurred (§5, honest, not silent). */
40
+ readonly reviewStartedAt: string | null;
41
+ readonly createdAt: string;
42
+ readonly updatedAt: string;
43
+ }
44
+ interface UploadedDocument {
45
+ readonly documentId: DocumentId;
46
+ readonly requestId: RecordsRequestId;
47
+ /** uploads NEVER auto-bind / auto-publish. */
48
+ readonly status: 'received';
49
+ }
50
+ /** One redacted identity row (name / species / breed / owner-safe field). Provenance absent. */
51
+ interface RecordIdentityField {
52
+ readonly label: string;
53
+ readonly value: string;
54
+ }
55
+ /**
56
+ * Who produced a reading. `owner_reported` is owner-entered (a home scale, typed into the pet profile);
57
+ * `clinic_document` is extracted from a vet document. The two now share one series, so a clinician reading a
58
+ * weight can tell them apart before dosing from it.
59
+ *
60
+ * A value this build does not know folds to `null` (unlabelled), never to a guess - see `normalizeOrigin`.
61
+ * `null` therefore means "the backend did not say", NOT "clinic".
62
+ */
63
+ type RecordOrigin = 'owner_reported' | 'clinic_document';
64
+ /**
65
+ * One extracted clinical fact. No `raw_value` / `source_span` / `source_bbox` / `source_page` /
66
+ * `source_doc_id` / `value_source` / `extraction_method` / `source_precedence` members - `origin` is the only
67
+ * provenance-adjacent field, and it is a display label (see `RecordOrigin`).
68
+ */
69
+ interface RecordEntity {
70
+ readonly key: string;
71
+ readonly category: string;
72
+ readonly label: string;
73
+ readonly value: string | null;
74
+ readonly unit: string | null;
75
+ readonly observedAt: string | null;
76
+ readonly status: string | null;
77
+ /** Who measured it. `null` when the backend did not label it (an older backend never does). */
78
+ readonly origin: RecordOrigin | null;
79
+ }
80
+ interface RecordSeriesPoint {
81
+ readonly at: string;
82
+ readonly value: number | null;
83
+ readonly display: string | null;
84
+ /** Who measured this reading. `null` when the backend did not label it - never assume `clinic_document`. */
85
+ readonly origin: RecordOrigin | null;
86
+ }
87
+ /** A time series of one entity (e.g. a weight trend). */
88
+ interface RecordSeries {
89
+ readonly key: string;
90
+ readonly label: string;
91
+ readonly points: readonly RecordSeriesPoint[];
92
+ }
93
+ /** A forward-looking item (a due vaccine / follow-up). */
94
+ interface RecordForwardItem {
95
+ readonly title: string;
96
+ readonly detail: string | null;
97
+ readonly dueAt: string | null;
98
+ }
99
+ /** Metadata for one source document, keyed by its id. No raw bytes / provenance. */
100
+ interface RecordDocumentMeta {
101
+ readonly docId: string;
102
+ readonly title: string | null;
103
+ readonly pageCount: number | null;
104
+ readonly receivedAt: string | null;
105
+ }
106
+ /**
107
+ * The parsed record, ALREADY partner-redacted server-side (§5). `isEmpty` is the normal pre-parse render;
108
+ * `withheld` is the §5 fail-closed suppression (redaction could not be proven safe) and renders the WITHHELD
109
+ * state, never empty, never raw.
110
+ */
111
+ interface RecordsView {
112
+ readonly petRef: PetRef;
113
+ readonly schemaVersion: string;
114
+ readonly isEmpty: boolean;
115
+ readonly withheld: boolean;
116
+ readonly generatedAt: string | null;
117
+ readonly identity: readonly RecordIdentityField[];
118
+ readonly entities: readonly RecordEntity[];
119
+ readonly entitySeries: readonly RecordSeries[];
120
+ readonly forwardLooking: readonly RecordForwardItem[];
121
+ readonly documents: Readonly<Record<string, RecordDocumentMeta>>;
122
+ /** BE-authored not-medical-advice notice, rendered verbatim. */
123
+ readonly disclaimer: string;
124
+ }
125
+ interface ConsentState {
126
+ readonly petRef: PetRef;
127
+ readonly granted: boolean;
128
+ /** consent-text version the user agreed to. */
129
+ readonly version: string | null;
130
+ readonly grantedAt: string | null;
131
+ }
132
+ interface CreateUploadRequestInput {
133
+ readonly petRef: PetRef;
134
+ /** /^[A-Za-z0-9._-]{8,128}$/ (§3.1). Idempotent: a replay returns the SAME request. */
135
+ readonly idempotencyKey: string;
136
+ }
137
+ interface GrantConsentInput {
138
+ readonly petRef: PetRef;
139
+ readonly consentVersion: string;
140
+ readonly idempotencyKey: string;
141
+ }
142
+ /**
143
+ * Why a records read/write was access-denied (all fold to `EverfurErrorCode = 'accessDenied'`, §7). The
144
+ * coarse reason selects the recovery affordance: `consent_required` -> consent CTA, `session_required` ->
145
+ * establish-session CTA, `entitlement` -> the CapabilityGate disabled surface.
146
+ */
147
+ type RecordsDenialReason = 'consent_required' | 'session_required' | 'entitlement';
148
+ /** Read the records denial reason off any settled error, defensively (null when absent). */
149
+ declare function recordsDenialReasonOf(error: EverfurError | null): RecordsDenialReason | null;
150
+
151
+ interface UploadDocumentInput {
152
+ readonly requestId: RecordsRequestId;
153
+ readonly file: FileHandle;
154
+ readonly onProgress?: (fraction: number) => void;
155
+ readonly signal?: AbortSignal;
156
+ }
157
+ interface RecordsController {
158
+ /** Create the self-upload request. Idempotent on `idempotencyKey`. Lands `awaiting_upload`. */
159
+ createUploadRequest(input: CreateUploadRequestInput): Promise<EverfurResult<RecordsRequestView>>;
160
+ /** Two-phase presigned upload of ONE document (§3.2). Bytes go DIRECT to S3. Resolves at `received`. */
161
+ uploadDocument(input: UploadDocumentInput): Promise<EverfurResult<UploadedDocument>>;
162
+ /** Poll one request's parse lifecycle. */
163
+ getRequest(id: RecordsRequestId): Promise<EverfurResult<RecordsRequestView>>;
164
+ /** All of this user's requests, newest-first (server-ordered). */
165
+ listRequests(): Promise<EverfurResult<readonly RecordsRequestView[]>>;
166
+ /** The parsed, partner-redacted record. Consent-gated + redaction-fail-closed. */
167
+ getRecord(pet: PetRef): Promise<EverfurResult<RecordsView>>;
168
+ /** Consent read-back. Never a hard failure for an absent row -> `granted:false`. */
169
+ getConsent(pet: PetRef): Promise<EverfurResult<ConsentState>>;
170
+ /** Grant content-exposure consent. Fail-closed audited server-side. Idempotent. */
171
+ grantConsent(input: GrantConsentInput): Promise<EverfurResult<ConsentState>>;
172
+ /** Revoke consent (prospective). Drops any cached record for the pet from memory. Idempotent. */
173
+ revokeConsent(pet: PetRef): Promise<EverfurResult<ConsentState>>;
174
+ /** The last record read for a pet, held in memory only; cleared on revoke. Null when none. */
175
+ peekCachedRecord(pet: PetRef): RecordsView | null;
176
+ /** Emit `records.capability.denied` (the rn CapabilityGate disabled surface calls this once, R12). */
177
+ reportCapabilityDenied(pet: PetRef | null): void;
178
+ }
179
+
180
+ type RecordsStatus = 'loading' | 'empty' | 'error' | 'populated';
181
+ interface UseEverfurRecordsState {
182
+ readonly status: RecordsStatus;
183
+ readonly record: RecordsView | null;
184
+ readonly requests: readonly RecordsRequestView[];
185
+ /** the most-recent request, whose timeline the populated state renders. */
186
+ readonly activeRequest: RecordsRequestView | null;
187
+ readonly consent: ConsentState | null;
188
+ readonly error: EverfurError | null;
189
+ /** drives the recovery affordance: consent CTA / establish-session CTA / disabled. */
190
+ readonly denialReason: RecordsDenialReason | null;
191
+ /** §5.1 fail-closed suppression: render the withheld notice, never empty, never raw. */
192
+ readonly withheld: boolean;
193
+ readonly isUploading: boolean;
194
+ readonly uploadProgress: number | null;
195
+ /** Create a self-upload request the user attaches documents to. */
196
+ createRequest(idempotencyKey: string): Promise<EverfurResult<RecordsRequestView>>;
197
+ /** Two-phase presigned upload of one document to the active request. */
198
+ uploadDocument(requestId: RecordsRequestView['id'], file: FileHandle): Promise<EverfurResult<UploadedDocument>>;
199
+ /** Grant content-exposure consent, then fetch the record. */
200
+ grantConsent(consentVersion: string, idempotencyKey: string): Promise<EverfurResult<ConsentState>>;
201
+ /** Revoke consent (prospective); drops the record from view. */
202
+ revokeConsent(): Promise<EverfurResult<ConsentState>>;
203
+ /** Re-run the surface fetch (error retry). */
204
+ refresh(): void;
205
+ }
206
+ declare function useEverfurRecords(opts: {
207
+ readonly petRef: PetRef;
208
+ /** Host/test seam: inject a controller directly instead of acquiring one from the runtime. */
209
+ readonly controller?: RecordsController;
210
+ }): UseEverfurRecordsState;
211
+
212
+ interface EverfurRecordsProps {
213
+ readonly petRef: PetRef;
214
+ /** Host/test seam: inject a controller instead of acquiring one from the runtime. */
215
+ readonly controller?: RecordsController;
216
+ /** Host file picker: resolves a picked FileHandle (native document picker lives in the host app). */
217
+ readonly onPickDocument?: () => Promise<FileHandle | null>;
218
+ /** The consent-text version the grant CTA records (host/product owned). */
219
+ readonly consentVersion?: string;
220
+ readonly style?: StyleProp<ViewStyle>;
221
+ }
222
+ declare function EverfurRecords(props: EverfurRecordsProps): ReactNode;
223
+
224
+ export { type ConsentState, type CreateUploadRequestInput, DocumentId, EverfurError, EverfurRecords, type EverfurRecordsProps, EverfurResult, FileHandle, type GrantConsentInput, PetRef, RECORDS_TERMINAL, type RecordDocumentMeta, type RecordEntity, type RecordForwardItem, type RecordIdentityField, type RecordOrigin, type RecordSeries, type RecordSeriesPoint, type RecordsController, type RecordsDenialReason, RecordsRequestId, type RecordsRequestStatus, type RecordsRequestView, type RecordsStatus, type RecordsView, type UploadDocumentInput, type UploadedDocument, type UseEverfurRecordsState, isTerminalStatus, recordsDenialReasonOf, useEverfurRecords };