dataspace-client-sdk-node 0.1.1

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 (56) hide show
  1. package/README.md +310 -0
  2. package/SDK_PARITY_MAP.md +120 -0
  3. package/TODO_PROMPT_NEXT_STEPS.md +185 -0
  4. package/artifacts/update-smart-wallet.js +1016 -0
  5. package/dist/builders.d.ts +12 -0
  6. package/dist/builders.js +17 -0
  7. package/dist/client.d.ts +333 -0
  8. package/dist/client.js +1229 -0
  9. package/dist/consent/pdfSignatureVerification.d.ts +18 -0
  10. package/dist/consent/pdfSignatureVerification.js +23 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +8 -0
  13. package/dist/sdk/dataspace-wallet-sdk-node/MultiWalletClient.d.ts +9 -0
  14. package/dist/sdk/dataspace-wallet-sdk-node/MultiWalletClient.js +21 -0
  15. package/dist/sdk/dataspace-wallet-sdk-node/WalletClient.d.ts +26 -0
  16. package/dist/sdk/dataspace-wallet-sdk-node/WalletClient.js +36 -0
  17. package/dist/sdk/dataspace-wallet-sdk-node/index.d.ts +6 -0
  18. package/dist/sdk/dataspace-wallet-sdk-node/index.js +6 -0
  19. package/dist/sdk/dataspace-wallet-sdk-node/provider.d.ts +24 -0
  20. package/dist/sdk/dataspace-wallet-sdk-node/provider.js +1 -0
  21. package/dist/sdk/dataspace-wallet-sdk-node/providers/memory-provider.d.ts +41 -0
  22. package/dist/sdk/dataspace-wallet-sdk-node/providers/memory-provider.js +216 -0
  23. package/dist/sdk/dataspace-wallet-sdk-node/providers/seed-provider.d.ts +22 -0
  24. package/dist/sdk/dataspace-wallet-sdk-node/providers/seed-provider.js +28 -0
  25. package/dist/sdk/dataspace-wallet-sdk-node/types.d.ts +51 -0
  26. package/dist/sdk/dataspace-wallet-sdk-node/types.js +1 -0
  27. package/dist/types.d.ts +445 -0
  28. package/dist/types.js +1 -0
  29. package/docs/API.md +745 -0
  30. package/docs/DATA_MODEL_ALIGNMENT.md +31 -0
  31. package/docs/DATA_PLANES_SCOPE_MATRIX.md +51 -0
  32. package/docs/DEVELOPER_USE_CASES.md +253 -0
  33. package/docs/E2E_BOOTSTRAP.md +54 -0
  34. package/docs/TODO_SMART_EHR_COMPAT.md +58 -0
  35. package/examples/backend-pkce-auth.mjs +119 -0
  36. package/examples/conversion-upload.mjs +52 -0
  37. package/examples/e2e-bootstrap-tenant.mjs +126 -0
  38. package/examples/e2e-individual-flow.mjs +43 -0
  39. package/examples/host-activate-and-employee.mjs +75 -0
  40. package/package.json +26 -0
  41. package/src/builders.ts +28 -0
  42. package/src/client.ts +1626 -0
  43. package/src/consent/pdfSignatureVerification.ts +41 -0
  44. package/src/index.ts +8 -0
  45. package/src/sdk/dataspace-wallet-sdk-node/MultiWalletClient.ts +25 -0
  46. package/src/sdk/dataspace-wallet-sdk-node/WalletClient.ts +63 -0
  47. package/src/sdk/dataspace-wallet-sdk-node/index.ts +6 -0
  48. package/src/sdk/dataspace-wallet-sdk-node/provider.ts +44 -0
  49. package/src/sdk/dataspace-wallet-sdk-node/providers/memory-provider.ts +310 -0
  50. package/src/sdk/dataspace-wallet-sdk-node/providers/seed-provider.ts +31 -0
  51. package/src/sdk/dataspace-wallet-sdk-node/types.ts +61 -0
  52. package/src/types.ts +497 -0
  53. package/tests/client.test.mjs +892 -0
  54. package/tests/uc5-org-onboarding.flow.test.mjs +145 -0
  55. package/tests/uc5-subject-data.flow.test.mjs +198 -0
  56. package/tsconfig.json +13 -0
