dataspace-client-sdk-node 0.1.2 → 0.2.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.
@@ -0,0 +1,49 @@
1
+ # E2E Local GW UC5 (Reproducible, No Mocks)
2
+
3
+ This test runs a real UC5 chain against a locally running GW in demo mode:
4
+
5
+ 1. Legal entity controller activates tenant (`Organization/_activate`).
6
+ 2. Individual controller bootstraps personal/individual organization (`Organization/_batch` + `Order/_batch`).
7
+ 3. Consent is created (`Consent/_batch`) with `organization/Composition.rs`.
8
+ 4. Professional requests SMART token and receives scoped token.
9
+
10
+ Test file:
11
+ - [live-gw-uc5.e2e.test.mjs](/Users/fernando/GITS/gdc-workspace/dataspace-client-sdk-node/tests/live-gw-uc5.e2e.test.mjs)
12
+
13
+ ## Prerequisites
14
+
15
+ 1. Start GW local in demo mode:
16
+ ```bash
17
+ npm -C /Users/fernando/GITS/gdc-workspace/gwtemplate-node-ts run api:local-demo
18
+ ```
19
+
20
+ 2. Provide ICA proof as either:
21
+ - `VP_TOKEN` (preferred, real signed VP), or
22
+ - `VP_TOKEN_FILE` pointing to a minimal fixture payload.
23
+
24
+ Default fixture included:
25
+ - [ica-vp-minimal.json](/Users/fernando/GITS/gdc-workspace/dataspace-client-sdk-node/tests/fixtures/ica-vp-minimal.json)
26
+ - Built at runtime into unsigned compact JWT only for local demo reproducibility.
27
+
28
+ 3. Use a tenant id aligned with your activation proof (`TENANT_ID`).
29
+
30
+ ## Run
31
+
32
+ ```bash
33
+ cd /Users/fernando/GITS/gdc-workspace/dataspace-client-sdk-node
34
+ BASE_URL=http://127.0.0.1:3000 \
35
+ VP_TOKEN_FILE=./tests/fixtures/ica-vp-minimal.json \
36
+ TENANT_ID=VATES-B00000000 \
37
+ JURISDICTION=ES \
38
+ SECTOR=health-care \
39
+ HOST_REGISTRY_SECTOR=test \
40
+ PROFESSIONAL_ID_TOKEN='eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJwcm9mZXNzaW9uYWwifQ.demo' \
41
+ npm run test:e2e:live-gw-uc5
42
+ ```
43
+
44
+ ## Notes
45
+
46
+ - This is a real integration test (no `fetch` mocks).
47
+ - `_activate` in this E2E uses `vp_token` in payload (no Bearer header required by the test).
48
+ - If `TENANT_ID` does not match activation proof context, downstream tenant-scoped steps can return `404`.
49
+ - The scripted scope assertion verifies `organization/Composition.rs` is granted in SMART token response.
@@ -0,0 +1,90 @@
1
+ # ENDPOINT_ID_CATALOG
2
+
3
+ Canonical endpoint-id construction for token cache/session reuse.
4
+
5
+ Use `client.getEndpointId(selector, providerDid?)` and avoid ad-hoc strings.
6
+
7
+ Selector shape:
8
+
9
+ ```ts
10
+ type EndpointSelector = {
11
+ section: string;
12
+ format: string;
13
+ resourceType: string;
14
+ action: string;
15
+ };
16
+ ```
17
+
18
+ Generation rule:
19
+ - With `providerDid`: `did:web:...#section:format:resourceType:action`
20
+ - Without `providerDid`: `section:format:resourceType:action`
21
+
22
+ ## Recommended selectors
23
+
24
+ ```ts
25
+ export const ENDPOINT_SELECTORS = {
26
+ ORG_COMPOSITION_SEARCH: {
27
+ section: 'organization',
28
+ format: 'org.hl7.fhir.r4',
29
+ resourceType: 'Composition',
30
+ action: '_search',
31
+ },
32
+ INDIVIDUAL_CONSENT_BATCH: {
33
+ section: 'individual',
34
+ format: 'org.hl7.fhir.r4',
35
+ resourceType: 'Consent',
36
+ action: '_batch',
37
+ },
38
+ INDIVIDUAL_COMMUNICATION_BATCH: {
39
+ section: 'individual',
40
+ format: 'org.hl7.fhir.r4',
41
+ resourceType: 'Communication',
42
+ action: '_batch',
43
+ },
44
+ INDIVIDUAL_DOCUMENTREFERENCE_BATCH: {
45
+ section: 'individual',
46
+ format: 'org.hl7.fhir.r4',
47
+ resourceType: 'DocumentReference',
48
+ action: '_batch',
49
+ },
50
+ IDENTITY_AUTH_TOKEN: {
51
+ section: 'identity',
52
+ format: 'auth',
53
+ resourceType: 'token',
54
+ action: '_token',
55
+ },
56
+ IDENTITY_AUTH_DCR: {
57
+ section: 'identity',
58
+ format: 'auth',
59
+ resourceType: 'device',
60
+ action: '_dcr',
61
+ },
62
+ IDENTITY_AUTH_EXCHANGE: {
63
+ section: 'identity',
64
+ format: 'auth',
65
+ resourceType: 'token',
66
+ action: '_exchange',
67
+ },
68
+ } as const;
69
+ ```
70
+
71
+ ## Example
72
+
73
+ ```ts
74
+ const targetEndpoint = client.getEndpointId(
75
+ ENDPOINT_SELECTORS.ORG_COMPOSITION_SEARCH,
76
+ ORG_CONTROLLER_DID_WEB,
77
+ );
78
+
79
+ const smart = await client.requestSmartTokenSimple({
80
+ idToken,
81
+ targetEndpoint,
82
+ scopes: ['organization/Composition.rs'],
83
+ });
84
+ ```
85
+
86
+ ## Alignment policy
87
+
88
+ - Prefer current namespaces and flows: `/host`, `/ica`, `/publisher`, and GW runtime `identity/auth`.
89
+ - Do not introduce new integrations based on legacy aliases.
90
+ - Keep endpoint-id selectors stable and explicit across Node + frontend SDKs.
@@ -0,0 +1,84 @@
1
+ # LEGAL_ORGANIZATION_FLOW_STEP_BY_STEP
2
+
3
+ Canonical legal-organization flow index.
4
+ This file avoids duplicating controller/practitioner details and points to the source guides.
5
+
6
+ ## Mandatory rules for integrators
7
+
8
+ Security planes:
9
+ - Transport plane: backend ↔ gateway channel protection (deployment-specific).
10
+ - Identity/business plane: user/controller/member authentication and authorization.
11
+ - Operator/hosting plane: infrastructure/operator lifecycle.
12
+
13
+ Keep these planes separated; do not treat transport credentials as user identity tokens.
14
+
15
+ Secure messaging note:
16
+ - Authentication for controller/member actions is identity-plane (`vp_token`, `idToken`, SMART/client_assertion).
17
+ - Backend-to-service P2P messages can additionally be signed/encrypted (embedded JWS/JWE) according to deployment communication mode.
18
+
19
+ Wallet profile:
20
+ - deterministic key derivation/profile rules are centralized in `BACKEND_NODE_INTEGRATION.md` ("Deterministic Wallet Profile").
21
+ - communication mode (`plain` / `strict` / `auto-detect`) is centralized in `BACKEND_NODE_INTEGRATION.md`.
22
+
23
+ - `jurisdiction` (country) is required in every step.
24
+ - Professional tenants are registered in one jurisdiction and all routes resolve against it.
25
+ - Identity auth routes and business/entity routes are different:
26
+ - identity: `/host/cds-{jurisdiction}/v1/{sector}/{tenantId}/identity/auth/...`
27
+ - business: `/{tenantId}/cds-{jurisdiction}/v1/{sector}/...`
28
+ - `vp_token` is for onboarding proof (`_activate`), not for runtime calls.
29
+ - Controller DCR/token and practitioner DCR/token are distinct flows.
30
+
31
+ ## Runtime context pattern (high-level)
32
+
33
+ ```ts
34
+ const profileContext = {
35
+ baseUrl: process.env.BASE_URL!,
36
+ jurisdiction: process.env.JURISDICTION!, // REQUIRED
37
+ sector: process.env.SECTOR || 'health-care',
38
+ };
39
+
40
+ const sessionContext = {
41
+ tenantId: currentSession.tenantId,
42
+ controller: currentSession.controller,
43
+ practitioner: currentSession.practitioner,
44
+ };
45
+ ```
46
+
47
+ Use `profileContext` for role/organization runtime context and `sessionContext` for logged-in user/session data.
48
+
49
+ ## Phase A: controller flow (authoritative)
50
+
51
+ 1. Build/sign VP token (`nonce`, no `jti` in VP for this flow).
52
+ 2. `_activate` organization in host registry.
53
+ 3. Read offer and explicit user acceptance.
54
+ 4. Submit `initialOrder`.
55
+ 5. Controller DCR bootstrap (`_exchange` then `_dcr`).
56
+ 6. Request controller runtime token (`_token`).
57
+ 7. Create employee/member in entity route.
58
+ 8. Extract activation code for practitioner.
59
+ 9. If license seats are exhausted: receive `Employee-license-offer-v1.0`, accept, submit `licenseOrder`, retry employee create.
60
+
61
+ Detailed guide (single source of truth):
62
+ - `CONTROLLER_FLOW_STEP_BY_STEP.md`
63
+
64
+ ## Phase B: practitioner flow (authoritative)
65
+
66
+ 1. Receive practitioner activation code from controller flow.
67
+ 2. Practitioner DCR bootstrap (`_exchange` then `_dcr`).
68
+ 3. Request practitioner SMART/runtime token (`_token`) with required scopes.
69
+ 4. Call protected organization/business endpoints.
70
+
71
+ Detailed guide (single source of truth):
72
+ - `PRACTITIONER_FLOW_STEP_BY_STEP.md`
73
+
74
+ ## Scope of this file
75
+
76
+ - Keep this file as top-level legal organization map.
77
+ - Put implementation details in:
78
+ - `CONTROLLER_FLOW_STEP_BY_STEP.md`
79
+ - `PRACTITIONER_FLOW_STEP_BY_STEP.md`
80
+ - `BACKEND_NODE_INTEGRATION.md`
81
+
82
+ Related references:
83
+ - `ENDPOINT_ID_CATALOG.md`
84
+ - `DATA_MODEL_ALIGNMENT.md`
@@ -0,0 +1,70 @@
1
+ # PERSONAL_FLOW_STEP_BY_STEP
2
+
3
+ Canonical flow for personal/family onboarding and consented access.
4
+
5
+ Security note:
6
+ - User authentication/authorization (id-token + scopes + consent) is independent from transport/message protection.
7
+ - Backend may enforce DIDComm message security (JWS/JWE) per deployment policy: `plain` / `strict` / `auto-detect`.
8
+
9
+ ## 1) Start individual/family organization onboarding
10
+
11
+ ```ts
12
+ const started = await client.startIndividualOrganizationSimple({
13
+ alternateName,
14
+ controllerEmail, // or controllerTelephone
15
+ controllerRole: 'org.hl7.v3.RoleCode|RESPRSN',
16
+ });
17
+ ```
18
+
19
+ ## 2) Show offer in UI and accept
20
+
21
+ ```ts
22
+ const offerId = started.offerId;
23
+ const offerPreview = started.offerPreview;
24
+ ```
25
+
26
+ ## 3) Confirm order (always)
27
+
28
+ ```ts
29
+ const order = await client.confirmIndividualOrganizationOrderSimple({ offerId: offerId! });
30
+ ```
31
+
32
+ ## 4) Configure consent/preauthorization
33
+
34
+ ```ts
35
+ const consent = await client.grantProfessionalAccessSimple(
36
+ { tenantId, jurisdiction, sector },
37
+ {
38
+ subjectDid,
39
+ actor: { identifier: practitionerDid },
40
+ actorRole: 'Practitioner',
41
+ purpose: 'TREAT',
42
+ actions: ['organization/Composition.rs'],
43
+ },
44
+ );
45
+ ```
46
+
47
+ ## 5) Optional: import/update index data
48
+
49
+ Use your ingestion path (`/publisher/...`) and then subject-side runtime operations.
50
+
51
+ ## 6) Professional requests token and reads allowed resources
52
+
53
+ ```ts
54
+ const smart = await client.requestSmartTokenSimple({
55
+ idToken: practitionerIdToken,
56
+ targetEndpoint: client.getEndpointId({
57
+ section: 'organization',
58
+ format: 'org.hl7.fhir.r4',
59
+ resourceType: 'Composition',
60
+ action: '_search',
61
+ }, practitionerDid),
62
+ scopes: ['organization/Composition.rs'],
63
+ });
64
+ ```
65
+
66
+ ## Notes
67
+
68
+ - For personal onboarding in GW, verification is integrated in the onboarding flow (`individual/org.schema/Organization/_batch` + `Order/_batch`).
69
+ - Keep Offer/Order UX explicit even when amount is `0`.
70
+ - Use endpoint-id selectors from `docs/ENDPOINT_ID_CATALOG.md`.
@@ -177,14 +177,17 @@ Even if amount is `0`, user acceptance and Order submission still happen.
177
177
  SDK method:
