gdc-sdk-node-ts 0.6.3 → 0.6.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 CHANGED
@@ -77,6 +77,88 @@ Open these tests when you want to see exact method calls and exact inputs:
77
77
  Portal-style `default-first` discovery with simple `getHosts(...)`,
78
78
  `getIndexProviders(...)`, and `getDigitalTwinProviders(...)` calls.
79
79
 
80
+ ## Live GW CORE Flow
81
+
82
+ Use [tests/live-gw-node-runtime.e2e.test.mjs](tests/live-gw-node-runtime.e2e.test.mjs)
83
+ as the canonical runtime flow.
84
+
85
+ Teaching rule:
86
+
87
+ - defaults come from `gdc-common-utils-ts/examples`
88
+ - override with env vars only when your tenant, bearer, or route is different
89
+ - local GW default is `http://127.0.0.1:3000`
90
+ - Docker-exposed GW can be overridden with `BASE_URL=http://127.0.0.1:8000`
91
+
92
+ Current live flow covered by the test suite:
93
+
94
+ 1. bootstrap tenant / legal organization
95
+ 2. bootstrap doctor or controller employee
96
+ 3. bootstrap individual and grant consent for the doctor
97
+ 4. ingest two IPS `Communication` bundles, each with one `MedicationStatement`
98
+ 5. read the IPS/clinical index and verify both medications are present
99
+ 6. persist audit/debug traces in `test-results/*.jsonl`
100
+
101
+ Shared example source of truth:
102
+
103
+ - tenant/route/controller/professional defaults:
104
+ [gdc-common-utils-ts/src/examples/shared.ts](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/src/examples/shared.ts)
105
+ - live employee defaults:
106
+ [gdc-common-utils-ts/src/examples/organization-controller.ts](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/src/examples/organization-controller.ts)
107
+ - live consent defaults:
108
+ [gdc-common-utils-ts/src/examples/individual-controller.ts](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/src/examples/individual-controller.ts)
109
+
110
+ The two medication defaults used by the live test are intentionally reusable:
111
+
112
+ - `Ibuprofen 400 mg`
113
+ - `Paracetamol 600 mg`
114
+ - both every `8` hours
115
+ - both `PRN` / `dosage-asneeded = true`
116
+ - note text keeps the `4` hour gap in English
117
+
118
+ Run the full live runtime baseline:
119
+
120
+ ```bash
121
+ npm run test:e2e:live-gw
122
+ ```
123
+
124
+ Run the IPS ingestion/search branch as well:
125
+
126
+ ```bash
127
+ RUN_LIVE_GW_E2E_IPS_INGESTION=1 \
128
+ npm run test:e2e:live-gw
129
+ ```
130
+
131
+ Common overrides:
132
+
133
+ ```bash
134
+ BASE_URL=http://127.0.0.1:3000 \
135
+ AUTH_BEARER=... \
136
+ TENANT_ID=VATES-B00112233 \
137
+ TENANT_ROUTE_ID=acme-live \
138
+ JURISDICTION=ES \
139
+ SECTOR=health-care \
140
+ SUBJECT_DID=did:web:api.acme.org:individual:123 \
141
+ RUN_LIVE_GW_E2E_IPS_INGESTION=1 \
142
+ LIVE_GW_NODE_E2E_DEBUG=1 \
143
+ npm run test:e2e:live-gw
144
+ ```
145
+
146
+ Docker-exposed GW example:
147
+
148
+ ```bash
149
+ BASE_URL=http://127.0.0.1:8000 \
150
+ RUN_LIVE_GW_E2E_IPS_INGESTION=1 \
151
+ npm run test:e2e:live-gw
152
+ ```
153
+
154
+ Documentation consistency rule for this repo family:
155
+
156
+ - scripts, README examples, Swagger examples, and internal tests must reuse the
157
+ same example data and flow order
158
+ - if a new request/response example is added, add it first to
159
+ `gdc-common-utils-ts/examples` and consume it from there instead of
160
+ re-hardcoding values locally
161
+
80
162
  ## Dataspace Discovery Quick Map
