gdc-sdk-node-ts 0.9.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -2
- package/dist/backend-profile-runtime.d.ts +214 -0
- package/dist/backend-profile-runtime.js +436 -0
- package/dist/consent-claim-helpers.d.ts +2 -1
- package/dist/constants/lifecycle.d.ts +1 -0
- package/dist/constants/lifecycle.js +2 -0
- package/dist/gdc-session-bridge.js +6 -2
- package/dist/host-onboarding.d.ts +6 -39
- package/dist/host-onboarding.js +8 -38
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/individual-controller-backend-runtime.d.ts +46 -0
- package/dist/individual-controller-backend-runtime.js +53 -0
- package/dist/individual-onboarding.d.ts +1 -0
- package/dist/individual-onboarding.js +1 -0
- package/dist/individual-start.d.ts +1 -10
- package/dist/legacy-compat.d.ts +2 -0
- package/dist/legacy-compat.js +1 -0
- package/dist/node-runtime-client.d.ts +141 -10
- package/dist/node-runtime-client.js +337 -26
- package/dist/orchestration/client-port.d.ts +46 -2
- package/dist/orchestration/host-onboarding-sdk.d.ts +16 -4
- package/dist/orchestration/host-onboarding-sdk.js +22 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +41 -1
- package/dist/orchestration/individual-controller-sdk.js +58 -0
- package/dist/orchestration/organization-controller-sdk.d.ts +79 -2
- package/dist/orchestration/organization-controller-sdk.js +101 -0
- package/dist/orchestration/personal-sdk.d.ts +19 -1
- package/dist/orchestration/personal-sdk.js +36 -0
- package/dist/orchestration/professional-sdk.d.ts +6 -1
- package/dist/orchestration/professional-sdk.js +7 -0
- package/dist/order-offer-summary.d.ts +6 -0
- package/dist/order-offer-summary.js +11 -0
- package/dist/organization-license-order.d.ts +40 -0
- package/dist/organization-license-order.js +42 -0
- package/dist/resource-operations.d.ts +204 -1
- package/dist/resource-operations.js +213 -14
- package/dist/session.js +1 -1
- package/package.json +17 -4
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { ActorKinds } from 'gdc-common-utils-ts/constants/actor-session';
|
|
3
|
+
import { ProfileAppTypes } from 'gdc-common-utils-ts/constants';
|
|
4
|
+
import { JobStatus } from 'gdc-common-utils-ts/models/confidential-job';
|
|
5
|
+
import { buildActorSessionDescriptorForActorKind, expandActorSessionDescriptorToFacades, prepareLoadedActorProfile, prepareLoadProfile, } from 'gdc-sdk-core-ts';
|
|
6
|
+
import { createActorSessionsFromFacades } from './gdc-session-bridge.js';
|
|
7
|
+
export const BackendSubjectIndexReadModes = Object.freeze({
|
|
8
|
+
LatestIps: 'latest-ips',
|
|
9
|
+
ClinicalBundle: 'clinical-bundle',
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Default backend-generic runtime implementation backed by injected adapters.
|
|
13
|
+
*
|
|
14
|
+
* This class is the first concrete v2 slice intended for backend consumers that
|
|
15
|
+
* need one reusable actor-aware profile runtime after authentication.
|
|
16
|
+
*/
|
|
17
|
+
export class BackendProfileRuntime {
|
|
18
|
+
constructor(adapters, options = {}) {
|
|
19
|
+
this.adapters = adapters;
|
|
20
|
+
this.options = options;
|
|
21
|
+
}
|
|
22
|
+
async loadProfile(input) {
|
|
23
|
+
const loadedProfile = await this.adapters.loadProfile(input);
|
|
24
|
+
return {
|
|
25
|
+
...loadedProfile,
|
|
26
|
+
actorSessions: createActorSessionsFromFacades(loadedProfile.facades, this.options.facadeClient),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async closeProfile(_profileKey) { }
|
|
30
|
+
async registerTrustedDevice(input) {
|
|
31
|
+
return this.adapters.registerTrustedDevice(input);
|
|
32
|
+
}
|
|
33
|
+
async connectToSubjectIndex(input) {
|
|
34
|
+
return this.adapters.connectToSubjectIndex(input);
|
|
35
|
+
}
|
|
36
|
+
async getSubjectIndexComposition(input) {
|
|
37
|
+
return this.adapters.getSubjectIndexComposition(input);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Current concrete backend profile runtime over one injected runtime client.
|
|
42
|
+
*
|
|
43
|
+
* This is the pragmatic v2 bridge for backend consumers that already possess
|
|
44
|
+
* an authenticated `RuntimeClient` and need `loadProfile(...)` to materialize
|
|
45
|
+
* actor facades immediately against the current GW CORE contract.
|
|
46
|
+
*/
|
|
47
|
+
export class DirectBackendProfileRuntime {
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.loadedProfiles = new Map();
|
|
50
|
+
this.options = options;
|
|
51
|
+
}
|
|
52
|
+
async loadProfile(input) {
|
|
53
|
+
const normalized = prepareLoadProfile(input);
|
|
54
|
+
const profileId = String(normalized.profileId
|
|
55
|
+
|| normalized.profileDid
|
|
56
|
+
|| normalized.subjectDid
|
|
57
|
+
|| normalized.providerDid).trim();
|
|
58
|
+
const resolvedAppType = normalized.appType || ProfileAppTypes.Family;
|
|
59
|
+
const descriptor = {
|
|
60
|
+
profileId,
|
|
61
|
+
actorKind: normalized.actorKind,
|
|
62
|
+
actorRole: normalized.actorRole,
|
|
63
|
+
providerDid: normalized.providerDid,
|
|
64
|
+
runtimeClass: normalized.runtimeClass,
|
|
65
|
+
profileDid: normalized.profileDid,
|
|
66
|
+
subjectDid: normalized.subjectDid,
|
|
67
|
+
email: normalized.email,
|
|
68
|
+
phone: normalized.phone,
|
|
69
|
+
deviceDid: normalized.deviceDid,
|
|
70
|
+
appType: resolvedAppType,
|
|
71
|
+
};
|
|
72
|
+
const session = buildActorSessionDescriptorForActorKind({
|
|
73
|
+
actorKind: normalized.actorKind,
|
|
74
|
+
appType: resolvedAppType,
|
|
75
|
+
profileId: descriptor.profileId,
|
|
76
|
+
profileDid: descriptor.profileDid,
|
|
77
|
+
role: descriptor.actorRole,
|
|
78
|
+
});
|
|
79
|
+
const facades = expandActorSessionDescriptorToFacades(session);
|
|
80
|
+
const jobManager = this.options.createJobManager
|
|
81
|
+
? this.options.createJobManager(descriptor, normalized)
|
|
82
|
+
: createJobManagerInMemory(descriptor);
|
|
83
|
+
const loadedProfile = prepareLoadedActorProfile({
|
|
84
|
+
descriptor,
|
|
85
|
+
session,
|
|
86
|
+
facades,
|
|
87
|
+
jobManager,
|
|
88
|
+
});
|
|
89
|
+
const backendProfile = {
|
|
90
|
+
...loadedProfile,
|
|
91
|
+
actorSessions: createActorSessionsFromFacades(loadedProfile.facades, this.options.facadeClient),
|
|
92
|
+
};
|
|
93
|
+
this.rememberLoadedProfile(backendProfile);
|
|
94
|
+
return backendProfile;
|
|
95
|
+
}
|
|
96
|
+
async closeProfile(profileKey) {
|
|
97
|
+
const profile = this.resolveLoadedProfile(profileKey);
|
|
98
|
+
profile.jobManager.shutdown();
|
|
99
|
+
this.forgetLoadedProfile(profile);
|
|
100
|
+
}
|
|
101
|
+
async registerTrustedDevice(input) {
|
|
102
|
+
if (this.options.registerTrustedDevice) {
|
|
103
|
+
return this.options.registerTrustedDevice(input);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
trustedDeviceId: input.deviceDid,
|
|
107
|
+
status: 'already-trusted',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
async connectToSubjectIndex(input) {
|
|
111
|
+
if (this.options.connectToSubjectIndex) {
|
|
112
|
+
return this.options.connectToSubjectIndex(input);
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
subjectId: input.subjectId,
|
|
116
|
+
userId: input.userId,
|
|
117
|
+
userRoleCode: input.userRoleCode,
|
|
118
|
+
status: 'already-connected',
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async getSubjectIndexComposition(input) {
|
|
122
|
+
if (this.options.getSubjectIndexComposition) {
|
|
123
|
+
return this.options.getSubjectIndexComposition(input);
|
|
124
|
+
}
|
|
125
|
+
const routeContext = this.options.defaultRouteContext;
|
|
126
|
+
if (!routeContext) {
|
|
127
|
+
throw new Error('DirectBackendProfileRuntime requires defaultRouteContext to read subject index data.');
|
|
128
|
+
}
|
|
129
|
+
const profile = this.resolveLoadedProfile(input.userId);
|
|
130
|
+
if (profile.descriptor.actorKind !== ActorKinds.IndividualController) {
|
|
131
|
+
throw new Error(`DirectBackendProfileRuntime currently resolves subject index reads through IndividualController only, not '${profile.descriptor.actorKind}'.`);
|
|
132
|
+
}
|
|
133
|
+
const sdk = requireBackendIndividualControllerSdk(profile);
|
|
134
|
+
if (this.options.subjectIndexReadMode === BackendSubjectIndexReadModes.ClinicalBundle) {
|
|
135
|
+
const searchResult = await sdk.searchClinicalBundle(routeContext, {
|
|
136
|
+
subject: input.subjectId,
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
subjectId: input.subjectId,
|
|
140
|
+
userId: input.userId,
|
|
141
|
+
userRoleCode: input.userRoleCode,
|
|
142
|
+
composition: searchResult.poll.body,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const latestIps = await sdk.getLatestIps(routeContext, {
|
|
146
|
+
subject: input.subjectId,
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
subjectId: input.subjectId,
|
|
150
|
+
userId: input.userId,
|
|
151
|
+
userRoleCode: input.userRoleCode,
|
|
152
|
+
composition: latestIps.poll.body,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
rememberLoadedProfile(profile) {
|
|
156
|
+
const keys = new Set([
|
|
157
|
+
profile.descriptor.profileId,
|
|
158
|
+
String(profile.descriptor.profileDid || '').trim(),
|
|
159
|
+
String(profile.descriptor.subjectDid || '').trim(),
|
|
160
|
+
String(profile.descriptor.email || '').trim(),
|
|
161
|
+
String(profile.descriptor.phone || '').trim(),
|
|
162
|
+
].filter(Boolean));
|
|
163
|
+
for (const key of keys) {
|
|
164
|
+
this.loadedProfiles.set(key, profile);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
forgetLoadedProfile(profile) {
|
|
168
|
+
const keys = new Set([
|
|
169
|
+
profile.descriptor.profileId,
|
|
170
|
+
String(profile.descriptor.profileDid || '').trim(),
|
|
171
|
+
String(profile.descriptor.subjectDid || '').trim(),
|
|
172
|
+
String(profile.descriptor.email || '').trim(),
|
|
173
|
+
String(profile.descriptor.phone || '').trim(),
|
|
174
|
+
].filter(Boolean));
|
|
175
|
+
for (const key of keys) {
|
|
176
|
+
this.loadedProfiles.delete(key);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
resolveLoadedProfile(userId) {
|
|
180
|
+
const normalizedUserId = String(userId || '').trim();
|
|
181
|
+
const direct = this.loadedProfiles.get(normalizedUserId);
|
|
182
|
+
if (direct) {
|
|
183
|
+
return direct;
|
|
184
|
+
}
|
|
185
|
+
throw new Error(`DirectBackendProfileRuntime has not loaded one backend profile for '${normalizedUserId}'.`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Minimal in-memory `JobManager` for backend runtimes that do not need durable
|
|
190
|
+
* persistence during one live session.
|
|
191
|
+
*/
|
|
192
|
+
export function createJobManagerInMemory(descriptor) {
|
|
193
|
+
let isInitialized = false;
|
|
194
|
+
let sequence = 0;
|
|
195
|
+
const jobs = new Map();
|
|
196
|
+
let listener;
|
|
197
|
+
function notify() {
|
|
198
|
+
listener?.();
|
|
199
|
+
}
|
|
200
|
+
function nextSequence() {
|
|
201
|
+
sequence += 1;
|
|
202
|
+
return sequence;
|
|
203
|
+
}
|
|
204
|
+
function inferFormType(content) {
|
|
205
|
+
const first = Array.isArray(content?.body?.data) ? content.body.data[0] : undefined;
|
|
206
|
+
return String(first?.type || content?.type || '').trim();
|
|
207
|
+
}
|
|
208
|
+
function cloneJob(job) {
|
|
209
|
+
return {
|
|
210
|
+
...job,
|
|
211
|
+
indexed: job.indexed ? structuredClone(job.indexed) : job.indexed,
|
|
212
|
+
content: job.content ? structuredClone(job.content) : job.content,
|
|
213
|
+
jwe: job.jwe ? structuredClone(job.jwe) : job.jwe,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function matchesQuery(job, query) {
|
|
217
|
+
const conditions = Array.isArray(query.where) ? query.where : [];
|
|
218
|
+
return conditions.every((condition) => {
|
|
219
|
+
const currentValue = job[condition.attribute];
|
|
220
|
+
if ('equals' in condition) {
|
|
221
|
+
return currentValue === condition.equals;
|
|
222
|
+
}
|
|
223
|
+
if ('in' in condition) {
|
|
224
|
+
return Array.isArray(condition.in) && condition.in.includes(currentValue);
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
descriptor: { ...descriptor },
|
|
231
|
+
get isInitialized() {
|
|
232
|
+
return isInitialized;
|
|
233
|
+
},
|
|
234
|
+
async initialize() {
|
|
235
|
+
isInitialized = true;
|
|
236
|
+
},
|
|
237
|
+
shutdown() {
|
|
238
|
+
isInitialized = false;
|
|
239
|
+
jobs.clear();
|
|
240
|
+
},
|
|
241
|
+
setListener(nextListener) {
|
|
242
|
+
listener = nextListener;
|
|
243
|
+
},
|
|
244
|
+
async createJob(content, selector) {
|
|
245
|
+
const now = Date.now();
|
|
246
|
+
const job = {
|
|
247
|
+
id: createRuntimeUuid(),
|
|
248
|
+
thid: String(content?.thid || '').trim() || undefined,
|
|
249
|
+
status: JobStatus.DRAFT,
|
|
250
|
+
sequence: nextSequence(),
|
|
251
|
+
createdAtTimestamp: now,
|
|
252
|
+
content: structuredClone(content),
|
|
253
|
+
...selector,
|
|
254
|
+
};
|
|
255
|
+
jobs.set(job.id, job);
|
|
256
|
+
notify();
|
|
257
|
+
return cloneJob(job);
|
|
258
|
+
},
|
|
259
|
+
async findDraftJobByFormType(formType) {
|
|
260
|
+
const normalizedFormType = String(formType || '').trim();
|
|
261
|
+
for (const job of jobs.values()) {
|
|
262
|
+
if (job.status !== JobStatus.DRAFT)
|
|
263
|
+
continue;
|
|
264
|
+
if (inferFormType(job.content) === normalizedFormType) {
|
|
265
|
+
return cloneJob(job);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
},
|
|
270
|
+
async createOrUpdateDraftJob(content, selector) {
|
|
271
|
+
const formType = inferFormType(content);
|
|
272
|
+
const existing = formType ? await this.findDraftJobByFormType(formType) : null;
|
|
273
|
+
if (!existing) {
|
|
274
|
+
return this.createJob(content, selector);
|
|
275
|
+
}
|
|
276
|
+
const current = jobs.get(existing.id);
|
|
277
|
+
if (!current) {
|
|
278
|
+
return this.createJob(content, selector);
|
|
279
|
+
}
|
|
280
|
+
const updated = {
|
|
281
|
+
...current,
|
|
282
|
+
...selector,
|
|
283
|
+
thid: String(content?.thid || '').trim() || current.thid,
|
|
284
|
+
content: structuredClone(content),
|
|
285
|
+
previousSequence: current.sequence,
|
|
286
|
+
sequence: nextSequence(),
|
|
287
|
+
};
|
|
288
|
+
jobs.set(updated.id, updated);
|
|
289
|
+
notify();
|
|
290
|
+
return cloneJob(updated);
|
|
291
|
+
},
|
|
292
|
+
async sync() { },
|
|
293
|
+
async queryJobs(query) {
|
|
294
|
+
const filtered = [...jobs.values()].filter(job => matchesQuery(job, query));
|
|
295
|
+
if (query.orderBy) {
|
|
296
|
+
const { attribute, direction } = query.orderBy;
|
|
297
|
+
filtered.sort((left, right) => {
|
|
298
|
+
const a = left[attribute];
|
|
299
|
+
const b = right[attribute];
|
|
300
|
+
if (a === b)
|
|
301
|
+
return 0;
|
|
302
|
+
const cmp = a > b ? 1 : -1;
|
|
303
|
+
return direction === 'desc' ? -cmp : cmp;
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
const offset = Math.max(0, Number(query.offset || 0));
|
|
307
|
+
const limit = query.limit == null ? filtered.length : Math.max(0, Number(query.limit));
|
|
308
|
+
return filtered.slice(offset, offset + limit).map(cloneJob);
|
|
309
|
+
},
|
|
310
|
+
async submitJob(job) {
|
|
311
|
+
const current = jobs.get(job.id);
|
|
312
|
+
if (!current) {
|
|
313
|
+
throw new Error(`JobManager in-memory store cannot submit unknown job '${job.id}'.`);
|
|
314
|
+
}
|
|
315
|
+
jobs.set(job.id, {
|
|
316
|
+
...current,
|
|
317
|
+
status: JobStatus.SENT,
|
|
318
|
+
previousSequence: current.sequence,
|
|
319
|
+
sequence: nextSequence(),
|
|
320
|
+
});
|
|
321
|
+
notify();
|
|
322
|
+
},
|
|
323
|
+
async sealJobWithToken(job) {
|
|
324
|
+
return job;
|
|
325
|
+
},
|
|
326
|
+
async getJobResponseByThid(thid) {
|
|
327
|
+
for (const job of jobs.values()) {
|
|
328
|
+
if (job.thid === thid && job.responseMessageId) {
|
|
329
|
+
return {
|
|
330
|
+
id: job.responseMessageId,
|
|
331
|
+
thid,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
},
|
|
337
|
+
generateId() {
|
|
338
|
+
return createRuntimeUuid();
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Requires one backend profile-runtime method from one runtime client.
|
|
344
|
+
*/
|
|
345
|
+
export function requireBackendProfileRuntimeMethod(client, method) {
|
|
346
|
+
const candidate = client[method];
|
|
347
|
+
if (typeof candidate !== 'function') {
|
|
348
|
+
throw new Error(`BackendProfileRuntimeClient does not implement '${String(method)}'.`);
|
|
349
|
+
}
|
|
350
|
+
return candidate.bind(client);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Canonical backend helper for loading one actor profile after authentication.
|
|
354
|
+
*/
|
|
355
|
+
export async function loadBackendProfile(client, input) {
|
|
356
|
+
return requireBackendProfileRuntimeMethod(client, 'loadProfile')(input);
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Canonical backend helper for closing one loaded actor profile and clearing
|
|
360
|
+
* runtime-owned in-memory state.
|
|
361
|
+
*/
|
|
362
|
+
export async function closeBackendProfile(client, profileKey) {
|
|
363
|
+
return requireBackendProfileRuntimeMethod(client, 'closeProfile')(profileKey);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Canonical backend helper for registering one trusted device/runtime context.
|
|
367
|
+
*/
|
|
368
|
+
export async function registerBackendTrustedDevice(client, input) {
|
|
369
|
+
return requireBackendProfileRuntimeMethod(client, 'registerTrustedDevice')(input);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Canonical backend helper for connecting one actor profile to one subject
|
|
373
|
+
* index after the profile is already loaded.
|
|
374
|
+
*/
|
|
375
|
+
export async function connectBackendToSubjectIndex(client, input) {
|
|
376
|
+
return requireBackendProfileRuntimeMethod(client, 'connectToSubjectIndex')(input);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Canonical backend helper for reading one subject index composition after the
|
|
380
|
+
* relationship is already established.
|
|
381
|
+
*/
|
|
382
|
+
export async function getBackendSubjectIndexComposition(client, input) {
|
|
383
|
+
return requireBackendProfileRuntimeMethod(client, 'getSubjectIndexComposition')(input);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns one materialized backend actor session by actor kind.
|
|
387
|
+
*
|
|
388
|
+
* Backend callers should use this instead of scanning `actorSessions` manually.
|
|
389
|
+
*/
|
|
390
|
+
export function requireBackendActorSession(profile, actorKind) {
|
|
391
|
+
const session = profile.actorSessions.find(candidate => candidate.actorKind === actorKind);
|
|
392
|
+
if (!session) {
|
|
393
|
+
throw new Error(`Loaded backend profile does not expose actor kind '${actorKind}'.`);
|
|
394
|
+
}
|
|
395
|
+
return session;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Returns the individual-controller session from one loaded backend profile.
|
|
399
|
+
*
|
|
400
|
+
* This helper is the first concrete bridge from the generic backend runtime to
|
|
401
|
+
* the current individual bootstrap/index use case.
|
|
402
|
+
*/
|
|
403
|
+
export function requireBackendIndividualControllerSession(profile) {
|
|
404
|
+
return requireBackendActorSession(profile, ActorKinds.IndividualController);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Materializes the individual-controller facade directly from one loaded
|
|
408
|
+
* backend profile.
|
|
409
|
+
*/
|
|
410
|
+
export function requireBackendIndividualControllerSdk(profile) {
|
|
411
|
+
return requireBackendIndividualControllerSession(profile).asIndividualController();
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Loads one backend profile and resolves the individual-controller session in
|
|
415
|
+
* one step.
|
|
416
|
+
*
|
|
417
|
+
* This is the first pragmatic use-case helper on top of the generic backend
|
|
418
|
+
* profile runtime, because the current stable CORE bootstrap baseline starts
|
|
419
|
+
* from the individual-controller flow.
|
|
420
|
+
*/
|
|
421
|
+
export async function loadBackendIndividualControllerProfile(client, input) {
|
|
422
|
+
const profile = await loadBackendProfile(client, input);
|
|
423
|
+
const session = requireBackendIndividualControllerSession(profile);
|
|
424
|
+
return {
|
|
425
|
+
profile,
|
|
426
|
+
session,
|
|
427
|
+
sdk: session.asIndividualController(),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function createRuntimeUuid() {
|
|
431
|
+
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
432
|
+
if (fromCrypto) {
|
|
433
|
+
return fromCrypto;
|
|
434
|
+
}
|
|
435
|
+
return `fallback-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
436
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Node runtime re-export of canonical consent claim helpers.
|
|
3
3
|
*/
|
|
4
|
-
export { addActorIdentifierList, addActorRoleList, addActors, addCategories, addCategoryList, addClaimValues, addPurposeList, addPurposes, addRoles, addSections, getActorIdentifierList, getActorRoleList, getActors, getCategories, getCategoryList, getClaimValues, getConsentDate, getConsentIdentifier, getConsentPeriodEnd, getConsentPeriodStart, getPurposeList, getPurposes, getRoles, getSections, setActorIdentifierList, setActorRoleList, setActors, setCategories, setCategoryList, setClaimValues, setConsentDate, setConsentIdentifier, setConsentPeriodEnd, setConsentPeriodStart, setPurposeList, setPurposes, setRoles, setSections,
|
|
4
|
+
export { addActorIdentifierList, addActorRoleList, addActors, addCategories, addCategoryList, addClaimValues, addPurposeList, addPurposes, addRoles, addSections, getActorIdentifierList, getActorRoleList, getActors, getCategories, getCategoryList, getClaimValues, getConsentDate, getConsentIdentifier, getConsentPeriodEnd, getConsentPeriodStart, getPurposeList, getPurposes, getRoles, getSections, setActorIdentifierList, setActorRoleList, setActors, setCategories, setCategoryList, setClaimValues, setConsentDate, setConsentIdentifier, setConsentPeriodEnd, setConsentPeriodStart, setPurposeList, setPurposes, setRoles, setSections, } from 'gdc-sdk-core-ts';
|
|
5
|
+
export type { ConsentInteroperableClaims, } from 'gdc-sdk-core-ts';
|
|
@@ -31,6 +31,7 @@ export declare const GwCoreLifecycleRequestType: Readonly<{
|
|
|
31
31
|
readonly IndividualOrganizationRegistration: "SubjectOrg-registration-form-v1.0";
|
|
32
32
|
readonly IndividualOrganizationDisable: "Family-disable-request-v1.0";
|
|
33
33
|
readonly IndividualOrganizationPurge: "Family-purge-request-v1.0";
|
|
34
|
+
readonly IndividualMemberPurge: "RelatedPerson-purge-request-v1.0";
|
|
34
35
|
}>;
|
|
35
36
|
/**
|
|
36
37
|
* Named TODO ids kept close to the current lifecycle implementation so the
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { LifecycleRequestType } from 'gdc-common-utils-ts';
|
|
2
3
|
/**
|
|
3
4
|
* GW CORE lifecycle route/action tokens used by the Node runtime SDK.
|
|
4
5
|
*
|
|
@@ -32,6 +33,7 @@ export const GwCoreLifecycleRequestType = Object.freeze({
|
|
|
32
33
|
IndividualOrganizationRegistration: 'SubjectOrg-registration-form-v1.0',
|
|
33
34
|
IndividualOrganizationDisable: 'Family-disable-request-v1.0',
|
|
34
35
|
IndividualOrganizationPurge: 'Family-purge-request-v1.0',
|
|
36
|
+
IndividualMemberPurge: LifecycleRequestType.RelatedPersonPurge,
|
|
35
37
|
});
|
|
36
38
|
/**
|
|
37
39
|
* Named TODO ids kept close to the current lifecycle implementation so the
|
|
@@ -3,14 +3,18 @@ import { ActorCapabilities } from 'gdc-common-utils-ts/constants/actor-session';
|
|
|
3
3
|
import { expandActorSessionDescriptorToFacades, filterCapabilitiesForActor, } from 'gdc-sdk-core-ts';
|
|
4
4
|
import { ActorSession, NodeActorSession } from './session.js';
|
|
5
5
|
const capabilityMap = {
|
|
6
|
-
[ActorCapabilities.
|
|
7
|
-
[ActorCapabilities.
|
|
6
|
+
[ActorCapabilities.HostingActivateOrganization]: ActorCapabilities.HostingActivateOrganization,
|
|
7
|
+
[ActorCapabilities.HostingConfirmOrder]: ActorCapabilities.HostingConfirmOrder,
|
|
8
|
+
[ActorCapabilities.HostingDisableHost]: ActorCapabilities.HostingDisableHost,
|
|
9
|
+
[ActorCapabilities.HostingPurgeHost]: ActorCapabilities.HostingPurgeHost,
|
|
8
10
|
[ActorCapabilities.OrganizationCreateEmployee]: ActorCapabilities.OrganizationCreateEmployee,
|
|
9
11
|
[ActorCapabilities.OrganizationActivateDevice]: ActorCapabilities.OrganizationActivateDevice,
|
|
10
12
|
[ActorCapabilities.OrganizationIssueActivationCode]: ActorCapabilities.OrganizationIssueActivationCode,
|
|
11
13
|
[ActorCapabilities.OrganizationRequestSmartToken]: ActorCapabilities.OrganizationRequestSmartToken,
|
|
12
14
|
[ActorCapabilities.OrganizationDisableEmployee]: ActorCapabilities.OrganizationDisableEmployee,
|
|
13
15
|
[ActorCapabilities.OrganizationPurgeEmployee]: ActorCapabilities.OrganizationPurgeEmployee,
|
|
16
|
+
[ActorCapabilities.OrganizationDisableTenant]: ActorCapabilities.OrganizationDisableTenant,
|
|
17
|
+
[ActorCapabilities.OrganizationPurgeTenant]: ActorCapabilities.OrganizationPurgeTenant,
|
|
14
18
|
[ActorCapabilities.IndividualBootstrap]: ActorCapabilities.IndividualBootstrap,
|
|
15
19
|
[ActorCapabilities.IndividualDisable]: ActorCapabilities.IndividualDisable,
|
|
16
20
|
[ActorCapabilities.IndividualPurge]: ActorCapabilities.IndividualPurge,
|
|
@@ -1,42 +1,9 @@
|
|
|
1
|
-
import type { PollOptions, SubmitAndPollResult } from './orchestration/client-port.js';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
2
|
+
* Compatibility re-export.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The canonical host/hosting facade contract now lives in `gdc-sdk-core-ts` so
|
|
5
|
+
* browser and Node runtimes can share the same orchestration surface. This
|
|
6
|
+
* file stays as a stable import path for existing Node consumers.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
hostNetwork?: string;
|
|
11
|
-
/** @deprecated Use `hostNetwork`. */
|
|
12
|
-
sector?: string;
|
|
13
|
-
controllerDid?: string;
|
|
14
|
-
hostDid?: string;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Input for legal-organization order confirmation in the host registry.
|
|
18
|
-
*/
|
|
19
|
-
export type LegalOrganizationOrderInput = {
|
|
20
|
-
offerId: string;
|
|
21
|
-
jurisdiction?: string;
|
|
22
|
-
hostNetwork?: string;
|
|
23
|
-
/** @deprecated Use `hostNetwork`. */
|
|
24
|
-
sector?: string;
|
|
25
|
-
dataType?: string;
|
|
26
|
-
additionalClaims?: Record<string, unknown>;
|
|
27
|
-
timeoutSeconds?: number;
|
|
28
|
-
intervalSeconds?: number;
|
|
29
|
-
};
|
|
30
|
-
type ConfirmLegalOrganizationOrderDeps = {
|
|
31
|
-
input: LegalOrganizationOrderInput;
|
|
32
|
-
hostCtx: HostRouteContext;
|
|
33
|
-
defaultTimeoutMs?: number;
|
|
34
|
-
defaultIntervalMs?: number;
|
|
35
|
-
hostRegistryOrderBatchPath: (ctx: HostRouteContext) => string;
|
|
36
|
-
hostRegistryOrderPollPath: (ctx: HostRouteContext) => string;
|
|
37
|
-
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
38
|
-
thid?: string;
|
|
39
|
-
} & Record<string, unknown>, options?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
40
|
-
};
|
|
41
|
-
export declare function confirmLegalOrganizationOrderWithDeps(deps: ConfirmLegalOrganizationOrderDeps): Promise<SubmitAndPollResult>;
|
|
42
|
-
export {};
|
|
8
|
+
export { confirmLegalOrganizationOrderWithDeps, HostLifecycleRequestType, HostedTenantLifecycleRequestType, submitHostedTenantLifecycleWithDeps, } from 'gdc-sdk-core-ts';
|
|
9
|
+
export type { HostingControllerFacade, HostLifecycleInput, HostRouteContext, HostedTenantLifecycleInput, LegalOrganizationOrderInput, } from 'gdc-sdk-core-ts';
|
package/dist/host-onboarding.js
CHANGED
|
@@ -1,39 +1,9 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
'Order.acceptedOffer.identifier': offerId,
|
|
11
|
-
...(deps.input.additionalClaims || {}),
|
|
12
|
-
};
|
|
13
|
-
const payload = {
|
|
14
|
-
jti: `jti-${createRuntimeUuid()}`,
|
|
15
|
-
iss: String(deps.hostCtx.controllerDid || '').trim() || undefined,
|
|
16
|
-
aud: String(deps.hostCtx.hostDid || '').trim() || undefined,
|
|
17
|
-
type: 'application/didcomm-plain+json',
|
|
18
|
-
thid: `order-${createRuntimeUuid()}`,
|
|
19
|
-
body: {
|
|
20
|
-
data: [{
|
|
21
|
-
type: deps.input.dataType || 'Organization-order-request-v1.0',
|
|
22
|
-
meta: { claims },
|
|
23
|
-
resource: { meta: { claims } },
|
|
24
|
-
}],
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
const pollOptions = resolvePollOptionsFromSeconds(deps.input.timeoutSeconds, deps.input.intervalSeconds, {
|
|
28
|
-
timeoutMs: deps.defaultTimeoutMs,
|
|
29
|
-
intervalMs: deps.defaultIntervalMs,
|
|
30
|
-
});
|
|
31
|
-
return deps.submitAndPoll(deps.hostRegistryOrderBatchPath(deps.hostCtx), deps.hostRegistryOrderPollPath(deps.hostCtx), payload, pollOptions);
|
|
32
|
-
}
|
|
33
|
-
function createRuntimeUuid() {
|
|
34
|
-
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
35
|
-
if (fromCrypto) {
|
|
36
|
-
return fromCrypto;
|
|
37
|
-
}
|
|
38
|
-
return `fallback-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
39
|
-
}
|
|
2
|
+
/**
|
|
3
|
+
* Compatibility re-export.
|
|
4
|
+
*
|
|
5
|
+
* The canonical host/hosting facade contract now lives in `gdc-sdk-core-ts` so
|
|
6
|
+
* browser and Node runtimes can share the same orchestration surface. This
|
|
7
|
+
* file stays as a stable import path for existing Node consumers.
|
|
8
|
+
*/
|
|
9
|
+
export { confirmLegalOrganizationOrderWithDeps, HostLifecycleRequestType, HostedTenantLifecycleRequestType, submitHostedTenantLifecycleWithDeps, } from 'gdc-sdk-core-ts';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,13 +2,18 @@ export * from 'gdc-sdk-core-ts';
|
|
|
2
2
|
export * from './runtime-contracts.js';
|
|
3
3
|
export * from './identity-bootstrap.js';
|
|
4
4
|
export * from './async-polling.js';
|
|
5
|
+
export * from './backend-profile-runtime.js';
|
|
6
|
+
export * from './individual-controller-backend-runtime.js';
|
|
5
7
|
export * from './poll-options.js';
|
|
6
8
|
export * from './host-onboarding.js';
|
|
7
9
|
export * from './individual-start.js';
|
|
8
10
|
export * from './individual-onboarding.js';
|
|
9
11
|
export * from './device-activation.js';
|
|
10
12
|
export * from './smart-token.js';
|
|
13
|
+
export * from './order-offer-summary.js';
|
|
14
|
+
export * from './organization-license-order.js';
|
|
11
15
|
export * from './resource-operations.js';
|
|
16
|
+
export * from './constants/lifecycle.js';
|
|
12
17
|
export * from './consent-claim-helpers.js';
|
|
13
18
|
export * from './session.js';
|
|
14
19
|
export * from './node-runtime-client.js';
|
package/dist/index.js
CHANGED
|
@@ -3,13 +3,18 @@ export * from 'gdc-sdk-core-ts';
|
|
|
3
3
|
export * from './runtime-contracts.js';
|
|
4
4
|
export * from './identity-bootstrap.js';
|
|
5
5
|
export * from './async-polling.js';
|
|
6
|
+
export * from './backend-profile-runtime.js';
|
|
7
|
+
export * from './individual-controller-backend-runtime.js';
|
|
6
8
|
export * from './poll-options.js';
|
|
7
9
|
export * from './host-onboarding.js';
|
|
8
10
|
export * from './individual-start.js';
|
|
9
11
|
export * from './individual-onboarding.js';
|
|
10
12
|
export * from './device-activation.js';
|
|
11
13
|
export * from './smart-token.js';
|
|
14
|
+
export * from './order-offer-summary.js';
|
|
15
|
+
export * from './organization-license-order.js';
|
|
12
16
|
export * from './resource-operations.js';
|
|
17
|
+
export * from './constants/lifecycle.js';
|
|
13
18
|
export * from './consent-claim-helpers.js';
|
|
14
19
|
export * from './session.js';
|
|
15
20
|
export * from './node-runtime-client.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SubmitAndPollResult } from 'gdc-sdk-core-ts';
|
|
2
|
+
import type { IndividualOrganizationConfirmOrderInput, RouteContext } from './individual-onboarding.js';
|
|
3
|
+
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } from './individual-start.js';
|
|
4
|
+
import type { ClinicalBundleSearchInput } from './resource-operations.js';
|
|
5
|
+
import { type BackendIndividualControllerProfile, type BackendProfileRuntimeClient } from './backend-profile-runtime.js';
|
|
6
|
+
import type { ProfileLoadRequest } from 'gdc-sdk-core-ts';
|
|
7
|
+
/**
|
|
8
|
+
* Backend use-case facade for the current individual-controller baseline.
|
|
9
|
+
*
|
|
10
|
+
* This class does not redefine the generic backend profile runtime. It wraps
|
|
11
|
+
* that runtime with the current stable CORE-facing actions that backend
|
|
12
|
+
* consumers need first:
|
|
13
|
+
*
|
|
14
|
+
* - load an individual-controller profile
|
|
15
|
+
* - start individual registration/bootstrap
|
|
16
|
+
* - confirm the returned order/offer
|
|
17
|
+
* - search the subject clinical index
|
|
18
|
+
* - request the latest IPS-oriented bundle
|
|
19
|
+
*/
|
|
20
|
+
export declare class IndividualControllerBackendRuntime {
|
|
21
|
+
private readonly profileRuntime;
|
|
22
|
+
constructor(profileRuntime: BackendProfileRuntimeClient);
|
|
23
|
+
/**
|
|
24
|
+
* Loads one individual-controller backend profile and materializes its actor
|
|
25
|
+
* facade in one step.
|
|
26
|
+
*/
|
|
27
|
+
loadProfile(input: ProfileLoadRequest): Promise<BackendIndividualControllerProfile>;
|
|
28
|
+
/**
|
|
29
|
+
* Starts the current CORE individual/family bootstrap flow.
|
|
30
|
+
*/
|
|
31
|
+
startIndividualOrganization(profile: BackendIndividualControllerProfile, input: IndividualOrganizationBootstrapInput): Promise<IndividualOrganizationStartResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Confirms the order returned by the individual bootstrap flow.
|
|
34
|
+
*/
|
|
35
|
+
confirmIndividualOrganizationOrder(profile: BackendIndividualControllerProfile, input: IndividualOrganizationConfirmOrderInput): Promise<SubmitAndPollResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Searches the current subject clinical bundle index through the loaded
|
|
38
|
+
* individual-controller facade.
|
|
39
|
+
*/
|
|
40
|
+
searchClinicalBundle(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: ClinicalBundleSearchInput): Promise<SubmitAndPollResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Reads the latest IPS-oriented bundle through the loaded
|
|
43
|
+
* individual-controller facade.
|
|
44
|
+
*/
|
|
45
|
+
getLatestIps(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: Omit<ClinicalBundleSearchInput, 'includedTypes'>): Promise<SubmitAndPollResult>;
|
|
46
|
+
}
|