gdc-sdk-node-ts 0.12.0 → 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.
@@ -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, type ConsentInteroperableClaims, } from 'gdc-sdk-core-ts';
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';
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ 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';
package/dist/index.js CHANGED
@@ -3,6 +3,8 @@ 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';
@@ -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
+ }
@@ -0,0 +1,53 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ import { loadBackendIndividualControllerProfile, } from './backend-profile-runtime.js';
3
+ /**
4
+ * Backend use-case facade for the current individual-controller baseline.
5
+ *
6
+ * This class does not redefine the generic backend profile runtime. It wraps
7
+ * that runtime with the current stable CORE-facing actions that backend
8
+ * consumers need first:
9
+ *
10
+ * - load an individual-controller profile
11
+ * - start individual registration/bootstrap
12
+ * - confirm the returned order/offer
13
+ * - search the subject clinical index
14
+ * - request the latest IPS-oriented bundle
15
+ */
16
+ export class IndividualControllerBackendRuntime {
17
+ constructor(profileRuntime) {
18
+ this.profileRuntime = profileRuntime;
19
+ }
20
+ /**
21
+ * Loads one individual-controller backend profile and materializes its actor
22
+ * facade in one step.
23
+ */
24
+ loadProfile(input) {
25
+ return loadBackendIndividualControllerProfile(this.profileRuntime, input);
26
+ }
27
+ /**
28
+ * Starts the current CORE individual/family bootstrap flow.
29
+ */
30
+ startIndividualOrganization(profile, input) {
31
+ return profile.sdk.startIndividualOrganization(input);
32
+ }
33
+ /**
34
+ * Confirms the order returned by the individual bootstrap flow.
35
+ */
36
+ confirmIndividualOrganizationOrder(profile, input) {
37
+ return profile.sdk.confirmIndividualOrganizationOrder(input);
38
+ }
39
+ /**
40
+ * Searches the current subject clinical bundle index through the loaded
41
+ * individual-controller facade.
42
+ */
43
+ searchClinicalBundle(profile, ctx, input) {
44
+ return profile.sdk.searchClinicalBundle(ctx, input);
45
+ }
46
+ /**
47
+ * Reads the latest IPS-oriented bundle through the loaded
48
+ * individual-controller facade.
49
+ */
50
+ getLatestIps(profile, ctx, input) {
51
+ return profile.sdk.getLatestIps(ctx, input);
52
+ }
53
+ }
@@ -1,12 +1,13 @@
1
+ import type { OrganizationDidBindingInput } from 'gdc-sdk-core-ts';
1
2
  import type { AppInfo } from 'gdc-sdk-core-ts';
2
3
  import { type ResolvedAppInfo } from 'gdc-sdk-core-ts';
3
4
  import { type HostRouteContext, type HostedTenantLifecycleInput } from './host-onboarding.js';
4
- import type { NodeOrganizationActivationInput } from './orchestration/client-port.js';
5
+ import type { NodeLegalOrganizationVerificationTransactionInput, NodeOrganizationDidBindingInput, NodeOrganizationActivationInput } from './orchestration/client-port.js';
5
6
  import { type IndividualOrganizationConfirmOrderInput, type RouteContext } from './individual-onboarding.js';
6
7
  import { type SmartTokenRequestInput } from './smart-token.js';