178
178
  - `createOrganizationEmployee(...)`
179
179
 
180
+ Use claim constants:
181
+ - `ClaimsPersonSchemaorg` from `gdc-common-utils-ts/constants/schemaorg`
182
+
180
183
  ```ts
181
184
  const employee = await client.createOrganizationEmployee(
182
185
  { tenantId, jurisdiction, sector },
183
186
  {
184
187
  employeeClaims: {
185
188
  '@context': 'org.schema',
186
- 'org.schema.Person.email': 'doctor@example.com',
187
- 'org.schema.Person.hasOccupation': 'ISCO-08|2211',
189
+ [ClaimsPersonSchemaorg.email]: 'doctor@example.com',
190
+ [ClaimsPersonSchemaorg.hasOccupation]: 'ISCO-08|2211',
188
191
  },
189
192
  },
190
193
  );
@@ -217,7 +220,12 @@ SDK method:
217
220
  ```ts
218
221
  const smart = await client.requestSmartTokenSimple({
219
222
  idToken: doctorUserIdToken,
220
- endpointId: 'doctor-portal',
223
+ targetEndpoint: client.getEndpointId({
224
+ section: 'organization',
225
+ format: 'org.hl7.fhir.r4',
226
+ resourceType: 'Composition',
227
+ action: '_search',
228
+ }, doctorDidWeb),
221
229
  scopes: ['organization/Composition.rs'],
222
230
  });