81
163
 
82
164
  Use the Node discovery layer when your backend or BFF needs to:
@@ -35,6 +35,8 @@ export declare class DefaultFirstDataspaceDiscovery {
35
35
  getDigitalTwinProviders(input: SimpleDataspaceDiscoveryRequest): Promise<PublishedProviderMatch[]>;
36
36
  private getProviders;
37
37
  private createResolver;
38
+ private buildBootstrapPlan;
39
+ private resolveDefaultPublishedProviders;
38
40
  }
39
41
  /**
40
42
  * Convenience factory for the default-first portal/backend discovery facade.
@@ -1,9 +1,57 @@
1
1
  // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
- import { DataspaceDiscoverySourceMode, ServiceCapabilityToken, createDataspaceDiscoveryDefaultsRegistry, DataspaceProtocolVersions, } from 'gdc-common-utils-ts';
2
+ import { DataspaceCoverageScope, DataspaceDiscoverySourceMode, ServiceCapabilityToken, createDataspaceDiscoveryDefaultsRegistry, DataspaceProtocolVersions, inferCoverageScopeFromCountryCode, isProviderServiceCapability, normalizeCountryCode, } from 'gdc-common-utils-ts';
3
3
  import { HttpDataspaceResolver } from './HttpDataspaceResolver.js';
4
4
  function normalizeString(value) {
5
5
  return typeof value === 'string' ? value.trim() : '';
6
6
  }
7
+ function equalsIgnoreCase(left, right) {
8
+ return left.trim().toLowerCase() === right.trim().toLowerCase();
9
+ }
10
+ function splitTokens(value) {
11
+ if (Array.isArray(value)) {
12
+ return value.map((entry) => normalizeString(entry)).filter(Boolean);
13
+ }
14
+ const raw = normalizeString(value);
15
+ if (!raw)
16
+ return [];
17
+ return raw.split(',').map((entry) => entry.trim()).filter(Boolean);
18
+ }
19
+ function buildCoverageTokens(areaServed, filterJurisdiction) {
20
+ const tokens = new Set(splitTokens(areaServed).map((token) => token.toUpperCase()));
21
+ const normalizedJurisdiction = normalizeCountryCode(filterJurisdiction);
22
+ if (normalizedJurisdiction) {
23
+ const inferred = inferCoverageScopeFromCountryCode(normalizedJurisdiction);
24
+ if (inferred)
25
+ tokens.add(inferred.toUpperCase());
26
+ }
27
+ return tokens;
28
+ }
29
+ function matchesProviderCoverage(provider, jurisdiction, coverageScope) {
30
+ const normalizedJurisdiction = normalizeCountryCode(jurisdiction);
31
+ const normalizedCoverageScope = normalizeString(coverageScope).toUpperCase();
32
+ if (!normalizedJurisdiction && !normalizedCoverageScope)
33
+ return true;
34
+ const tokens = buildCoverageTokens(provider.areaServed, jurisdiction);
35
+ if (normalizedJurisdiction && tokens.has(normalizedJurisdiction))
36
+ return true;
37
+ if (normalizedCoverageScope && tokens.has(normalizedCoverageScope))
38
+ return true;
39
+ if (normalizedCoverageScope === DataspaceCoverageScope.EuropeanUnion) {
40
+ return Array.from(tokens).some((token) => inferCoverageScopeFromCountryCode(token) === DataspaceCoverageScope.EuropeanUnion);
41
+ }
42
+ return false;
43
+ }
44
+ function matchesDefaultPublishedProvider(provider, input, providerCapability) {
45
+ if (!equalsIgnoreCase(provider.category, input.sector))
46
+ return false;
47
+ if (!isProviderServiceCapability(provider.serviceType))
48
+ return false;
49
+ if (!equalsIgnoreCase(provider.serviceType, providerCapability))
50
+ return false;
51
+ if (!matchesProviderCoverage(provider, input.jurisdiction, input.coverageScope))
52
+ return false;
53
+ return true;
54
+ }
7
55
  function isDefaultsRegistry(value) {
8
56
  return Boolean(value)
9
57
  && typeof value === 'object'
@@ -60,7 +108,15 @@ export class DefaultFirstDataspaceDiscovery {
60
108
  return this.getProviders(input, ServiceCapabilityToken.DigitalTwinProvider);
61
109
  }
62
110
  async getProviders(input, providerCapability) {
63
- const resolver = this.createResolver(input, [providerCapability]);
111
+ const bootstrapPlan = this.buildBootstrapPlan(input, [providerCapability]);
112
+ const defaultPublishedProviders = this.resolveDefaultPublishedProviders(bootstrapPlan.hostingOperators, input, providerCapability);
113
+ if (defaultPublishedProviders.length > 0) {
114
+ return defaultPublishedProviders;
115
+ }
116
+ const resolver = new HttpDataspaceResolver({
117
+ hostingOperators: bootstrapPlan.hostingOperators,
118
+ fetcher: this.fetcher,
119
+ });
64
120
  return resolver.resolvePublishedProviders({
65
121
  sector: input.sector,
66
122
  jurisdiction: input.jurisdiction,
@@ -69,7 +125,14 @@ export class DefaultFirstDataspaceDiscovery {
69
125
  });
70
126
  }
71
127
  createResolver(input, requiredCapabilities) {
72
- const bootstrapPlan = this.defaultsRegistry.buildBootstrapPlan({
128
+ const bootstrapPlan = this.buildBootstrapPlan(input, requiredCapabilities);
129
+ return new HttpDataspaceResolver({
130
+ hostingOperators: bootstrapPlan.hostingOperators,
131
+ fetcher: this.fetcher,
132
+ });
133
+ }
134
+ buildBootstrapPlan(input, requiredCapabilities) {
135
+ return this.defaultsRegistry.buildBootstrapPlan({
73
136
  jurisdiction: input.jurisdiction,
74
137
  version: this.version,
75
138
  networkType: this.networkType,
@@ -78,10 +141,18 @@ export class DefaultFirstDataspaceDiscovery {
78
141
  requiredCapabilities,
79
142
  sourceMode: DataspaceDiscoverySourceMode.DefaultFirst,
80
143
  });
81
- return new HttpDataspaceResolver({
82
- hostingOperators: bootstrapPlan.hostingOperators,
83
- fetcher: this.fetcher,
84
- });
144
+ }
145
+ resolveDefaultPublishedProviders(hosts, input, providerCapability) {
146
+ return hosts.flatMap((host) => (host.publishedProviders || [])
147
+ .filter((provider) => matchesDefaultPublishedProvider(provider, input, providerCapability))
148
+ .map((provider) => ({
149
+ providerDid: provider.providerDid,
150
+ record: provider,
151
+ hostingOperator: host.record,
152
+ hostingOperatorDid: host.operatorDid,
153
+ discoveryUrl: provider.discoveryUrl || host.discoveryUrl,
154
+ catalogUrl: provider.catalogUrl || host.catalogUrl,
155
+ })));
85
156
  }
86
157
  }
87
158
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-sdk-node-ts",
3
- "version": "0.6.3",
3
+ "version": "0.6.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.",
@@ -17,8 +17,8 @@
17
17
  "test:e2e:live-gw": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-node-runtime.e2e.test.mjs"
18
18
  },
19
19
  "dependencies": {
20
- "gdc-common-utils-ts": "^1.14.2",
21
- "gdc-sdk-core-ts": "^0.6.3"
20
+ "gdc-common-utils-ts": "^1.14.10",
21
+ "gdc-sdk-core-ts": "^0.6.9"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.14.10",