gdc-sdk-node-ts 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.
- package/README.md +166 -0
- package/dist/async-polling.d.ts +7 -0
- package/dist/async-polling.js +26 -0
- package/dist/device-activation.d.ts +44 -0
- package/dist/device-activation.js +44 -0
- package/dist/gdc-session-bridge.d.ts +11 -0
- package/dist/gdc-session-bridge.js +74 -0
- package/dist/host-onboarding.d.ts +38 -0
- package/dist/host-onboarding.js +39 -0
- package/dist/identity-bootstrap.d.ts +30 -0
- package/dist/identity-bootstrap.js +32 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +24 -0
- package/dist/individual-onboarding.d.ts +35 -0
- package/dist/individual-onboarding.js +38 -0
- package/dist/individual-start.d.ts +87 -0
- package/dist/individual-start.js +82 -0
- package/dist/legacy-compat.d.ts +22 -0
- package/dist/legacy-compat.js +18 -0
- package/dist/node-runtime-client.d.ts +195 -0
- package/dist/node-runtime-client.js +483 -0
- package/dist/orchestration/client-port.d.ts +47 -0
- package/dist/orchestration/client-port.js +31 -0
- package/dist/orchestration/host-onboarding-sdk.d.ts +14 -0
- package/dist/orchestration/host-onboarding-sdk.js +15 -0
- package/dist/orchestration/individual-controller-sdk.d.ts +54 -0
- package/dist/orchestration/individual-controller-sdk.js +70 -0
- package/dist/orchestration/individual-member-sdk.d.ts +17 -0
- package/dist/orchestration/individual-member-sdk.js +20 -0
- package/dist/orchestration/organization-controller-sdk.d.ts +46 -0
- package/dist/orchestration/organization-controller-sdk.js +56 -0
- package/dist/orchestration/organization-employee-sdk.d.ts +9 -0
- package/dist/orchestration/organization-employee-sdk.js +13 -0
- package/dist/orchestration/personal-sdk.d.ts +22 -0
- package/dist/orchestration/personal-sdk.js +34 -0
- package/dist/orchestration/professional-sdk.d.ts +58 -0
- package/dist/orchestration/professional-sdk.js +63 -0
- package/dist/poll-options.d.ts +1 -0
- package/dist/poll-options.js +2 -0
- package/dist/resource-operations.d.ts +225 -0
- package/dist/resource-operations.js +184 -0
- package/dist/runtime-contracts.d.ts +65 -0
- package/dist/runtime-contracts.js +7 -0
- package/dist/session.d.ts +64 -0
- package/dist/session.js +80 -0
- package/dist/simple-device-activation.d.ts +44 -0
- package/dist/simple-device-activation.js +44 -0
- package/dist/simple-host-onboarding.d.ts +27 -0
- package/dist/simple-host-onboarding.js +39 -0
- package/dist/simple-individual-onboarding.d.ts +27 -0
- package/dist/simple-individual-onboarding.js +38 -0
- package/dist/simple-individual-start.d.ts +45 -0
- package/dist/simple-individual-start.js +59 -0
- package/dist/simple-poll-options.d.ts +5 -0
- package/dist/simple-poll-options.js +17 -0
- package/dist/simple-smart-token.d.ts +58 -0
- package/dist/simple-smart-token.js +85 -0
- package/dist/smart-token.d.ts +135 -0
- package/dist/smart-token.js +100 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# gdc-sdk-node-ts
|
|
2
|
+
|
|
3
|
+
Target Node runtime package for the converged GDC SDK family.
|
|
4
|
+
|
|
5
|
+
Key docs:
|
|
6
|
+
|
|
7
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
8
|
+
- [SECURITY.md](SECURITY.md)
|
|
9
|
+
- [TEST_CORE.md](TEST_CORE.md)
|
|
10
|
+
- [SDK_INTEGRATION_101.md](SDK_INTEGRATION_101.md)
|
|
11
|
+
|
|
12
|
+
Current status:
|
|
13
|
+
|
|
14
|
+
- package created
|
|
15
|
+
- build/test baseline created
|
|
16
|
+
- migration target from `dataspace-client-sdk-node` completed for live runtime path
|
|
17
|
+
- runtime contract skeleton declared
|
|
18
|
+
- actor-scoped node session bridge implemented
|
|
19
|
+
- first actor-scoped orchestration facades implemented on top of `GdcNodeRuntimeClient`
|
|
20
|
+
- shared async submit/poll helpers implemented for converged Node orchestration
|
|
21
|
+
- live GW E2E migrated here with `gdc-sdk-node-ts` runtime client only, with JSONL debug/HTTP trace artifacts under `test-results/`
|
|
22
|
+
|
|
23
|
+
Not migrated yet:
|
|
24
|
+
|
|
25
|
+
- full wallet/runtime adapter parity from legacy package
|
|
26
|
+
- secure E2E script parity in this package
|
|
27
|
+
- full live use-case parity matrix vs legacy suite
|
|
28
|
+
|
|
29
|
+
Live validation:
|
|
30
|
+
|
|
31
|
+
- `npm run test:e2e:live-gw`
|
|
32
|
+
- core coverage summary for memory/thesis justification: `TEST_CORE.md`
|
|
33
|
+
- optional:
|
|
34
|
+
- `BASE_URL=http://127.0.0.1:8000`
|
|
35
|
+
- `RUN_LIVE_GW_E2E_IPS_INGESTION=1`
|
|
36
|
+
- `LIVE_GW_NODE_E2E_DEBUG=1`
|
|
37
|
+
- artifacts:
|
|
38
|
+
- `test-results/live-gw-node-runtime-debug-*.jsonl`
|
|
39
|
+
- `test-results/live-gw-http-trace-*.jsonl`
|
|
40
|
+
|
|
41
|
+
Runtime migration note:
|
|
42
|
+
|
|
43
|
+
- the live E2E in this package no longer imports `dataspace-client-sdk-node`
|
|
44
|
+
- actor-scoped facades now run on the in-package `GdcNodeHttpClient`
|
|
45
|
+
- remaining migration scope is parity hardening, not runtime ownership
|
|
46
|
+
- this package now consumes the published `gdc-common-utils-ts` `^1.4.22` line; the sibling checkout is only needed for source browsing and optional local cross-repo work
|
|
47
|
+
|
|
48
|
+
Role in the transition:
|
|
49
|
+
|
|
50
|
+
- `gdc-sdk-core-ts` will own shared actor/capability contracts
|
|
51
|
+
- `gdc-sdk-node-ts` will own Node runtime adapters and backend-facing orchestration
|
|
52
|
+
- `dataspace-client-sdk-node` is now the legacy source repo for migration, not the final name
|
|
53
|
+
|
|
54
|
+
Reusable payload source of truth:
|
|
55
|
+
|
|
56
|
+
- [../gdc-common-utils-ts/src/examples/organization-controller.ts](../gdc-common-utils-ts/src/examples/organization-controller.ts)
|
|
57
|
+
- `_activate`, legal order, employee creation, employee device activation
|
|
58
|
+
- [../gdc-common-utils-ts/src/examples/individual-controller.ts](../gdc-common-utils-ts/src/examples/individual-controller.ts)
|
|
59
|
+
- individual bootstrap, consent, search, communication ingestion, digital twin
|
|
60
|
+
- [../gdc-common-utils-ts/src/examples/professional.ts](../gdc-common-utils-ts/src/examples/professional.ts)
|
|
61
|
+
- SMART token and clinical access request examples
|
|
62
|
+
- reusable professional role/permission scenarios by section and expected FHIR types
|
|
63
|
+
- reusable consent-vs-smart matrices for actor targeting by email, organization, or jurisdiction
|
|
64
|
+
- [../gdc-common-utils-ts/src/examples/shared.ts](../gdc-common-utils-ts/src/examples/shared.ts)
|
|
65
|
+
- shared route contexts and helper builders
|
|
66
|
+
- [../gdc-common-utils-ts/src/examples/api-flow-examples.ts](../gdc-common-utils-ts/src/examples/api-flow-examples.ts)
|
|
67
|
+
- preferred compatibility aggregator when one import surface is needed without using the overloaded term `contract`
|
|
68
|
+
- [tests/fixtures/ica-vp-minimal.json](tests/fixtures/ica-vp-minimal.json)
|
|
69
|
+
- minimal VP fixture used by live GW onboarding/smart flows
|
|
70
|
+
|
|
71
|
+
CORE vs extension note:
|
|
72
|
+
|
|
73
|
+
- shared CORE examples are email-first for individual/controller bootstrap
|
|
74
|
+
- `subjectPhone`, `subjectGivenName`, and phone-first controller onboarding are compatibility or extension concerns, not required CORE GW contract fields
|
|
75
|
+
- route `tenantId` examples use identifier-style values such as `acme-id`, not friendly alternate names
|
|
76
|
+
- individual/family bootstrap uses `org.schema.Organization.owner.*` claims for the human owner/controller
|
|
77
|
+
- legal organization activation uses `Person` representative semantics plus VC `memberOf` / `hasOccupation`
|
|
78
|
+
|
|
79
|
+
## API Index
|
|
80
|
+
|
|
81
|
+
The canonical API contract should live in JSDoc on exported code. The README is the linked index.
|
|
82
|
+
|
|
83
|
+
### Core document helpers re-exported from `gdc-sdk-core-ts`
|
|
84
|
+
|
|
85
|
+
- [`createCommunicationResource(...)`](../gdc-sdk-core-ts/src/communication-resource-helpers.ts)
|
|
86
|
+
- Creates a minimal FHIR `Communication` resource.
|
|
87
|
+
- Main params: `subject`, `sender?`, `recipient?`, `sent?`, `status?`, `category?`, `noteText?`, `claims?`.
|
|
88
|
+
- [`addFhirResourceToCommunication(...)`](../gdc-sdk-core-ts/src/communication-resource-helpers.ts)
|
|
89
|
+
- Attaches a FHIR resource to `Communication.payload`, optionally wrapped as `DocumentReference`.
|
|
90
|
+
- Main params: `communication`, `resource`, `noteText?`, `asDocumentReference?`, `attachmentTitle?`, `attachmentContentType?`, `documentDescription?`, `documentDate?`, `documentSubject?`.
|
|
91
|
+
- [`addClaimsResourceToCommunication(...)`](../gdc-sdk-core-ts/src/communication-resource-helpers.ts)
|
|
92
|
+
- Attaches a claims-only pseudo-resource using `meta.claims`.
|
|
93
|
+
- Main params: `communication`, `resourceType`, `claims`, `options?`.
|
|
94
|
+
- [`buildCommunicationBatchMessage(...)`](../gdc-sdk-core-ts/src/communication-resource-helpers.ts)
|
|
95
|
+
- Wraps a FHIR `Communication` into a GW-ready batch envelope.
|
|
96
|
+
- Main params: `communication`, `thid?`, `jti?`, `iss?`, `aud?`, `requestUrl?`, `entryType?`, `messageType?`, `fhirVersion?`.
|
|
97
|
+
- [`createCommunicationFacade()`](../gdc-sdk-core-ts/src/communication-document-facade.ts)
|
|
98
|
+
- Creates the high-level document access facade.
|
|
99
|
+
- [`getDocumentFromCommunication(...)`](../gdc-sdk-core-ts/src/communication-document-facade.ts)
|
|
100
|
+
- Resolves the first attached document and hides direct attachment vs `DocumentReference`.
|
|
101
|
+
- [`createFhirDocumentFacade(...)`](../gdc-sdk-core-ts/src/communication-document-facade.ts)
|
|
102
|
+
- Exposes `getBundle()`, `getSections()`, `getResources(resourceType?)`, `getByDates(resourceType, start, end?)`, `getContainingTextOrDisplay(resourceType, text)`.
|
|
103
|
+
- [`createCommunicationDraft(...)`](../gdc-sdk-core-ts/src/communication-draft.ts)
|
|
104
|
+
- Starts an in-memory communication draft.
|
|
105
|
+
- [`addFhirResourceToDraft(...)`](../gdc-sdk-core-ts/src/communication-draft.ts)
|
|
106
|
+
- Appends a concrete FHIR resource to the draft.
|
|
107
|
+
- [`addClaimsResourceToDraft(...)`](../gdc-sdk-core-ts/src/communication-draft.ts)
|
|
108
|
+
- Appends a claims-only pseudo-resource to the draft.
|
|
109
|
+
- [`createOutboxJobFromDraft(...)`](../gdc-sdk-core-ts/src/communication-draft.ts)
|
|
110
|
+
- Freezes the draft into a transport-oriented outbox job.
|
|
111
|
+
- [`updateOutboxJobStatus(...)`](../gdc-sdk-core-ts/src/communication-draft.ts)
|
|
112
|
+
- Updates the outbox job status and transport result metadata.
|
|
113
|
+
- [`IOutboxRepository`](../gdc-sdk-core-ts/src/communication-outbox.ts)
|
|
114
|
+
- [`OutboxRepositoryMemory`](../gdc-sdk-core-ts/src/communication-outbox.ts)
|
|
115
|
+
- [`createHeartRateObservation(...)`](../gdc-sdk-core-ts/src/vital-signs.ts)
|
|
116
|
+
- [`createBodyTemperatureObservation(...)`](../gdc-sdk-core-ts/src/vital-signs.ts)
|
|
117
|
+
- [`createBloodPressureObservation(...)`](../gdc-sdk-core-ts/src/vital-signs.ts)
|
|
118
|
+
|
|
119
|
+
### Node runtime client
|
|
120
|
+
|
|
121
|
+
- [`NodeHttpClient`](src/node-runtime-client.ts)
|
|
122
|
+
- Main runtime class for submit/poll orchestration against the GW.
|
|
123
|
+
- [`NodeHttpClient.ingestCommunicationAndUpdateIndex(...)`](src/node-runtime-client.ts)
|
|
124
|
+
- Sends a `Communication` ingestion request and polls until indexed.
|
|
125
|
+
- Main params: `ctx`, `input.communicationPayload`, `input.pathFormatSegment?`, `input.autoConvertClaimsToFhirR4?`, `input.pollOptions?`.
|
|
126
|
+
- [`NodeHttpClient.submitCommunicationAndPoll(...)`](src/node-runtime-client.ts)
|
|
127
|
+
- Alias of `ingestCommunicationAndUpdateIndex(...)`.
|
|
128
|
+
- [`NodeHttpClient.searchClinicalBundle(...)`](src/node-runtime-client.ts)
|
|
129
|
+
- Executes clinical `Bundle/_search`.
|
|
130
|
+
- Main params: `ctx`, `input.subject`, `input.section?`, `input.date?`, `input.includedTypes?`, `input.code?`, `input.category?`, `input.author?`, `input.pollOptions?`.
|
|
131
|
+
- [`NodeHttpClient.searchLatestIps(...)`](src/node-runtime-client.ts)
|
|
132
|
+
- Shortcut for latest IPS-oriented document search.
|
|
133
|
+
- [`NodeHttpClient.grantProfessionalAccess(...)`](src/node-runtime-client.ts)
|
|
134
|
+
- Sends a consent-grant flow for a professional actor.
|
|
135
|
+
- [`NodeHttpClient.requestSmartToken(...)`](src/node-runtime-client.ts)
|
|
136
|
+
- Requests SMART/OpenID token material through the GW.
|
|
137
|
+
- Main params: `input.actorDid`, `input.subjectDid`, `input.scopes`, `input.idToken`, optional `input.vpToken`, and optional route compatibility fields when the client was not initialized with a default `ctx`.
|
|
138
|
+
|
|
139
|
+
### Runtime configuration
|
|
140
|
+
|
|
141
|
+
- [`NodeRuntimeConfig`](src/runtime-contracts.ts)
|
|
142
|
+
- Includes `interopMode?`, `persistencePolicy?`, and `outboxRepositoryFactory?` so node runtimes can declare `demo`/`compat`/`strict` mode and choose `memory` vs `server-remote` persistence explicitly.
|
|
143
|
+
- [`initializeCommunicationIdentityFromSeed(...)`](src/identity-bootstrap.ts)
|
|
144
|
+
- Node SDK wrapper for the shared technical communication identity bootstrap helper from `gdc-common-utils-ts`.
|
|
145
|
+
|
|
146
|
+
### Low-level orchestration helpers
|
|
147
|
+
|
|
148
|
+
- [`createOrganizationEmployeeWithDeps(...)`](src/resource-operations.ts)
|
|
149
|
+
- Creates an employee/person batch payload for CORE GW using canonical `org.schema.Person.*` claims.
|
|
150
|
+
- [`importIpsOrFhirAndUpdateIndexWithDeps(...)`](src/resource-operations.ts)
|
|
151
|
+
- [`upsertRelatedPersonAndPollWithDeps(...)`](src/resource-operations.ts)
|
|
152
|
+
- Creates or updates a `RelatedPerson` for family/caregiver roles outside employee/controller flows.
|
|
153
|
+
- [`ingestCommunicationAndUpdateIndexWithDeps(...)`](src/resource-operations.ts)
|
|
154
|
+
- [`searchClinicalBundleWithDeps(...)`](src/resource-operations.ts)
|
|
155
|
+
- [`searchLatestIpsWithDeps(...)`](src/resource-operations.ts)
|
|
156
|
+
- [`grantProfessionalAccessWithDeps(...)`](src/resource-operations.ts)
|
|
157
|
+
- Builds a consent grant where actor targeting should normally be passed as canonical `Consent.actor-identifier` input: a `did:web`, email, `tel:+...`, country code, or comma-separated list of those values.
|
|
158
|
+
|
|
159
|
+
These functions are runtime-oriented building blocks. For application-level document handling, prefer the re-exported communication/document helpers from `gdc-sdk-core-ts`.
|
|
160
|
+
|
|
161
|
+
### Documentation rule
|
|
162
|
+
|
|
163
|
+
- JSDoc on exported code is canonical.
|
|
164
|
+
- README entries should link to source and summarize the most important parameters.
|
|
165
|
+
- If you add a public method/function, document it in JSDoc first and then add it here.
|
|
166
|
+
- If a public payload shape is used in tests or docs, keep its reusable example in the relevant module under [`../gdc-common-utils-ts/src/examples/`](../gdc-common-utils-ts/src/examples/) and link that specific flow file from the relevant markdown section.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AsyncPollRequest, PollOptions, PollResult } from './orchestration/client-port.js';
|
|
2
|
+
export type AcceptedPollResponse = {
|
|
3
|
+
status: number;
|
|
4
|
+
body: unknown;
|
|
5
|
+
retryAfterMs?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function pollUntilCompleteWithMethod(pollOnce: (path: string, request: AsyncPollRequest) => Promise<AcceptedPollResponse>, path: string, request: AsyncPollRequest, options?: PollOptions): Promise<PollResult>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
export async function pollUntilCompleteWithMethod(pollOnce, path, request, options) {
|
|
3
|
+
const timeoutMs = options?.timeoutMs ?? 60000;
|
|
4
|
+
const intervalMs = options?.intervalMs ?? 2000;
|
|
5
|
+
const startedAt = Date.now();
|
|
6
|
+
let attempts = 0;
|
|
7
|
+
while (true) {
|
|
8
|
+
attempts += 1;
|
|
9
|
+
const result = await pollOnce(path, request);
|
|
10
|
+
if (result.status !== 202) {
|
|
11
|
+
return {
|
|
12
|
+
status: result.status,
|
|
13
|
+
body: result.body,
|
|
14
|
+
attempts,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (Date.now() - startedAt > timeoutMs) {
|
|
18
|
+
throw new Error(`Polling timeout after ${attempts} attempts (${timeoutMs}ms).`);
|
|
19
|
+
}
|
|
20
|
+
const waitMs = options?.intervalMs ?? result.retryAfterMs ?? intervalMs;
|
|
21
|
+
await sleep(waitMs);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function sleep(ms) {
|
|
25
|
+
return new Promise((resolve) => setTimeout(resolve, Math.max(0, Math.floor(ms))));
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PollOptions, SubmitAndPollResult } from './orchestration/client-port.js';
|
|
2
|
+
import type { RouteContext } from './individual-onboarding.js';
|
|
3
|
+
export type EmployeeDeviceActivationInput = {
|
|
4
|
+
activationCode: string;
|
|
5
|
+
idToken: string;
|
|
6
|
+
dcrPayload: Record<string, unknown>;
|
|
7
|
+
pollOptions?: PollOptions;
|
|
8
|
+
};
|
|
9
|
+
export type EmployeeDeviceActivationRequestInput = {
|
|
10
|
+
tenantId?: string;
|
|
11
|
+
jurisdiction?: string;
|
|
12
|
+
sector?: string;
|
|
13
|
+
activationCode: string;
|
|
14
|
+
idToken: string;
|
|
15
|
+
dcrPayload: Record<string, unknown>;
|
|
16
|
+
timeoutSeconds?: number;
|
|
17
|
+
intervalSeconds?: number;
|
|
18
|
+
};
|
|
19
|
+
export type EmployeeDeviceActivationResult = {
|
|
20
|
+
initialAccessToken: string;
|
|
21
|
+
exchange: SubmitAndPollResult;
|
|
22
|
+
dcr: SubmitAndPollResult;
|
|
23
|
+
};
|
|
24
|
+
type ActivateEmployeeDeviceDeps = {
|
|
25
|
+
routeCtx: RouteContext;
|
|
26
|
+
input: EmployeeDeviceActivationInput;
|
|
27
|
+
identityTokenExchangePath: (ctx: RouteContext) => string;
|
|
28
|
+
identityTokenExchangePollPath: (ctx: RouteContext) => string;
|
|
29
|
+
identityDeviceDcrPath: (ctx: RouteContext) => string;
|
|
30
|
+
identityDeviceDcrPollPath: (ctx: RouteContext) => string;
|
|
31
|
+
submitAndPollWithBearerToken: (bearerToken: string | undefined, submitPath: string, pollPath: string, payload: {
|
|
32
|
+
thid?: string;
|
|
33
|
+
} & Record<string, unknown>, pollOptions?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
34
|
+
};
|
|
35
|
+
type ActivateEmployeeDeviceRequestDeps = {
|
|
36
|
+
routeCtx: RouteContext;
|
|
37
|
+
input: EmployeeDeviceActivationRequestInput;
|
|
38
|
+
defaultTimeoutMs?: number;
|
|
39
|
+
defaultIntervalMs?: number;
|
|
40
|
+
activateEmployeeDeviceWithActivationCode: (routeCtx: RouteContext, input: EmployeeDeviceActivationInput) => Promise<EmployeeDeviceActivationResult>;
|
|
41
|
+
};
|
|
42
|
+
export declare function activateEmployeeDeviceWithActivationCodeWithDeps(deps: ActivateEmployeeDeviceDeps): Promise<EmployeeDeviceActivationResult>;
|
|
43
|
+
export declare function activateEmployeeDeviceWithActivationRequestWithDeps(deps: ActivateEmployeeDeviceRequestDeps): Promise<EmployeeDeviceActivationResult>;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
3
|
+
export async function activateEmployeeDeviceWithActivationCodeWithDeps(deps) {
|
|
4
|
+
const exchangePayload = {
|
|
5
|
+
thid: `exchange-${createRuntimeUuid()}`,
|
|
6
|
+
subject_token: deps.input.activationCode,
|
|
7
|
+
};
|
|
8
|
+
const exchange = await deps.submitAndPollWithBearerToken(deps.input.idToken, deps.identityTokenExchangePath(deps.routeCtx), deps.identityTokenExchangePollPath(deps.routeCtx), exchangePayload, deps.input.pollOptions);
|
|
9
|
+
const pollBody = exchange.poll.body || {};
|
|
10
|
+
const exchangeBody = (pollBody.body || pollBody);
|
|
11
|
+
const initialAccessToken = String(exchangeBody.initial_access_token || exchangeBody.access_token || '').trim();
|
|
12
|
+
if (!initialAccessToken) {
|
|
13
|
+
throw new Error('activateEmployeeDeviceWithActivationCode: missing initial_access_token in exchange response.');
|
|
14
|
+
}
|
|
15
|
+
const dcrPayload = {
|
|
16
|
+
thid: `dcr-${createRuntimeUuid()}`,
|
|
17
|
+
...deps.input.dcrPayload,
|
|
18
|
+
};
|
|
19
|
+
const dcr = await deps.submitAndPollWithBearerToken(initialAccessToken, deps.identityDeviceDcrPath(deps.routeCtx), deps.identityDeviceDcrPollPath(deps.routeCtx), dcrPayload, deps.input.pollOptions);
|
|
20
|
+
return {
|
|
21
|
+
initialAccessToken,
|
|
22
|
+
exchange,
|
|
23
|
+
dcr,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export async function activateEmployeeDeviceWithActivationRequestWithDeps(deps) {
|
|
27
|
+
const pollOptions = resolvePollOptionsFromSeconds(deps.input.timeoutSeconds, deps.input.intervalSeconds, {
|
|
28
|
+
timeoutMs: deps.defaultTimeoutMs,
|
|
29
|
+
intervalMs: deps.defaultIntervalMs,
|
|
30
|
+
});
|
|
31
|
+
return deps.activateEmployeeDeviceWithActivationCode(deps.routeCtx, {
|
|
32
|
+
activationCode: deps.input.activationCode,
|
|
33
|
+
idToken: deps.input.idToken,
|
|
34
|
+
dcrPayload: deps.input.dcrPayload,
|
|
35
|
+
pollOptions,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function createRuntimeUuid() {
|
|
39
|
+
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
40
|
+
if (fromCrypto) {
|
|
41
|
+
return fromCrypto;
|
|
42
|
+
}
|
|
43
|
+
return `fallback-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ActorKind, type ActorFacadeDescriptor, type ActorSessionDescriptor } from '../../gdc-sdk-core-ts/dist/index.js';
|
|
2
|
+
import { ActorSession, NodeActorSession } from './session.js';
|
|
3
|
+
import type { RuntimeClient } from './orchestration/client-port.js';
|
|
4
|
+
export declare function createNodeActorSessionsFromFacades(facades: ActorFacadeDescriptor[], client?: RuntimeClient): NodeActorSession[];
|
|
5
|
+
export declare function createNodeActorSessionFromFacade(facade: ActorFacadeDescriptor, client?: RuntimeClient): NodeActorSession;
|
|
6
|
+
export declare function createNodeActorSessionsFromDescriptor(descriptor: ActorSessionDescriptor, client?: RuntimeClient): NodeActorSession[];
|
|
7
|
+
export declare function createNodeActorSessionFromDescriptor(descriptor: ActorSessionDescriptor, actorKind: ActorKind, client?: RuntimeClient): NodeActorSession;
|
|
8
|
+
export declare function createActorSessionsFromFacades(facades: ActorFacadeDescriptor[], client?: RuntimeClient): ActorSession[];
|
|
9
|
+
export declare function createActorSessionFromFacade(facade: ActorFacadeDescriptor, client?: RuntimeClient): ActorSession;
|
|
10
|
+
export declare function createActorSessionsFromDescriptor(descriptor: ActorSessionDescriptor, client?: RuntimeClient): ActorSession[];
|
|
11
|
+
export declare function createActorSessionFromDescriptor(descriptor: ActorSessionDescriptor, actorKind: ActorKind, client?: RuntimeClient): ActorSession;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { expandActorSessionDescriptorToFacades, filterCapabilitiesForActor, } from '../../gdc-sdk-core-ts/dist/index.js';
|
|
3
|
+
import { ActorSession, NodeActorSession } from './session.js';
|
|
4
|
+
const capabilityMap = {
|
|
5
|
+
'organization.create_employee': 'organization.create_employee',
|
|
6
|
+
'organization.issue_activation_code': 'organization.issue_activation_code',
|
|
7
|
+
'organization.request_smart_token': 'organization.request_smart_token',
|
|
8
|
+
'individual.bootstrap': 'individual.bootstrap',
|
|
9
|
+
'individual.import_ips': 'individual.import_ips',
|
|
10
|
+
'individual.generate_digital_twin': 'individual.generate_digital_twin',
|
|
11
|
+
'consent.grant_professional_access': 'consent.grant_professional_access',
|
|
12
|
+
'professional.medication': 'professional.medication',
|
|
13
|
+
'professional.appointment': 'professional.appointment',
|
|
14
|
+
'professional.request_smart_token': 'professional.request_smart_token',
|
|
15
|
+
};
|
|
16
|
+
function mapCapabilities(capabilities) {
|
|
17
|
+
return [...new Set(capabilities.map(capability => capabilityMap[capability]))];
|
|
18
|
+
}
|
|
19
|
+
export function createNodeActorSessionsFromFacades(facades, client) {
|
|
20
|
+
return facades.map(facade => new NodeActorSession({
|
|
21
|
+
actorKind: facade.actorKind,
|
|
22
|
+
actorDid: facade.profileDid,
|
|
23
|
+
capabilities: mapCapabilities(filterCapabilitiesForActor(facade.actorKind, facade.capabilities)),
|
|
24
|
+
}, client));
|
|
25
|
+
}
|
|
26
|
+
export function createNodeActorSessionFromFacade(facade, client) {
|
|
27
|
+
return new NodeActorSession({
|
|
28
|
+
actorKind: facade.actorKind,
|
|
29
|
+
actorDid: facade.profileDid,
|
|
30
|
+
capabilities: mapCapabilities(filterCapabilitiesForActor(facade.actorKind, facade.capabilities)),
|
|
31
|
+
}, client);
|
|
32
|
+
}
|
|
33
|
+
export function createNodeActorSessionsFromDescriptor(descriptor, client) {
|
|
34
|
+
return createNodeActorSessionsFromFacades(expandActorSessionDescriptorToFacades(descriptor), client);
|
|
35
|
+
}
|
|
36
|
+
export function createNodeActorSessionFromDescriptor(descriptor, actorKind, client) {
|
|
37
|
+
if (!descriptor.actorKinds.includes(actorKind)) {
|
|
38
|
+
throw new Error(`Descriptor does not expose actor kind '${actorKind}'.`);
|
|
39
|
+
}
|
|
40
|
+
const facade = expandActorSessionDescriptorToFacades(descriptor)
|
|
41
|
+
.find(candidate => candidate.actorKind === actorKind);
|
|
42
|
+
if (!facade) {
|
|
43
|
+
throw new Error(`Descriptor does not expose actor kind '${actorKind}'.`);
|
|
44
|
+
}
|
|
45
|
+
return createNodeActorSessionFromFacade(facade, client);
|
|
46
|
+
}
|
|
47
|
+
export function createActorSessionsFromFacades(facades, client) {
|
|
48
|
+
return facades.map(facade => new ActorSession({
|
|
49
|
+
actorKind: facade.actorKind,
|
|
50
|
+
actorDid: facade.profileDid,
|
|
51
|
+
capabilities: mapCapabilities(filterCapabilitiesForActor(facade.actorKind, facade.capabilities)),
|
|
52
|
+
}, client));
|
|
53
|
+
}
|
|
54
|
+
export function createActorSessionFromFacade(facade, client) {
|
|
55
|
+
return new ActorSession({
|
|
56
|
+
actorKind: facade.actorKind,
|
|
57
|
+
actorDid: facade.profileDid,
|
|
58
|
+
capabilities: mapCapabilities(filterCapabilitiesForActor(facade.actorKind, facade.capabilities)),
|
|
59
|
+
}, client);
|
|
60
|
+
}
|
|
61
|
+
export function createActorSessionsFromDescriptor(descriptor, client) {
|
|
62
|
+
return createActorSessionsFromFacades(expandActorSessionDescriptorToFacades(descriptor), client);
|
|
63
|
+
}
|
|
64
|
+
export function createActorSessionFromDescriptor(descriptor, actorKind, client) {
|
|
65
|
+
if (!descriptor.actorKinds.includes(actorKind)) {
|
|
66
|
+
throw new Error(`Descriptor does not expose actor kind '${actorKind}'.`);
|
|
67
|
+
}
|
|
68
|
+
const facade = expandActorSessionDescriptorToFacades(descriptor)
|
|
69
|
+
.find(candidate => candidate.actorKind === actorKind);
|
|
70
|
+
if (!facade) {
|
|
71
|
+
throw new Error(`Descriptor does not expose actor kind '${actorKind}'.`);
|
|
72
|
+
}
|
|
73
|
+
return createActorSessionFromFacade(facade, client);
|
|
74
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { PollOptions, SubmitAndPollResult } from './orchestration/client-port.js';
|
|
2
|
+
/**
|
|
3
|
+
* Current host-registry route context for existing host endpoints.
|
|
4
|
+
*
|
|
5
|
+
* This is a routing object for host registry calls. It is not the same thing as
|
|
6
|
+
* a node-operator discovery descriptor.
|
|
7
|
+
*/
|
|
8
|
+
export type HostRouteContext = {
|
|
9
|
+
jurisdiction: string;
|
|
10
|
+
sector: string;
|
|
11
|
+
controllerDid?: string;
|
|
12
|
+
hostDid?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Input for legal-organization order confirmation in the host registry.
|
|
16
|
+
*/
|
|
17
|
+
export type LegalOrganizationOrderInput = {
|
|
18
|
+
offerId: string;
|
|
19
|
+
jurisdiction?: string;
|
|
20
|
+
sector?: string;
|
|
21
|
+
dataType?: string;
|
|
22
|
+
additionalClaims?: Record<string, unknown>;
|
|
23
|
+
timeoutSeconds?: number;
|
|
24
|
+
intervalSeconds?: number;
|
|
25
|
+
};
|
|
26
|
+
type ConfirmLegalOrganizationOrderDeps = {
|
|
27
|
+
input: LegalOrganizationOrderInput;
|
|
28
|
+
hostCtx: HostRouteContext;
|
|
29
|
+
defaultTimeoutMs?: number;
|
|
30
|
+
defaultIntervalMs?: number;
|
|
31
|
+
hostRegistryOrderBatchPath: (ctx: HostRouteContext) => string;
|
|
32
|
+
hostRegistryOrderPollPath: (ctx: HostRouteContext) => string;
|
|
33
|
+
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
34
|
+
thid?: string;
|
|
35
|
+
} & Record<string, unknown>, options?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
36
|
+
};
|
|
37
|
+
export declare function confirmLegalOrganizationOrderWithDeps(deps: ConfirmLegalOrganizationOrderDeps): Promise<SubmitAndPollResult>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
3
|
+
export async function confirmLegalOrganizationOrderWithDeps(deps) {
|
|
4
|
+
const offerId = String(deps.input.offerId || '').trim();
|
|
5
|
+
if (!offerId) {
|
|
6
|
+
throw new Error('confirmLegalOrganizationOrder requires offerId.');
|
|
7
|
+
}
|
|
8
|
+
const claims = {
|
|
9
|
+
'@context': 'org.schema',
|
|
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
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type CommunicationIdentityBootstrapOptions, type CommunicationIdentityBootstrapResult } from 'gdc-common-utils-ts/utils/communication-identity';
|
|
2
|
+
/**
|
|
3
|
+
* Node SDK convenience wrapper for the shared technical communication identity
|
|
4
|
+
* bootstrap helper defined in `gdc-common-utils-ts`.
|
|
5
|
+
*
|
|
6
|
+
* Use this from node backends when you want the bootstrap API to be reachable
|
|
7
|
+
* directly from `gdc-sdk-node-ts`, while keeping the implementation shared.
|
|
8
|
+
*
|
|
9
|
+
* This bootstraps the technical device/portal/app communication identity used
|
|
10
|
+
* to secure DIDComm/JOSE envelopes. It is distinct from the personal wallet or
|
|
11
|
+
* controller identity that may later sign user-controlled operations such as
|
|
12
|
+
* access-token or consent requests.
|
|
13
|
+
*
|
|
14
|
+
* Implemented today:
|
|
15
|
+
* - deterministic/random technical transport identity bootstrap
|
|
16
|
+
* - direct reuse of shared JOSE header and key-shape helpers
|
|
17
|
+
*
|
|
18
|
+
* Still pending in the node SDK:
|
|
19
|
+
* - first-class controller/person identity bootstrap API
|
|
20
|
+
* - integrated persistence of deviceIdentity vs actorIdentity vs providerIdentity
|
|
21
|
+
* - direct coupling with remote DID/discovery resolution
|
|
22
|
+
*
|
|
23
|
+
* Canonical copyable payload examples for related bootstrap flows live in:
|
|
24
|
+
* `gdc-common-utils-ts/examples`
|
|
25
|
+
*
|
|
26
|
+
* @param options Stable seed/bootstrap options. See the shared
|
|
27
|
+
* `CommunicationIdentityBootstrapOptions` JSDoc in `gdc-common-utils-ts`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function initializeCommunicationIdentityFromSeed(options: CommunicationIdentityBootstrapOptions): Promise<CommunicationIdentityBootstrapResult>;
|
|
30
|
+
export type { CommunicationIdentityBootstrapOptions as NodeSdkCommunicationIdentityBootstrapOptions, CommunicationIdentityBootstrapResult as NodeSdkCommunicationIdentityBootstrapResult, } from 'gdc-common-utils-ts/utils/communication-identity';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { initializeCommunicationIdentityFromSeed as initializeSharedCommunicationIdentityFromSeed, } from 'gdc-common-utils-ts/utils/communication-identity';
|
|
3
|
+
/**
|
|
4
|
+
* Node SDK convenience wrapper for the shared technical communication identity
|
|
5
|
+
* bootstrap helper defined in `gdc-common-utils-ts`.
|
|
6
|
+
*
|
|
7
|
+
* Use this from node backends when you want the bootstrap API to be reachable
|
|
8
|
+
* directly from `gdc-sdk-node-ts`, while keeping the implementation shared.
|
|
9
|
+
*
|
|
10
|
+
* This bootstraps the technical device/portal/app communication identity used
|
|
11
|
+
* to secure DIDComm/JOSE envelopes. It is distinct from the personal wallet or
|
|
12
|
+
* controller identity that may later sign user-controlled operations such as
|
|
13
|
+
* access-token or consent requests.
|
|
14
|
+
*
|
|
15
|
+
* Implemented today:
|
|
16
|
+
* - deterministic/random technical transport identity bootstrap
|
|
17
|
+
* - direct reuse of shared JOSE header and key-shape helpers
|
|
18
|
+
*
|
|
19
|
+
* Still pending in the node SDK:
|
|
20
|
+
* - first-class controller/person identity bootstrap API
|
|
21
|
+
* - integrated persistence of deviceIdentity vs actorIdentity vs providerIdentity
|
|
22
|
+
* - direct coupling with remote DID/discovery resolution
|
|
23
|
+
*
|
|
24
|
+
* Canonical copyable payload examples for related bootstrap flows live in:
|
|
25
|
+
* `gdc-common-utils-ts/examples`
|
|
26
|
+
*
|
|
27
|
+
* @param options Stable seed/bootstrap options. See the shared
|
|
28
|
+
* `CommunicationIdentityBootstrapOptions` JSDoc in `gdc-common-utils-ts`.
|
|
29
|
+
*/
|
|
30
|
+
export async function initializeCommunicationIdentityFromSeed(options) {
|
|
31
|
+
return initializeSharedCommunicationIdentityFromSeed(options);
|
|
32
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export * from '../../gdc-sdk-core-ts/dist/index.js';
|
|
2
|
+
export * from './runtime-contracts.js';
|
|
3
|
+
export * from './identity-bootstrap.js';
|
|
4
|
+
export * from './async-polling.js';
|
|
5
|
+
export * from './poll-options.js';
|
|
6
|
+
export * from './host-onboarding.js';
|
|
7
|
+
export * from './individual-start.js';
|
|
8
|
+
export * from './individual-onboarding.js';
|
|
9
|
+
export * from './device-activation.js';
|
|
10
|
+
export * from './smart-token.js';
|
|
11
|
+
export * from './resource-operations.js';
|
|
12
|
+
export * from './session.js';
|
|
13
|
+
export * from './node-runtime-client.js';
|
|
14
|
+
export * from './gdc-session-bridge.js';
|
|
15
|
+
export * from './orchestration/client-port.js';
|
|
16
|
+
export * from './orchestration/host-onboarding-sdk.js';
|
|
17
|
+
export * from './orchestration/organization-controller-sdk.js';
|
|
18
|
+
export * from './orchestration/organization-employee-sdk.js';
|
|
19
|
+
export * from './orchestration/individual-controller-sdk.js';
|
|
20
|
+
export * from './orchestration/individual-member-sdk.js';
|
|
21
|
+
export * from './orchestration/personal-sdk.js';
|
|
22
|
+
export * from './orchestration/professional-sdk.js';
|
|
23
|
+
export * from './legacy-compat.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
export * from '../../gdc-sdk-core-ts/dist/index.js';
|
|
3
|
+
export * from './runtime-contracts.js';
|
|
4
|
+
export * from './identity-bootstrap.js';
|
|
5
|
+
export * from './async-polling.js';
|
|
6
|
+
export * from './poll-options.js';
|
|
7
|
+
export * from './host-onboarding.js';
|
|
8
|
+
export * from './individual-start.js';
|
|
9
|
+
export * from './individual-onboarding.js';
|
|
10
|
+
export * from './device-activation.js';
|
|
11
|
+
export * from './smart-token.js';
|
|
12
|
+
export * from './resource-operations.js';
|
|
13
|
+
export * from './session.js';
|
|
14
|
+
export * from './node-runtime-client.js';
|
|
15
|
+
export * from './gdc-session-bridge.js';
|
|
16
|
+
export * from './orchestration/client-port.js';
|
|
17
|
+
export * from './orchestration/host-onboarding-sdk.js';
|
|
18
|
+
export * from './orchestration/organization-controller-sdk.js';
|
|
19
|
+
export * from './orchestration/organization-employee-sdk.js';
|
|
20
|
+
export * from './orchestration/individual-controller-sdk.js';
|
|
21
|
+
export * from './orchestration/individual-member-sdk.js';
|
|
22
|
+
export * from './orchestration/personal-sdk.js';
|
|
23
|
+
export * from './orchestration/professional-sdk.js';
|
|
24
|
+
export * from './legacy-compat.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DataspaceSector } from 'gdc-common-utils-ts/constants';
|
|
2
|
+
import type { PollOptions, SubmitAndPollResult } from './orchestration/client-port.js';
|
|
3
|
+
export type RouteContext = {
|
|
4
|
+
tenantId: string;
|
|
5
|
+
jurisdiction: string;
|
|
6
|
+
sector: DataspaceSector | string;
|
|
7
|
+
};
|
|
8
|
+
export type IndividualOrganizationConfirmOrderInput = {
|
|
9
|
+
/**
|
|
10
|
+
* Preferred route identifier for the selected personal indexing service provider.
|
|
11
|
+
*/
|
|
12
|
+
serviceProviderDid?: string;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Use `serviceProviderDid`.
|
|
15
|
+
*/
|
|
16
|
+
tenantId?: string;
|
|
17
|
+
jurisdiction?: string;
|
|
18
|
+
sector?: string;
|
|
19
|
+
offerId: string;
|
|
20
|
+
timeoutSeconds?: number;
|
|
21
|
+
intervalSeconds?: number;
|
|
22
|
+
};
|
|
23
|
+
type ConfirmIndividualOrganizationOrderDeps = {
|
|
24
|
+
input: IndividualOrganizationConfirmOrderInput;
|
|
25
|
+
routeCtx: RouteContext;
|
|
26
|
+
defaultTimeoutMs?: number;
|
|
27
|
+
defaultIntervalMs?: number;
|
|
28
|
+
individualFamilyOrderBatchPath: (ctx: RouteContext) => string;
|
|
29
|
+
individualFamilyOrderPollPath: (ctx: RouteContext) => string;
|
|
30
|
+
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
31
|
+
thid?: string;
|
|
32
|
+
} & Record<string, unknown>, options?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
33
|
+
};
|
|
34
|
+
export declare function confirmIndividualOrganizationOrderWithDeps(deps: ConfirmIndividualOrganizationOrderDeps): Promise<SubmitAndPollResult>;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
3
|
+
export async function confirmIndividualOrganizationOrderWithDeps(deps) {
|
|
4
|
+
const offerId = String(deps.input.offerId || '').trim();
|
|
5
|
+
if (!offerId) {
|
|
6
|
+
throw new Error('confirmIndividualOrganizationOrder requires offerId.');
|
|
7
|
+
}
|
|
8
|
+
const orderClaims = {
|
|
9
|
+
'@context': 'org.schema',
|
|
10
|
+
'Order.acceptedOffer.identifier': offerId,
|
|
11
|
+
};
|
|
12
|
+
const payload = {
|
|
13
|
+
jti: `jti-${createRuntimeUuid()}`,
|
|
14
|
+
iss: deps.routeCtx.tenantId,
|
|
15
|
+
aud: deps.routeCtx.tenantId,
|
|
16
|
+
type: 'application/didcomm-plain+json',
|
|
17
|
+
thid: `family-order-${createRuntimeUuid()}`,
|
|
18
|
+
body: {
|
|
19
|
+
data: [{
|
|
20
|
+
type: 'Family-order-request-v1.0',
|
|
21
|
+
meta: { claims: orderClaims },
|
|
22
|
+
resource: { meta: { claims: orderClaims } },
|
|
23
|
+
}],
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const pollOptions = resolvePollOptionsFromSeconds(deps.input.timeoutSeconds, deps.input.intervalSeconds, {
|
|
27
|
+
timeoutMs: deps.defaultTimeoutMs,
|
|
28
|
+
intervalMs: deps.defaultIntervalMs,
|
|
29
|
+
});
|
|
30
|
+
return deps.submitAndPoll(deps.individualFamilyOrderBatchPath(deps.routeCtx), deps.individualFamilyOrderPollPath(deps.routeCtx), payload, pollOptions);
|
|
31
|
+
}
|
|
32
|
+
function createRuntimeUuid() {
|
|
33
|
+
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
34
|
+
if (fromCrypto) {
|
|
35
|
+
return fromCrypto;
|
|
36
|
+
}
|
|
37
|
+
return `fallback-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
38
|
+
}
|