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 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-HIGH_LEVEL_CLINICAL_PROFILE_WRITES.md](./docs/101-HIGH_LEVEL_CLINICAL_PROFILE_WRITES.md)
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
- 4. [docs/101-PROFESSIONAL-CONSENT-SMART.md](./docs/101-PROFESSIONAL-CONSENT-SMART.md)
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
- 5. [docs/101-AUTHORIZED_SUBJECT_DIRECTORY.md](./docs/101-AUTHORIZED_SUBJECT_DIRECTORY.md)
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
- 6. [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
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
- 7. [tests/101-live-full-cycle-bff-runtime.e2e.test.mjs](./tests/101-live-full-cycle-bff-runtime.e2e.test.mjs)
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
- 8. [docs/101-LIVE_GW_LOCAL.md](./docs/101-LIVE_GW_LOCAL.md)
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
- 9. [docs/101-DISCOVERY.md](./docs/101-DISCOVERY.md)
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
- 10. [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)
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
- 11. [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)
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
- 12. [gdc-common-utils-ts/src/examples/](https://github.com/Global-DataCare/gdc-common-utils-ts/tree/main/src/examples)
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
- 13. [gdc-common-utils-ts/docs/101-LIFECYCLE.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-LIFECYCLE.md)
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
- 14. [tests/101-backend-profile-runtime.test.mjs](./tests/101-backend-profile-runtime.test.mjs)
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
- 15. [tests/101-individual-controller-backend-runtime.test.mjs](./tests/101-individual-controller-backend-runtime.test.mjs)
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
- 16. [docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md](./docs/V2_INDIVIDUAL_REGISTRATION_RECONCILIATION.md)
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
- 17. [docs/NEXT_STEPS.md](./docs/NEXT_STEPS.md)
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
@@ -51,3 +51,4 @@ export * from './orchestration/professional-sdk.js';
51
51
  export * from './orchestration/digital-twin-sdk.js';
52
52
  export * from './legacy-compat.js';
53
53
  export * from './local-terminology-bff.js';
54
+ export * from './pdqm-patient-match.js';
package/dist/index.js CHANGED
@@ -52,3 +52,4 @@ export * from './orchestration/professional-sdk.js';
52
52
  export * from './orchestration/digital-twin-sdk.js';
53
53
  export * from './legacy-compat.js';
54
54
  export * from './local-terminology-bff.js';
55
+ export * from './pdqm-patient-match.js';
@@ -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.4",
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.5",
42
- "gdc-sdk-core-ts": "2.9.3"
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",