223
231
  ```
@@ -0,0 +1,182 @@
1
+ # PRACTITIONER_FLOW_STEP_BY_STEP
2
+
3
+ Flow for physician/practitioner employee after controller has issued `activationCode`.
4
+
5
+ ## Rules first
6
+
7
+ - `jurisdiction` is mandatory (country context for tenant routing and authorization).
8
+ - `activationCode` is single-use bootstrap material for identity activation.
9
+ - Identity token endpoints and entity/business endpoints are different concerns:
10
+ - identity token flow path: `/host/cds-{jurisdiction}/v1/{sector}/{tenantId}/identity/auth/...`
11
+ - entity/business paths: `/{tenantId}/cds-{jurisdiction}/v1/{sector}/...`
12
+ - Practitioner signs `client_assertion` with their private signing key when required by the token endpoint.
13
+ - Message transport may also use backend wallet JWS/JWE protection (deployment policy: `plain` / `strict` / `auto-detect`).
14
+
15
+ ## 1) Receive activation code
16
+
17
+ Input from controller flow:
18
+ - `activationCode`
19
+
20
+ Runtime context:
21
+
22
+ ```ts
23
+ const profileContext = {
24
+ baseUrl: process.env.BASE_URL!,
25
+ jurisdiction: process.env.JURISDICTION!, // REQUIRED
26
+ sector: process.env.SECTOR || 'health-care',
27
+ };
28
+
29
+ const sessionContext = {
30
+ tenantId: currentSession.tenantId,
31
+ practitionerDidWeb: currentSession.practitioner.didWeb,
32
+ practitionerIdToken: currentSession.idToken,
33
+ practitionerPublicJwk: currentSession.practitioner.publicJwk,
34
+ };
35
+ ```
36
+
37
+ ## 2) Activate device identity (DCR bootstrap)
38
+
39
+ ```ts
40
+ const client = new DataspaceNodeClient({
41
+ baseUrl: profileContext.baseUrl,
42
+ ctx: {
43
+ tenantId: sessionContext.tenantId,
44
+ jurisdiction: profileContext.jurisdiction,
45
+ sector: profileContext.sector,
46
+ },
47
+ });
48
+
49
+ const device = await client.activateEmployeeDeviceWithActivationCodeSimple({
50
+ tenantId: sessionContext.tenantId,
51
+ jurisdiction: profileContext.jurisdiction,
52
+ sector: profileContext.sector,
53
+ activationCode,
54
+ idToken: sessionContext.practitionerIdToken,
55
+ dcrPayload: {
56
+ application_type: 'web',
57
+ token_endpoint_auth_method: 'private_key_jwt',
58
+ jwks: { keys: [sessionContext.practitionerPublicJwk] },
59
+ },
60
+ });
61
+ ```
62
+
63
+ ## 3) Request SMART token for protected operations
64
+
65
+ `targetEndpoint` is only a local token-target identifier. Authorization is defined by `scopes`.
66
+
67
+ ```ts
68
+ const smart = await client.requestSmartTokenSimple({
69
+ tenantId: sessionContext.tenantId,
70
+ jurisdiction: profileContext.jurisdiction,
71
+ sector: profileContext.sector,
72
+ idToken: sessionContext.practitionerIdToken,
73
+ targetEndpoint: `smart:practitioner:${sessionContext.practitionerDidWeb}:ips-read`,
74
+ scopes: [
75
+ 'organization/Composition.rs',
76
+ 'organization/Consent.cruds',
77
+ 'organization/Communication.cruds',
78
+ ],
79
+ });
80
+ ```
81
+
82
+ IPS note:
83
+ - Access to IPS sections is authorized via scopes (for example `organization/Composition.rs`) and consent/policy checks.
84
+ - Do not derive authorization from `targetEndpoint` or from a single endpoint selector.
85
+
86
+ ## 3.1) Where JWT signing happens (`private_key_jwt`)
87
+
88
+ If your token endpoint requires `client_assertion` (`private_key_jwt`), the JWT must be signed with the practitioner's/controller's private key.
89
+
90
+ Option A (recommended): SDK signs and sends `client_assertion` for you.
91
+
92
+ ```ts
93
+ const token = await client.authenticateBackendSmartStandard({
94
+ clientId: sessionContext.practitionerDidWeb,
95
+ scopes: ['organization/Composition.rs'],
96
+ targetEndpoint: `smart:practitioner:${sessionContext.practitionerDidWeb}:ips-read`,
97
+ tokenUrl: `${profileContext.baseUrl}/token`,
98
+ audience: `${profileContext.baseUrl}/token`,
99
+ walletContext: {
100
+ tenantId: sessionContext.tenantId,
101
+ jurisdiction: profileContext.jurisdiction,
102
+ sector: profileContext.sector,
103
+ },
104
+ publicJwk: sessionContext.practitionerPublicJwk,
105
+ });
106
+ ```
107
+
108
+ Option B (manual): build/sign JWT yourself, then attach it in token request.
109
+
110
+ ```ts
111
+ const now = Math.floor(Date.now() / 1000);
112
+ const encodedHeader = base64url(JSON.stringify({
113
+ alg: 'ES384',
114
+ typ: 'JWT',
115
+ kid: sessionContext.practitionerPublicJwk.kid,
116
+ }));
117
+ const encodedPayload = base64url(JSON.stringify({
118
+ iss: sessionContext.practitionerDidWeb,
119
+ sub: sessionContext.practitionerDidWeb,
120
+ aud: `${profileContext.baseUrl}/token`,
121
+ iat: now,
122
+ exp: now + 300,
123
+ jti: crypto.randomUUID(),
124
+ }));
125
+ const signingInput = `${encodedHeader}.${encodedPayload}`; // what must be signed
126
+
127
+ const signatureBase64Url = await externalSigner(signingInput); // integrator-managed signer
128
+ const clientAssertion = `${encodedHeader}.${encodedPayload}.${signatureBase64Url}`;
129
+
130
+ // Equivalent high-level helper style:
131
+ // const clientAssertion = await wallet.signCompactJws({ header, claims });
132
+ ```
133
+
134
+ ```ts
135
+ const tokenRequestBody = {
136
+ grant_type: 'client_credentials',
137
+ client_id: sessionContext.practitionerDidWeb,
138
+ scope: 'organization/Composition.rs organization/Consent.cruds organization/Communication.cruds',
139
+ client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
140
+ client_assertion, // signed JWT is attached here
141
+ };
142
+ ```
143
+
144
+ Integrator note:
145
+ - SDK can help generate/sign compact JWTs, but key custody/signature execution belongs to the integrator.
146
+ - The signer may be wallet SDK, secure enclave, KMS, HSM, or remote signature service.
147
+
148
+ ```ts
149
+ // Alternative helper form if your signer abstraction already returns compact JWS:
150
+ const clientAssertion = await wallet.signCompactJws({
151
+ header: {
152
+ alg: 'ES384',
153
+ typ: 'JWT',
154
+ kid: sessionContext.practitionerPublicJwk.kid,
155
+ },
156
+ claims: {
157
+ iss: sessionContext.practitionerDidWeb,
158
+ sub: sessionContext.practitionerDidWeb,
159
+ aud: `${profileContext.baseUrl}/token`,
160
+ iat: now,
161
+ exp: now + 300,
162
+ jti: crypto.randomUUID(),
163
+ },
164
+ });
165
+ ```
166
+
167
+ For the current GW `identity/auth/_token` flow documented in this SDK, `requestSmartTokenSimple(...)` is id-token based.
168
+ Use `private_key_jwt` flow when your deployment exposes a standards token endpoint that requires `client_assertion`.
169
+
170
+ ## 4) Call protected APIs with returned bearer
171
+
172
+ Use `smart.accessToken` in subsequent requests.
173
+
174
+ Complete path examples:
175
+ - exchange activation code:
176
+ `/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_exchange`
177
+ - DCR:
178
+ `/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_dcr`
179
+ - SMART token:
180
+ `/host/cds-ES/v1/health-care/{tenantId}/identity/auth/_token`
181
+ - example protected entity route (if practitioner is allowed):
182
+ `/{tenantId}/cds-ES/v1/health-care/entity/org.schema/Employee/_search`
@@ -1,4 +1,5 @@
1
1
  import { DataspaceNodeClient } from '../dist/index.js';
2
+ import { ClaimsPersonSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
2
3
 
3
4
  function parseCsv(value, fallback = []) {
4
5
  const items = String(value || '')
@@ -106,8 +107,8 @@ async function main() {
106
107
  {
107
108
  employeeClaims: {
108
109
  '@context': 'org.schema',
109
- 'org.schema.Person.email': process.env.CONTROLLER_EMAIL || 'controller@example.com',
110
- 'org.schema.Person.hasOccupation': process.env.CONTROLLER_ROLE || 'ISCO-08|1342',
110
+ [ClaimsPersonSchemaorg.email]: process.env.CONTROLLER_EMAIL || 'controller@example.com',
111
+ [ClaimsPersonSchemaorg.hasOccupation]: process.env.CONTROLLER_ROLE || 'ISCO-08|1342',
111
112
  },
112
113
  },
113
114
  pollOptions,
@@ -1,4 +1,9 @@
1
1
  import { DataspaceNodeClient, createDidcommPlainMessage } from '../dist/index.js';
2
+ import {
3
+ ClaimsOrganizationSchemaorg,
4
+ ClaimsPersonSchemaorg,
5
+ ClaimsServiceSchemaorg,
6
+ } from 'gdc-common-utils-ts/constants/schemaorg';
2
7
 
3
8
  const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
4
9
  const bearerToken = process.env.AUTH_BEARER || 'demo-token';
@@ -21,14 +26,14 @@ const payload = createDidcommPlainMessage({
21
26
  claims: {
22
27
  '@context': 'org.schema',
23
28
  '@type': 'template',
24
- 'org.schema.Organization.address.addressCountry': 'ES',
25
- 'org.schema.Organization.identifier.additionalType': 'UUID',
26
- 'org.schema.Organization.identifier.value': `family-${Date.now()}`,
27
- 'org.schema.Person.email': 'adult1@example.com',
28
- 'org.schema.Service.category': ctx.sector,
29
- 'org.schema.Service.identifier': 'did:web:api-provider.example.com',
30
- 'org.schema.Service.serviceType': 'http://terminology.hl7.org/CodeSystem/v3-ActReason|SRVC',
31
- 'org.schema.Service.termsOfService': 'https://provider.example.com/terms',
29
+ [ClaimsOrganizationSchemaorg.addressCountry]: 'ES',
30
+ [ClaimsOrganizationSchemaorg.identifierType]: 'UUID',
31
+ [ClaimsOrganizationSchemaorg.identifierValue]: `family-${Date.now()}`,
32
+ [ClaimsPersonSchemaorg.email]: 'adult1@example.com',
33
+ [ClaimsServiceSchemaorg.category]: ctx.sector,
34
+ [ClaimsServiceSchemaorg.identifier]: 'did:web:api-provider.example.com',
35
+ [ClaimsServiceSchemaorg.serviceType]: 'http://terminology.hl7.org/CodeSystem/v3-ActReason|SRVC',
36
+ [ClaimsServiceSchemaorg.termsOfService]: 'https://provider.example.com/terms',
32
37
  },
33
38
  },
34
39
  },
@@ -1,4 +1,5 @@
1
1
  import { DataspaceNodeClient, createDidcommPlainMessage } from '../dist/index.js';
2
+ import { ClaimsPersonSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
2
3
 
3
4
  const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
4
5
  const bearerToken = process.env.AUTH_BEARER || 'demo-token';
@@ -56,8 +57,8 @@ const employeePayload = createDidcommPlainMessage({
56
57
  meta: {
57
58
  claims: {
58
59
  '@context': 'org.schema',
59
- 'org.schema.Person.email': process.env.EMPLOYEE_EMAIL || 'doctor1@acme.org',
60
- 'org.schema.Person.hasOccupation': process.env.EMPLOYEE_ROLE || 'ISCO-08|2211',
60
+ [ClaimsPersonSchemaorg.email]: process.env.EMPLOYEE_EMAIL || 'doctor1@acme.org',
61
+ [ClaimsPersonSchemaorg.hasOccupation]: process.env.EMPLOYEE_ROLE || 'ISCO-08|2211',
61
62
  },
62
63
  },
63
64
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataspace-client-sdk-node",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Node.js SDK skeleton for GW/UNID DIDComm plain batch + async polling flows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,7 +9,8 @@
9
9
  "build": "tsc -p tsconfig.json",
10
10
  "type-check": "tsc -p tsconfig.json --noEmit",
11
11
  "test": "npm run build && node --test tests/*.test.mjs",
12
- "example:e2e-bootstrap-tenant": "npm run build && node examples/e2e-bootstrap-tenant.mjs"
12
+ "example:e2e-bootstrap-tenant": "npm run build && node examples/e2e-bootstrap-tenant.mjs",
13
+ "test:e2e:live-gw-uc5": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-uc5.e2e.test.mjs"
13
14
  },
14
15
  "engines": {
15
16
  "node": ">=22"
@@ -20,7 +21,7 @@
20
21
  },
21
22
  "dependencies": {
22
23
  "@noble/post-quantum": "^0.6.1",
23
- "gdc-common-utils-ts": "^1.4.8",
24
+ "gdc-common-utils-ts": "^1.4.12",
24
25
  "node-fetch": "^3.3.2"
25
26
  }
26
27
  }