@@ -7,13 +7,15 @@ import type { TableEntry } from './table-entry';
7
7
type EnhancedDistribution = Dataset [ 'getDistributions' ] [ number ]
8
8
9
9
10
- export class DcatApChV2DistributionAdapter implements EnhancedDistribution {
10
+ export class DcatApChV2DistributionAdapter {
11
11
#distribution: EnhancedDistribution | undefined ;
12
12
#dataset: DcatApChV2DatasetAdapter ;
13
13
14
14
constructor ( d : EnhancedDistribution , dataset : DcatApChV2DatasetAdapter ) {
15
15
this . #distribution = d ;
16
16
this . #dataset = dataset ;
17
+
18
+ console . log ( 'id' , this . #distribution?. id ) ;
17
19
}
18
20
19
21
/**
@@ -93,7 +95,7 @@ export class DcatApChV2DistributionAdapter implements EnhancedDistribution {
93
95
94
96
// Try to parse the byte size as a number.
95
97
// Piveau returns it as a string with dots as thousands separators which is not valid for Number()
96
- const byteSizeNumber = Number ( byteSizeValue . replace ( / \. / g, '' ) ) ; // Remove dots for thousands separators
98
+ const byteSizeNumber = Number ( byteSizeValue . replace ( / \. / g, '' ) . replace ( / , / g , '' ) . replace ( / \s + / g , '' ) ) ; // Remove spaces for thousands separators
97
99
98
100
if ( isNaN ( byteSizeNumber ) ) {
99
101
return byteSizeValue ; // Return the raw value if parsing fails
@@ -115,45 +117,166 @@ export class DcatApChV2DistributionAdapter implements EnhancedDistribution {
115
117
return `${ size % 1 === 0 ? size : size . toFixed ( 2 ) } ${ units [ unitIndex ] } ` ;
116
118
}
117
119
118
-
119
-
120
- get getPropertyTable ( ) {
121
- return this . #distribution?. getPropertyTable || [ ] ;
122
- }
123
-
124
-
120
+ /**
121
+ * Get the download URLs of the distribution.
122
+ *
123
+ * From dcat-ap-ch:
124
+ * Property download URL
125
+ * Requirement level Optional
126
+ * Cardinality 0..n
127
+ * URI dcat:downloadURL
128
+ * Range rdfs:Resource
129
+ * Usage Note
130
+ * - In case of a downloadable file, it is good practice to repeat the mandatory accessURL in this more specific property,
131
+ * to indicate to the data user that the distribution has this extra characteristic of being downloadable. The downloadURLs
132
+ * MAY thus be the same as the accessURLs but they MAY also differ.
133
+ */
125
134
get downloadUrls ( ) {
126
135
return this . #distribution?. downloadUrls || [ ] ;
127
136
}
128
137
138
+ /**
139
+ * Get the access URLs of the distribution.
140
+ *
141
+ * From dcat-ap-ch:
142
+ * Property access URL
143
+ * Requirement level Mandatory
144
+ * Cardinality 1..n
145
+ * URI dcat:accessURL
146
+ * Range rdfs:Resource
147
+ * Usage Note
148
+ * - This property contains a URL that gives access to a Distribution of the Dataset. The resource at the access URL may contain
149
+ * information about how to get the Dataset.
150
+ */
129
151
get accessUrls ( ) {
130
152
return this . #distribution?. accessUrls || [ ] ;
131
153
}
132
154
133
- get format ( ) {
134
- return this . #distribution?. format ?? '' ;
155
+ /**
156
+ * Get the format of the distribution.
157
+ *
158
+ * From dcat-ap-ch:
159
+ * Property format
160
+ * Requirement level Recommended
161
+ * Cardinality 0..1
162
+ * URI dct:format
163
+ * Range dct:MediaTypeOrExtent
164
+ * Usage Note
165
+ * - This property refers to the file format of the Distribution.CV to be used: [VOCAB-EU-FILE-TYPE]
166
+ * - CV to be used: [VOCAB-EU-FILE-TYPE]
167
+ * - If a format is not available:
168
+ * a) media type ([IANA-MEDIA-TYPES]) should be used
169
+ * b) If necessary, a discussion to evaluate the adoption within the EU should be launched (Contact point: [VOCAB-EU-OP-CONTACT]).
170
+ */
171
+ get format ( ) : string {
172
+ const format = this . #distribution?. format
173
+ if ( format ) {
174
+ return format ;
175
+ }
176
+ // Fallback: get mediaType from property table
177
+ const mediaTypeNode = this . #distribution?. getPropertyTable . find ( node => node . id === 'mediaType' ) ;
178
+ if ( ! mediaTypeNode || ! mediaTypeNode . data ?. length ) {
179
+ return '' ;
180
+ }
181
+ const mediaType = mediaTypeNode ?. data [ 0 ] ?. data ?? '' ;
182
+ if ( typeof mediaType !== 'string' ) {
183
+ return '' ;
184
+ }
185
+ return mediaType ;
135
186
}
136
187
188
+ /**
189
+ * Get the license of the distribution if available
190
+ *
191
+ * From dcat-ap-ch:
192
+ * Property license
193
+ * Requirement level Mandatory
194
+ * Cardinality 1..1
195
+ * URI dct:license
196
+ * Range dct:LicenseDocument
197
+ * Usage Note
198
+ * This property refers to the licence under which the Distribution is made available.
199
+ * CV to used: [VOCAB-CH-LICENSE]
200
+ */
137
201
get license ( ) {
138
- return this . #distribution?. license ;
202
+ const lic = this . #distribution?. license ;
203
+ const licIri = lic ?. resource
204
+ if ( ! licIri ) {
205
+ return undefined ;
206
+ }
207
+ return licIri
139
208
}
140
209
141
- get issued ( ) {
142
- return this . #distribution?. issued || '' ;
210
+
211
+ /**
212
+ * Get the release date of the distribution if available
213
+ * Property release date
214
+ * Requirement level Optional
215
+ * Cardinality 0..1
216
+ * URI dct:issued
217
+ * Range rdfs:Literal (typed as as xsd:date, xsd:dateTime, xsd:gYear or xsd:gYearMonth)
218
+ * Usage Note
219
+ * - This property contains the date of formal issuance (e.g., publication) of the Distribution.
220
+ * - Date of formal issuance (publication) of the distribution
221
+ * - UsageThe first time issuance of the distribution.
222
+ *
223
+ * @returns {Date | undefined } The release date as a Date object, or undefined if not available or invalid.
224
+ */
225
+ get releaseDate ( ) {
226
+ const releaseDateString = this . #distribution?. issued || '' ;
227
+ if ( ! releaseDateString ) {
228
+ return undefined ;
229
+ }
230
+ const releaseDate = new Date ( releaseDateString ) ;
231
+ return isNaN ( releaseDate . getTime ( ) ) ? undefined : releaseDate ;
143
232
}
144
233
234
+ /**
235
+ * Get the modified date of the distribution if available
236
+ *
237
+ * from dcat-ap-ch:
238
+ * Property: update/modification date
239
+ * This property contains the most recent date on which the Distribution was changed or modified.
240
+ * Property update/ modification date
241
+ * Requirement level Recommended
242
+ * Cardinality 0..1
243
+ * URI dct:modified
244
+ * Range rdfs:Literal (typed as as xsd:date, xsd:dateTime, xsd:gYear or xsd:gYearMonth)
245
+ * Usage Note
246
+ *
247
+ * @returns {Date | undefined } The modified date as a Date object, or undefined if not available or invalid.
248
+ */
145
249
get modified ( ) {
146
- return this . #distribution?. modified || '' ;
250
+ const modifiedDateString = this . #distribution?. modified || '' ;
251
+ if ( ! modifiedDateString ) {
252
+ return undefined ;
253
+ }
254
+ const modifiedDate = new Date ( modifiedDateString ) ;
255
+ return isNaN ( modifiedDate . getTime ( ) ) ? undefined : modifiedDate ;
147
256
}
148
257
258
+ /**
259
+ * Get the id of the distribution
260
+ *
261
+ * Note: This is not part of dcat-ap-ch, but added by piveau
262
+ */
149
263
get id ( ) {
150
264
return this . #distribution?. id || '' ;
151
265
}
152
266
153
- get created ( ) {
154
- return this . #distribution?. created ;
155
- }
156
-
267
+ /**
268
+ * Property Language
269
+ * Requirement level Optional
270
+ * Cardinality 0..n
271
+ * URI dct:language
272
+ * Range rdfs:Literal
273
+ * Usage Note
274
+ * - This property refers to a language used in the Distribution.
275
+ * - This property can be repeated if the metadata is provided in multiple languages.
276
+ * - The property MUST be set if the distribution is language-dependent or if it is given in some of the languages
277
+ * German, French, Italian and English but not in all four languages.
278
+ * - CV to be used: [VOCAB-EU-LANGUAGE]
279
+ */
157
280
get languages ( ) {
158
281
return this . #distribution?. languages || [ ] ;
159
282
}
@@ -170,18 +293,14 @@ export class DcatApChV2DistributionAdapter implements EnhancedDistribution {
170
293
171
294
172
295
get propertyTable ( ) {
173
- const rootNode = this . #dataset . getPropertyTable ;
296
+ const rootNode = this . #distribution ? .getPropertyTable ;
174
297
if ( ! rootNode ) {
175
298
return [ ] ;
176
299
}
177
300
178
- // const ignoredNode = ['catalogRecord'];
179
- const ignoredNode : string [ ] = [ ]
301
+ const ignoredNode = [ 'byteSize' ] ;
180
302
const nodesToConsider = rootNode . filter ( n => n . data ) . filter ( n => ! ignoredNode . includes ( n . id ) ) ;
181
303
182
- console . log ( 'flatNodes' , nodesToConsider ) ;
183
-
184
-
185
304
const table : TableEntry [ ] = [ ] ;
186
305
for ( const node of nodesToConsider ) {
187
306
0 commit comments