@startinblox/components-ds4go 3.0.2 → 3.1.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.
- package/.storybook/preview.ts +1 -0
- package/biome.json +1 -1
- package/dist/custom-getter-ZPFnoSjt-BCNOlbJZ-B4tuxA42.js +338 -0
- package/dist/en-BySYJZMr-CWZl5AwU-CWZl5AwU.js +14 -0
- package/dist/fr-BZZDTsmw-CNDWt66j-CNDWt66j.js +14 -0
- package/dist/index-BSwVRtNS.js +104980 -0
- package/dist/index.js +1 -3032
- package/dist/quill.snow-C_A_QkE8-D-uedtvC-D-uedtvC.js +13 -0
- package/dist/slimselect-NFLzJMfV-DZ7j6Vsj-DZ7j6Vsj.js +5 -0
- package/package.json +9 -8
- package/src/components/cards/ds4go-card-catalog.ts +132 -0
- package/src/components/catalog/ds4go-catalog-filter-holder.ts +459 -0
- package/src/components/catalog/ds4go-customer-holder.ts +162 -0
- package/src/components/catalog/ds4go-fact-bundle-holder.ts +7 -7
- package/src/components/modal/ds4go-customer-modal.ts +134 -0
- package/src/components/modal/ds4go-fact-bundle-modal.ts +2 -2
- package/src/components/solid-customer-list.ts +195 -0
- package/src/components/solid-dsif-explorer-poc.ts +8 -8
- package/src/components/solid-dsp-connector.ts +12 -4
- package/src/components/solid-fact-bundle-creation.ts +266 -169
- package/src/components/solid-fact-bundle.ts +9 -4
- package/src/helpers/components/orbitComponent.ts +12 -13
- package/src/helpers/i18n/configureLocalization.ts +12 -5
- package/src/helpers/index.ts +0 -2
- package/src/styles/cards/ds4go-card-catalog.scss +149 -0
- package/src/styles/fact-bundle-creation.scss +6 -2
- package/src/styles/modal/ds4go-customer-modal.scss +91 -0
- package/src/styles/modal/ds4go-fact-bundle-modal.scss +1 -1
- package/vite.config.ts +7 -7
- package/src/components/solid-boilerplate.ts +0 -76
- package/src/helpers/components/ResourceMapper.ts +0 -469
- package/src/helpers/components/orbitDspComponent.ts +0 -250
- package/src/helpers/mappings/dsp-mapping-config.ts +0 -545
|
@@ -1,545 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DSP (Dataspace Protocol) Mapping Configuration
|
|
3
|
-
*
|
|
4
|
-
* Defines how DSP catalog datasets are mapped to TEMS-compatible resources.
|
|
5
|
-
*
|
|
6
|
-
* Source structure (simplified):
|
|
7
|
-
* {
|
|
8
|
-
* '@id': 'urn:uuid:dataset-id',
|
|
9
|
-
* 'dcat:distribution': [{
|
|
10
|
-
* 'dct:title': 'Dataset Name',
|
|
11
|
-
* 'dct:description': 'Description',
|
|
12
|
-
* 'dcat:keyword': ['keyword1', 'keyword2'],
|
|
13
|
-
* 'dcat:endpointURL': 'https://service.com/endpoint',
|
|
14
|
-
* 'foaf:thumbnail': { 'rdf:resource': 'https://image.com/logo.png' },
|
|
15
|
-
* 'dcterms:creator': {
|
|
16
|
-
* 'foaf:name': 'Creator Name',
|
|
17
|
-
* 'foaf:thumbnail': { 'rdf:resource': 'https://creator.com/logo.png' }
|
|
18
|
-
* }
|
|
19
|
-
* }],
|
|
20
|
-
* 'odrl:hasPolicy': { ... }
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* Note: Properties can be at dataset level OR in dcat:distribution[0]
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import {
|
|
27
|
-
type MappingContext,
|
|
28
|
-
processPolicyTransform,
|
|
29
|
-
type ResourceMapperConfig,
|
|
30
|
-
stripUrnPrefix,
|
|
31
|
-
} from "@helpers/components/ResourceMapper";
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get properties from dataset, checking distribution first, then dataset level, then EDC properties
|
|
35
|
-
*/
|
|
36
|
-
function getProperties(source: any): any {
|
|
37
|
-
return source["dcat:distribution"]?.[0] || source["properties"] || source;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get EDC-style endpoint URL from properties
|
|
42
|
-
* Priority: source-level dcat:endpointUrl (actual data endpoint) first
|
|
43
|
-
*/
|
|
44
|
-
function getEndpointUrl(source: any): string {
|
|
45
|
-
const props = getProperties(source);
|
|
46
|
-
// Check source-level first (EDC catalog returns actual endpoint at top level)
|
|
47
|
-
return (
|
|
48
|
-
source["dcat:endpointUrl"] ||
|
|
49
|
-
source["dcat:endpointURL"] ||
|
|
50
|
-
source["http://www.w3.org/ns/dcat#endpointUrl"] ||
|
|
51
|
-
source["endpointUrl"] ||
|
|
52
|
-
source["endpointURL"] ||
|
|
53
|
-
// Then check distribution/props level
|
|
54
|
-
props["http://www.w3.org/ns/dcat#endpointUrl"] ||
|
|
55
|
-
props["dcat:endpointUrl"] ||
|
|
56
|
-
props["dcat:endpointURL"] ||
|
|
57
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
58
|
-
props["endpointURL"] ||
|
|
59
|
-
props["endpointUrl"] ||
|
|
60
|
-
""
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get content type from EDC properties
|
|
66
|
-
* Priority: source-level fields first
|
|
67
|
-
*/
|
|
68
|
-
function getContentType(source: any): string {
|
|
69
|
-
const props = getProperties(source);
|
|
70
|
-
// Check source-level first (EDC catalog returns these at top level)
|
|
71
|
-
return (
|
|
72
|
-
source["contenttype"] ||
|
|
73
|
-
source["contentType"] ||
|
|
74
|
-
source["http://www.w3.org/ns/dcat#mediaType"] ||
|
|
75
|
-
source["dcat:mediaType"] ||
|
|
76
|
-
// Then check distribution/props level
|
|
77
|
-
props["contenttype"] ||
|
|
78
|
-
props["contentType"] ||
|
|
79
|
-
props["http://www.w3.org/ns/dcat#mediaType"] ||
|
|
80
|
-
props["dcat:mediaType"] ||
|
|
81
|
-
""
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get field with multiple fallback paths
|
|
87
|
-
*/
|
|
88
|
-
// function getFieldWithFallbacks(source: any, paths: string[][]): any {
|
|
89
|
-
// for (const path of paths) {
|
|
90
|
-
// const value = getNestedValue(source, path);
|
|
91
|
-
// if (value !== undefined && value !== null && value !== "") {
|
|
92
|
-
// return value;
|
|
93
|
-
// }
|
|
94
|
-
// }
|
|
95
|
-
// return undefined;
|
|
96
|
-
// }
|
|
97
|
-
|
|
98
|
-
export const dspMappingConfig: ResourceMapperConfig = {
|
|
99
|
-
baseFields: {
|
|
100
|
-
"@id": {
|
|
101
|
-
source: ["@id"],
|
|
102
|
-
transform: (value, source, context: MappingContext) => {
|
|
103
|
-
const stripped = stripUrnPrefix(value || source["id"] || "");
|
|
104
|
-
const slug = stripped || value?.split("/").pop() || "unknown";
|
|
105
|
-
// Include providerParticipantId in the @id to make it unique per provider
|
|
106
|
-
// This prevents collision when different providers have assets with the same ID
|
|
107
|
-
const providerPrefix = context.providerParticipantId
|
|
108
|
-
? `${encodeURIComponent(context.providerParticipantId)}/`
|
|
109
|
-
: "";
|
|
110
|
-
// FIXME: Avoid magic strings
|
|
111
|
-
return `${context.temsServiceBase || "https://api.tems.example.com/services/"}${providerPrefix}${encodeURIComponent(slug)}/`;
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
"@type": {
|
|
115
|
-
source: [],
|
|
116
|
-
defaultValue: "tems:Service",
|
|
117
|
-
},
|
|
118
|
-
name: {
|
|
119
|
-
source: [],
|
|
120
|
-
transform: (_, source) => {
|
|
121
|
-
const props = getProperties(source);
|
|
122
|
-
// Check multiple possible locations for the asset name
|
|
123
|
-
// Priority: source-level fields > DCAT/DCTERMS fields > EDC namespace fields > id fields
|
|
124
|
-
return (
|
|
125
|
-
// Source-level fields (EDC catalog returns these at top level)
|
|
126
|
-
source["name"] ||
|
|
127
|
-
source["title"] ||
|
|
128
|
-
source["dct:title"] ||
|
|
129
|
-
source["dcterms:title"] ||
|
|
130
|
-
// EDC namespace fields at source level
|
|
131
|
-
source["https://w3id.org/edc/v0.0.1/ns/name"] ||
|
|
132
|
-
source["edc:name"] ||
|
|
133
|
-
// Distribution/props level
|
|
134
|
-
props["dct:title"] ||
|
|
135
|
-
props["dcterms:title"] ||
|
|
136
|
-
props["title"] ||
|
|
137
|
-
props["https://w3id.org/edc/v0.0.1/ns/name"] ||
|
|
138
|
-
props["edc:name"] ||
|
|
139
|
-
props["name"] ||
|
|
140
|
-
// Fall back to ID but extract meaningful part
|
|
141
|
-
(source["@id"]?.startsWith("urn:uuid:")
|
|
142
|
-
? source["@id"]
|
|
143
|
-
: source["@id"]?.split("/").pop() || source["@id"]) ||
|
|
144
|
-
source["id"] ||
|
|
145
|
-
""
|
|
146
|
-
);
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
description: {
|
|
150
|
-
source: [],
|
|
151
|
-
transform: (_, source) => {
|
|
152
|
-
const props = getProperties(source);
|
|
153
|
-
// Check multiple possible locations for description
|
|
154
|
-
// Priority: source-level fields first
|
|
155
|
-
return (
|
|
156
|
-
// Source-level fields (EDC catalog returns these at top level)
|
|
157
|
-
source["description"] ||
|
|
158
|
-
source["dct:description"] ||
|
|
159
|
-
source["dcterms:description"] ||
|
|
160
|
-
source["https://w3id.org/edc/v0.0.1/ns/description"] ||
|
|
161
|
-
source["edc:description"] ||
|
|
162
|
-
// Distribution/props level
|
|
163
|
-
props["dct:description"] ||
|
|
164
|
-
props["dcterms:description"] ||
|
|
165
|
-
props["description"] ||
|
|
166
|
-
props["https://w3id.org/edc/v0.0.1/ns/description"] ||
|
|
167
|
-
props["edc:description"] ||
|
|
168
|
-
""
|
|
169
|
-
);
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
long_description: {
|
|
173
|
-
source: [],
|
|
174
|
-
transform: (_, source) => {
|
|
175
|
-
const props = getProperties(source);
|
|
176
|
-
const keywords = Array.isArray(props["dcat:keyword"])
|
|
177
|
-
? props["dcat:keyword"]
|
|
178
|
-
: props["dcat:keyword"]
|
|
179
|
-
? [props["dcat:keyword"]]
|
|
180
|
-
: [];
|
|
181
|
-
const description =
|
|
182
|
-
props["dct:description"] ||
|
|
183
|
-
props["dcterms:description"] ||
|
|
184
|
-
props["description"] ||
|
|
185
|
-
"";
|
|
186
|
-
return keywords.length > 0
|
|
187
|
-
? `Keywords: ${keywords.join(", ")}`
|
|
188
|
-
: description;
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
url: {
|
|
192
|
-
source: [],
|
|
193
|
-
transform: (_, source) => getEndpointUrl(source),
|
|
194
|
-
},
|
|
195
|
-
endpointUrl: {
|
|
196
|
-
source: [],
|
|
197
|
-
transform: (_, source) => getEndpointUrl(source),
|
|
198
|
-
},
|
|
199
|
-
contentType: {
|
|
200
|
-
source: [],
|
|
201
|
-
transform: (_, source) => getContentType(source),
|
|
202
|
-
},
|
|
203
|
-
activation_status: {
|
|
204
|
-
source: [],
|
|
205
|
-
transform: (_, source) => {
|
|
206
|
-
const props = getProperties(source);
|
|
207
|
-
const endpointURL =
|
|
208
|
-
props["dcat:endpointURL"] ||
|
|
209
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
210
|
-
props["endpointURL"] ||
|
|
211
|
-
"";
|
|
212
|
-
return endpointURL.trim().length > 0;
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
is_in_app: {
|
|
216
|
-
source: [],
|
|
217
|
-
transform: (_, source) => {
|
|
218
|
-
const props = getProperties(source);
|
|
219
|
-
const endpointURL =
|
|
220
|
-
props["dcat:endpointURL"] ||
|
|
221
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
222
|
-
props["endpointURL"] ||
|
|
223
|
-
"";
|
|
224
|
-
return endpointURL.trim().length > 0;
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
is_external: {
|
|
228
|
-
source: [],
|
|
229
|
-
transform: (_, source) => {
|
|
230
|
-
const props = getProperties(source);
|
|
231
|
-
const endpointURL =
|
|
232
|
-
props["dcat:endpointURL"] ||
|
|
233
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
234
|
-
props["endpointURL"] ||
|
|
235
|
-
"";
|
|
236
|
-
return endpointURL.trim().length > 0;
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
is_api: {
|
|
240
|
-
source: [],
|
|
241
|
-
transform: (_, source) => {
|
|
242
|
-
const props = getProperties(source);
|
|
243
|
-
const endpointURL =
|
|
244
|
-
props["dcat:endpointURL"] ||
|
|
245
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
246
|
-
props["endpointURL"] ||
|
|
247
|
-
"";
|
|
248
|
-
return endpointURL.trim().length > 0;
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
contact_url: {
|
|
252
|
-
source: [],
|
|
253
|
-
transform: (_, source) => {
|
|
254
|
-
const props = getProperties(source);
|
|
255
|
-
return (
|
|
256
|
-
props["dcat:endpointDescription"] || props["dct:conformsTo"] || ""
|
|
257
|
-
);
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
documentation_url: {
|
|
261
|
-
source: [],
|
|
262
|
-
transform: (_, source) => {
|
|
263
|
-
const props = getProperties(source);
|
|
264
|
-
return (
|
|
265
|
-
props["dcat:endpointDescription"] || props["dct:conformsTo"] || ""
|
|
266
|
-
);
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
creation_date: {
|
|
270
|
-
source: [],
|
|
271
|
-
transform: (_, source) => {
|
|
272
|
-
const props = getProperties(source);
|
|
273
|
-
return (
|
|
274
|
-
props["dct:issued"] ||
|
|
275
|
-
props["dcterms:issued"] ||
|
|
276
|
-
new Date().toISOString()
|
|
277
|
-
);
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
update_date: {
|
|
281
|
-
source: [],
|
|
282
|
-
transform: (_, source) => {
|
|
283
|
-
const props = getProperties(source);
|
|
284
|
-
const creationDate =
|
|
285
|
-
props["dct:issued"] ||
|
|
286
|
-
props["dcterms:issued"] ||
|
|
287
|
-
new Date().toISOString();
|
|
288
|
-
return (
|
|
289
|
-
props["dct:modified"] || props["dcterms:modified"] || creationDate
|
|
290
|
-
);
|
|
291
|
-
},
|
|
292
|
-
},
|
|
293
|
-
release_date: {
|
|
294
|
-
source: [],
|
|
295
|
-
transform: (_, source) => {
|
|
296
|
-
const props = getProperties(source);
|
|
297
|
-
return (
|
|
298
|
-
props["dct:issued"] ||
|
|
299
|
-
props["dcterms:issued"] ||
|
|
300
|
-
new Date().toISOString()
|
|
301
|
-
);
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
last_update: {
|
|
305
|
-
source: [],
|
|
306
|
-
transform: (_, source) => {
|
|
307
|
-
const props = getProperties(source);
|
|
308
|
-
const creationDate =
|
|
309
|
-
props["dct:issued"] ||
|
|
310
|
-
props["dcterms:issued"] ||
|
|
311
|
-
new Date().toISOString();
|
|
312
|
-
return (
|
|
313
|
-
props["dct:modified"] || props["dcterms:modified"] || creationDate
|
|
314
|
-
);
|
|
315
|
-
},
|
|
316
|
-
},
|
|
317
|
-
activation_date: {
|
|
318
|
-
source: [],
|
|
319
|
-
defaultValue: null,
|
|
320
|
-
},
|
|
321
|
-
licence: {
|
|
322
|
-
source: [],
|
|
323
|
-
defaultValue: null,
|
|
324
|
-
},
|
|
325
|
-
developper: {
|
|
326
|
-
source: [],
|
|
327
|
-
defaultValue: null,
|
|
328
|
-
},
|
|
329
|
-
data_offers: {
|
|
330
|
-
source: [],
|
|
331
|
-
defaultValue: [],
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
containerFields: {
|
|
336
|
-
categories: {
|
|
337
|
-
source: [],
|
|
338
|
-
containerType: "ldp:Container",
|
|
339
|
-
itemType: "tems:Category",
|
|
340
|
-
transform: (_, source) => {
|
|
341
|
-
const props = getProperties(source);
|
|
342
|
-
const keywords = props["dcat:keyword"];
|
|
343
|
-
if (!keywords) return [];
|
|
344
|
-
return Array.isArray(keywords) ? keywords : [keywords];
|
|
345
|
-
},
|
|
346
|
-
itemFields: {
|
|
347
|
-
"@id": (kw, _index, context) =>
|
|
348
|
-
`${context.temsCategoryBase || "https://api.tems.example.com/categories/"}${encodeURIComponent(kw)}/`,
|
|
349
|
-
name: (kw) => kw,
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
images: {
|
|
353
|
-
source: [],
|
|
354
|
-
containerType: "ldp:Container",
|
|
355
|
-
itemType: "tems:Image",
|
|
356
|
-
transform: (_, source) => {
|
|
357
|
-
const props = getProperties(source);
|
|
358
|
-
const imageUrls: string[] = [];
|
|
359
|
-
|
|
360
|
-
// Check for thumbnail in properties
|
|
361
|
-
if (props["foaf:thumbnail"]?.["rdf:resource"]) {
|
|
362
|
-
imageUrls.push(props["foaf:thumbnail"]["rdf:resource"]);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Check for creator thumbnail
|
|
366
|
-
if (props["dcterms:creator"]?.["foaf:thumbnail"]?.["rdf:resource"]) {
|
|
367
|
-
imageUrls.push(
|
|
368
|
-
props["dcterms:creator"]["foaf:thumbnail"]["rdf:resource"],
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return imageUrls;
|
|
373
|
-
},
|
|
374
|
-
itemFields: {
|
|
375
|
-
"@id": (url, index, context) => {
|
|
376
|
-
const filename = url.split("/").pop() || `image-${index}`;
|
|
377
|
-
// FIXME: Avoid magic strings
|
|
378
|
-
return `${context.temsImageBase || "https://api.tems.example.com/images/"}${encodeURIComponent(filename)}/`;
|
|
379
|
-
},
|
|
380
|
-
url: (url) => url,
|
|
381
|
-
iframe: () => false,
|
|
382
|
-
name: (url) => url.split("/").pop() || "image",
|
|
383
|
-
},
|
|
384
|
-
},
|
|
385
|
-
},
|
|
386
|
-
|
|
387
|
-
nestedObjects: {
|
|
388
|
-
provider: {
|
|
389
|
-
source: [],
|
|
390
|
-
type: "tems:Provider",
|
|
391
|
-
fields: {
|
|
392
|
-
"@id": {
|
|
393
|
-
source: [],
|
|
394
|
-
transform: (_, _source, context: MappingContext) => {
|
|
395
|
-
// Provider info comes from context (DSPProviderConfig)
|
|
396
|
-
const providerSlug =
|
|
397
|
-
context.providerParticipantId ||
|
|
398
|
-
context.providerName ||
|
|
399
|
-
"unknown";
|
|
400
|
-
// FIXME: Avoid magic strings
|
|
401
|
-
return `${context.temsProviderBase || "https://api.tems.example.com/providers/"}${encodeURIComponent(providerSlug)}/`;
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
name: {
|
|
405
|
-
source: [],
|
|
406
|
-
transform: (_, source, context: MappingContext) => {
|
|
407
|
-
const props = getProperties(source);
|
|
408
|
-
return (
|
|
409
|
-
props["dcterms:creator"]?.["foaf:name"] ||
|
|
410
|
-
context.providerName ||
|
|
411
|
-
""
|
|
412
|
-
);
|
|
413
|
-
},
|
|
414
|
-
},
|
|
415
|
-
image: {
|
|
416
|
-
source: [],
|
|
417
|
-
transform: (_, source, context: MappingContext) => {
|
|
418
|
-
const props = getProperties(source);
|
|
419
|
-
const logoUrl =
|
|
420
|
-
props["dcterms:creator"]?.["foaf:thumbnail"]?.["rdf:resource"];
|
|
421
|
-
|
|
422
|
-
if (!logoUrl) return undefined;
|
|
423
|
-
|
|
424
|
-
const filename = logoUrl.split("/").pop() || "provider-logo";
|
|
425
|
-
return {
|
|
426
|
-
// FIXME: Avoid magic strings
|
|
427
|
-
"@id": `${context.temsImageBase || "https://api.tems.example.com/images/"}${encodeURIComponent(filename)}/`,
|
|
428
|
-
"@type": "tems:Image",
|
|
429
|
-
iframe: false,
|
|
430
|
-
url: logoUrl,
|
|
431
|
-
name: filename,
|
|
432
|
-
};
|
|
433
|
-
},
|
|
434
|
-
},
|
|
435
|
-
},
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
|
|
439
|
-
contractFields: {
|
|
440
|
-
counterPartyAddress: {
|
|
441
|
-
source: [],
|
|
442
|
-
transform: (_, _source, context: MappingContext) =>
|
|
443
|
-
context.providerAddress,
|
|
444
|
-
},
|
|
445
|
-
counterPartyId: {
|
|
446
|
-
source: [],
|
|
447
|
-
transform: (_, _source, context: MappingContext) =>
|
|
448
|
-
context.providerParticipantId || context.providerName,
|
|
449
|
-
},
|
|
450
|
-
assetId: {
|
|
451
|
-
source: ["@id"],
|
|
452
|
-
transform: (value, source) => stripUrnPrefix(value || source["id"] || ""),
|
|
453
|
-
},
|
|
454
|
-
datasetId: {
|
|
455
|
-
source: ["@id"],
|
|
456
|
-
transform: (value, source) => stripUrnPrefix(value || source["id"] || ""),
|
|
457
|
-
},
|
|
458
|
-
// Index endpoint URL for index assets - try multiple property variations
|
|
459
|
-
// Priority: source-level dcat:endpointUrl (index endpoint) over props-level dcat:endpointURL (protocol URL)
|
|
460
|
-
indexEndpointUrl: {
|
|
461
|
-
source: [],
|
|
462
|
-
transform: (_, source, context: MappingContext) => {
|
|
463
|
-
const props = getProperties(source);
|
|
464
|
-
// DEBUG: Log all possible sources for endpoint URL
|
|
465
|
-
console.log("[DSP Mapping] indexEndpointUrl extraction for:", {
|
|
466
|
-
assetId: source["@id"] || source["id"],
|
|
467
|
-
assetName: source["name"] || props["name"] || props["dct:title"],
|
|
468
|
-
provider: context.providerName,
|
|
469
|
-
providerParticipantId: context.providerParticipantId,
|
|
470
|
-
"source.dcat:endpointUrl": source["dcat:endpointUrl"],
|
|
471
|
-
"props.dcat:endpointUrl": props["dcat:endpointUrl"],
|
|
472
|
-
"source.dcat:endpointURL": source["dcat:endpointURL"],
|
|
473
|
-
"props.dcat:accessService": props["dcat:accessService"],
|
|
474
|
-
});
|
|
475
|
-
// Prioritize source-level (lowercase Url) which contains the actual index endpoint
|
|
476
|
-
// over props-level (uppercase URL) which may contain the protocol URL
|
|
477
|
-
const result =
|
|
478
|
-
source["dcat:endpointUrl"] ||
|
|
479
|
-
props["dcat:endpointUrl"] ||
|
|
480
|
-
source["dcat:endpointURL"] ||
|
|
481
|
-
props["dcat:accessService"]?.["dcat:endpointUrl"] ||
|
|
482
|
-
props["dcat:accessService"]?.["dcat:endpointURL"] ||
|
|
483
|
-
props["endpointUrl"] ||
|
|
484
|
-
props["endpointURL"] ||
|
|
485
|
-
undefined;
|
|
486
|
-
console.log("[DSP Mapping] indexEndpointUrl result:", result);
|
|
487
|
-
return result;
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
policy: {
|
|
491
|
-
source: ["odrl:hasPolicy"],
|
|
492
|
-
fallback: (source) => source["hasPolicy"],
|
|
493
|
-
transform: (policy, source, context) => {
|
|
494
|
-
if (!policy) return undefined;
|
|
495
|
-
|
|
496
|
-
// Use the processPolicyTransform helper
|
|
497
|
-
const processed = processPolicyTransform(policy, source, context);
|
|
498
|
-
|
|
499
|
-
// Additional processing for permissions, prohibitions, obligations
|
|
500
|
-
if (processed) {
|
|
501
|
-
const processRules = (rules: any) => {
|
|
502
|
-
if (Array.isArray(rules)) {
|
|
503
|
-
return rules.map((rule) => {
|
|
504
|
-
if (rule["@id"]) {
|
|
505
|
-
rule["@id"] = stripUrnPrefix(rule["@id"]);
|
|
506
|
-
}
|
|
507
|
-
return rule;
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
return rules;
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
if (processed["odrl:permission"]) {
|
|
514
|
-
processed["odrl:permission"] = processRules(
|
|
515
|
-
processed["odrl:permission"],
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
if (processed["odrl:prohibition"]) {
|
|
519
|
-
processed["odrl:prohibition"] = processRules(
|
|
520
|
-
processed["odrl:prohibition"],
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
if (processed["odrl:obligation"]) {
|
|
524
|
-
processed["odrl:obligation"] = processRules(
|
|
525
|
-
processed["odrl:obligation"],
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
return processed;
|
|
531
|
-
},
|
|
532
|
-
},
|
|
533
|
-
},
|
|
534
|
-
|
|
535
|
-
// Post-processing to add provider metadata fields
|
|
536
|
-
postProcess: (resource, _source, context: MappingContext) => {
|
|
537
|
-
return {
|
|
538
|
-
...resource,
|
|
539
|
-
_provider: context.providerName,
|
|
540
|
-
_providerAddress: context.providerAddress,
|
|
541
|
-
_providerColor: context.providerColor || "#1976d2",
|
|
542
|
-
_providerParticipantId: context.providerParticipantId,
|
|
543
|
-
};
|
|
544
|
-
},
|
|
545
|
-
};
|