gdc-sdk-node-ts 2.9.4 → 2.9.5
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 +18 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/node-runtime-client.d.ts +10 -0
- package/dist/node-runtime-client.js +17 -0
- package/dist/pdqm-patient-match.d.ts +44 -0
- package/dist/pdqm-patient-match.js +63 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -72,50 +72,53 @@ If you are integrating this package for the first time, open these in order:
|
|
|
72
72
|
2. [docs/101-SDK_END_TO_END.md](./docs/101-SDK_END_TO_END.md)
|
|
73
73
|
Ordered onboarding guide with end-to-end journeys, copy/paste snippets, and
|
|
74
74
|
the recommended reading path for new backend integrators.
|
|
75
|
-
3. [docs/101-
|
|
75
|
+
3. [docs/101-PDQM_PATIENT_MATCH.md](./docs/101-PDQM_PATIENT_MATCH.md)
|
|
76
|
+
Resolve only `indexProviderDid` in Fabric, then use the high-level Node SDK
|
|
77
|
+
to call IHE PDQm `POST Patient/$match` with one FHIR `Parameters` request.
|
|
78
|
+
4. [docs/101-HIGH_LEVEL_CLINICAL_PROFILE_WRITES.md](./docs/101-HIGH_LEVEL_CLINICAL_PROFILE_WRITES.md)
|
|
76
79
|
Focused subset of the end-to-end guide: load a professional or individual
|
|
77
80
|
member/controller profile, create or import clinical data in the selected
|
|
78
81
|
index provider, and verify it through an authoritative summary readback.
|
|
79
|
-
|
|
82
|
+
5. [docs/101-PROFESSIONAL-CONSENT-SMART.md](./docs/101-PROFESSIONAL-CONSENT-SMART.md)
|
|
80
83
|
Canonical professional DID, consent, VP and SMART flow without literal
|
|
81
84
|
sections or caller-built audience URLs.
|
|
82
|
-
|
|
85
|
+
6. [docs/101-AUTHORIZED_SUBJECT_DIRECTORY.md](./docs/101-AUTHORIZED_SUBJECT_DIRECTORY.md)
|
|
83
86
|
Signed OpenID account discovery of already-authorized subjects without
|
|
84
87
|
treating the account token as VP, SMART or wallet proof.
|
|
85
|
-
|
|
88
|
+
7. [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
|
|
86
89
|
Real backend setup plus the public runtime entrypoints:
|
|
87
90
|
`HostOnboardingSdk`, `OrganizationControllerSdk`,
|
|
88
91
|
`IndividualControllerSdk`, `ProfessionalSdk`, route-context usage, and the
|
|
89
92
|
canonical `ProfileRuntime -> loadProfile(...) -> workspace/session -> actor facade -> submit/poll` shape.
|
|
90
|
-
|
|
93
|
+
8. [tests/101-live-full-cycle-bff-runtime.e2e.test.mjs](./tests/101-live-full-cycle-bff-runtime.e2e.test.mjs)
|
|
91
94
|
Canonical live backend/BFF walkthrough on a fresh local GW lifecycle:
|
|
92
95
|
host/tenant activation, employee provisioning, individual bootstrap,
|
|
93
96
|
consent grant, professional SMART token, clinical read, and final cleanup.
|
|
94
|
-
|
|
97
|
+
9. [docs/101-LIVE_GW_LOCAL.md](./docs/101-LIVE_GW_LOCAL.md)
|
|
95
98
|
Exact TTY/local/Docker commands for running the SDK against a real local GW
|
|
96
99
|
CORE, including tenant bootstrap and employee-seat setup.
|
|
97
|
-
|
|
100
|
+
10. [docs/101-DISCOVERY.md](./docs/101-DISCOVERY.md)
|
|
98
101
|
Node/BFF dataspace discovery, hosting-operator resolution, provider
|
|
99
102
|
resolution, and the correct integration boundary for fallback and cache.
|
|
100
|
-
|
|
103
|
+
11. [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)
|
|
101
104
|
Actor split and business-flow map across organization, individual,
|
|
102
105
|
permissions, invitation, import, and SMART flows.
|
|
103
|
-
|
|
106
|
+
12. [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)
|
|
104
107
|
Canonical portal/BFF functional map over GW CORE, including the domain
|
|
105
108
|
split between `employees`, `related persons`, `members`, and `consents`.
|
|
106
|
-
|
|
109
|
+
13. [gdc-common-utils-ts/src/examples/](https://github.com/Global-DataCare/gdc-common-utils-ts/tree/main/src/examples)
|
|
107
110
|
Shared payload values used by the docs and tests.
|
|
108
|
-
|
|
111
|
+
14. [gdc-common-utils-ts/docs/101-LIFECYCLE.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-LIFECYCLE.md)
|
|
109
112
|
Canonical `enable/disable/delete` semantics and copy/paste placeholders.
|
|
110
|
-
|
|
113
|
+
15. [tests/101-backend-profile-runtime.test.mjs](./tests/101-backend-profile-runtime.test.mjs)
|
|
111
114
|
Technical runtime slice for profile/device/session orchestration internals.
|
|
112
115
|
Read this after the public actor SDK guides, not before them.
|
|
113
|
-
|
|
116
|
+
16. [tests/101-individual-controller-backend-runtime.test.mjs](./tests/101-individual-controller-backend-runtime.test.mjs)
|
|
114
117
|
Technical wrapper slice around the generic profile runtime. This is not the
|
|
115
118
|
main onboarding path for new integrators.
|
|
116
|
-
|
|
119
|
+
17. [docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md](./docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md)
|
|
117
120
|
Historical reconciliation note for the current CORE registration baseline.
|
|
118
|
-
|
|
121
|
+
18. [docs/NEXT_STEPS.md](./docs/NEXT_STEPS.md)
|
|
119
122
|
Follow-up scope after GW CORE live validation, including the future user job
|
|
120
123
|
manager boundary.
|
|
121
124
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import { type FhirR5SubscriptionBatchInput } from './fhir-r5-subscription-runtim
|
|
|
22
22
|
import type { FhirR5SubscriptionTopic } from 'gdc-common-utils-ts/models/fhir-r5-subscription';
|
|
23
23
|
import { type DigitalTwinMaterializationInput, type DigitalTwinSearchInput, type DigitalTwinSelectionInput } from './digital-twin.js';
|
|
24
24
|
import { type AuthorizedIndividualSubject, type AuthorizedIndividualSubjectDirectoryInput } from './authorized-subject-directory.js';
|
|
25
|
+
import { type FhirPatientMatchBundle, type MatchPatientAtIndexProviderInput } from './pdqm-patient-match.js';
|
|
25
26
|
export type HttpRuntimeClientOptions = {
|
|
26
27
|
baseUrl: string;
|
|
27
28
|
bearerToken?: string;
|
|
@@ -125,6 +126,15 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
125
126
|
* Returns the configured ICA-issued runtime/software proof token, when present.
|
|
126
127
|
*/
|
|
127
128
|
getRuntimeVpToken(): string | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Matches a known human identifier at the index provider resolved in Fabric.
|
|
131
|
+
*
|
|
132
|
+
* The BFF supplies the provider DID and its discovered FHIR base URL. This
|
|
133
|
+
* method never forwards the Fabric lookup hash. It sends one IHE PDQm
|
|
134
|
+
* `Parameters` request and returns the resulting FHIR search `Bundle`, while
|
|
135
|
+
* applying the runtime's configured FHIR, DIDComm plain or strict profile.
|
|
136
|
+
*/
|
|
137
|
+
matchPatientAtIndexProvider(input: MatchPatientAtIndexProviderInput): Promise<FhirPatientMatchBundle>;
|
|
128
138
|
/**
|
|
129
139
|
* Builds a canonical GDC v1 resource/action path from a route context.
|
|
130
140
|
*/
|
|
@@ -20,6 +20,7 @@ import { runtimeUuid, wrapBundleAsGatewayTransactionMessage } from './runtime-me
|
|
|
20
20
|
import { submitFhirR5SubscriptionBatchWithDeps, submitFhirR5SubscriptionTopicBatchWithDeps, } from './fhir-r5-subscription-runtime.js';
|
|
21
21
|
import { materializeDigitalTwinWithDeps, saveDigitalTwinSelectionWithDeps, searchDigitalTwinsWithDeps, } from './digital-twin.js';
|
|
22
22
|
import { listAuthorizedIndividualSubjectsWithDeps, } from './authorized-subject-directory.js';
|
|
23
|
+
import { matchPatientAtIndexProviderWithDeps, } from './pdqm-patient-match.js';
|
|
23
24
|
const bootstrapFacade = createBootstrapFacade();
|
|
24
25
|
/**
|
|
25
26
|
* Runtime-oriented HTTP client for Node backends, BFFs, and workers that need
|
|
@@ -93,6 +94,22 @@ export class HttpRuntimeClient {
|
|
|
93
94
|
getRuntimeVpToken() {
|
|
94
95
|
return this.runtimeVpToken;
|
|
95
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Matches a known human identifier at the index provider resolved in Fabric.
|
|
99
|
+
*
|
|
100
|
+
* The BFF supplies the provider DID and its discovered FHIR base URL. This
|
|
101
|
+
* method never forwards the Fabric lookup hash. It sends one IHE PDQm
|
|
102
|
+
* `Parameters` request and returns the resulting FHIR search `Bundle`, while
|
|
103
|
+
* applying the runtime's configured FHIR, DIDComm plain or strict profile.
|
|
104
|
+
*/
|
|
105
|
+
async matchPatientAtIndexProvider(input) {
|
|
106
|
+
return matchPatientAtIndexProviderWithDeps(input, {
|
|
107
|
+
transportProfile: this.transportProfile,
|
|
108
|
+
secureTransportAdapter: this.secureTransportAdapter,
|
|
109
|
+
createUuid: runtimeUuid,
|
|
110
|
+
post: async (url, rendered) => postRenderedWithRuntimeConfig(this.transportConfig, url, rendered),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
96
113
|
/**
|
|
97
114
|
* Builds a canonical GDC v1 resource/action path from a route context.
|
|
98
115
|
*/
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type FhirPatientMatchInput, type SecureDidcommTransportAdapter, type TransportProfile } from 'gdc-sdk-core-ts';
|
|
2
|
+
export type MatchPatientAtIndexProviderInput = Readonly<{
|
|
3
|
+
/** Provider FHIR base discovered from the resolved index-provider DID. */
|
|
4
|
+
fhirBaseUrl: string;
|
|
5
|
+
/** Patient containing the governed identifier known by the requesting BFF. */
|
|
6
|
+
patient: FhirPatientMatchInput;
|
|
7
|
+
/** DID of the authenticated professional, member or controller making the request. */
|
|
8
|
+
requesterDid: string;
|
|
9
|
+
/** Provider DID returned by the public subject-identifier ledger lookup. */
|
|
10
|
+
indexProviderDid: string;
|
|
11
|
+
/** Optional PDQm control that excludes possible, lower-confidence matches. */
|
|
12
|
+
onlyCertainMatches?: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
export type FhirPatientMatchBundle = Readonly<{
|
|
15
|
+
resourceType: 'Bundle';
|
|
16
|
+
type: 'searchset';
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}>;
|
|
19
|
+
type PatientMatchDependencies = Readonly<{
|
|
20
|
+
transportProfile: TransportProfile;
|
|
21
|
+
secureTransportAdapter?: SecureDidcommTransportAdapter;
|
|
22
|
+
createUuid: () => string;
|
|
23
|
+
post: (url: string, request: Readonly<{
|
|
24
|
+
contentType: string;
|
|
25
|
+
accept: string;
|
|
26
|
+
body: Record<string, unknown> | string;
|
|
27
|
+
}>) => Promise<Readonly<{
|
|
28
|
+
status: number;
|
|
29
|
+
body: unknown;
|
|
30
|
+
}>>;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Calls the resolved provider's IHE PDQm `POST Patient/$match` facade.
|
|
34
|
+
*
|
|
35
|
+
* The opaque subject-identifier hash is deliberately absent: it stops at the
|
|
36
|
+
* preceding Fabric lookup. Native FHIR sends one `Parameters` body. DIDComm
|
|
37
|
+
* plain places that same resource in the only `body.data[]` entry. Strict mode
|
|
38
|
+
* signs and encrypts the identical DIDComm message through the wallet adapter
|
|
39
|
+
* and sends `request=<JWE>` as `application/x-www-form-urlencoded`.
|
|
40
|
+
*
|
|
41
|
+
* @see https://profiles.ihe.net/ITI/PDQm/ITI-119.html
|
|
42
|
+
*/
|
|
43
|
+
export declare function matchPatientAtIndexProviderWithDeps(input: MatchPatientAtIndexProviderInput, dependencies: PatientMatchDependencies): Promise<FhirPatientMatchBundle>;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { buildPdqmPatientMatchGatewayBody, buildPdqmPatientMatchRequest, decodeTransportResponse, renderGatewayMessageRequest, TransportProfiles, } from 'gdc-sdk-core-ts';
|
|
3
|
+
function requiredDid(value, name) {
|
|
4
|
+
const normalized = String(value || '').trim();
|
|
5
|
+
if (!normalized.startsWith('did:'))
|
|
6
|
+
throw new TypeError(`${name} must be a DID.`);
|
|
7
|
+
return normalized;
|
|
8
|
+
}
|
|
9
|
+
function readPatientMatchBundle(value) {
|
|
10
|
+
const candidate = value && typeof value === 'object' && !Array.isArray(value)
|
|
11
|
+
&& 'body' in value
|
|
12
|
+
? value.body
|
|
13
|
+
: value;
|
|
14
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
15
|
+
throw new Error('PDQm Patient/$match response must contain one FHIR search Bundle.');
|
|
16
|
+
}
|
|
17
|
+
const bundle = candidate;
|
|
18
|
+
if (bundle.resourceType !== 'Bundle' || bundle.type !== 'searchset') {
|
|
19
|
+
throw new Error('PDQm Patient/$match response must contain one FHIR search Bundle.');
|
|
20
|
+
}
|
|
21
|
+
return bundle;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Calls the resolved provider's IHE PDQm `POST Patient/$match` facade.
|
|
25
|
+
*
|
|
26
|
+
* The opaque subject-identifier hash is deliberately absent: it stops at the
|
|
27
|
+
* preceding Fabric lookup. Native FHIR sends one `Parameters` body. DIDComm
|
|
28
|
+
* plain places that same resource in the only `body.data[]` entry. Strict mode
|
|
29
|
+
* signs and encrypts the identical DIDComm message through the wallet adapter
|
|
30
|
+
* and sends `request=<JWE>` as `application/x-www-form-urlencoded`.
|
|
31
|
+
*
|
|
32
|
+
* @see https://profiles.ihe.net/ITI/PDQm/ITI-119.html
|
|
33
|
+
*/
|
|
34
|
+
export async function matchPatientAtIndexProviderWithDeps(input, dependencies) {
|
|
35
|
+
const requesterDid = requiredDid(input.requesterDid, 'requesterDid');
|
|
36
|
+
const indexProviderDid = requiredDid(input.indexProviderDid, 'indexProviderDid');
|
|
37
|
+
const matchRequest = buildPdqmPatientMatchRequest({
|
|
38
|
+
fhirBaseUrl: input.fhirBaseUrl,
|
|
39
|
+
patient: input.patient,
|
|
40
|
+
onlyCertainMatches: input.onlyCertainMatches,
|
|
41
|
+
});
|
|
42
|
+
const thid = `pdqm-patient-match-${dependencies.createUuid()}`;
|
|
43
|
+
const rendered = dependencies.transportProfile === TransportProfiles.FhirJson
|
|
44
|
+
? {
|
|
45
|
+
contentType: TransportProfiles.FhirJson,
|
|
46
|
+
accept: 'application/fhir+json, application/json',
|
|
47
|
+
body: matchRequest.body,
|
|
48
|
+
}
|
|
49
|
+
: await renderGatewayMessageRequest({
|
|
50
|
+
id: dependencies.createUuid(),
|
|
51
|
+
thid,
|
|
52
|
+
type: TransportProfiles.DidcommPlainJson,
|
|
53
|
+
from: requesterDid,
|
|
54
|
+
to: [indexProviderDid],
|
|
55
|
+
body: buildPdqmPatientMatchGatewayBody(matchRequest),
|
|
56
|
+
}, dependencies.transportProfile, dependencies.secureTransportAdapter);
|
|
57
|
+
const response = await dependencies.post(matchRequest.url, rendered);
|
|
58
|
+
if (response.status < 200 || response.status >= 300) {
|
|
59
|
+
throw new Error(`PDQm Patient/$match failed with HTTP ${response.status}.`);
|
|
60
|
+
}
|
|
61
|
+
const decoded = await decodeTransportResponse(response.body, dependencies.transportProfile, dependencies.secureTransportAdapter);
|
|
62
|
+
return readPatientMatchBundle(decoded);
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.5",
|
|
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.",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"gdc-common-utils-ts": "2.9.
|
|
42
|
-
"gdc-sdk-core-ts": "2.9.
|
|
41
|
+
"gdc-common-utils-ts": "2.9.7",
|
|
42
|
+
"gdc-sdk-core-ts": "2.9.5"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^20.14.10",
|