gdc-sdk-node-ts 0.9.1 → 0.12.0

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.
@@ -1,5 +1,8 @@
1
1
  // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
- import { HealthcareBasicSections } from 'gdc-common-utils-ts/constants';
2
+ import { HealthcareBasicSections, ResourceTypesFhirR4 } from 'gdc-common-utils-ts/constants';
3
+ import { Format } from 'gdc-common-utils-ts/constants/Schemas';
4
+ import { RelatedPersonClaim } from 'gdc-common-utils-ts/models/interoperable-claims/related-person-claims';
5
+ import { createInteroperableResourceOperationEditor, IndividualOrganizationLifecycleDraft, LicenseOfferSearchEditor, LicenseOrderSearchEditor, InteroperableLifecycleStatuses, LicenseListSearchEditor, } from 'gdc-common-utils-ts';
3
6
  import { GwCoreLifecycleRequestMethod, GwCoreLifecycleRequestType, GwCoreLifecycleTodo, } from './constants/lifecycle.js';
4
7
  import { buildEmployeeBatchEntry, buildEmployeeSearchBundle, } from 'gdc-sdk-core-ts';
5
8
  export async function createOrganizationEmployeeWithDeps(routeCtx, input, options, deps) {
@@ -43,6 +46,69 @@ export async function searchOrganizationEmployeesWithDeps(routeCtx, input, deps)
43
46
  body: buildEmployeeSearchBundle({ claims: input.employeeClaims }),
44
47
  }, input.pollOptions);
45
48
  }
49
+ /**
50
+ * Searches license seats for one organization/tenant through `License/_search`.
51
+ */
52
+ export async function searchOrganizationLicensesWithDeps(routeCtx, input, deps) {
53
+ return deps.submitAndPoll(deps.organizationLicenseSearchPath(routeCtx), deps.organizationLicenseSearchPollPath(routeCtx), {
54
+ thid: input.requestThid || `organization-license-search-${createRuntimeUuid()}`,
55
+ body: {
56
+ resourceType: 'Bundle',
57
+ type: 'batch',
58
+ entry: [
59
+ new LicenseListSearchEditor(input.licenseQuery || {})
60
+ .buildSearchEntry(),
61
+ ],
62
+ },
63
+ }, input.pollOptions);
64
+ }
65
+ /**
66
+ * Lists license seats using the same canonical `License/_search` route with no
67
+ * mandatory filters.
68
+ */
69
+ export async function listOrganizationLicensesWithDeps(routeCtx, input, deps) {
70
+ return searchOrganizationLicensesWithDeps(routeCtx, input || {}, deps);
71
+ }
72
+ /**
73
+ * Searches commercial license offers for one organization/tenant through
74
+ * `Offer/_search`.
75
+ */
76
+ export async function searchOrganizationLicenseOffersWithDeps(routeCtx, input, deps) {
77
+ return deps.submitAndPoll(deps.organizationLicenseOfferSearchPath(routeCtx), deps.organizationLicenseOfferSearchPollPath(routeCtx), {
78
+ thid: input.requestThid || `organization-license-offer-search-${createRuntimeUuid()}`,
79
+ body: {
80
+ resourceType: 'Bundle',
81
+ type: 'batch',
82
+ data: [
83
+ new LicenseOfferSearchEditor(input.offerQuery || {})
84
+ .buildSearchEntry(),
85
+ ],
86
+ },
87
+ }, input.pollOptions);
88
+ }
89
+ export async function listOrganizationLicenseOffersWithDeps(routeCtx, input, deps) {
90
+ return searchOrganizationLicenseOffersWithDeps(routeCtx, input || {}, deps);
91
+ }
92
+ /**
93
+ * Searches commercial license orders/payment projections for one
94
+ * organization/tenant through `Order/_search`.
95
+ */
96
+ export async function searchOrganizationLicenseOrdersWithDeps(routeCtx, input, deps) {
97
+ return deps.submitAndPoll(deps.organizationLicenseOrderSearchPath(routeCtx), deps.organizationLicenseOrderSearchPollPath(routeCtx), {
98
+ thid: input.requestThid || `organization-license-order-search-${createRuntimeUuid()}`,
99
+ body: {
100
+ resourceType: 'Bundle',
101
+ type: 'batch',
102
+ data: [
103
+ new LicenseOrderSearchEditor(input.orderQuery || {})
104
+ .buildSearchEntry(),
105
+ ],
106
+ },
107
+ }, input.pollOptions);
108
+ }
109
+ export async function listOrganizationLicenseOrdersWithDeps(routeCtx, input, deps) {
110
+ return searchOrganizationLicenseOrdersWithDeps(routeCtx, input || {}, deps);
111
+ }
46
112
  export async function disableIndividualOrganizationWithDeps(routeCtx, input, options, deps) {
47
113
  // TODO(gw-core-lifecycle-target-patch-individual-disable): migrate from
48
114
  // explicit `_disable` to `_batch + PATCH` only after GW CORE supports it.
@@ -66,6 +132,62 @@ export async function purgeIndividualOrganizationWithDeps(routeCtx, input, optio
66
132
  });