package/src/types.ts ADDED
@@ -0,0 +1,497 @@
1
+ import type { WalletProvider } from './sdk/dataspace-wallet-sdk-node/provider.js';
2
+ import type { PublicJwk, WalletContext } from './sdk/dataspace-wallet-sdk-node/types.js';
3
+
4
+ export type DidcommPlainMessage = {
5
+ jti: string;
6
+ thid: string;
7
+ iss: string;
8
+ aud: string;
9
+ type: string;
10
+ body: Record<string, unknown>;
11
+ meta?: Record<string, unknown>;
12
+ };
13
+
14
+ export type AsyncPollRequest = {
15
+ thid: string;
16
+ };
17
+
18
+ export type RouteContext = {
19
+ tenantId: string;
20
+ jurisdiction: string;
21
+ sector: string;
22
+ };
23
+
24
+ export type V1Section = 'registry' | 'entity' | 'identity' | 'individual' | 'digitaltwin' | string;
25
+
26
+ export type V1Action =
27
+ | '_batch'
28
+ | '_search'
29
+ | '_search-response'
30
+ | '_batch-response'
31
+ | '_activate'
32
+ | '_activate-response'
33
+ | '_dcr'
34
+ | '_dcr-response'
35
+ | '_exchange'
36
+ | '_exchange-response'
37
+ | '_issue'
38
+ | 'token'
39
+ | 'token-response'
40
+ | '_custom'
41
+ | '_custom-response'
42
+ | string;
43
+
44
+ export type HostRouteContext = {
45
+ jurisdiction: string;
46
+ sector: string;
47
+ };
48
+
49
+ export type SubmitResponse = {
50
+ status: number;
51
+ location?: string;
52
+ body: unknown;
53
+ };
54
+
55
+ export type PollOptions = {
56
+ timeoutMs?: number;
57
+ intervalMs?: number;
58
+ };
59
+
60
+ export type PollResult = {
61
+ status: number;
62
+ body: unknown;
63
+ attempts: number;
64
+ };
65
+
66
+ export type SubmitAndPollResult = {
67
+ submit: SubmitResponse;
68
+ poll: PollResult;
69
+ };
70
+
71
+ /** Status of a family-organization registration lookup or create attempt. */
72
+ export type FamilyRegistrationStatus = 'new_created' | 'resume_required' | 'already_exists' | 'not_found';
73
+
74
+ /**
75
+ * Minimal reference to a SubjectOrganization — the identity root for a subject.
76
+ * Any field can serve as a resolution key. `organizationId` and `did` are canonical;
77
+ * `telephone` + `nickname` are composite lookup keys used during onboarding.
78
+ */
79
+ export type SubjectOrganizationRef = {
80
+ /** Vault UUID of the org.schema/Organization resource. */
81
+ organizationId?: string;
82
+ /** Decentralized identifier: did:web:...individual:<id> */
83
+ did?: string;
84
+ /** E.164 phone — used as resolution key during registration (`org.schema.Organization.owner.telephone`). */
85
+ telephone?: string;
86
+ /** `org.schema.Organization.alternateName` (nickname / usualname). */
87
+ nickname?: string;
88
+ /** Optional ISO-8601 date (`org.schema.Organization.foundingDate`) — used as tiebreaker during lookup. */
89
+ birthDate?: string;
90
+ };
91
+
92
+ /**
93
+ * Granular access domain for a SubjectOrganization.
94
+ *
95
+ * Health sub-domains map to FHIR Level 4 Record-keeping and Data Exchange categories:
96
+ * health.clinical — Condition, Procedure, AllergyIntolerance, FamilyMemberHistory, …
97
+ * health.diagnostics — Observation, DiagnosticReport, ImagingStudy, Specimen, …
98
+ * health.genomics — MolecularSequence, GenomicStudy, …
99
+ * health.medications — MedicationRequest, MedicationStatement, MedicationDispense, …
100
+ * health.workflow — Appointment, Task, ServiceRequest, CarePlan, …
101
+ * health.financial — Claim, Coverage, ExplanationOfBenefit, …
102
+ *
103
+ * TODO: Clinical and diagnostics sub-domain must define LOINC codes for specific health sections:
104
+ * - Document section codes (LOINC codes used in CCDA sections).
105
+ * - See https://hl7.org/fhir/valueset-doc-section-codes.html
106
+ * 10154-3 Chief complaint Narrative - Reported
107
+ * 10157-6 History of family member diseases Narrative
108
+ * 10160-0 History of Medication use Narrative
109
+ * 10164-2 History of Present illness Narrative
110
+ * 10183-2 Hospital discharge medications Narrative
111
+ * 10184-0 Hospital discharge physical findings Narrative
112
+ * 10187-3 Review of systems Narrative - Reported
113
+ * 10210-3 Physical findings of General status Narrative
114
+ * 10216-0 Surgical operation note fluids Narrative
115
+ * 10218-6 Surgical operation note postoperative diagnosis Narrative
116
+ * 10223-6 Surgical operation note surgical procedure Narrative
117
+ * 10222-8 Surgical operation note surgical complications [Interpretation] Narrative
118
+ * 11329-0 History general Narrative - Reported
119
+ * 11348-0 History of Past illness Narrative
120
+ * 11369-6 History of Immunization Narrative
121
+ * 57852-6 Problem list Narrative - Reported
122
+ * 11493-4 Hospital discharge studies summary Narrative
123
+ * 11535-2 Hospital discharge Dx Narrative
124
+ * 11537-8 Surgical drains Narrative
125
+ * 18776-5 Plan of care note
126
+ * 18841-7 Hospital consultations Document
127
+ * 29299-5 Reason for visit Narrative
128
+ * 29545-1 Physical findings Narrative
129
+ * 29549-3 Medication administered Narrative
130
+ * 29554-3 Procedure Narrative
131
+ * 29762-2 Social history Narrative
132
+ * 30954-2 Relevant diagnostic tests/laboratory data Narrative
133
+ * 42344-2 Discharge diet (narrative)
134
+ * 42346-7 Medications on admission (narrative)
135
+ * 42348-3 Advance directives
136
+ * 42349-1 Reason for referral (narrative)
137
+ * 46240-8 History of Hospitalizations+Outpatient visits Narrative
138
+ * 46241-6 Hospital admission diagnosis Narrative - Reported
139
+ * 46264-8 History of medical device use
140
+ * 47420-5 Functional status assessment note
141
+ * 47519-4 History of Procedures Document
142
+ * 48765-2 Allergies and adverse reactions Document
143
+ * 48768-6 Payment sources Document
144
+ * 51848-0 Evaluation note
145
+ * 55109-3 Complications Document
146
+ * 55122-6 Surgical operation note implants Narrative
147
+ * 59768-2 Procedure indications [Interpretation] Narrative
148
+ * 59769-0 Postprocedure diagnosis Narrative
149
+ * 59770-8 Procedure estimated blood loss Narrative
150
+ * 59771-6 Procedure implants Narrative
151
+ * 59772-4 Planned procedure Narrative
152
+ * 59773-2 Procedure specimens taken Narrative
153
+ * 59775-7 Procedure disposition Narrative
154
+ * 59776-5 Procedure findings Narrative
155
+ * 61149-1 Objective Narrative
156
+ * 61150-9 Subjective Narrative
157
+ * 69730-0 Instructions
158
+ * 8648-8 Hospital course Narrative
159
+ * 8653-8 Hospital Discharge instructions
160
+ * 8716-3 Vital signs
161
+ */
162
+ export type AccessDomain =
163
+ | 'health.clinical'
164
+ | 'health.diagnostics'
165
+ | 'health.genomics'
166
+ | 'health.medications'
167
+ | 'health.workflow'
168
+ | 'health.financial';
169
+ /**
170
+ * Resolved access context for an actor operating on a SubjectOrganization.
171
+ * Controller has default access to all domains; this can be restricted per consent.
172
+ */
173
+ export type SubjectOrganizationAccessContext = {
174
+ subjectOrganization: SubjectOrganizationRef;
175
+ /** DID or phone of the actor (controller, caregiver, self, professional). */
176
+ controllerActorRef?: string;
177
+ /** Domains the actor is currently authorized to access. */
178
+ grantedDomains: AccessDomain[];
179
+ /** SMART bearer token (issued when backend supports subject-scoped organization tokens). */
180
+ accessToken?: string;
181
+ /** ID of the default consent rule bootstrapped for this controller. */
182
+ consentId?: string;
183
+ /** Lifecycle state of the access context. */
184
+ status?: 'ready' | 'consent_pending' | 'token_pending';
185
+ };
186
+
187
+ /** Summary returned by `searchFamilyOrganization` or parsed from a family `_batch` response. */
188
+ export type FamilyOrganizationSummary = {
189
+ status: FamilyRegistrationStatus;
190
+ offerId?: string;
191
+ organizationId?: string;
192
+ /** Subject identity snapshot. Shares the same shape as SubjectOrganizationRef. */
193
+ subjectInfo?: SubjectOrganizationRef;
194
+ missingFields?: string[];
195
+ updatedAt?: string;
196
+ };
197
+
198
+ /**
199
+ * Input for organization activation in GW using ICA-derived proof material.
200
+ *
201
+ * `vpToken` is required because GW activation validates the VP proof.
202
+ * VC and regulatory evidence are optional enrichments used by policy/business checks.
203
+ */
204
+ export type GatewayOrganizationActivationInput = {
205
+ vpToken: string;
206
+ organizationVc?: string;
207
+ legalRepresentativeVc?: string;
208
+ regulatoryEvidence?: Record<string, unknown>;
209
+ additionalClaims?: Record<string, unknown>;
210
+ };
211
+
212
+ /**
213
+ * Input for device activation based on activation code exchange + DCR.
214
+ */
215
+ export type EmployeeDeviceActivationInput = {
216
+ activationCode: string;
217
+ idToken: string;
218
+ dcrPayload: Record<string, unknown>;
219
+ pollOptions?: PollOptions;
220
+ };
221
+
222
+ /**
223
+ * Result of device activation flow.
224
+ *
225
+ * - `exchange` is the Token/_exchange submit+poll result.
226
+ * - `dcr` is the Device/_dcr submit+poll result.
227
+ */
228
+ export type EmployeeDeviceActivationResult = {
229
+ initialAccessToken: string;
230
+ exchange: SubmitAndPollResult;
231
+ dcr: SubmitAndPollResult;
232
+ };
233
+
234
+ /**
235
+ * Input for UC 5.3 organization employee creation.
236
+ */
237
+ export type OrganizationEmployeeCreationInput = {
238
+ employeeClaims: Record<string, unknown>;
239
+ dataType?: string;
240
+ };
241
+
242
+ /**
243
+ * Input for UC 5.1 subject organization bootstrap.
244
+ */
245
+ export type SubjectOrganizationBootstrapInput = {
246
+ registrationPayload: { thid?: string } & Record<string, unknown>;
247
+ confirmationPayload?: { thid?: string } & Record<string, unknown>;
248
+ pollOptions?: PollOptions;
249
+ };
250
+
251
+ /**
252
+ * Result for UC 5.1 subject organization bootstrap.
253
+ */
254
+ export type SubjectOrganizationBootstrapResult = {
255
+ registration: SubmitAndPollResult;
256
+ confirmation?: SubmitAndPollResult;
257
+ };
258
+
259
+ /**
260
+ * Input for UC 5.5 IPS/FHIR import and index update.
261
+ */
262
+ export type IpsOrFhirImportInput = {
263
+ compositionPayload: { thid?: string } & Record<string, unknown>;
264
+ format?: 'api' | 'r4';
265
+ pollOptions?: PollOptions;
266
+ };
267
+
268
+ export type ConsentActorTargetInput = {
269
+ /** Canonical actor identifier (did:web:..., urn:taxid:..., urn:tel:..., email, etc.). */
270
+ identifier?: string;
271
+ /** Preferred URL/domain alias resolved to did:web:<host>. */
272
+ url?: string;
273
+ /** Legacy alias kept for backwards compatibility. */
274
+ didWeb?: string;
275
+ /** Legacy alias kept for backwards compatibility. */
276
+ organizationUrl?: string;
277
+ organizationTaxId?: string;
278
+ email?: string;
279
+ phone?: string;
280
+ };
281
+
282
+ /**
283
+ * Input for UC 5.6 consent submission from minimal frontend fields.
284
+ */
285
+ export type GrantProfessionalAccessSimpleInput = {
286
+ subjectDid?: string;
287
+ subjectPhone?: string;
288
+ subjectGivenName?: string;
289
+ actor: ConsentActorTargetInput;
290
+ actorRole: string;
291
+ purpose: string;
292
+ actions: string[];
293
+ consentIdentifier?: string;
294
+ consentDate?: string;
295
+ decision?: 'permit' | 'deny';
296
+ attachmentContentType?: string;
297
+ attachmentBase64?: string;
298
+ dataType?: string;
299
+ pollOptions?: PollOptions;
300
+ };
301
+
302
+ export type GrantProfessionalAccessSimpleResult = {
303
+ thid: string;
304
+ consent: SubmitAndPollResult;
305
+ subjectIdentifier: string;
306
+ actorIdentifier: string;
307
+ consentClaims: Record<string, unknown>;
308
+ claimsCid?: string;
309
+ };
310
+
311
+ /**
312
+ * Input for UC 5.7 digital twin generation from subject data.
313
+ */
314
+ export type DigitalTwinGenerationInput = {
315
+ compositionPayload: { thid?: string } & Record<string, unknown>;
316
+ format?: 'api' | 'r4';
317
+ pollOptions?: PollOptions;
318
+ };
319
+
320
+ export type PhoneReminderWindowInput = {
321
+ offsetMinutes: number;
322
+ remindAt: string;
323
+ };
324
+
325
+ export type CreatePhoneReminderTasksInput = {
326
+ windows: PhoneReminderWindowInput[];
327
+ locale?: string;
328
+ /**
329
+ * Optional snapshot/fallback phone for the subject.
330
+ *
331
+ * Canonical resolution should come from `subjectRef` (UUID/resource reference)
332
+ * in backend task execution. Provide this only when you explicitly want to
333
+ * persist a denormalized value for audit/fallback or to avoid lookup at runtime.
334
+ */
335
+ notificationPhone?: string;
336
+ /**
337
+ * Optional snapshot/fallback phone for the controller/owner.
338
+ *
339
+ * Canonical resolution should come from `ownerRef` (e.g. did:web / RelatedPerson ref)
340
+ * in backend task execution. Provide this only for audit/fallback/optimization.
341
+ */
342
+ controllerPhone?: string;
343
+ subjectRef: string;
344
+ ownerRef: string;
345
+ focusRef: string;
346
+ subjectDisplay?: string;
347
+ /**
348
+ * Context summary for what this reminder is based on
349
+ * (appointment, medication schedule, or another domain event).
350
+ * Mapped to Task claim `based-on-display`.
351
+ */
352
+ reminderSummary?: string;
353
+ /**
354
+ * @deprecated Use `reminderSummary` instead.
355
+ */
356
+ appointmentSummary?: string;
357
+ callSid?: string;
358
+ dataType?: string;
359
+ /**
360
+ * Short task title (e.g. "Reminder phone call", "Medication reminder").
361
+ * Mapped to Task resource `description`.
362
+ */
363
+ description?: string;
364
+ maxAttempts?: number;
365
+ };
366
+
367
+ export type MedicationIntakeTimeInput = {
368
+ /** HH:mm (24h), example: 08:00 */
369
+ hhmm: string;
370
+ };
371
+
372
+ /** Canonical flat claim shape: `<ResourceType>.<concrete-param>` */
373
+ export type FlatInteroperableClaims = Record<`${string}.${string}`, unknown>;
374
+
375
+ export type MedicationOverlapCheckInput = {
376
+ subjectRef: string;
377
+ /** Canonical flat claims (FHIR-style, lowercase/hyphen params). */
378
+ claims?: FlatInteroperableClaims;
379
+ startDate: string;
380
+ endDate?: string;
381
+ intakeTimes: MedicationIntakeTimeInput[];
382
+ repeatIntervalHhmm?: string;
383
+ maxDailyIntakes?: number;
384
+ /**
385
+ * Optional tolerance in minutes for "same-time" collision.
386
+ * If omitted, backend default policy applies.
387
+ */
388
+ overlapToleranceMinutes?: number;
389
+ };
390
+
391
+ export type MedicationRegistrationInput = {
392
+ locale?: string;
393
+ subjectRef: string;
394
+ ownerRef: string;
395
+ notificationPhone?: string;
396
+ controllerPhone?: string;
397
+ /** Canonical flat claims (FHIR-style, lowercase/hyphen params). */
398
+ claims?: FlatInteroperableClaims;
399
+ medicationDescription?: string;
400
+ doseValue?: string;
401
+ doseUnitOrFormCode?: string;
402
+ intakeTimes?: MedicationIntakeTimeInput[];
403
+ repeatIntervalHhmm?: string;
404
+ maxDailyIntakes?: number;
405
+ startDate?: string;
406
+ durationDays?: number;
407
+ endDate?: string;
408
+ maxAttempts?: number;
409
+ };
410
+
411
+ export type ClientOptions = {
412
+ baseUrl: string;
413
+ bearerToken?: string;
414
+ defaultHeaders?: Record<string, string>;
415
+ wallet?: WalletProvider;
416
+ };
417
+
418
+ /**
419
+ * Options for identity-exchange.v1 backend PKCE + token exchange flow.
420
+ * Equivalent to Python connector_sdk `authenticate_backend_pkce_and_exchange`.
421
+ */
422
+ export type BackendPkceAuthOptions = {
423
+ /** Route context providing tenantId, jurisdiction, sector. */
424
+ ctx: RouteContext;
425
+ /** API key issued by ICA for this service (used as client_id in DCR). */
426
+ apiKey: string;
427
+ /**
428
+ * Service public JWK bound to the API key via DCR.
429
+ * Optional when the client was constructed with a wallet provider.
430
+ */
431
+ controllerPublicJwk?: PublicJwk | Record<string, unknown>;
432
+ /**
433
+ * Optional wallet resolution context when it differs from `ctx`.
434
+ * Defaults to the route context values.
435
+ */
436
+ walletContext?: WalletContext;
437
+ /** Requested scopes for the SMART bearer token. */
438
+ scopes: string[];
439
+ /** Cache key for the resulting bearer token. Defaults to `pkce:<apiKey prefix>`. */
440
+ endpointId?: string;
441
+ /** PKCE code verifier. Auto-generated with randomUUID if not provided. */
442
+ codeVerifier?: string;
443
+ /** Polling options for each async step. */
444
+ pollOptions?: PollOptions;
445
+ };
446
+
447
+ export type BackendPkceAuthResult = {
448
+ /** `fetched`: new token obtained. `cached`: valid token already in cache. `failed`: flow error. */
449
+ status: 'fetched' | 'cached' | 'failed';
450
+ endpointId: string;
451
+ accessToken: string;
452
+ tokenType: string;
453
+ scopes: string[];
454
+ /** Present on failure: name of the step that failed (`_dcr`, `_code`, `_token`, `_exchange`). */
455
+ step?: string;
456
+ };
457
+
458
+ export type BackendSmartAuthOptions = {
459
+ clientId: string;
460
+ scopes: string[];
461
+ endpointId?: string;
462
+ tokenUrl?: string;
463
+ tokenPath?: string;
464
+ audience?: string;
465
+ assertionTtlSeconds?: number;
466
+ additionalTokenFields?: Record<string, string>;
467
+ publicJwk?: PublicJwk | Record<string, unknown>;
468
+ walletContext?: WalletContext;
469
+ };
470
+
471
+ export type BackendSmartAuthResult = {
472
+ status: 'fetched' | 'cached' | 'failed';
473
+ profile: 'smart-backend.v1';
474
+ endpointId: string;
475
+ accessToken?: string;
476
+ tokenType?: string;
477
+ scopes?: string[];
478
+ expiresAt?: string;
479
+ statusCode?: number;
480
+ response?: unknown;
481
+ };
482
+
483
+ export type SmartTokenExchangeInput = {
484
+ endpointId: string;
485
+ scopes: string[];
486
+ exchangePayload: Record<string, unknown>;
487
+ path?: string;
488
+ };
489
+
490
+ export type SmartTokenExchangeResult = {
491
+ status: 'fetched' | 'cached' | 'failed';
492
+ accessToken?: string;
493
+ tokenType?: string;
494
+ scopes?: string[];
495
+ statusCode?: number;
496
+ response?: unknown;
497
+ };