dataconv-client-sdk-ts 0.3.1 → 0.4.1
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 +358 -57
- package/dist/DataConvClient.d.ts +23 -1
- package/dist/DataConvClient.d.ts.map +1 -1
- package/dist/DataConvClient.js +206 -12
- package/dist/DataConvClient.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +860 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workbook-inspection.d.ts +4 -0
- package/dist/workbook-inspection.d.ts.map +1 -0
- package/dist/workbook-inspection.js +43 -0
- package/dist/workbook-inspection.js.map +1 -0
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -2,14 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for consuming the `adapter-ingestion-py` pre-conversion API.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
5
|
+
## Table of contents
|
|
6
|
+
|
|
7
|
+
- [DataConv Client SDK for TypeScript](#dataconv-client-sdk-for-typescript)
|
|
8
|
+
- [Table of contents](#table-of-contents)
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Configuration](#configuration)
|
|
12
|
+
- [Discover form fields](#discover-form-fields)
|
|
13
|
+
- [Field selection tracking (UI dedup)](#field-selection-tracking-ui-dedup)
|
|
14
|
+
- [React example: multi-dropdown dedup](#react-example-multi-dropdown-dedup)
|
|
15
|
+
- [End-to-end flow](#end-to-end-flow)
|
|
16
|
+
- [Multipart / local file upload](#multipart--local-file-upload)
|
|
17
|
+
- [Backend initialization](#backend-initialization)
|
|
18
|
+
- [CLI](#cli)
|
|
19
|
+
- [Recommended local setup (no IP/DID flags in commands)](#recommended-local-setup-no-ipdid-flags-in-commands)
|
|
20
|
+
- [Command helper and endpoint-resolution conventions](#command-helper-and-endpoint-resolution-conventions)
|
|
21
|
+
- [One-shot evidence script](#one-shot-evidence-script)
|
|
22
|
+
- [Notes](#notes)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Discover frontend field descriptors from `/.well-known/api-config.json`
|
|
29
|
+
- Track which fields have already been selected across UI dropdowns
|
|
30
|
+
- Tenant/software configuration creation and polling
|
|
8
31
|
- Excel/XLSX upload via DIDComm attachment or `multipart/form-data`
|
|
9
32
|
- `_upload-response` polling
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
33
|
+
- Promotion through `Composition/_patch` and `Patient/_batch`
|
|
34
|
+
- Tenant-scoped dataset search under `/publisher/.../dataset/{resourceType}/_search`
|
|
35
|
+
- Helpers to read the converted `Bundle` and keep the last received response
|
|
36
|
+
|
|
37
|
+
---
|
|
13
38
|
|
|
14
39
|
## Installation
|
|
15
40
|
|
|
@@ -23,11 +48,161 @@ npm install dataconv-client-sdk-ts
|
|
|
23
48
|
DATACONV_BASE_URL=http://localhost:8080
|
|
24
49
|
```
|
|
25
50
|
|
|
26
|
-
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Discover form fields
|
|
54
|
+
|
|
55
|
+
The client reads the API discovery document published by the server and returns frontend-ready field descriptors.
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { DataConvClient } from 'dataconv-client-sdk-ts';
|
|
59
|
+
|
|
60
|
+
const client = new DataConvClient({
|
|
61
|
+
issuerDid: 'did:web:clinic.example:employee:loader',
|
|
62
|
+
tenantId: 'VATES-B00000000',
|
|
63
|
+
jurisdiction: 'ES',
|
|
64
|
+
crypto: globalThis.crypto
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const apiConfig = await client.getWellKnownApiConfig();
|
|
68
|
+
|
|
69
|
+
console.log(apiConfig.language); // "es"
|
|
70
|
+
console.log(apiConfig.fields);
|
|
71
|
+
// [
|
|
72
|
+
// { code: 'section', display: 'Departamento o sección: ...' },
|
|
73
|
+
// { code: 'coverage_insurer', display: 'Identificador o nombre de la aseguradora' }
|
|
74
|
+
// ]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The returned object includes:
|
|
78
|
+
|
|
79
|
+
| Property | Type | Description |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `language` | `string` | Language code of the API config (`"es"`, ...) |
|
|
82
|
+
| `fields` | `{ code, display }[]` | Ready-to-use options for dropdowns |
|
|
83
|
+
| `supportedFields` | `Record<string, string>` | Raw `code → display` map |
|
|
84
|
+
| `endpoints` | `Record<string, string>` | Endpoint paths for `create`, `upload`, etc. |
|
|
85
|
+
|
|
86
|
+
The recommended frontend flow is:
|
|
87
|
+
|
|
88
|
+
1. Read `fields` from `getWellKnownApiConfig()`.
|
|
89
|
+
2. Let the user map spreadsheet columns to those field codes.
|
|
90
|
+
3. Submit `mappingConfig.fieldMap` using those same codes.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Field selection tracking (UI dedup)
|
|
95
|
+
|
|
96
|
+
The SDK keeps a per-session set of already-selected field codes so the UI can prevent a user from assigning the same field to two different dropdowns.
|
|
27
97
|
|
|
28
|
-
|
|
98
|
+
| Method | Returns | Description |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `selectField(code, mappedTo?)` | `boolean` | `true` if added, `false` if already selected |
|
|
101
|
+
| `unselectField(code)` | `boolean` | `true` if removed, `false` if not present |
|
|
102
|
+
| `isFieldSelected(code)` | `boolean` | Whether the code is currently selected |
|
|
103
|
+
| `getSelectedFieldCodes()` | `string[]` | All currently selected codes |
|
|
104
|
+
| `getSelectedFieldMappings()` | `Record<string, string>` | Map of selected field code → mapped source column |
|
|
105
|
+
| `getSelectedMappingForField(code)` | `string \| undefined` | Source column currently associated to the selected code |
|
|
106
|
+
| `clearSelectedFields()` | `void` | Reset selection state |
|
|
29
107
|
|
|
30
|
-
|
|
108
|
+
```ts
|
|
109
|
+
client.selectField('section'); // true
|
|
110
|
+
client.selectField('section'); // false → already selected
|
|
111
|
+
client.selectField('concept', 'CONCEPTO');
|
|
112
|
+
client.getSelectedMappingForField('concept'); // 'CONCEPTO'
|
|
113
|
+
client.isFieldSelected('section'); // true
|
|
114
|
+
client.unselectField('section'); // true
|
|
115
|
+
client.getSelectedFieldCodes(); // []
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### React example: multi-dropdown dedup
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
124
|
+
import { DataConvClient } from 'dataconv-client-sdk-ts';
|
|
125
|
+
|
|
126
|
+
const client = new DataConvClient({
|
|
127
|
+
issuerDid: 'did:web:clinic.example:employee:loader',
|
|
128
|
+
tenantId: 'VATES-B00000000',
|
|
129
|
+
jurisdiction: 'ES',
|
|
130
|
+
crypto: globalThis.crypto
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
type FieldOption = { code: string; display: string };
|
|
134
|
+
|
|
135
|
+
export function FieldMappingForm() {
|
|
136
|
+
const [options, setOptions] = useState<FieldOption[]>([]);
|
|
137
|
+
const [mapping, setMapping] = useState<Record<string, string>>({
|
|
138
|
+
colA: '',
|
|
139
|
+
colB: '',
|
|
140
|
+
colC: ''
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
let mounted = true;
|
|
145
|
+
client.getSupportedFields().then((fields) => {
|
|
146
|
+
if (mounted) setOptions(fields);
|
|
147
|
+
});
|
|
148
|
+
return () => {
|
|
149
|
+
mounted = false;
|
|
150
|
+
client.clearSelectedFields();
|
|
151
|
+
};
|
|
152
|
+
}, []);
|
|
153
|
+
|
|
154
|
+
const selectedSet = useMemo(() => new Set(client.getSelectedFieldCodes()), [mapping]);
|
|
155
|
+
|
|
156
|
+
const onChangeField = (columnKey: string, newCode: string) => {
|
|
157
|
+
const previousCode = mapping[columnKey];
|
|
158
|
+
if (previousCode) {
|
|
159
|
+
client.unselectField(previousCode);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (newCode && !client.selectField(newCode, columnKey)) {
|
|
163
|
+
const mappedTo = client.getSelectedMappingForField(newCode);
|
|
164
|
+
if (previousCode) {
|
|
165
|
+
client.selectField(previousCode);
|
|
166
|
+
}
|
|
167
|
+
alert(`El campo ${newCode} ya ha sido seleccionado${mappedTo ? ` en ${mappedTo}` : ''}.`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
setMapping((current) => ({ ...current, [columnKey]: newCode }));
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<>
|
|
176
|
+
{Object.keys(mapping).map((columnKey) => (
|
|
177
|
+
<select
|
|
178
|
+
key={columnKey}
|
|
179
|
+
value={mapping[columnKey]}
|
|
180
|
+
onChange={(event) => onChangeField(columnKey, event.target.value)}
|
|
181
|
+
>
|
|
182
|
+
<option value="">Selecciona un campo</option>
|
|
183
|
+
{options.map((field) => {
|
|
184
|
+
const selectedInAnotherDropdown =
|
|
185
|
+
selectedSet.has(field.code) && mapping[columnKey] !== field.code;
|
|
186
|
+
return (
|
|
187
|
+
<option key={field.code} value={field.code} disabled={selectedInAnotherDropdown}>
|
|
188
|
+
{field.display}
|
|
189
|
+
</option>
|
|
190
|
+
);
|
|
191
|
+
})}
|
|
192
|
+
</select>
|
|
193
|
+
))}
|
|
194
|
+
</>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## End-to-end flow
|
|
202
|
+
|
|
203
|
+
Minimum steps to go from field discovery to promoted resources:
|
|
204
|
+
|
|
205
|
+
1. Discover fields and initialize the client.
|
|
31
206
|
2. Create the tenant/software configuration.
|
|
32
207
|
3. Wait for `_create-response`.
|
|
33
208
|
4. Upload the Excel file.
|
|
@@ -52,8 +227,6 @@ client.setVpToken('<vp_token>');
|
|
|
52
227
|
|
|
53
228
|
// 1. Discover frontend field descriptors from the API.
|
|
54
229
|
const apiConfig = await client.getWellKnownApiConfig();
|
|
55
|
-
|
|
56
|
-
// Example UI options:
|
|
57
230
|
const fieldOptions = apiConfig.fields;
|
|
58
231
|
// [
|
|
59
232
|
// { code: 'section', display: 'Departamento o sección: ...' },
|
|
@@ -108,8 +281,11 @@ const conversionResponse = await client.pollUploadResponse({
|
|
|
108
281
|
});
|
|
109
282
|
|
|
110
283
|
const convertedBundle = client.getConvertedBundle(conversionResponse);
|
|
284
|
+
const mainDiagnostic = client.getMainDiagnosticInfoByResponse(conversionResponse);
|
|
111
285
|
const storedConfigs = client.getSuccessfulTenantConfigs(configResponse);
|
|
112
286
|
|
|
287
|
+
console.log(mainDiagnostic);
|
|
288
|
+
|
|
113
289
|
// 6. Confirm promotion of the reviewed thread.
|
|
114
290
|
const patchResponse = await client.patchConversion({
|
|
115
291
|
thid: uploadResult.thid,
|
|
@@ -132,6 +308,13 @@ const searchResponse = await client.searchResources({
|
|
|
132
308
|
});
|
|
133
309
|
```
|
|
134
310
|
|
|
311
|
+
For DIDComm polling responses, the SDK also exposes:
|
|
312
|
+
|
|
313
|
+
- `getMainDiagnosticInfoByResponse(response)` — reads `OperationOutcome.issue[0].diagnostics` from a response.
|
|
314
|
+
- `getMainDiagnosticInfo()` — reads it from the last stored config/conversion response.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
135
318
|
## Multipart / local file upload
|
|
136
319
|
|
|
137
320
|
```ts
|
|
@@ -142,60 +325,28 @@ await client.uploadSpreadsheetMultipart({
|
|
|
142
325
|
});
|
|
143
326
|
```
|
|
144
327
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
The client can read the API discovery document published by the server and return frontend-ready field descriptors.
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
const apiConfig = await client.getWellKnownApiConfig();
|
|
151
|
-
|
|
152
|
-
console.log(apiConfig.language); // "es"
|
|
153
|
-
console.log(apiConfig.fields);
|
|
154
|
-
// [
|
|
155
|
-
// { code: 'section', display: 'Departamento o sección: ...' },
|
|
156
|
-
// { code: 'coverage_insurer', display: 'Identificador o nombre de la aseguradora' }
|
|
157
|
-
// ]
|
|
158
|
-
|
|
159
|
-
const supportedFields = await client.getSupportedFields();
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The returned object includes:
|
|
163
|
-
|
|
164
|
-
- `language`
|
|
165
|
-
- `supportedFields` as raw `code -> display`
|
|
166
|
-
- `fields` as `{ code, display }[]`
|
|
167
|
-
- `endpoints` for `create`, `createResponse`, `upload`, and `uploadResponse`
|
|
168
|
-
|
|
169
|
-
The recommended frontend flow is:
|
|
170
|
-
|
|
171
|
-
1. Read `fields` from `/.well-known/api-config.json`.
|
|
172
|
-
2. Let the user map spreadsheet columns to those field codes.
|
|
173
|
-
3. Submit `mappingConfig.fieldMap` using those same codes.
|
|
328
|
+
---
|
|
174
329
|
|
|
175
330
|
## Backend initialization
|
|
176
331
|
|
|
177
|
-
If the backend instantiates the SDK after `Organization/_activate`, it can inject `axios` or `fetch
|
|
332
|
+
If the backend instantiates the SDK after `Organization/_activate`, it can inject `axios` or `fetch`:
|
|
178
333
|
|
|
179
334
|
```ts
|
|
180
335
|
import axios from 'axios';
|
|
181
336
|
import { DataConvClient } from 'dataconv-client-sdk-ts';
|
|
182
337
|
|
|
183
|
-
const httpClient = axios.create({
|
|
184
|
-
baseURL: process.env.DATACONV_BASE_URL
|
|
185
|
-
});
|
|
186
|
-
|
|
187
338
|
const client = new DataConvClient({
|
|
188
339
|
issuerDid: activatedOrganizationDid,
|
|
189
340
|
tenantId: tenantAlternateName,
|
|
190
341
|
jurisdiction: 'ES',
|
|
191
|
-
httpClient,
|
|
342
|
+
httpClient: axios.create({ baseURL: process.env.DATACONV_BASE_URL }),
|
|
192
343
|
crypto: globalThis.crypto
|
|
193
344
|
});
|
|
194
345
|
|
|
195
346
|
client.setVpToken(vpTokenFromActivation);
|
|
196
347
|
```
|
|
197
348
|
|
|
198
|
-
|
|
349
|
+
Also works with `fetch`:
|
|
199
350
|
|
|
200
351
|
```ts
|
|
201
352
|
const client = new DataConvClient({
|
|
@@ -207,17 +358,167 @@ const client = new DataConvClient({
|
|
|
207
358
|
});
|
|
208
359
|
```
|
|
209
360
|
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## CLI
|
|
364
|
+
|
|
365
|
+
The package exposes a CLI that can first create mapping config, then upload a file, wait for `_upload-response`, save the full DIDComm response to JSON, and print the main outcome summary.
|
|
366
|
+
|
|
367
|
+
### Local setup
|
|
368
|
+
|
|
369
|
+
Copy `.env.example` to `.env.local`, fill in your values, and source it before running commands:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
cp .env.example .env.local
|
|
373
|
+
# edit .env.local: tenantId, issuerDid, base URL, DATACONV_ID_TOKEN
|
|
374
|
+
source .env.local
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
The helper script `scripts/evidencia-publicacion.sh` loads `.env.local` automatically (falls back to `.env.example`).
|
|
378
|
+
|
|
379
|
+
For advanced DID document-based endpoint resolution and full command reference, see [docs/cli-reference.md](docs/cli-reference.md).
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# 1) login against your IdP (store OIDC id_token locally)
|
|
383
|
+
dataconv login --id-token "$DATACONV_ID_TOKEN"
|
|
384
|
+
|
|
385
|
+
# 2) exchange Bearer access token
|
|
386
|
+
dataconv exchange --scope "excel/_upload Subject/_search ChargeItem/_search DocumentReference/_search"
|
|
387
|
+
|
|
388
|
+
# 3) optional tenant-admin step: create a constrained API key
|
|
389
|
+
dataconv api-key-create --email ops@example.com --target "publisher/cds-es/v1/animal-care/vates-a00000001/dataset/*/*/_upload"
|
|
390
|
+
|
|
391
|
+
# 4) upload + automatic polling
|
|
392
|
+
dataconv upload ./examples/example-api-config.xlsx \
|
|
393
|
+
--output-json ./artifacts/upload-response.json
|
|
394
|
+
|
|
395
|
+
# 5) optional: patch/batch after review, then search with Bearer token
|
|
396
|
+
dataconv search --resource-type DocumentReference --params '{"_count": 5}'
|
|
397
|
+
|
|
398
|
+
# optional alternative to patch
|
|
399
|
+
dataconv batch --thid "<thid-obtenido-de-upload>"
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Output includes:
|
|
403
|
+
|
|
404
|
+
- exact public upload URL used
|
|
405
|
+
- Excel path and size in KB
|
|
406
|
+
- `Location` header from `_upload`
|
|
407
|
+
- `thid`
|
|
408
|
+
- exact polling URL used
|
|
409
|
+
- output JSON file path
|
|
410
|
+
- main `OperationOutcome.issue[0].description` when available (fallback: `diagnostics`)
|
|
411
|
+
|
|
412
|
+
When `--mapping-json` is provided to `upload`, CLI creates tenant mapping config first and polls `config/_create-response` before submitting the spreadsheet.
|
|
413
|
+
|
|
414
|
+
The CLI prints evidence-style process logs, for example:
|
|
415
|
+
|
|
416
|
+
- authentication/exchange against configured dataspace name
|
|
417
|
+
- upload accepted with `thid`
|
|
418
|
+
- automatic `_upload-response` polling
|
|
419
|
+
- final summary and JSON artifact path
|
|
420
|
+
|
|
421
|
+
### Command helper and endpoint-resolution conventions
|
|
422
|
+
|
|
423
|
+
Use per-command help to see expected conventions:
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
dataconv help exchange
|
|
427
|
+
dataconv help upload
|
|
428
|
+
dataconv search --help
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Service IDs used as CLI resolution metadata:
|
|
432
|
+
|
|
433
|
+
- `exchange`: `#identity:openid:token:_exchange`
|
|
434
|
+
- `upload` (update): `#dataset:{softwareId}:{resourceType}:_upload`
|
|
435
|
+
- `patch` (publish): `#dataset:{softwareId}:{resourceType}:_patch`
|
|
436
|
+
- `batch` (publish): `#dataset:{softwareId}:{resourceType}:_batch`
|
|
437
|
+
- `search`: `#dataset:api:{resourceType}:_search`
|
|
438
|
+
|
|
439
|
+
Fallback env vars for localhost testing:
|
|
440
|
+
|
|
441
|
+
- `PUBLISHER_OPENID_EXCHANGE`
|
|
442
|
+
- `PUBLISHER_DATASET_UPDATE`
|
|
443
|
+
- `PUBLISHER_DATASET_PATCH`
|
|
444
|
+
- `PUBLISHER_DATASET_BATCH`
|
|
445
|
+
- `PUBLISHER_DATASET_SEARCH`
|
|
446
|
+
|
|
447
|
+
Important contract note:
|
|
448
|
+
|
|
449
|
+
- `--organization-did` and `--service-id` are stored as CLI-side endpoint-resolution context.
|
|
450
|
+
- The `/exchange` request body remains OpenAPI-compatible (no extra payload fields derived from service-id/fallback metadata).
|
|
451
|
+
|
|
452
|
+
### One-shot evidence script
|
|
453
|
+
|
|
454
|
+
Use the included helper to run login/exchange/upload/search in one shot:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
chmod +x ./scripts/publish-dataset.sh
|
|
458
|
+
./scripts/evidencia-publicacion.sh
|
|
459
|
+
|
|
460
|
+
# opcional: forzar mapping JSON externo + promoción por batch
|
|
461
|
+
DATACONV_PUBLICACION_MAPPING_JSON=./examples/mappings/qvet-v1.json \
|
|
462
|
+
DATACONV_PUBLICACION_HEADER_ROW_INDEX=1 \
|
|
463
|
+
DATACONV_PROMOTION_MODE=batch \
|
|
464
|
+
./scripts/evidencia-publicacion.sh
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Generated files:
|
|
468
|
+
|
|
469
|
+
- `./artifacts/datasets/upload-response.json`
|
|
470
|
+
- `./artifacts/datasets/search-subject.json`
|
|
471
|
+
- `./artifacts/datasets/search-documentreference.json`
|
|
472
|
+
- `./artifacts/datasets/dcat-files.json`
|
|
473
|
+
|
|
474
|
+
Notes on scope model and flow:
|
|
475
|
+
|
|
476
|
+
- You can request endpoint-action scopes (recommended for evaluator logs), e.g. `excel/_upload` or `DocumentReference/_search`.
|
|
477
|
+
- Backend accepts these action scopes as equivalent to coarse scopes (`dataconv.upload` / `dataconv.read`).
|
|
478
|
+
- `tenantId`, `jurisdiction`, `sector`, and `softwareId` are taken from env/profile defaults (recommended tenant format: `VATES-<NIF>`).
|
|
479
|
+
- API keys do **not** mint `id_token`s. The `id_token` always comes from the external IdP/login step.
|
|
480
|
+
- API keys are used at `/exchange` time to constrain or delegate scopes. The resulting Bearer `access_token` is what you use for config, upload, patch/batch, and search.
|
|
481
|
+
- For explicit exceptional non-confidential mode, send `api_key_profile=api-key-exception.v1` in `/exchange` payload (server must allow it).
|
|
482
|
+
- Recommended API key authorization model is atomic:
|
|
483
|
+
- one rule entry (`data[].resource`) = one consent-like authorization rule = one ODRL policy object.
|
|
484
|
+
- include `scope` (mandatory), and preferably `target` + `instrument` (ODRL).
|
|
485
|
+
|
|
486
|
+
When `--service-did` is used, resolve it locally with either `--resolved-base-url` or the `DATACONV_SERVICE_DID_MAP` env variable:
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
export DATACONV_SERVICE_DID_MAP='{"did:web:dataconv-api.example.org":"http://127.0.0.1:8080"}'
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
> **DEMO_MODE** — If the backend runs with `DEMO_MODE=true`, generate a test `id_token` without a real IdP:
|
|
493
|
+
>
|
|
494
|
+
> ```bash
|
|
495
|
+
> # genera un id_token demo (alg:none, solo requiere campo email en el payload)
|
|
496
|
+
> export DATACONV_ID_TOKEN=$(node -e '
|
|
497
|
+
> const h = Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url");
|
|
498
|
+
> const p = Buffer.from(JSON.stringify({email:"admin@example.com"})).toString("base64url");
|
|
499
|
+
> console.log(`${h}.${p}.`);
|
|
500
|
+
> ')
|
|
501
|
+
> # eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIn0.
|
|
502
|
+
> ```
|
|
503
|
+
>
|
|
504
|
+
> Use the token with `--authorization-bearer "$DATACONV_ID_TOKEN"`. No signature verification is performed in demo mode; only the `email` claim is required.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
210
508
|
## Notes
|
|
211
509
|
|
|
212
|
-
-
|
|
213
|
-
- `sector` is
|
|
510
|
+
- `tenantId` is the operational tenant identifier, typically the organization's VAT/taxId.
|
|
511
|
+
- `sector` is part of the public route for publisher config, dataset publication, and dataset search.
|
|
214
512
|
- `patchConversion()` defaults to `Composition/_patch`.
|
|
215
513
|
- `batchPromotion()` defaults to `Patient/_batch`.
|
|
216
|
-
- `searchResources()` resolves to `/
|
|
217
|
-
-
|
|
218
|
-
-
|
|
219
|
-
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
- `
|
|
223
|
-
|
|
514
|
+
- `searchResources()` resolves to `/publisher/cds-{jurisdiction}/v1/{sector}/{tenantId}/dataset/{resourceType}/_search`.
|
|
515
|
+
- Search parameter names are normalized to lowercase (`userSelected` → `userselected`).
|
|
516
|
+
- Search comparators are prefixed in the value: `ge2026-01-01`, `gt...`, `le...`, `lt...`.
|
|
517
|
+
- The backend may require `vp_token` and/or `id_token` depending on `PRECONV_AUTH_MODE`.
|
|
518
|
+
- CSV upload is modeled in the SDK but the current backend only accepts Excel/XLSX.
|
|
519
|
+
- `gdc-common-utils-ts` is an npm dependency; this SDK adds concrete pre-conversion types on top of those DIDComm helpers.
|
|
520
|
+
- ICA VCs and `controller.publicKeyJwk` belong to the `_activate` onboarding flow. `DataConvClient` is used afterwards, once the tenant is already activated.
|
|
521
|
+
|
|
522
|
+
## Roadmap and Briefing
|
|
523
|
+
- `BRIEFING_DATASPACE_EN.md`
|
|
524
|
+
- `TODO_ROADMAP.md`
|
package/dist/DataConvClient.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataConvBatchOptions, ConversionResultEntry, ConvertedBundleResource, CreateTenantConfigOptions, DataConvClientConfig, DataConvConversionPollOptions, DataConvCreateResult, DataConvDidCommResponse, DataConvMultipartUploadOptions, DataConvOperationOutcome, DataConvPatchOptions, DataConvPatchResponse, DataConvSearchBundle, DataConvSearchOptions, DataConvTenantConfigPollOptions, DataConvUploadDidCommOptions, DataConvUploadResult, DataConvSupportedField, DataConvWellKnownApiConfig, TenantAdapterConfigEntry, TenantAdapterConfigResource } from './types.js';
|
|
1
|
+
import type { DataConvBatchOptions, ConversionResultEntry, ConvertedBundleResource, CreateTenantConfigOptions, DataConvClientConfig, DataConvConversionPollOptions, DataConvCreateResult, DataConvDidCommResponse, DataConvApiKeyCreateActionsOptions, DataConvApiKeyCreateActionsResult, DataConvApiKeyAuthorizationRule, DataConvApiKeyLifecycleOptions, DataConvApiKeyLifecycleResult, DataConvExchangeTokenOptions, DataConvExchangeTokenResult, DataConvMultipartUploadOptions, DataConvOperationOutcome, DataConvOrganizationTenantActivationOptions, DataConvOrganizationTenantActivationResult, DataConvPatchOptions, DataConvPatchResponse, DataConvSearchBundle, DataConvSearchOptions, DataConvTenantConfigPollOptions, DataConvUploadDidCommOptions, DataConvUploadResult, DataConvSupportedField, DataConvWellKnownApiConfig, TenantAdapterConfigEntry, TenantAdapterConfigResource } from './types.js';
|
|
2
2
|
export declare class DataConvClient {
|
|
3
3
|
private readonly config;
|
|
4
4
|
private readonly httpClient?;
|
|
@@ -12,17 +12,39 @@ export declare class DataConvClient {
|
|
|
12
12
|
private vpToken?;
|
|
13
13
|
private lastTenantConfigResponse?;
|
|
14
14
|
private lastConversionResponse?;
|
|
15
|
+
private selectedFieldCodes;
|
|
16
|
+
private selectedFieldMappings;
|
|
15
17
|
constructor(config: DataConvClientConfig);
|
|
16
18
|
setIdToken(idToken: string): void;
|
|
17
19
|
setVpToken(vpToken: string): void;
|
|
20
|
+
activateOrganizationTenant(options: DataConvOrganizationTenantActivationOptions): Promise<DataConvOrganizationTenantActivationResult>;
|
|
18
21
|
getLastTenantConfigResponse(): DataConvDidCommResponse<TenantAdapterConfigResource> | undefined;
|
|
19
22
|
getLastConversionResponse(): DataConvDidCommResponse<ConvertedBundleResource> | undefined;
|
|
20
23
|
clearStoredResponses(): void;
|
|
24
|
+
exchangeToken(options: DataConvExchangeTokenOptions): Promise<DataConvExchangeTokenResult>;
|
|
25
|
+
createTenantApiKeyActions(options: DataConvApiKeyCreateActionsOptions): Promise<DataConvApiKeyCreateActionsResult>;
|
|
26
|
+
createTenantApiKeyRules(options: Omit<DataConvApiKeyCreateActionsOptions, 'actions'> & {
|
|
27
|
+
rules: DataConvApiKeyAuthorizationRule[];
|
|
28
|
+
}): Promise<DataConvApiKeyCreateActionsResult>;
|
|
29
|
+
disableTenantApiKeyActions(options: DataConvApiKeyLifecycleOptions): Promise<DataConvApiKeyLifecycleResult>;
|
|
30
|
+
removeTenantApiKeyActions(options: DataConvApiKeyLifecycleOptions): Promise<DataConvApiKeyLifecycleResult>;
|
|
31
|
+
private updateTenantApiKeyActions;
|
|
21
32
|
getTenantConfigEntries(response?: DataConvDidCommResponse<TenantAdapterConfigResource> | undefined): Array<TenantAdapterConfigEntry<TenantAdapterConfigResource>>;
|
|
22
33
|
getSuccessfulTenantConfigs(response?: DataConvDidCommResponse<TenantAdapterConfigResource> | undefined): TenantAdapterConfigResource[];
|
|
23
34
|
getConversionEntry(response?: DataConvDidCommResponse<ConvertedBundleResource> | undefined): ConversionResultEntry | undefined;
|
|
24
35
|
getConvertedBundle(response?: DataConvDidCommResponse<ConvertedBundleResource> | undefined): ConvertedBundleResource | undefined;
|
|
25
36
|
getResponseIssues<TResource>(response: DataConvDidCommResponse<TResource> | undefined): DataConvOperationOutcome | undefined;
|
|
37
|
+
getMainDiagnosticInfoByResponse<TResource>(response: DataConvDidCommResponse<TResource> | undefined): string | undefined;
|
|
38
|
+
getMainIssueDescriptionByResponse<TResource>(response: DataConvDidCommResponse<TResource> | undefined): string | undefined;
|
|
39
|
+
getSelectedFieldCodes(): string[];
|
|
40
|
+
getSelectedFieldMappings(): Record<string, string>;
|
|
41
|
+
getSelectedMappingForField(code: string): string | undefined;
|
|
42
|
+
isFieldSelected(code: string): boolean;
|
|
43
|
+
selectField(code: string, mappedTo?: string): boolean;
|
|
44
|
+
unselectField(code: string): boolean;
|
|
45
|
+
clearSelectedFields(): void;
|
|
46
|
+
getMainDiagnosticInfo(): string | undefined;
|
|
47
|
+
getMainIssueDescription(): string | undefined;
|
|
26
48
|
getWellKnownApiConfig(): Promise<DataConvWellKnownApiConfig>;
|
|
27
49
|
getSupportedFields(): Promise<DataConvSupportedField[]>;
|
|
28
50
|
createTenantConfig(options: CreateTenantConfigOptions): Promise<DataConvCreateResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataConvClient.d.ts","sourceRoot":"","sources":["../src/DataConvClient.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,oBAAoB,EAGpB,uBAAuB,EACvB,8BAA8B,EAC9B,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAE1B,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAEpB,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"DataConvClient.d.ts","sourceRoot":"","sources":["../src/DataConvClient.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,oBAAoB,EAGpB,uBAAuB,EACvB,kCAAkC,EAClC,iCAAiC,EACjC,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,8BAA8B,EAC9B,wBAAwB,EACxB,2CAA2C,EAC3C,0CAA0C,EAC1C,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAE1B,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAEpB,qBAAa,cAAc;IAgBb,OAAO,CAAC,QAAQ,CAAC,MAAM;IAfnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAE3C,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,wBAAwB,CAAC,CAAuD;IACxF,OAAO,CAAC,sBAAsB,CAAC,CAAmD;IAClF,OAAO,CAAC,kBAAkB,CAA0B;IACpD,OAAO,CAAC,qBAAqB,CAAkC;gBAElC,MAAM,EAAE,oBAAoB;IAYzD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,0BAA0B,CAC9B,OAAO,EAAE,2CAA2C,GACnD,OAAO,CAAC,0CAA0C,CAAC;IAmBtD,2BAA2B,IAAI,uBAAuB,CAAC,2BAA2B,CAAC,GAAG,SAAS;IAI/F,yBAAyB,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,GAAG,SAAS;IAIzF,oBAAoB,IAAI,IAAI;IAKtB,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAkC1F,yBAAyB,CAAC,OAAO,EAAE,kCAAkC,GAAG,OAAO,CAAC,iCAAiC,CAAC;IAIlH,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,kCAAkC,EAAE,SAAS,CAAC,GAAG;QAC3F,KAAK,EAAE,+BAA+B,EAAE,CAAC;KAC1C,GAAG,OAAO,CAAC,iCAAiC,CAAC;IAexC,0BAA0B,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAI3G,yBAAyB,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,6BAA6B,CAAC;YAIlG,yBAAyB;IA8BvC,sBAAsB,CACpB,QAAQ,GAAE,uBAAuB,CAAC,2BAA2B,CAAC,GAAG,SAAyC,GACzG,KAAK,CAAC,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;IAK/D,0BAA0B,CACxB,QAAQ,GAAE,uBAAuB,CAAC,2BAA2B,CAAC,GAAG,SAAyC,GACzG,2BAA2B,EAAE;IAOhC,kBAAkB,CAChB,QAAQ,GAAE,uBAAuB,CAAC,uBAAuB,CAAC,GAAG,SAAuC,GACnG,qBAAqB,GAAG,SAAS;IAQpC,kBAAkB,CAChB,QAAQ,GAAE,uBAAuB,CAAC,uBAAuB,CAAC,GAAG,SAAuC,GACnG,uBAAuB,GAAG,SAAS;IAItC,iBAAiB,CAAC,SAAS,EACzB,QAAQ,EAAE,uBAAuB,CAAC,SAAS,CAAC,GAAG,SAAS,GACvD,wBAAwB,GAAG,SAAS;IAIvC,+BAA+B,CAAC,SAAS,EACvC,QAAQ,EAAE,uBAAuB,CAAC,SAAS,CAAC,GAAG,SAAS,GACvD,MAAM,GAAG,SAAS;IA8BrB,iCAAiC,CAAC,SAAS,EACzC,QAAQ,EAAE,uBAAuB,CAAC,SAAS,CAAC,GAAG,SAAS,GACvD,MAAM,GAAG,SAAS;IAyBrB,qBAAqB,IAAI,MAAM,EAAE;IAIjC,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIlD,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ5D,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAItC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAgBrD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMpC,mBAAmB,IAAI,IAAI;IAK3B,qBAAqB,IAAI,MAAM,GAAG,SAAS;IAI3C,uBAAuB,IAAI,MAAM,GAAG,SAAS;IAIvC,qBAAqB,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAiD5D,kBAAkB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAKvD,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIrF,YAAY,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAqC/E,wBAAwB,CAC5B,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;IAI1D,UAAU,CACd,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;IA6B1D,yBAAyB,CAC7B,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;IAgB1D,iBAAiB,CACrB,MAAM,EAAE,MAAM,GAAG,UAAU,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,oBAAoB,CAAC;IAO1B,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,oBAAoB,CAAC;IAI1B,gBAAgB,CACpB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,oBAAoB,CAAC;YAIlB,aAAa;IA0CrB,0BAA0B,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIlG,cAAc,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA4CtF,sBAAsB,CAC1B,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAItD,kBAAkB,CACtB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAiCtD,wBAAwB,CAC5B,MAAM,EAAE,MAAM,GAAG,UAAU,EAC3B,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAiBtD,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAiC9E,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAiC7E,eAAe,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAiC7B,iBAAiB;YAqBjB,OAAO;IAiDrB,OAAO,CAAC,WAAW;CASpB"}
|