67
133
  return deps.submitAndPoll(deps.individualOrganizationPurgePath(routeCtx), deps.individualOrganizationPurgePollPath(routeCtx), payload, options);
68
134
  }
135
+ /**
136
+ * Searches license seats for one individual/family controller context through
137
+ * the shared `License/_search` route.
138
+ */
139
+ export async function searchIndividualLicensesWithDeps(routeCtx, input, deps) {
140
+ return deps.submitAndPoll(deps.individualLicenseSearchPath(routeCtx), deps.individualLicenseSearchPollPath(routeCtx), {
141
+ thid: input.requestThid || `individual-license-search-${createRuntimeUuid()}`,
142
+ body: {
143
+ resourceType: 'Bundle',
144
+ type: 'batch',
145
+ entry: [
146
+ new LicenseListSearchEditor(input.licenseQuery || {})
147
+ .buildSearchEntry(),
148
+ ],
149
+ },
150
+ }, input.pollOptions);
151
+ }
152
+ /**
153
+ * Lists license seats for the individual/family side using the same canonical
154
+ * search route without mandatory filters.
155
+ */
156
+ export async function listIndividualLicensesWithDeps(routeCtx, input, deps) {
157
+ return searchIndividualLicensesWithDeps(routeCtx, input || {}, deps);
158
+ }
159
+ export async function searchIndividualLicenseOffersWithDeps(routeCtx, input, deps) {
160
+ return deps.submitAndPoll(deps.individualLicenseOfferSearchPath(routeCtx), deps.individualLicenseOfferSearchPollPath(routeCtx), {
161
+ thid: input.requestThid || `individual-license-offer-search-${createRuntimeUuid()}`,
162
+ body: {
163
+ resourceType: 'Bundle',
164
+ type: 'batch',
165
+ data: [
166
+ new LicenseOfferSearchEditor(input.offerQuery || {})
167
+ .buildSearchEntry(),
168
+ ],
169
+ },
170
+ }, input.pollOptions);
171
+ }
172
+ export async function listIndividualLicenseOffersWithDeps(routeCtx, input, deps) {
173
+ return searchIndividualLicenseOffersWithDeps(routeCtx, input || {}, deps);
174
+ }
175
+ export async function searchIndividualLicenseOrdersWithDeps(routeCtx, input, deps) {
176
+ return deps.submitAndPoll(deps.individualLicenseOrderSearchPath(routeCtx), deps.individualLicenseOrderSearchPollPath(routeCtx), {
177
+ thid: input.requestThid || `individual-license-order-search-${createRuntimeUuid()}`,
178
+ body: {
179
+ resourceType: 'Bundle',
180
+ type: 'batch',
181
+ data: [
182
+ new LicenseOrderSearchEditor(input.orderQuery || {})
183
+ .buildSearchEntry(),
184
+ ],
185
+ },
186
+ }, input.pollOptions);
187
+ }
188
+ export async function listIndividualLicenseOrdersWithDeps(routeCtx, input, deps) {
189
+ return searchIndividualLicenseOrdersWithDeps(routeCtx, input || {}, deps);
190
+ }
69
191
  export async function importIpsOrFhirAndUpdateIndexWithDeps(routeCtx, input, deps) {
70
192
  const payload = {
71
193
  thid: input.compositionPayload.thid || `composition-${createRuntimeUuid()}`,
@@ -79,6 +201,65 @@ export async function importIpsOrFhirAndUpdateIndexWithDeps(routeCtx, input, dep
79
201
  : deps.individualCompositionR4PollPath(routeCtx);
80
202
  return deps.submitAndPoll(submitPath, pollPath, payload, input.pollOptions);
81
203
  }
204
+ export async function disableIndividualMemberWithDeps(routeCtx, input, options, deps) {
205
+ const claims = {
206
+ '@context': String(input.memberClaims?.['@context'] || Format.FHIR_API).trim() || Format.FHIR_API,
207
+ ...(input.memberClaims || {}),
208
+ };
209
+ const resource = createInteroperableResourceOperationEditor()
210
+ .setResourceType(ResourceTypesFhirR4.RelatedPerson)
211
+ .setIdentifierClaimKey(RelatedPersonClaim.IdentifierValue)
212
+ .setBusinessIdentifier(String(claims[RelatedPersonClaim.IdentifierValue] || claims[RelatedPersonClaim.Identifier] || '').trim())
213
+ .setClaims(claims)
214
+ .setLifecycleStatus(InteroperableLifecycleStatuses.Inactive)
215
+ .buildLifecycleResource();
216
+ const payload = {
217
+ thid: `relatedperson-disable-${createRuntimeUuid()}`,
218
+ body: {
219
+ resourceType: 'Bundle',
220
+ type: 'batch',
221
+ entry: [{
222
+ request: { method: GwCoreLifecycleRequestMethod.Post },
223
+ meta: { claims },
224
+ resource: {
225
+ ...resource,
226
+ ...(input.resourceId ? { id: input.resourceId } : {}),
227
+ },
228
+ }],
229
+ },
230
+ };
231
+ return deps.submitAndPoll(deps.individualRelatedPersonBatchPath(routeCtx), deps.individualRelatedPersonPollPath(routeCtx), payload, options);
232
+ }
233
+ export async function purgeIndividualMemberWithDeps(routeCtx, input, options, deps) {
234
+ const claims = {
235
+ '@context': String(input.memberClaims?.['@context'] || Format.FHIR_API).trim() || Format.FHIR_API,
236
+ ...(input.memberClaims || {}),
237
+ };
238
+ const resource = createInteroperableResourceOperationEditor()
239
+ .setResourceType(ResourceTypesFhirR4.RelatedPerson)
240
+ .setIdentifierClaimKey(RelatedPersonClaim.IdentifierValue)
241
+ .setBusinessIdentifier(String(claims[RelatedPersonClaim.IdentifierValue] || claims[RelatedPersonClaim.Identifier] || '').trim())
242
+ .setClaims(claims)
243
+ .setLifecycleStatus(InteroperableLifecycleStatuses.Purged)
244
+ .buildLifecycleResource();
245
+ const payload = {
246
+ thid: `relatedperson-purge-${createRuntimeUuid()}`,
247
+ body: {
248
+ resourceType: 'Bundle',
249
+ type: 'batch',
250
+ entry: [{
251
+ type: input.dataType || GwCoreLifecycleRequestType.IndividualMemberPurge,
252
+ request: { method: GwCoreLifecycleRequestMethod.Post },
253
+ meta: { claims },
254
+ resource: {
255
+ ...resource,
256
+ ...(input.resourceId ? { id: input.resourceId } : {}),
257
+ },
258
+ }],
259
+ },
260
+ };
261
+ return deps.submitAndPoll(deps.individualRelatedPersonPurgePath(routeCtx), deps.individualRelatedPersonPurgePollPath(routeCtx), payload, options);
262
+ }
82
263
  export async function upsertRelatedPersonAndPollWithDeps(routeCtx, input, deps) {
83
264
  const payload = {
84
265
  thid: input.relatedPersonPayload.thid || `relatedperson-${createRuntimeUuid()}`,
@@ -204,23 +385,19 @@ function buildEmployeeLifecyclePayload(input) {
204
385
  }
205
386
  function buildIndividualOrganizationLifecyclePayload(input) {
206
387
  const claims = input.organizationClaims || {};
388
+ const payload = new IndividualOrganizationLifecycleDraft()
389
+ .setClaims(claims)
390
+ .setRequestType(input.requestType)
391
+ .setThreadId(`${input.thidPrefix}-${createRuntimeUuid()}`);
392
+ if (input.resourceId) {
393
+ payload.setResourceId(input.resourceId);
394
+ }
207
395
  return {
208
396
  jti: `jti-${createRuntimeUuid()}`,
209
397
  iss: input.routeCtx.tenantId,
210
398
  aud: input.routeCtx.tenantId,
211
399
  type: 'application/didcomm-plain+json',
212
- thid: `${input.thidPrefix}-${createRuntimeUuid()}`,
213
- body: {
214
- data: [{
215
- type: input.requestType,
216
- request: { method: GwCoreLifecycleRequestMethod.Post },
217
- meta: { claims },
218
- resource: {
219
- ...(input.resourceId ? { id: input.resourceId } : {}),
220
- meta: { claims },
221
- },
222
- }],
223
- },
400
+ ...payload.buildCurrentGwPayload(),
224
401
  };
225
402
  }
226
403
  function buildBundleSearchQuery(input) {
package/dist/session.js CHANGED
@@ -30,7 +30,7 @@ export class ActorSession {
30
30
  }
31
31
  asHostOnboarding() {
32
32
  this.assertActorKind(ActorKinds.HostOnboarding);
33
- return new HostOnboardingSdk(this.requireClient());
33
+ return new HostOnboardingSdk(this.requireClient(), this.capabilities);
34
34
  }
35
35
  asOrganizationController() {
36
36
  this.assertActorKind(ActorKinds.OrganizationController);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-sdk-node-ts",
3
- "version": "0.9.1",
3
+ "version": "0.12.0",
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.",
@@ -13,12 +13,21 @@
13
13
  "scripts": {
14
14
  "build": "tsc -p tsconfig.json",
15
15
  "type-check": "tsc -p tsconfig.json --noEmit",
16
+ "local:close": "PORTS=3000 bash ./scripts/local-close.sh",
17
+ "docker:close": "PORTS=8000 bash ./scripts/local-close.sh",
16
18
  "test": "npm run build && node --test tests/*.test.mjs",
17
- "test:e2e:live-gw": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-node-runtime.e2e.test.mjs"
19
+ "test:e2e:live-gw": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-node-runtime.e2e.test.mjs",
20
+ "test:e2e:live-gw:professional": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_SUITE=professional node --test tests/live-gw-node-runtime.e2e.test.mjs",
21
+ "test:e2e:live-gw:individual": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_SUITE=individual node --test tests/live-gw-node-runtime.e2e.test.mjs",
22
+ "test:e2e:live-gw:clinical": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_SUITE=clinical node --test tests/live-gw-node-runtime.e2e.test.mjs",
23
+ "test:e2e:live-gw:didcomm-plain": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_TRANSPORT=didcomm-plain node --test tests/live-gw-node-runtime.e2e.test.mjs",
24
+ "test:e2e:live-gw:legacy-fhir": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_TRANSPORT=legacy-fhir node --test tests/live-gw-node-runtime.e2e.test.mjs",
25
+ "test:e2e:live-gw:all": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_TRANSPORT=all node --test tests/live-gw-node-runtime.e2e.test.mjs",
26
+ "test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
18
27
  },
19
28
  "dependencies": {
20
- "gdc-common-utils-ts": "^1.20.1",
21
- "gdc-sdk-core-ts": "^0.9.1"
29
+ "gdc-common-utils-ts": "^1.24.0",
30
+ "gdc-sdk-core-ts": "^0.11.0"
22
31
  },
23
32
  "devDependencies": {
24
33
  "@types/node": "^20.14.10",