7
8
  import { type OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
8
9
  import { type IndividualOrganizationBootstrapInput, type IndividualOrganizationStartResult } from './individual-start.js';
9
- import { type CommunicationIngestionInput, type ClinicalBundleSearchInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualOrganizationLifecycleInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RelatedPersonUpsertInput } from './resource-operations.js';
10
+ import { type CommunicationIngestionInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualOrganizationLifecycleInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RelatedPersonUpsertInput } from './resource-operations.js';
10
11
  import type { LegalOrganizationOrderInput } from './host-onboarding.js';
11
12
  import type { SmartTokenExchangeResult } from './smart-token.js';
12
13
  import type { NodeRuntimeClient, PollOptions, PollResult, SubmitAndPollResult, SubmitPayload, SubmitResponse } from './orchestration/client-port.js';
@@ -109,9 +110,45 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
109
110
  * Convenience wrapper that performs submit and poll in sequence.
110
111
  */
111
112
  submitAndPoll(submitPath: string, pollPath: string, payload: SubmitPayload, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
113
+ /**
114
+ * Starts the host-side legal-organization verification transaction that GW
115
+ * CORE forwards to ICA `_verify`.
116
+ *
117
+ * Runtime ownership:
118
+ * - builds the canonical shared business bundle from `sdk-core/common-utils`
119
+ * - keeps communication/runtime transport concerns at the outer message layer
120
+ * - keeps the controller business key inside the submitted bundle payload
121
+ *
122
+ * Flow separation:
123
+ * - `_transaction` is the first host onboarding step
124
+ * - `_activate` remains a later step that consumes the ICA proof
125
+ */
126
+ submitLegalOrganizationVerificationTransaction(hostCtx: HostRouteContext, input: NodeLegalOrganizationVerificationTransactionInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
127
+ /**
128
+ * Submits one tenant-scoped DID document binding request.
129
+ *
130
+ * Binding semantics:
131
+ * - the tenant path identifies the existing organization
132
+ * - `organization.url` carries the public alias/domain list
133
+ * - `controller.sameAs` is optional corroborating identity material
134
+ * - the flow does not rotate or replace organization public keys
135
+ */
136
+ submitOrganizationDidBinding(ctx: RouteContext, input: NodeOrganizationDidBindingInput | OrganizationDidBindingInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
112
137
  /**
113
138
  * Activates a legal organization in the gateway host registry using an ICA
114
139
  * proof token already obtained by the caller.
140
+ *
141
+ * Plaintext transport note:
142
+ * - this Node runtime currently submits `_activate` as
143
+ * `application/didcomm-plaintext+json`
144
+ * - because there is no real outer JWS/JWE envelope in that mode, the
145
+ * runtime mirrors the technical communication metadata derived from
146
+ * `controller.publicKeyJwk` / `controller.jwks` into `meta.jws.protected`
147
+ * and `meta.jwe.header`
148
+ * - secure JOSE transports should carry those values in the real protected
149
+ * headers instead of plaintext `meta`
150
+ * - this mirrored metadata is transport fallback only; the canonical
151
+ * activation contract remains `body.vp_token` plus `body.controller.*`
115
152
  */
116
153
  activateOrganizationInGatewayFromIcaProof(hostCtx: HostRouteContext, input: NodeOrganizationActivationInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
117
154
  /**
@@ -274,6 +311,11 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
274
311
  * @param input Communication payload plus route/format options.
275
312
  */
276
313
  ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
314
+ /**
315
+ * Searches communication channel records by subject and participant
316
+ * identifiers through `Communication/_search`.
317
+ */
318
+ searchCommunicationParticipants(ctx: RouteContext, input: CommunicationParticipantRuntimeSearchInput): Promise<SubmitAndPollResult>;
277
319
  /**
278
320
  * Alias for `ingestCommunicationAndUpdateIndex(...)`.
279
321
  *
@@ -319,8 +361,15 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
319
361
  private parseResponseBody;
320
362
  private requireRouteContext;
321
363
  private routeCtxFromInput;
364
+ /**
365
+ * Reuses the shared bundle business contract while keeping attachment
366
+ * transport fields at the DIDComm/plaintext message layer expected by GW.
367
+ */
368
+ private wrapBundleAsGatewayTransactionMessage;
322
369
  private hostRegistryPath;
323
370
  private requireHostRouteContext;
371
+ hostRegistryOrganizationTransactionPath(ctx?: HostRouteContext): string;
372
+ hostRegistryOrganizationTransactionPollPath(ctx?: HostRouteContext): string;
324
373
  hostRegistryOrganizationActivatePath(ctx?: HostRouteContext): string;
325
374
  hostRegistryOrganizationActivatePollPath(ctx?: HostRouteContext): string;
326
375
  hostRegistryOrganizationDisablePath(ctx?: HostRouteContext): string;
@@ -335,6 +384,8 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
335
384
  employeeSearchPollPath(ctx?: RouteContext): string;
336
385
  organizationLicenseSearchPath(ctx?: RouteContext): string;
337
386
  organizationLicenseSearchPollPath(ctx?: RouteContext): string;
387
+ organizationDidBindingPath(ctx?: RouteContext): string;
388
+ organizationDidBindingPollPath(ctx?: RouteContext): string;
338
389
  organizationLicenseOfferSearchPath(ctx?: RouteContext): string;
339
390
  organizationLicenseOfferSearchPollPath(ctx?: RouteContext): string;
340
391
  organizationLicenseOrderSearchPath(ctx?: RouteContext): string;
@@ -365,6 +416,8 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
365
416
  individualConsentR4PollPath(ctx: RouteContext): string;
366
417
  individualCommunicationBatchPath(ctx: RouteContext, format: 'org.hl7.fhir.api' | 'org.hl7.fhir.r4'): string;
367
418
  individualCommunicationPollPath(ctx: RouteContext, format: 'org.hl7.fhir.api' | 'org.hl7.fhir.r4'): string;
419
+ individualCommunicationSearchPath(ctx: RouteContext): string;
420
+ individualCommunicationSearchPollPath(ctx: RouteContext): string;
368
421
  individualBundleSearchPath(ctx: RouteContext): string;
369
422
  individualBundleSearchPollPath(ctx: RouteContext): string;
370
423
  identityTokenExchangePath(ctx: RouteContext): string;