gdc-sdk-node-ts 2.3.4 → 2.3.6
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 +20 -13
- package/dist/node-runtime-client.d.ts +24 -1
- package/dist/node-runtime-client.js +23 -1
- package/dist/orchestration/client-port.d.ts +3 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +5 -1
- package/dist/orchestration/individual-controller-sdk.js +10 -0
- package/dist/orchestration/individual-member-sdk.d.ts +5 -1
- package/dist/orchestration/individual-member-sdk.js +8 -0
- package/dist/orchestration/personal-sdk.d.ts +5 -1
- package/dist/orchestration/personal-sdk.js +8 -0
- package/dist/orchestration/professional-sdk.d.ts +10 -1
- package/dist/orchestration/professional-sdk.js +13 -0
- package/dist/resource-operations.d.ts +23 -5
- package/dist/resource-operations.js +17 -1
- package/dist/server-profile-session.js +7 -2
- package/dist/smart-token.d.ts +7 -0
- package/dist/smart-token.js +41 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -66,43 +66,46 @@ If you are integrating this package for the first time, open these in order:
|
|
|
66
66
|
1. [gdc-sdk-core-ts/docs/101-SDK_PACKAGE_BOUNDARIES.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-SDK_PACKAGE_BOUNDARIES.md)
|
|
67
67
|
Why `core`, `node`, and `front` are separate packages, what belongs in each
|
|
68
68
|
one, and why actor-scoped facades must stay aligned across runtimes.
|
|
69
|
-
|
|
69
|
+
2. [docs/101-SDK_END_TO_END.md](./docs/101-SDK_END_TO_END.md)
|
|
70
70
|
Ordered onboarding guide with end-to-end journeys, copy/paste snippets, and
|
|
71
71
|
the recommended reading path for new backend integrators.
|
|
72
|
-
|
|
72
|
+
3. [docs/101-PROFESSIONAL-CONSENT-SMART.md](./docs/101-PROFESSIONAL-CONSENT-SMART.md)
|
|
73
|
+
Canonical professional DID, consent, VP and SMART flow without literal
|
|
74
|
+
sections or caller-built audience URLs.
|
|
75
|
+
4. [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
|
|
73
76
|
Real backend setup plus the public runtime entrypoints:
|
|
74
77
|
`HostOnboardingSdk`, `OrganizationControllerSdk`,
|
|
75
78
|
`IndividualControllerSdk`, `ProfessionalSdk`, route-context usage, and the
|
|
76
79
|
canonical `ProfileRuntime -> loadProfile(...) -> workspace/session -> actor facade -> submit/poll` shape.
|
|
77
|
-
|
|
80
|
+
5. [tests/101-live-full-cycle-bff-runtime.e2e.test.mjs](./tests/101-live-full-cycle-bff-runtime.e2e.test.mjs)
|
|
78
81
|
Canonical live backend/BFF walkthrough on a fresh local GW lifecycle:
|
|
79
82
|
host/tenant activation, employee provisioning, individual bootstrap,
|
|
80
83
|
consent grant, professional SMART token, clinical read, and final cleanup.
|
|
81
|
-
|
|
84
|
+
6. [docs/101-LIVE_GW_LOCAL.md](./docs/101-LIVE_GW_LOCAL.md)
|
|
82
85
|
Exact TTY/local/Docker commands for running the SDK against a real local GW
|
|
83
86
|
CORE, including tenant bootstrap and employee-seat setup.
|
|
84
|
-
|
|
87
|
+
7. [docs/101-DISCOVERY.md](./docs/101-DISCOVERY.md)
|
|
85
88
|
Node/BFF dataspace discovery, hosting-operator resolution, provider
|
|
86
89
|
resolution, and the correct integration boundary for fallback and cache.
|
|
87
|
-
|
|
90
|
+
8. [gdc-sdk-core-ts/docs/101-SDK_FLOWS.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-SDK_FLOWS.md)
|
|
88
91
|
Actor split and business-flow map across organization, individual,
|
|
89
92
|
permissions, invitation, import, and SMART flows.
|
|
90
|
-
|
|
93
|
+
9. [gwtemplate-node-ts/docs/PORTAL_API_TO_GW_CORE.md](https://github.com/Global-DataCare/gwtemplate-node-ts/blob/main/docs/PORTAL_API_TO_GW_CORE.md)
|
|
91
94
|
Canonical portal/BFF functional map over GW CORE, including the domain
|
|
92
95
|
split between `employees`, `related persons`, `members`, and `consents`.
|
|
93
|
-
|
|
96
|
+
10. [gdc-common-utils-ts/src/examples/](https://github.com/Global-DataCare/gdc-common-utils-ts/tree/main/src/examples)
|
|
94
97
|
Shared payload values used by the docs and tests.
|
|
95
|
-
|
|
98
|
+
11. [gdc-common-utils-ts/docs/101-LIFECYCLE.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-LIFECYCLE.md)
|
|
96
99
|
Canonical `enable/disable/delete` semantics and copy/paste placeholders.
|
|
97
|
-
|
|
100
|
+
12. [tests/101-backend-profile-runtime.test.mjs](./tests/101-backend-profile-runtime.test.mjs)
|
|
98
101
|
Technical runtime slice for profile/device/session orchestration internals.
|
|
99
102
|
Read this after the public actor SDK guides, not before them.
|
|
100
|
-
|
|
103
|
+
13. [tests/101-individual-controller-backend-runtime.test.mjs](./tests/101-individual-controller-backend-runtime.test.mjs)
|
|
101
104
|
Technical wrapper slice around the generic profile runtime. This is not the
|
|
102
105
|
main onboarding path for new integrators.
|
|
103
|
-
|
|
106
|
+
14. [docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md](./docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md)
|
|
104
107
|
Historical reconciliation note for the current CORE registration baseline.
|
|
105
|
-
|
|
108
|
+
15. [docs/NEXT_STEPS.md](./docs/NEXT_STEPS.md)
|
|
106
109
|
Follow-up scope after GW CORE live validation, including the future user job
|
|
107
110
|
manager boundary.
|
|
108
111
|
|
|
@@ -647,6 +650,10 @@ modules below.
|
|
|
647
650
|
- [`NodeHttpClient.ingestCommunicationAndUpdateIndex(...)`](src/node-runtime-client.ts)
|
|
648
651
|
- [`NodeHttpClient.submitCommunicationAndPoll(...)`](src/node-runtime-client.ts)
|
|
649
652
|
- [`NodeHttpClient.searchClinicalBundle(...)`](src/node-runtime-client.ts)
|
|
653
|
+
- [`NodeHttpClient.updateClinicalSection(...)`](src/node-runtime-client.ts) for
|
|
654
|
+
one explicit section carried by a batch/collection Communication
|
|
655
|
+
- [`NodeHttpClient.updateClinicalSummary(...)`](src/node-runtime-client.ts) for
|
|
656
|
+
a Composition-first multi-section document
|
|
650
657
|
- [`NodeHttpClient.searchLatestIps(...)`](src/node-runtime-client.ts)
|
|
651
658
|
- [`NodeHttpClient.grantProfessionalAccess(...)`](src/node-runtime-client.ts)
|
|
652
659
|
- [`NodeHttpClient.requestSmartToken(...)`](src/node-runtime-client.ts)
|
|
@@ -11,7 +11,7 @@ import { type SmartTokenRequestInput } from './smart-token.js';
|
|
|
11
11
|
import { type EmployeeDeviceActivationRequestInput, type EmployeeDeviceActivationResult } from './device-activation.js';
|
|
12
12
|
import { type OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
13
13
|
import { type IndividualOrganizationBootstrapInput, type IndividualOrganizationStartResult } from './individual-start.js';
|
|
14
|
-
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
14
|
+
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSectionUpdateInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type ClinicalSummaryUpdateInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
15
15
|
import type { LegalOrganizationOrderInput } from './host-onboarding.js';
|
|
16
16
|
import type { SmartTokenExchangeResult } from './smart-token.js';
|
|
17
17
|
import type { NodeRuntimeClient, PollOptions, PollResult, SubmitAndPollResult, SubmitPayload, SubmitResponse } from './orchestration/client-port.js';
|
|
@@ -57,6 +57,12 @@ export type HttpRuntimeClientOptions = {
|
|
|
57
57
|
communicationFormatRenderers?: CommunicationClinicalFormatRenderers;
|
|
58
58
|
/** Injectable fetch implementation for BFF adapters and deterministic tests. */
|
|
59
59
|
fetchImpl?: typeof fetch;
|
|
60
|
+
/**
|
|
61
|
+
* Optional trusted provider-index/DID resolver for subject-scoped SMART
|
|
62
|
+
* requests. The runtime uses the resolved endpoint for transport and JWT
|
|
63
|
+
* audience; application-level callers do not need to pass `audience`.
|
|
64
|
+
*/
|
|
65
|
+
smartTokenEndpointResolver?: (subjectDid: string) => Promise<string | undefined>;
|
|
60
66
|
};
|
|
61
67
|
/**
|
|
62
68
|
* @deprecated Prefer `HttpRuntimeClientOptions`.
|
|
@@ -82,6 +88,7 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
82
88
|
private readonly secureTransportAdapter?;
|
|
83
89
|
private readonly communicationFormatRenderers;
|
|
84
90
|
private readonly fetchImpl?;
|
|
91
|
+
private readonly smartTokenEndpointResolver?;
|
|
85
92
|
private readonly httpTraceFile?;
|
|
86
93
|
private readonly tokenCache;
|
|
87
94
|
private readonly paths;
|
|
@@ -402,6 +409,22 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
402
409
|
* @param input Communication payload plus route/format options.
|
|
403
410
|
*/
|
|
404
411
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
412
|
+
/**
|
|
413
|
+
* Updates exactly one clinical section.
|
|
414
|
+
*
|
|
415
|
+
* The attached payload must be a `Bundle.type=batch|collection`, and the
|
|
416
|
+
* exact section is carried on the outer Communication. This flow is suitable
|
|
417
|
+
* for vital-sign or other explicitly section-scoped updates; it does not
|
|
418
|
+
* replace a multi-section IPS document.
|
|
419
|
+
*/
|
|
420
|
+
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
421
|
+
/**
|
|
422
|
+
* Updates several clinical sections as one Composition-first document.
|
|
423
|
+
*
|
|
424
|
+
* The attached payload must be `Bundle.type=document` with `Composition` in
|
|
425
|
+
* `entry[0]`; its `section[].entry[]` references delimit the updated data.
|
|
426
|
+
*/
|
|
427
|
+
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
405
428
|
/**
|
|
406
429
|
* Reads the authoritative clinical document currently available for one
|
|
407
430
|
* subject through an auditable `Communication` request to `Subject/$summary`.
|
|
@@ -12,7 +12,7 @@ import { activateEmployeeDeviceWithActivationCodeWithDeps, activateEmployeeDevic
|
|
|
12
12
|
import { extractOfferIdFromResponseBody, extractOfferPreviewFromResponseBody, } from './order-offer-summary.js';
|
|
13
13
|
import { confirmOrganizationLicenseOrderWithDeps } from './organization-license-order.js';
|
|
14
14
|
import { startIndividualOrganizationWithDeps } from './individual-start.js';
|
|
15
|
-
import { createOrganizationEmployeeWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, ingestCommunicationAndUpdateIndexWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, } from './resource-operations.js';
|
|
15
|
+
import { createOrganizationEmployeeWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, buildClinicalSectionUpdateIngestion, buildClinicalSummaryUpdateIngestion, ingestCommunicationAndUpdateIndexWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, } from './resource-operations.js';
|
|
16
16
|
import { submitAndPollWithMethods } from './orchestration/client-port.js';
|
|
17
17
|
import { buildRuntimeHeaders, fetchWithTimeout, parseResponseBody, pollBatchResponseWithRuntimeConfig, postJsonWithRuntimeConfig, postRenderedWithRuntimeConfig, } from './runtime-transport.js';
|
|
18
18
|
import { activateOrganizationInGatewayFromIcaProofWithDeps, submitLegalOrganizationIssueWithDeps, submitLegalOrganizationVerificationTransactionWithDeps, submitOrganizationDidBindingWithDeps, } from './runtime-host-submission.js';
|
|
@@ -68,6 +68,7 @@ export class HttpRuntimeClient {
|
|
|
68
68
|
this.secureTransportAdapter = options.secureTransportAdapter;
|
|
69
69
|
this.communicationFormatRenderers = options.communicationFormatRenderers || {};
|
|
70
70
|
this.fetchImpl = options.fetchImpl;
|
|
71
|
+
this.smartTokenEndpointResolver = options.smartTokenEndpointResolver;
|
|
71
72
|
this.httpTraceFile = String(process.env.SDK_HTTP_TRACE_FILE || '').trim() || undefined;
|
|
72
73
|
this.paths = new RuntimeClientPaths(this.ctx);
|
|
73
74
|
}
|
|
@@ -690,6 +691,7 @@ export class HttpRuntimeClient {
|
|
|
690
691
|
identityTokenExchangePollPath: this.paths.identityTokenExchangePollPath.bind(this.paths),
|
|
691
692
|
identityOpenIdSmartTokenPath: this.paths.identityOpenIdSmartTokenPath.bind(this.paths),
|
|
692
693
|
identityOpenIdSmartTokenPollPath: this.paths.identityOpenIdSmartTokenPollPath.bind(this.paths),
|
|
694
|
+
resolveSmartTokenEndpoint: this.smartTokenEndpointResolver,
|
|
693
695
|
submitAndPoll: this.submitAndPoll.bind(this),
|
|
694
696
|
setTokenCache: (tokenCacheKey, token) => this.tokenCache.set(tokenCacheKey, token),
|
|
695
697
|
});
|
|
@@ -743,6 +745,26 @@ export class HttpRuntimeClient {
|
|
|
743
745
|
submitAndPoll: this.submitAndPoll.bind(this),
|
|
744
746
|
});
|
|
745
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Updates exactly one clinical section.
|
|
750
|
+
*
|
|
751
|
+
* The attached payload must be a `Bundle.type=batch|collection`, and the
|
|
752
|
+
* exact section is carried on the outer Communication. This flow is suitable
|
|
753
|
+
* for vital-sign or other explicitly section-scoped updates; it does not
|
|
754
|
+
* replace a multi-section IPS document.
|
|
755
|
+
*/
|
|
756
|
+
async updateClinicalSection(ctx, input) {
|
|
757
|
+
return this.ingestCommunicationAndUpdateIndex(ctx, buildClinicalSectionUpdateIngestion(input));
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Updates several clinical sections as one Composition-first document.
|
|
761
|
+
*
|
|
762
|
+
* The attached payload must be `Bundle.type=document` with `Composition` in
|
|
763
|
+
* `entry[0]`; its `section[].entry[]` references delimit the updated data.
|
|
764
|
+
*/
|
|
765
|
+
async updateClinicalSummary(ctx, input) {
|
|
766
|
+
return this.ingestCommunicationAndUpdateIndex(ctx, buildClinicalSummaryUpdateIngestion(input));
|
|
767
|
+
}
|
|
746
768
|
/**
|
|
747
769
|
* Reads the authoritative clinical document currently available for one
|
|
748
770
|
* subject through an auditable `Communication` request to `Subject/$summary`.
|
|
@@ -13,7 +13,7 @@ import type { FamilyOrganizationSearchInput } from '../family-organization-searc
|
|
|
13
13
|
import type { EnsureFamilyOrganizationRegistrationInput, EnsureFamilyOrganizationRegistrationResult } from '../family-organization-registration.js';
|
|
14
14
|
import type { OrganizationLicenseOrderConfirmInput } from '../organization-license-order.js';
|
|
15
15
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
16
|
-
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
16
|
+
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
17
17
|
/**
|
|
18
18
|
* Shared node-runtime activation input.
|
|
19
19
|
*
|
|
@@ -89,6 +89,8 @@ export type RuntimeClient = {
|
|
|
89
89
|
disableIndividualOrganization?: (ctx: RouteContext, input: IndividualOrganizationLifecycleInput, pollOptions?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
90
90
|
purgeIndividualOrganization?: (ctx: RouteContext, input: IndividualOrganizationLifecycleInput, pollOptions?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
91
91
|
ingestCommunicationAndUpdateIndex?: (ctx: RouteContext, input: CommunicationIngestionInput) => Promise<SubmitAndPollResult>;
|
|
92
|
+
updateClinicalSection?: (ctx: RouteContext, input: ClinicalSectionUpdateInput) => Promise<SubmitAndPollResult>;
|
|
93
|
+
updateClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryUpdateInput) => Promise<SubmitAndPollResult>;
|
|
92
94
|
requestClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryRequestInput) => Promise<ClinicalSummaryReadResult>;
|
|
93
95
|
registerBlockchainArtifactAndUpdateIndex?: (ctx: RouteContext, input: BlockchainArtifactRegistrationInput) => Promise<SubmitAndPollResult>;
|
|
94
96
|
searchCommunicationParticipants?: (ctx: RouteContext, input: CommunicationParticipantRuntimeSearchInput) => Promise<SubmitAndPollResult>;
|
|
@@ -7,7 +7,7 @@ import type { IndividualOrganizationConfirmOrderInput, RouteContext } from '../i
|
|
|
7
7
|
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } from '../individual-start.js';
|
|
8
8
|
import type { NodeCapability } from '../session.js';
|
|
9
9
|
import type { IndividualOrganizationLifecycleInput } from 'gdc-sdk-core-ts';
|
|
10
|
-
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
10
|
+
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
11
11
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
12
12
|
/**
|
|
13
13
|
* Individual-controller oriented facade over a `NodeRuntimeClient`.
|
|
@@ -90,6 +90,10 @@ export declare class IndividualControllerSdk {
|
|
|
90
90
|
* Ingests a FHIR `Communication` and waits for indexing.
|
|
91
91
|
*/
|
|
92
92
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
93
|
+
/** Updates one exact clinical section through a section-scoped batch/collection. */
|
|
94
|
+
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
95
|
+
/** Updates the multi-section summary through a Composition-first document. */
|
|
96
|
+
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
93
97
|
/**
|
|
94
98
|
* Reads the subject's available clinical document through
|
|
95
99
|
* `Communication -> Subject/$summary -> FHIR Parameters`.
|
|
@@ -128,6 +128,16 @@ export class IndividualControllerSdk {
|
|
|
128
128
|
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'ingestCommunicationAndUpdateIndex');
|
|
129
129
|
return requireClientMethod(this.client, 'ingestCommunicationAndUpdateIndex')(ctx, input);
|
|
130
130
|
}
|
|
131
|
+
/** Updates one exact clinical section through a section-scoped batch/collection. */
|
|
132
|
+
updateClinicalSection(ctx, input) {
|
|
133
|
+
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'updateClinicalSection');
|
|
134
|
+
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
135
|
+
}
|
|
136
|
+
/** Updates the multi-section summary through a Composition-first document. */
|
|
137
|
+
updateClinicalSummary(ctx, input) {
|
|
138
|
+
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'updateClinicalSummary');
|
|
139
|
+
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
140
|
+
}
|
|
131
141
|
/**
|
|
132
142
|
* Reads the subject's available clinical document through
|
|
133
143
|
* `Communication -> Subject/$summary -> FHIR Parameters`.
|
|
@@ -2,7 +2,7 @@ import { type IndividualMemberCredentialInput, type IndividualMemberVpPayloadInp
|
|
|
2
2
|
import { type NodeRuntimeClient } from './client-port.js';
|
|
3
3
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
4
4
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
5
|
-
import type { ClinicalBundleSearchInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, CommunicationIngestionInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
5
|
+
import type { ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
6
6
|
export declare class IndividualMemberSdk {
|
|
7
7
|
private readonly client;
|
|
8
8
|
constructor(client: NodeRuntimeClient);
|
|
@@ -23,6 +23,10 @@ export declare class IndividualMemberSdk {
|
|
|
23
23
|
* SMART token and accepted RelatedPerson/Consent relationship.
|
|
24
24
|
*/
|
|
25
25
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
26
|
+
/** Updates one authorized clinical section through a scoped batch/collection. */
|
|
27
|
+
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
28
|
+
/** Updates an authorized multi-section summary document. */
|
|
29
|
+
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
26
30
|
/** Reads the member-authorized `$summary` document without mutating the subject index. */
|
|
27
31
|
requestClinicalSummary(ctx: RouteContext, input: ClinicalSummaryRequestInput): Promise<ClinicalSummaryReadResult>;
|
|
28
32
|
/** Reads subject-scoped clinical documents permitted to this member. */
|
|
@@ -28,6 +28,14 @@ export class IndividualMemberSdk {
|
|
|
28
28
|
ingestCommunicationAndUpdateIndex(ctx, input) {
|
|
29
29
|
return requireClientMethod(this.client, 'ingestCommunicationAndUpdateIndex')(ctx, input);
|
|
30
30
|
}
|
|
31
|
+
/** Updates one authorized clinical section through a scoped batch/collection. */
|
|
32
|
+
updateClinicalSection(ctx, input) {
|
|
33
|
+
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
34
|
+
}
|
|
35
|
+
/** Updates an authorized multi-section summary document. */
|
|
36
|
+
updateClinicalSummary(ctx, input) {
|
|
37
|
+
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
38
|
+
}
|
|
31
39
|
/** Reads the member-authorized `$summary` document without mutating the subject index. */
|
|
32
40
|
requestClinicalSummary(ctx, input) {
|
|
33
41
|
return requireClientMethod(this.client, 'requestClinicalSummary')(ctx, input);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
|
|
2
2
|
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } from '../individual-start.js';
|
|
3
3
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
4
|
-
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput } from '../resource-operations.js';
|
|
4
|
+
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput } from '../resource-operations.js';
|
|
5
5
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
6
6
|
export declare class PersonalSdk {
|
|
7
7
|
private readonly client;
|
|
@@ -14,6 +14,10 @@ export declare class PersonalSdk {
|
|
|
14
14
|
importIpsOrFhirAndUpdateIndex(ctx: RouteContext, input: IpsOrFhirImportInput): Promise<SubmitAndPollResult>;
|
|
15
15
|
/** Ingests canonical Communication and waits for projection completion. */
|
|
16
16
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
17
|
+
/** Updates one exact clinical section through a section-scoped batch/collection. */
|
|
18
|
+
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
19
|
+
/** Updates the multi-section clinical summary through a Composition-first document. */
|
|
20
|
+
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
17
21
|
/** Reads the current subject through Communication `$summary`; it performs no ingestion. */
|
|
18
22
|
requestClinicalSummary(ctx: RouteContext, input: ClinicalSummaryRequestInput): Promise<ClinicalSummaryReadResult>;
|
|
19
23
|
/** Registers one FHIR resource or raw artifact on blockchain before communication. */
|
|
@@ -20,6 +20,14 @@ export class PersonalSdk {
|
|
|
20
20
|
ingestCommunicationAndUpdateIndex(ctx, input) {
|
|
21
21
|
return requireClientMethod(this.client, 'ingestCommunicationAndUpdateIndex')(ctx, input);
|
|
22
22
|
}
|
|
23
|
+
/** Updates one exact clinical section through a section-scoped batch/collection. */
|
|
24
|
+
updateClinicalSection(ctx, input) {
|
|
25
|
+
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
26
|
+
}
|
|
27
|
+
/** Updates the multi-section clinical summary through a Composition-first document. */
|
|
28
|
+
updateClinicalSummary(ctx, input) {
|
|
29
|
+
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
30
|
+
}
|
|
23
31
|
/** Reads the current subject through Communication `$summary`; it performs no ingestion. */
|
|
24
32
|
requestClinicalSummary(ctx, input) {
|
|
25
33
|
return requireClientMethod(this.client, 'requestClinicalSummary')(ctx, input);
|
|
@@ -2,7 +2,7 @@ import { type ProfessionalEmployeeCredentialInput, type ProfessionalSmartVpPaylo
|
|
|
2
2
|
import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
|
|
3
3
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
4
4
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
5
|
-
import type { BlockchainArtifactRegistrationInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, VitalSignBatchCommunicationFromSearchResponseInput } from '../resource-operations.js';
|
|
5
|
+
import type { BlockchainArtifactRegistrationInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, VitalSignBatchCommunicationFromSearchResponseInput } from '../resource-operations.js';
|
|
6
6
|
/**
|
|
7
7
|
* Professional-oriented facade for runtime actions that belong to the
|
|
8
8
|
* professional actor itself after tenant and employee provisioning have already
|
|
@@ -26,6 +26,11 @@ export declare class ProfessionalSdk {
|
|
|
26
26
|
* - `subjectDid`
|
|
27
27
|
* - requested `scopes`
|
|
28
28
|
*
|
|
29
|
+
* The actor DID must be the same identifier used by the consent grant and
|
|
30
|
+
* the professional VP. High-level callers omit `audience`; the runtime
|
|
31
|
+
* resolves the subject provider's SMART endpoint or uses the exact endpoint
|
|
32
|
+
* of its configured GW route.
|
|
33
|
+
*
|
|
29
34
|
* Tenant route context can be inherited from the configured
|
|
30
35
|
* `NodeHttpClient({ ctx })` instead of being repeated on every call.
|
|
31
36
|
*/
|
|
@@ -70,6 +75,10 @@ export declare class ProfessionalSdk {
|
|
|
70
75
|
* Ingests a FHIR `Communication` and waits for indexing.
|
|
71
76
|
*/
|
|
72
77
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
78
|
+
/** Updates one consent-authorized clinical section through a scoped batch/collection. */
|
|
79
|
+
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
80
|
+
/** Updates a consent-authorized multi-section summary document. */
|
|
81
|
+
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
73
82
|
/**
|
|
74
83
|
* Registers one FHIR resource or raw document artifact on blockchain before
|
|
75
84
|
* the artifact is attached to a Communication.
|
|
@@ -26,6 +26,11 @@ export class ProfessionalSdk {
|
|
|
26
26
|
* - `subjectDid`
|
|
27
27
|
* - requested `scopes`
|
|
28
28
|
*
|
|
29
|
+
* The actor DID must be the same identifier used by the consent grant and
|
|
30
|
+
* the professional VP. High-level callers omit `audience`; the runtime
|
|
31
|
+
* resolves the subject provider's SMART endpoint or uses the exact endpoint
|
|
32
|
+
* of its configured GW route.
|
|
33
|
+
*
|
|
29
34
|
* Tenant route context can be inherited from the configured
|
|
30
35
|
* `NodeHttpClient({ ctx })` instead of being repeated on every call.
|
|
31
36
|
*/
|
|
@@ -84,6 +89,14 @@ export class ProfessionalSdk {
|
|
|
84
89
|
ingestCommunicationAndUpdateIndex(ctx, input) {
|
|
85
90
|
return requireClientMethod(this.client, 'ingestCommunicationAndUpdateIndex')(ctx, input);
|
|
86
91
|
}
|
|
92
|
+
/** Updates one consent-authorized clinical section through a scoped batch/collection. */
|
|
93
|
+
updateClinicalSection(ctx, input) {
|
|
94
|
+
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
95
|
+
}
|
|
96
|
+
/** Updates a consent-authorized multi-section summary document. */
|
|
97
|
+
updateClinicalSummary(ctx, input) {
|
|
98
|
+
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
99
|
+
}
|
|
87
100
|
/**
|
|
88
101
|
* Registers one FHIR resource or raw document artifact on blockchain before
|
|
89
102
|
* the artifact is attached to a Communication.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DeviceAppType } from 'gdc-common-utils-ts/constants/device';
|
|
2
|
-
import { type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput } from 'gdc-sdk-core-ts';
|
|
2
|
+
import { type ClinicalSectionUpdateCommunicationInput, type ClinicalUpdateCommunicationInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput } from 'gdc-sdk-core-ts';
|
|
3
3
|
import type { LicenseOfferSearchState, LicenseOrderSearchState } from 'gdc-common-utils-ts/utils/license-commercial-search';
|
|
4
4
|
import type { LicenseListSearchState } from 'gdc-common-utils-ts/utils/license-list-search';
|
|
5
5
|
import type { BundleSearchQuery, CommMsgExtendedCommunicationOutboxJob, CommunicationOutboxJob, CommunicationInput, DateRange, EmployeeSearchValue, IndividualOrganizationLifecycleInput, TransportProfile } from 'gdc-sdk-core-ts';
|
|
@@ -232,6 +232,20 @@ export type CommunicationIngestionInput = {
|
|
|
232
232
|
intervalMs?: number;
|
|
233
233
|
};
|
|
234
234
|
};
|
|
235
|
+
type ClinicalUpdateRuntimeOptions = Readonly<{
|
|
236
|
+
transportProfile?: TransportProfile;
|
|
237
|
+
clinicalFormat?: string;
|
|
238
|
+
pollOptions?: {
|
|
239
|
+
timeoutMs?: number;
|
|
240
|
+
intervalMs?: number;
|
|
241
|
+
};
|
|
242
|
+
}>;
|
|
243
|
+
/** Updates exactly one clinical section through a scoped batch/collection. */
|
|
244
|
+
export type ClinicalSectionUpdateInput = ClinicalSectionUpdateCommunicationInput & ClinicalUpdateRuntimeOptions;
|
|
245
|
+
/** Updates one complete multi-section clinical summary document. */
|
|
246
|
+
export type ClinicalSummaryUpdateInput = ClinicalUpdateCommunicationInput & ClinicalUpdateRuntimeOptions;
|
|
247
|
+
export declare function buildClinicalSectionUpdateIngestion(input: ClinicalSectionUpdateInput): CommunicationIngestionInput;
|
|
248
|
+
export declare function buildClinicalSummaryUpdateIngestion(input: ClinicalSummaryUpdateInput): CommunicationIngestionInput;
|
|
235
249
|
export type BlockchainArtifactRegistrationInput = {
|
|
236
250
|
subject: string;
|
|
237
251
|
resource?: Record<string, unknown>;
|
|
@@ -351,15 +365,19 @@ export type GrantProfessionalAccessInput = {
|
|
|
351
365
|
/**
|
|
352
366
|
* Canonical flat actor identifier for the actor receiving the permission.
|
|
353
367
|
*
|
|
354
|
-
*
|
|
355
|
-
* - `did:web
|
|
368
|
+
* Canonical professional grant input:
|
|
369
|
+
* - the exact `did:web:...:employee:<multibase>:<role>` actor DID reused by
|
|
370
|
+
* the employee profile, VP credential subject and SMART request
|
|
371
|
+
*
|
|
372
|
+
* Compatibility input forms:
|
|
356
373
|
* - `user@example.org`
|
|
357
374
|
* - `tel:+34600111222`
|
|
358
375
|
* - `ES`
|
|
359
376
|
* - comma-separated lists or string arrays of those tokens
|
|
360
377
|
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
378
|
+
* Email/phone targets and legacy structured objects remain accepted for
|
|
379
|
+
* compatibility, but they do not automatically authorize a later SMART
|
|
380
|
+
* request made with a different derived professional DID.
|
|
363
381
|
*/
|
|
364
382
|
actorId?: ConsentActorTargetInput;
|
|
365
383
|
/**
|
|
@@ -3,9 +3,25 @@ import { HealthcareBasicSections, ResourceTypesFhirR4 } from 'gdc-common-utils-t
|
|
|
3
3
|
import { Format } from 'gdc-common-utils-ts/constants/Schemas';
|
|
4
4
|
import { RelatedPersonClaim } from 'gdc-common-utils-ts/models/interoperable-claims/related-person-claims';
|
|
5
5
|
import { buildCommunicationParticipantSearchBundle, buildBlockchainArtifactDocumentReference, BundleQuery, createInteroperableResourceOperationEditor, IndividualOrganizationLifecycleEditor, LicenseOfferSearchEditor, LicenseOrderSearchEditor, InteroperableLifecycleStatuses, LicenseListSearchEditor, buildLicenseIssueEntry, buildLicensePurchaseEntry, } from 'gdc-common-utils-ts';
|
|
6
|
-
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, readClinicalSummaryOperationResult, } from 'gdc-sdk-core-ts';
|
|
6
|
+
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, createClinicalSectionUpdateOutboxJob, createClinicalSummaryUpdateOutboxJob, readClinicalSummaryOperationResult, } from 'gdc-sdk-core-ts';
|
|
7
7
|
import { GwCoreLifecycleRequestMethod, GwCoreLifecycleRequestType, GwCoreLifecycleTodo, } from './constants/lifecycle.js';
|
|
8
8
|
import { buildEmployeeBatchEntry, buildEmployeeSearchBundle, ConsentClaims, } from 'gdc-sdk-core-ts';
|
|
9
|
+
export function buildClinicalSectionUpdateIngestion(input) {
|
|
10
|
+
return {
|
|
11
|
+
communicationJob: createClinicalSectionUpdateOutboxJob(input),
|
|
12
|
+
clinicalFormat: input.clinicalFormat,
|
|
13
|
+
transportProfile: input.transportProfile,
|
|
14
|
+
pollOptions: input.pollOptions,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function buildClinicalSummaryUpdateIngestion(input) {
|
|
18
|
+
return {
|
|
19
|
+
communicationJob: createClinicalSummaryUpdateOutboxJob(input),
|
|
20
|
+
clinicalFormat: input.clinicalFormat,
|
|
21
|
+
transportProfile: input.transportProfile,
|
|
22
|
+
pollOptions: input.pollOptions,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
9
25
|
export async function createOrganizationEmployeeWithDeps(routeCtx, input, options, deps) {
|
|
10
26
|
const payload = buildEmployeeLifecyclePayload({
|
|
11
27
|
routeCtx,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
import { NodeManagedWallet } from './node-managed-wallet.js';
|
|
4
4
|
import { NodeHttpClient } from './node-runtime-client.js';
|
|
5
|
+
import { buildIdentityOpenIdSmartTokenPath } from './runtime-paths.js';
|
|
5
6
|
import { ProfilePinRejectedError, openServerProfileSecret, protectServerProfileSecret, } from './server-profile-protection.js';
|
|
6
7
|
/**
|
|
7
8
|
* Coordinates device registration, two-factor profile protection and SMART sessions.
|
|
@@ -95,14 +96,18 @@ export class ServerProfileSessionManager {
|
|
|
95
96
|
}
|
|
96
97
|
profile = await this.ensureRequiredStorageProfile(profile, seed);
|
|
97
98
|
const wallet = await this.createWallet(profile.profileId, seed);
|
|
98
|
-
const
|
|
99
|
+
const smartTokenEndpoint = [
|
|
100
|
+
this.options.gatewayBaseUrl.replace(/\/+$/, ''),
|
|
101
|
+
buildIdentityOpenIdSmartTokenPath(profile.routeContext),
|
|
102
|
+
].join('');
|
|
103
|
+
const assertion = await buildWalletClientAssertion(wallet, profile, smartTokenEndpoint, now);
|
|
99
104
|
const token = await this.createClient(profile.routeContext, input.idToken).requestSmartToken({
|
|
100
105
|
...profile.routeContext,
|
|
101
106
|
actorDid: profile.actorDid,
|
|
102
107
|
subjectDid: input.subjectDid,
|
|
103
108
|
clientId: profile.clientId,
|
|
104
109
|
issuer: profile.clientId,
|
|
105
|
-
audience:
|
|
110
|
+
audience: smartTokenEndpoint,
|
|
106
111
|
idToken: input.idToken,
|
|
107
112
|
vpToken,
|
|
108
113
|
clientAssertion: assertion,
|
package/dist/smart-token.d.ts
CHANGED
|
@@ -93,6 +93,13 @@ type RequestSmartTokenDeps = {
|
|
|
93
93
|
identityTokenExchangePollPath: (ctx: RouteContext) => string;
|
|
94
94
|
identityOpenIdSmartTokenPath: (ctx: RouteContext) => string;
|
|
95
95
|
identityOpenIdSmartTokenPollPath: (ctx: RouteContext) => string;
|
|
96
|
+
/**
|
|
97
|
+
* Trusted runtime resolver for the provider that owns the subject.
|
|
98
|
+
*
|
|
99
|
+
* Product code may back this with an index/DID discovery adapter. The
|
|
100
|
+
* high-level caller does not receive or manage the resolver's cache.
|
|
101
|
+
*/
|
|
102
|
+
resolveSmartTokenEndpoint?: (subjectDid: string) => Promise<string | undefined>;
|
|
96
103
|
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
97
104
|
thid?: string;
|
|
98
105
|
} & Record<string, unknown>, options?: PollOptions) => Promise<SubmitAndPollResult>;
|
package/dist/smart-token.js
CHANGED
|
@@ -27,7 +27,19 @@ export async function requestSmartTokenWithDeps(deps) {
|
|
|
27
27
|
if (deps.input.smartTokenKind === 'openid-smart') {
|
|
28
28
|
const actorDid = String(deps.input.actorDid || '').trim() || undefined;
|
|
29
29
|
const resolvedClientId = deps.input.clientId || actorDid || deps.input.subjectDid || deps.routeCtx.tenantId;
|
|
30
|
-
const
|
|
30
|
+
const configuredSubmitPath = deps.identityOpenIdSmartTokenPath(deps.routeCtx);
|
|
31
|
+
const configuredPollPath = deps.identityOpenIdSmartTokenPollPath(deps.routeCtx);
|
|
32
|
+
const explicitAudience = String(deps.input.audience || '').trim();
|
|
33
|
+
const subjectDid = String(deps.input.subjectDid || '').trim();
|
|
34
|
+
const discoveredEndpoint = !explicitAudience && subjectDid && deps.resolveSmartTokenEndpoint
|
|
35
|
+
? normalizeResolvedSmartTokenEndpoint(await deps.resolveSmartTokenEndpoint(subjectDid))
|
|
36
|
+
: undefined;
|
|
37
|
+
const configuredEndpoint = joinRuntimeUrl(deps.baseUrl, configuredSubmitPath);
|
|
38
|
+
const resolvedAudience = explicitAudience || discoveredEndpoint || configuredEndpoint;
|
|
39
|
+
const submitPath = discoveredEndpoint || configuredSubmitPath;
|
|
40
|
+
const pollPath = discoveredEndpoint
|
|
41
|
+
? smartTokenPollEndpointFromTokenEndpoint(discoveredEndpoint)
|
|
42
|
+
: configuredPollPath;
|
|
31
43
|
const clientAssertion = await resolveClientAssertion({
|
|
32
44
|
clientAssertion: deps.input.clientAssertion,
|
|
33
45
|
clientAssertionBuilder: deps.input.clientAssertionBuilder,
|
|
@@ -59,7 +71,7 @@ export async function requestSmartTokenWithDeps(deps) {
|
|
|
59
71
|
},
|
|
60
72
|
...(deps.input.additionalClaims || {}),
|
|
61
73
|
};
|
|
62
|
-
const exchange = await deps.submitAndPoll(
|
|
74
|
+
const exchange = await deps.submitAndPoll(submitPath, pollPath, smartPayload, pollOptions);
|
|
63
75
|
return resolveTokenExchangeResult(exchange, normalizedScopes, tokenCacheKey, deps.setTokenCache);
|
|
64
76
|
}
|
|
65
77
|
const payload = {
|
|
@@ -75,6 +87,33 @@ export async function requestSmartTokenWithDeps(deps) {
|
|
|
75
87
|
const exchange = await deps.submitAndPoll(deps.identityTokenExchangePath(deps.routeCtx), deps.identityTokenExchangePollPath(deps.routeCtx), payload, pollOptions);
|
|
76
88
|
return resolveTokenExchangeResult(exchange, normalizedScopes, tokenCacheKey, deps.setTokenCache);
|
|
77
89
|
}
|
|
90
|
+
function joinRuntimeUrl(baseUrl, path) {
|
|
91
|
+
return `${String(baseUrl || '').replace(/\/+$/, '')}/${String(path || '').replace(/^\/+/, '')}`;
|
|
92
|
+
}
|
|
93
|
+
function normalizeResolvedSmartTokenEndpoint(value) {
|
|
94
|
+
const normalized = String(value || '').trim();
|
|
95
|
+
if (!normalized)
|
|
96
|
+
return undefined;
|
|
97
|
+
let endpoint;
|
|
98
|
+
try {
|
|
99
|
+
endpoint = new URL(normalized);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new Error('Resolved SMART token endpoint must be an absolute HTTP(S) URL.');
|
|
103
|
+
}
|
|
104
|
+
if (!['http:', 'https:'].includes(endpoint.protocol)) {
|
|
105
|
+
throw new Error('Resolved SMART token endpoint must use HTTP(S).');
|
|
106
|
+
}
|
|
107
|
+
if (!endpoint.pathname.endsWith('/identity/openid/smart/token')) {
|
|
108
|
+
throw new Error('Resolved SMART token endpoint must target /identity/openid/smart/token.');
|
|
109
|
+
}
|
|
110
|
+
return endpoint.toString();
|
|
111
|
+
}
|
|
112
|
+
function smartTokenPollEndpointFromTokenEndpoint(tokenEndpoint) {
|
|
113
|
+
const endpoint = new URL(tokenEndpoint);
|
|
114
|
+
endpoint.pathname = endpoint.pathname.replace(/\/identity\/openid\/smart\/token$/, '/identity/openid/smart/_batch-response');
|
|
115
|
+
return endpoint.toString();
|
|
116
|
+
}
|
|
78
117
|
async function resolveClientAssertion(input) {
|
|
79
118
|
const explicit = String(input.clientAssertion || '').trim();
|
|
80
119
|
if (explicit)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "Next-generation Node runtime package for the GDC SDK family",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Antifraud Services Inc.",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"gdc-common-utils-ts": "^2.3.
|
|
40
|
-
"gdc-sdk-core-ts": "~2.3.
|
|
39
|
+
"gdc-common-utils-ts": "^2.3.8",
|
|
40
|
+
"gdc-sdk-core-ts": "~2.3.5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^20.14.10",
|