geonetwork-ui 2.3.0-dev.28c8df17 → 2.3.0-dev.376e0e90
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/esm2022/libs/api/metadata-converter/src/index.mjs +5 -5
- package/esm2022/libs/api/metadata-converter/src/lib/base.converter.mjs +14 -0
- package/esm2022/libs/api/metadata-converter/src/lib/find-converter.mjs +15 -0
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/atomic-operations.mjs +3 -3
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.converter.mjs +52 -0
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +3 -3
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/index.mjs +4 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/index.mjs +2 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.mjs +123 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.mjs +116 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.mjs +138 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/index.mjs +2 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +242 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +58 -62
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.mjs +18 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.mjs +14 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/role.mapper.mjs +48 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.mjs +18 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.mjs +64 -0
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +75 -58
- package/esm2022/libs/api/metadata-converter/src/lib/xml-utils.mjs +76 -14
- package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +4 -4
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +8 -8
- package/fesm2022/geonetwork-ui.mjs +822 -245
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/metadata-converter/src/index.d.ts +4 -4
- package/libs/api/metadata-converter/src/index.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/{metadata-base.mapper.d.ts → base.converter.d.ts} +3 -3
- package/libs/api/metadata-converter/src/lib/base.converter.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/find-converter.d.ts +3 -0
- package/libs/api/metadata-converter/src/lib/find-converter.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/gn4/{gn4.metadata.mapper.d.ts → gn4.converter.d.ts} +5 -5
- package/libs/api/metadata-converter/src/lib/gn4/gn4.converter.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/gn4/index.d.ts +4 -0
- package/libs/api/metadata-converter/src/lib/gn4/index.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/index.d.ts +2 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/index.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts +9 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts +20 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.d.ts +21 -0
- package/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/index.d.ts +2 -0
- package/libs/api/metadata-converter/src/lib/iso19139/index.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts +11 -0
- package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +34 -6
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.d.ts +8 -0
- package/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/utils/role.mapper.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.d.ts.map +1 -0
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +39 -3
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/xml-utils.d.ts +14 -1
- package/libs/api/metadata-converter/src/lib/xml-utils.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +2 -2
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +6 -4
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/libs/api/metadata-converter/src/index.ts +4 -4
- package/src/libs/api/metadata-converter/src/lib/{metadata-base.mapper.ts → base.converter.ts} +2 -2
- package/src/libs/api/metadata-converter/src/lib/find-converter.ts +16 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +32 -5
- package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +11 -4
- package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +33 -7
- package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +580 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +2 -2
- package/src/libs/api/metadata-converter/src/lib/gn4/{gn4.metadata.mapper.ts → gn4.converter.ts} +2 -2
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +2 -2
- package/src/libs/api/metadata-converter/src/lib/gn4/index.ts +3 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/index.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +176 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +329 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +513 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/index.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +327 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +121 -82
- package/src/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.ts +20 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +175 -95
- package/src/libs/api/metadata-converter/src/lib/xml-utils.ts +84 -16
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +2 -2
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +9 -4
- package/src/libs/feature/editor/src/lib/services/editor.service.ts +27 -16
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.mjs +0 -52
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.mjs +0 -14
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/role.mapper.mjs +0 -48
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/status.mapper.mjs +0 -18
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/update-frequency.mapper.mjs +0 -64
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/converter.mjs +0 -130
- package/esm2022/libs/api/metadata-converter/src/lib/metadata-base.mapper.mjs +0 -14
- package/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/iso19139/codelists/role.mapper.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/iso19139/codelists/status.mapper.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/iso19139/codelists/update-frequency.mapper.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/iso19139/converter.d.ts +0 -4
- package/libs/api/metadata-converter/src/lib/iso19139/converter.d.ts.map +0 -1
- package/libs/api/metadata-converter/src/lib/metadata-base.mapper.d.ts.map +0 -1
- package/src/libs/api/metadata-converter/src/lib/iso19139/converter.ts +0 -196
- /package/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/keyword.mapper.d.ts +0 -0
- /package/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/role.mapper.d.ts +0 -0
- /package/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/status.mapper.d.ts +0 -0
- /package/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/update-frequency.mapper.d.ts +0 -0
- /package/src/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/keyword.mapper.ts +0 -0
- /package/src/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/role.mapper.ts +0 -0
- /package/src/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/status.mapper.ts +0 -0
- /package/src/libs/api/metadata-converter/src/lib/iso19139/{codelists → utils}/update-frequency.mapper.ts +0 -0
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
} from '../xml-utils'
|
|
37
37
|
import {
|
|
38
38
|
ChainableFunction,
|
|
39
|
+
combine,
|
|
39
40
|
fallback,
|
|
40
41
|
filterArray,
|
|
41
42
|
getAtIndex,
|
|
@@ -47,8 +48,9 @@ import {
|
|
|
47
48
|
} from '../function-utils'
|
|
48
49
|
import format from 'date-fns/format'
|
|
49
50
|
import { readKind } from './read-parts'
|
|
51
|
+
import { namePartsToFull } from './utils/individual-name'
|
|
50
52
|
|
|
51
|
-
function writeCharacterString(
|
|
53
|
+
export function writeCharacterString(
|
|
52
54
|
text: string
|
|
53
55
|
): ChainableFunction<XmlElement, XmlElement> {
|
|
54
56
|
return tap(
|
|
@@ -56,7 +58,9 @@ function writeCharacterString(
|
|
|
56
58
|
)
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
function writeLinkage(
|
|
61
|
+
export function writeLinkage(
|
|
62
|
+
url: URL
|
|
63
|
+
): ChainableFunction<XmlElement, XmlElement> {
|
|
60
64
|
return tap(
|
|
61
65
|
pipe(
|
|
62
66
|
findNestedChildOrCreate('gmd:linkage', 'gmd:URL'),
|
|
@@ -65,7 +69,7 @@ function writeLinkage(url: URL): ChainableFunction<XmlElement, XmlElement> {
|
|
|
65
69
|
)
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
function writeAnchor(
|
|
72
|
+
export function writeAnchor(
|
|
69
73
|
url: URL,
|
|
70
74
|
text?: string
|
|
71
75
|
): ChainableFunction<XmlElement, XmlElement> {
|
|
@@ -78,7 +82,9 @@ function writeAnchor(
|
|
|
78
82
|
)
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
function writeDateTime(
|
|
85
|
+
export function writeDateTime(
|
|
86
|
+
date: Date
|
|
87
|
+
): ChainableFunction<XmlElement, XmlElement> {
|
|
82
88
|
return tap(
|
|
83
89
|
pipe(
|
|
84
90
|
findChildOrCreate('gco:DateTime'),
|
|
@@ -87,7 +93,9 @@ function writeDateTime(date: Date): ChainableFunction<XmlElement, XmlElement> {
|
|
|
87
93
|
)
|
|
88
94
|
}
|
|
89
95
|
|
|
90
|
-
function writeDate(
|
|
96
|
+
export function writeDate(
|
|
97
|
+
date: Date
|
|
98
|
+
): ChainableFunction<XmlElement, XmlElement> {
|
|
91
99
|
return tap(
|
|
92
100
|
pipe(
|
|
93
101
|
findChildOrCreate('gco:Date'),
|
|
@@ -96,7 +104,7 @@ function writeDate(date: Date): ChainableFunction<XmlElement, XmlElement> {
|
|
|
96
104
|
)
|
|
97
105
|
}
|
|
98
106
|
|
|
99
|
-
function getProgressCode(status: RecordStatus): string {
|
|
107
|
+
export function getProgressCode(status: RecordStatus): string {
|
|
100
108
|
switch (status) {
|
|
101
109
|
case 'completed':
|
|
102
110
|
return 'completed'
|
|
@@ -115,7 +123,7 @@ function getProgressCode(status: RecordStatus): string {
|
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
function getRoleCode(role: Role): string {
|
|
126
|
+
export function getRoleCode(role: Role): string {
|
|
119
127
|
switch (role) {
|
|
120
128
|
case 'author':
|
|
121
129
|
return 'author'
|
|
@@ -164,7 +172,7 @@ function getRoleCode(role: Role): string {
|
|
|
164
172
|
}
|
|
165
173
|
}
|
|
166
174
|
|
|
167
|
-
function getDistributionProtocol(
|
|
175
|
+
export function getDistributionProtocol(
|
|
168
176
|
distribution: DatasetServiceDistribution
|
|
169
177
|
): string {
|
|
170
178
|
switch (distribution.accessServiceProtocol.toLowerCase()) {
|
|
@@ -179,7 +187,7 @@ function getDistributionProtocol(
|
|
|
179
187
|
}
|
|
180
188
|
}
|
|
181
189
|
|
|
182
|
-
function getMaintenanceFrequencyCode(
|
|
190
|
+
export function getMaintenanceFrequencyCode(
|
|
183
191
|
updateFrequency: UpdateFrequencyCode
|
|
184
192
|
): string | null {
|
|
185
193
|
switch (updateFrequency) {
|
|
@@ -198,7 +206,7 @@ function getMaintenanceFrequencyCode(
|
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
208
|
|
|
201
|
-
function getISODuration(updateFrequency: UpdateFrequencyCustom): string {
|
|
209
|
+
export function getISODuration(updateFrequency: UpdateFrequencyCustom): string {
|
|
202
210
|
const duration = {
|
|
203
211
|
years: 0,
|
|
204
212
|
months: 0,
|
|
@@ -227,19 +235,61 @@ function getISODuration(updateFrequency: UpdateFrequencyCustom): string {
|
|
|
227
235
|
return `P${duration.years}Y${duration.months}M${duration.days}D${hours}`
|
|
228
236
|
}
|
|
229
237
|
|
|
230
|
-
function appendResponsibleParty(contact: Individual) {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
238
|
+
export function appendResponsibleParty(contact: Individual) {
|
|
239
|
+
const fullName = namePartsToFull(contact.firstName, contact.lastName)
|
|
240
|
+
|
|
241
|
+
const createAddress = pipe(
|
|
242
|
+
createElement('gmd:address'),
|
|
243
|
+
createChild('gmd:CI_Address'),
|
|
244
|
+
appendChildren(
|
|
245
|
+
pipe(
|
|
246
|
+
createElement('gmd:electronicMailAddress'),
|
|
247
|
+
writeCharacterString(contact.email)
|
|
248
|
+
)
|
|
249
|
+
),
|
|
250
|
+
contact.address
|
|
251
|
+
? appendChildren(
|
|
252
|
+
pipe(
|
|
253
|
+
createElement('gmd:deliveryPoint'),
|
|
254
|
+
writeCharacterString(contact.address)
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
: noop
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
const createContact = pipe(
|
|
261
|
+
createElement('gmd:contactInfo'),
|
|
262
|
+
createChild('gmd:CI_Contact'),
|
|
263
|
+
contact.phone
|
|
264
|
+
? appendChildren(
|
|
265
|
+
pipe(
|
|
266
|
+
createElement('gmd:phone'),
|
|
267
|
+
createChild('gmd:CI_Telephone'),
|
|
268
|
+
createChild('gmd:voice'),
|
|
269
|
+
writeCharacterString(contact.phone)
|
|
270
|
+
)
|
|
271
|
+
)
|
|
272
|
+
: noop,
|
|
273
|
+
appendChildren(createAddress),
|
|
274
|
+
'website' in contact.organization
|
|
275
|
+
? appendChildren(
|
|
276
|
+
pipe(
|
|
277
|
+
createElement('gmd:onlineResource'),
|
|
278
|
+
createChild('gmd:CI_OnlineResource'),
|
|
279
|
+
writeLinkage(contact.organization.website)
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
: noop
|
|
283
|
+
)
|
|
284
|
+
|
|
235
285
|
return appendChildren(
|
|
236
286
|
pipe(
|
|
237
287
|
createElement('gmd:CI_ResponsibleParty'),
|
|
238
|
-
|
|
288
|
+
fullName
|
|
239
289
|
? appendChildren(
|
|
240
290
|
pipe(
|
|
241
291
|
createElement('gmd:individualName'),
|
|
242
|
-
writeCharacterString(
|
|
292
|
+
writeCharacterString(fullName)
|
|
243
293
|
)
|
|
244
294
|
)
|
|
245
295
|
: noop,
|
|
@@ -256,27 +306,7 @@ function appendResponsibleParty(contact: Individual) {
|
|
|
256
306
|
createElement('gmd:organisationName'),
|
|
257
307
|
writeCharacterString(contact.organization.name)
|
|
258
308
|
),
|
|
259
|
-
|
|
260
|
-
createElement('gmd:contactInfo'),
|
|
261
|
-
createChild('gmd:CI_Contact'),
|
|
262
|
-
appendChildren(
|
|
263
|
-
pipe(
|
|
264
|
-
createElement('gmd:address'),
|
|
265
|
-
createChild('gmd:CI_Address'),
|
|
266
|
-
createChild('gmd:electronicMailAddress'),
|
|
267
|
-
writeCharacterString(contact.email)
|
|
268
|
-
)
|
|
269
|
-
),
|
|
270
|
-
'website' in contact.organization
|
|
271
|
-
? appendChildren(
|
|
272
|
-
pipe(
|
|
273
|
-
createElement('gmd:onlineResource'),
|
|
274
|
-
createChild('gmd:CI_OnlineResource'),
|
|
275
|
-
writeLinkage(contact.organization.website)
|
|
276
|
-
)
|
|
277
|
-
)
|
|
278
|
-
: noop
|
|
279
|
-
),
|
|
309
|
+
createContact,
|
|
280
310
|
pipe(
|
|
281
311
|
createElement('gmd:role'),
|
|
282
312
|
createChild('gmd:CI_RoleCode'),
|
|
@@ -291,7 +321,7 @@ function appendResponsibleParty(contact: Individual) {
|
|
|
291
321
|
)
|
|
292
322
|
}
|
|
293
323
|
|
|
294
|
-
function updateCitationDate(
|
|
324
|
+
export function updateCitationDate(
|
|
295
325
|
date: Date,
|
|
296
326
|
type: 'revision' | 'creation' | 'publication'
|
|
297
327
|
) {
|
|
@@ -311,8 +341,8 @@ function updateCitationDate(
|
|
|
311
341
|
)
|
|
312
342
|
}
|
|
313
343
|
|
|
314
|
-
function appendCitationDate(
|
|
315
|
-
date,
|
|
344
|
+
export function appendCitationDate(
|
|
345
|
+
date: Date,
|
|
316
346
|
type: 'revision' | 'creation' | 'publication'
|
|
317
347
|
) {
|
|
318
348
|
return appendChildren(
|
|
@@ -335,12 +365,12 @@ function appendCitationDate(
|
|
|
335
365
|
)
|
|
336
366
|
}
|
|
337
367
|
|
|
338
|
-
function removeKeywords() {
|
|
368
|
+
export function removeKeywords() {
|
|
339
369
|
return removeChildren(pipe(findNestedElements('gmd:descriptiveKeywords')))
|
|
340
370
|
}
|
|
341
371
|
|
|
342
372
|
// returns a <gmd:thesaurusName> element
|
|
343
|
-
function createThesaurus(thesaurus: KeywordThesaurus) {
|
|
373
|
+
export function createThesaurus(thesaurus: KeywordThesaurus) {
|
|
344
374
|
return pipe(
|
|
345
375
|
createElement('gmd:thesaurusName'),
|
|
346
376
|
createChild('gmd:CI_Citation'),
|
|
@@ -365,14 +395,15 @@ function createThesaurus(thesaurus: KeywordThesaurus) {
|
|
|
365
395
|
)
|
|
366
396
|
}
|
|
367
397
|
|
|
368
|
-
function appendKeywords(keywords: Keyword[]) {
|
|
398
|
+
export function appendKeywords(keywords: Keyword[]) {
|
|
399
|
+
// keywords are grouped by thesaurus if they have one, otherwise by type
|
|
369
400
|
const keywordsByThesaurus: Keyword[][] = keywords.reduce((acc, keyword) => {
|
|
370
401
|
const thesaurusId = keyword.thesaurus?.id
|
|
371
402
|
const type = keyword.type
|
|
372
403
|
let existingGroup = acc.find((group) =>
|
|
373
|
-
|
|
374
|
-
? group[0].thesaurus
|
|
375
|
-
: group[0].type === type
|
|
404
|
+
thesaurusId
|
|
405
|
+
? group[0].thesaurus?.id === thesaurusId
|
|
406
|
+
: group[0].type === type && !group[0].thesaurus
|
|
376
407
|
)
|
|
377
408
|
if (!existingGroup) {
|
|
378
409
|
existingGroup = []
|
|
@@ -413,7 +444,7 @@ function appendKeywords(keywords: Keyword[]) {
|
|
|
413
444
|
)
|
|
414
445
|
}
|
|
415
446
|
|
|
416
|
-
function createConstraint(
|
|
447
|
+
export function createConstraint(
|
|
417
448
|
constraint: Constraint,
|
|
418
449
|
type: 'legal' | 'security' | 'other'
|
|
419
450
|
) {
|
|
@@ -471,7 +502,7 @@ function createConstraint(
|
|
|
471
502
|
)
|
|
472
503
|
}
|
|
473
504
|
|
|
474
|
-
function removeOtherConstraints() {
|
|
505
|
+
export function removeOtherConstraints() {
|
|
475
506
|
return removeChildren(
|
|
476
507
|
pipe(
|
|
477
508
|
findChildrenElement('gmd:resourceConstraints'),
|
|
@@ -485,7 +516,7 @@ function removeOtherConstraints() {
|
|
|
485
516
|
)
|
|
486
517
|
}
|
|
487
518
|
|
|
488
|
-
function removeSecurityConstraints() {
|
|
519
|
+
export function removeSecurityConstraints() {
|
|
489
520
|
return removeChildren(
|
|
490
521
|
pipe(
|
|
491
522
|
findChildrenElement('gmd:resourceConstraints'),
|
|
@@ -499,7 +530,7 @@ function removeSecurityConstraints() {
|
|
|
499
530
|
)
|
|
500
531
|
}
|
|
501
532
|
|
|
502
|
-
function removeLegalConstraints() {
|
|
533
|
+
export function removeLegalConstraints() {
|
|
503
534
|
return removeChildren(
|
|
504
535
|
pipe(
|
|
505
536
|
findChildrenElement('gmd:resourceConstraints'),
|
|
@@ -519,7 +550,7 @@ function removeLegalConstraints() {
|
|
|
519
550
|
)
|
|
520
551
|
}
|
|
521
552
|
|
|
522
|
-
function removeLicenses() {
|
|
553
|
+
export function removeLicenses() {
|
|
523
554
|
return removeChildren(
|
|
524
555
|
pipe(
|
|
525
556
|
findChildrenElement('gmd:resourceConstraints'),
|
|
@@ -539,7 +570,7 @@ function removeLicenses() {
|
|
|
539
570
|
)
|
|
540
571
|
}
|
|
541
572
|
|
|
542
|
-
function createLicense(license: Constraint) {
|
|
573
|
+
export function createLicense(license: Constraint) {
|
|
543
574
|
return pipe(
|
|
544
575
|
createElement('gmd:resourceConstraints'),
|
|
545
576
|
createChild('gmd:MD_LegalConstraints'),
|
|
@@ -572,44 +603,52 @@ function createLicense(license: Constraint) {
|
|
|
572
603
|
)
|
|
573
604
|
}
|
|
574
605
|
|
|
575
|
-
function removeDistributions() {
|
|
606
|
+
export function removeDistributions() {
|
|
576
607
|
return pipe(removeChildrenByName('gmd:distributionInfo'))
|
|
577
608
|
}
|
|
578
609
|
|
|
579
|
-
function
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
writeCharacterString(distribution.mimeType)
|
|
590
|
-
),
|
|
591
|
-
pipe(
|
|
592
|
-
createElement('gmd:version'),
|
|
593
|
-
writeCharacterString('1.0') // hardcoding this as it most likely won't be used but is mandatory
|
|
594
|
-
)
|
|
595
|
-
)
|
|
596
|
-
)
|
|
610
|
+
function appendDistributionFormat(mimeType: string) {
|
|
611
|
+
return appendChildren(
|
|
612
|
+
pipe(
|
|
613
|
+
createElement('gmd:distributionFormat'),
|
|
614
|
+
createChild('gmd:MD_Format'),
|
|
615
|
+
appendChildren(
|
|
616
|
+
pipe(createElement('gmd:name'), writeCharacterString(mimeType)),
|
|
617
|
+
pipe(
|
|
618
|
+
createElement('gmd:version'),
|
|
619
|
+
writeCharacterString('1.0') // hardcoding this as it most likely won't be used but is mandatory
|
|
597
620
|
)
|
|
598
|
-
|
|
621
|
+
)
|
|
622
|
+
)
|
|
623
|
+
)
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export function createDistributionInfo() {
|
|
627
|
+
return pipe(
|
|
628
|
+
createElement('gmd:distributionInfo'),
|
|
629
|
+
createChild('gmd:MD_Distribution')
|
|
630
|
+
)
|
|
631
|
+
}
|
|
599
632
|
|
|
600
|
-
|
|
633
|
+
// apply to MD_Distribution
|
|
634
|
+
export function appendDistribution(
|
|
635
|
+
distribution: DatasetDistribution,
|
|
636
|
+
appendFormatFn: (
|
|
637
|
+
mimeType: string
|
|
638
|
+
) => ChainableFunction<XmlElement, XmlElement>
|
|
639
|
+
) {
|
|
640
|
+
let name: string
|
|
641
|
+
let functionCode: string
|
|
642
|
+
let protocol: string
|
|
601
643
|
if (distribution.type === 'service') {
|
|
602
|
-
linkageUrl = distribution.url.toString()
|
|
603
644
|
name = distribution.identifierInService // this is for GeoNetwork to know the layer name
|
|
604
645
|
functionCode = 'download'
|
|
605
646
|
protocol = getDistributionProtocol(distribution)
|
|
606
647
|
} else if (distribution.type === 'download') {
|
|
607
|
-
linkageUrl = distribution.url.toString()
|
|
608
648
|
name = distribution.name
|
|
609
649
|
functionCode = 'download'
|
|
610
650
|
protocol = 'WWW:DOWNLOAD'
|
|
611
651
|
} else {
|
|
612
|
-
linkageUrl = distribution.url.toString()
|
|
613
652
|
name = distribution.name
|
|
614
653
|
functionCode = 'information'
|
|
615
654
|
protocol = 'WWW:LINK'
|
|
@@ -620,7 +659,7 @@ function createDistribution(distribution: DatasetDistribution) {
|
|
|
620
659
|
createChild('gmd:MD_DigitalTransferOptions'),
|
|
621
660
|
createChild('gmd:onLine'),
|
|
622
661
|
createChild('gmd:CI_OnlineResource'),
|
|
623
|
-
writeLinkage(
|
|
662
|
+
writeLinkage(distribution.url),
|
|
624
663
|
'description' in distribution
|
|
625
664
|
? appendChildren(
|
|
626
665
|
pipe(
|
|
@@ -649,9 +688,7 @@ function createDistribution(distribution: DatasetDistribution) {
|
|
|
649
688
|
)
|
|
650
689
|
)
|
|
651
690
|
return pipe(
|
|
652
|
-
|
|
653
|
-
createChild('gmd:MD_Distribution'),
|
|
654
|
-
appendDistributionFormat,
|
|
691
|
+
'mimeType' in distribution ? appendFormatFn(distribution.mimeType) : noop,
|
|
655
692
|
appendTransferOptions
|
|
656
693
|
)
|
|
657
694
|
}
|
|
@@ -660,7 +697,7 @@ function createDistribution(distribution: DatasetDistribution) {
|
|
|
660
697
|
* Looks for srv:SV_ServiceIdentification or gmd:MD_DataIdentification element
|
|
661
698
|
* depending on record type, create if missing
|
|
662
699
|
*/
|
|
663
|
-
function findOrCreateIdentification() {
|
|
700
|
+
export function findOrCreateIdentification() {
|
|
664
701
|
return (rootEl: XmlElement) => {
|
|
665
702
|
const kind = readKind(rootEl)
|
|
666
703
|
let eltName = 'gmd:MD_DataIdentification'
|
|
@@ -669,7 +706,7 @@ function findOrCreateIdentification() {
|
|
|
669
706
|
}
|
|
670
707
|
}
|
|
671
708
|
|
|
672
|
-
function findOrCreateDistribution() {
|
|
709
|
+
export function findOrCreateDistribution() {
|
|
673
710
|
return (rootEl: XmlElement) => {
|
|
674
711
|
return findNestedChildOrCreate(
|
|
675
712
|
'gmd:distributionInfo',
|
|
@@ -763,11 +800,26 @@ export function writeStatus(record: DatasetRecord, rootEl: XmlElement) {
|
|
|
763
800
|
}
|
|
764
801
|
|
|
765
802
|
export function writeContacts(record: CatalogRecord, rootEl: XmlElement) {
|
|
803
|
+
pipe(
|
|
804
|
+
removeChildrenByName('gmd:contact'),
|
|
805
|
+
appendChildren(
|
|
806
|
+
...record.contacts.map((contact) =>
|
|
807
|
+
pipe(createElement('gmd:contact'), appendResponsibleParty(contact))
|
|
808
|
+
)
|
|
809
|
+
)
|
|
810
|
+
)(rootEl)
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export function writeContactsForResource(
|
|
814
|
+
record: CatalogRecord,
|
|
815
|
+
rootEl: XmlElement
|
|
816
|
+
) {
|
|
766
817
|
pipe(
|
|
767
818
|
findOrCreateIdentification(),
|
|
768
819
|
removeChildrenByName('gmd:pointOfContact'),
|
|
820
|
+
removeChildrenByName('gmd:contact'),
|
|
769
821
|
appendChildren(
|
|
770
|
-
...record.
|
|
822
|
+
...record.contactsForResource.map((contact) =>
|
|
771
823
|
pipe(
|
|
772
824
|
createElement('gmd:pointOfContact'),
|
|
773
825
|
appendResponsibleParty(contact)
|
|
@@ -878,26 +930,47 @@ export function writeUpdateFrequency(
|
|
|
878
930
|
)(rootEl)
|
|
879
931
|
}
|
|
880
932
|
|
|
881
|
-
export function
|
|
882
|
-
|
|
933
|
+
export function writeResourceCreated(
|
|
934
|
+
record: DatasetRecord,
|
|
935
|
+
rootEl: XmlElement
|
|
936
|
+
) {
|
|
937
|
+
if (!('resourceCreated' in record)) return
|
|
883
938
|
pipe(
|
|
884
939
|
findOrCreateIdentification(),
|
|
885
940
|
findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'),
|
|
886
941
|
fallback(
|
|
887
|
-
updateCitationDate(record.
|
|
888
|
-
appendCitationDate(record.
|
|
942
|
+
updateCitationDate(record.resourceCreated, 'creation'),
|
|
943
|
+
appendCitationDate(record.resourceCreated, 'creation')
|
|
889
944
|
)
|
|
890
945
|
)(rootEl)
|
|
891
946
|
}
|
|
892
947
|
|
|
893
|
-
export function
|
|
894
|
-
|
|
948
|
+
export function writeResourceUpdated(
|
|
949
|
+
record: DatasetRecord,
|
|
950
|
+
rootEl: XmlElement
|
|
951
|
+
) {
|
|
952
|
+
if (!('resourceUpdated' in record)) return
|
|
895
953
|
pipe(
|
|
896
954
|
findOrCreateIdentification(),
|
|
897
955
|
findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'),
|
|
898
956
|
fallback(
|
|
899
|
-
updateCitationDate(record.
|
|
900
|
-
appendCitationDate(record.
|
|
957
|
+
updateCitationDate(record.resourceUpdated, 'revision'),
|
|
958
|
+
appendCitationDate(record.resourceUpdated, 'revision')
|
|
959
|
+
)
|
|
960
|
+
)(rootEl)
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
export function writeResourcePublished(
|
|
964
|
+
record: DatasetRecord,
|
|
965
|
+
rootEl: XmlElement
|
|
966
|
+
) {
|
|
967
|
+
if (!('resourcePublished' in record)) return
|
|
968
|
+
pipe(
|
|
969
|
+
findOrCreateIdentification(),
|
|
970
|
+
findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'),
|
|
971
|
+
fallback(
|
|
972
|
+
updateCitationDate(record.resourcePublished, 'publication'),
|
|
973
|
+
appendCitationDate(record.resourcePublished, 'publication')
|
|
901
974
|
)
|
|
902
975
|
)(rootEl)
|
|
903
976
|
}
|
|
@@ -955,7 +1028,14 @@ export function writeGraphicOverviews(
|
|
|
955
1028
|
export function writeDistributions(record: DatasetRecord, rootEl: XmlElement) {
|
|
956
1029
|
pipe(
|
|
957
1030
|
removeDistributions(),
|
|
958
|
-
appendChildren(
|
|
1031
|
+
appendChildren(
|
|
1032
|
+
...record.distributions.map((d) =>
|
|
1033
|
+
pipe(
|
|
1034
|
+
createDistributionInfo(),
|
|
1035
|
+
appendDistribution(d, appendDistributionFormat)
|
|
1036
|
+
)
|
|
1037
|
+
)
|
|
1038
|
+
)
|
|
959
1039
|
)(rootEl)
|
|
960
1040
|
}
|
|
961
1041
|
|
|
@@ -972,7 +1052,7 @@ export function writeLineage(record: DatasetRecord, rootEl: XmlElement) {
|
|
|
972
1052
|
)(rootEl)
|
|
973
1053
|
}
|
|
974
1054
|
|
|
975
|
-
function getServiceEndpointProtocol(endpoint: ServiceEndpoint): string {
|
|
1055
|
+
export function getServiceEndpointProtocol(endpoint: ServiceEndpoint): string {
|
|
976
1056
|
switch (endpoint.protocol.toLowerCase()) {
|
|
977
1057
|
case 'wfs':
|
|
978
1058
|
return 'OGC:WFS'
|
|
@@ -985,7 +1065,7 @@ function getServiceEndpointProtocol(endpoint: ServiceEndpoint): string {
|
|
|
985
1065
|
}
|
|
986
1066
|
}
|
|
987
1067
|
|
|
988
|
-
function createOnlineResource(onlineResource: ServiceOnlineResource) {
|
|
1068
|
+
export function createOnlineResource(onlineResource: ServiceOnlineResource) {
|
|
989
1069
|
let linkageUrl, functionCode, protocol
|
|
990
1070
|
if (onlineResource.type === 'endpoint') {
|
|
991
1071
|
linkageUrl = onlineResource.endpointUrl.toString()
|
|
@@ -33,6 +33,7 @@ export function createDocument(rootEl: XmlElement): XmlDocument {
|
|
|
33
33
|
function collectNamespaceFromName(name: string) {
|
|
34
34
|
const namespace = extractNamespace(name)
|
|
35
35
|
if (namespace === 'xmlns' || namespace === null) return
|
|
36
|
+
if (rootEl.attributes[`xmlns:${namespace}`]) return
|
|
36
37
|
if (!NAMESPACES[namespace]) {
|
|
37
38
|
throw new Error(`No known URI for namespace ${namespace}`)
|
|
38
39
|
}
|
|
@@ -55,11 +56,16 @@ export function createDocument(rootEl: XmlElement): XmlDocument {
|
|
|
55
56
|
/**
|
|
56
57
|
* Will do nothing if no namespace present
|
|
57
58
|
*/
|
|
58
|
-
function stripNamespace(name: string): string {
|
|
59
|
+
export function stripNamespace(name: string): string {
|
|
59
60
|
const colon = name.indexOf(':')
|
|
60
61
|
return colon > -1 ? name.substring(colon + 1) : name
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
export function getNamespace(name: string): string {
|
|
65
|
+
const colon = name.indexOf(':')
|
|
66
|
+
return colon > -1 ? name.substring(0, colon) : ''
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
function getElementName(element: XmlElement): string {
|
|
64
70
|
return element.name || ''
|
|
65
71
|
}
|
|
@@ -115,7 +121,7 @@ export function allChildrenElement(element: XmlElement): Array<XmlElement> {
|
|
|
115
121
|
* returns an empty array if no matching element
|
|
116
122
|
*/
|
|
117
123
|
export function findNestedElements(
|
|
118
|
-
...elementNames
|
|
124
|
+
...elementNames: string[]
|
|
119
125
|
): ChainableFunction<XmlElement, Array<XmlElement>> {
|
|
120
126
|
return (el) => {
|
|
121
127
|
function lookFor(elNameIndex: number) {
|
|
@@ -248,6 +254,29 @@ const NAMESPACES = {
|
|
|
248
254
|
gsr: 'http://www.isotc211.org/2005/gsr',
|
|
249
255
|
gmi: 'http://www.isotc211.org/2005/gmi',
|
|
250
256
|
xlink: 'http://www.w3.org/1999/xlink',
|
|
257
|
+
mdb: 'http://standards.iso.org/iso/19115/-3/mdb/2.0',
|
|
258
|
+
mdq: 'http://standards.iso.org/iso/19157/-2/mdq/1.0',
|
|
259
|
+
msr: 'http://standards.iso.org/iso/19115/-3/msr/2.0',
|
|
260
|
+
mrs: 'http://standards.iso.org/iso/19115/-3/mrs/1.0',
|
|
261
|
+
mmi: 'http://standards.iso.org/iso/19115/-3/mmi/1.0',
|
|
262
|
+
mrl: 'http://standards.iso.org/iso/19115/-3/mrl/2.0',
|
|
263
|
+
mdt: 'http://standards.iso.org/iso/19115/-3/mdt/2.0',
|
|
264
|
+
mrd: 'http://standards.iso.org/iso/19115/-3/mrd/1.0',
|
|
265
|
+
mds: 'http://standards.iso.org/iso/19115/-3/mds/2.0',
|
|
266
|
+
mpc: 'http://standards.iso.org/iso/19115/-3/mpc/1.0',
|
|
267
|
+
mcc: 'http://standards.iso.org/iso/19115/-3/mcc/1.0',
|
|
268
|
+
mac: 'http://standards.iso.org/iso/19115/-3/mac/2.0',
|
|
269
|
+
mco: 'http://standards.iso.org/iso/19115/-3/mco/1.0',
|
|
270
|
+
mda: 'http://standards.iso.org/iso/19115/-3/mda/1.0',
|
|
271
|
+
mex: 'http://standards.iso.org/iso/19115/-3/mex/1.0',
|
|
272
|
+
gex: 'http://standards.iso.org/iso/19115/-3/gex/1.0',
|
|
273
|
+
gcx: 'http://standards.iso.org/iso/19115/-3/gcx/1.0',
|
|
274
|
+
mas: 'http://standards.iso.org/iso/19115/-3/mas/1.0',
|
|
275
|
+
mri: 'http://standards.iso.org/iso/19115/-3/mri/1.0',
|
|
276
|
+
cit: 'http://standards.iso.org/iso/19115/-3/cit/2.0',
|
|
277
|
+
cat: 'http://standards.iso.org/iso/19115/-3/cat/1.0',
|
|
278
|
+
lan: 'http://standards.iso.org/iso/19115/-3/lan/1.0',
|
|
279
|
+
mrc: 'http://standards.iso.org/iso/19115/-3/mrc/2.0',
|
|
251
280
|
}
|
|
252
281
|
|
|
253
282
|
/**
|
|
@@ -268,6 +297,13 @@ export function addAttribute(
|
|
|
268
297
|
return element
|
|
269
298
|
}
|
|
270
299
|
}
|
|
300
|
+
function getTreeRoot(element: XmlElement): XmlElement {
|
|
301
|
+
let root = element
|
|
302
|
+
while (root.parent instanceof XmlElement) {
|
|
303
|
+
root = root.parent
|
|
304
|
+
}
|
|
305
|
+
return root
|
|
306
|
+
}
|
|
271
307
|
|
|
272
308
|
// stays on the parent element
|
|
273
309
|
// if the given elements are part of a subtree, will add the root of subtree
|
|
@@ -276,22 +312,26 @@ export function appendChildren(
|
|
|
276
312
|
): ChainableFunction<XmlElement, XmlElement> {
|
|
277
313
|
return (element) => {
|
|
278
314
|
if (!element) return null
|
|
279
|
-
element.children.push(
|
|
280
|
-
...childrenFns
|
|
281
|
-
.map((fn) => fn())
|
|
282
|
-
.map((el) => {
|
|
283
|
-
let root = el
|
|
284
|
-
while (root.parent instanceof XmlElement) {
|
|
285
|
-
root = root.parent
|
|
286
|
-
}
|
|
287
|
-
return root
|
|
288
|
-
})
|
|
289
|
-
)
|
|
315
|
+
element.children.push(...childrenFns.map((fn) => fn()).map(getTreeRoot))
|
|
290
316
|
element.children.forEach((el) => (el.parent = element))
|
|
291
317
|
return element
|
|
292
318
|
}
|
|
293
319
|
}
|
|
294
320
|
|
|
321
|
+
// switch to the tip of the subtree
|
|
322
|
+
export function appendChildTree(
|
|
323
|
+
childrenFn: ChainableFunction<void, XmlElement>
|
|
324
|
+
): ChainableFunction<XmlElement, XmlElement> {
|
|
325
|
+
return (element) => {
|
|
326
|
+
if (!element) return null
|
|
327
|
+
const treeTip = childrenFn()
|
|
328
|
+
const treeRoot = getTreeRoot(treeTip)
|
|
329
|
+
element.children.push(treeRoot)
|
|
330
|
+
treeRoot.parent = element
|
|
331
|
+
return treeTip
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
295
335
|
// switches to the child element
|
|
296
336
|
export function createChild(
|
|
297
337
|
childName: string
|
|
@@ -349,6 +389,7 @@ export function removeAllChildren(): ChainableFunction<XmlElement, XmlElement> {
|
|
|
349
389
|
}
|
|
350
390
|
}
|
|
351
391
|
|
|
392
|
+
// stays on the same element
|
|
352
393
|
export function removeChildrenByName(
|
|
353
394
|
name: string
|
|
354
395
|
): ChainableFunction<XmlElement, XmlElement> {
|
|
@@ -372,11 +413,38 @@ export function removeChildren(
|
|
|
372
413
|
childrenFn: ChainableFunction<XmlElement, Array<XmlElement>>
|
|
373
414
|
): ChainableFunction<XmlElement, XmlElement> {
|
|
374
415
|
return (element) => {
|
|
375
|
-
const
|
|
376
|
-
|
|
416
|
+
const childrenToRemove = childrenFn(element)
|
|
417
|
+
childrenToRemove.forEach((child) => (child.parent = null))
|
|
377
418
|
element.children = element.children.filter(
|
|
378
|
-
(child) =>
|
|
419
|
+
(child) =>
|
|
420
|
+
child instanceof XmlElement && childrenToRemove.indexOf(child) === -1
|
|
379
421
|
)
|
|
380
422
|
return element
|
|
381
423
|
}
|
|
382
424
|
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Renames elements in the XML tree according to the map
|
|
428
|
+
* Either specify a full element name like 'gmd:MD_Metadata' or simply a namespace like 'gmd'
|
|
429
|
+
* @param rootElement
|
|
430
|
+
* @param replaceMap
|
|
431
|
+
*/
|
|
432
|
+
export function renameElements(
|
|
433
|
+
rootElement: XmlElement,
|
|
434
|
+
replaceMap: Record<string, string>
|
|
435
|
+
) {
|
|
436
|
+
function doReplace(element: XmlElement) {
|
|
437
|
+
if (element.name in replaceMap) {
|
|
438
|
+
element.name = replaceMap[element.name]
|
|
439
|
+
} else if (element.name && getNamespace(element.name) in replaceMap) {
|
|
440
|
+
element.name = `${
|
|
441
|
+
replaceMap[getNamespace(element.name)]
|
|
442
|
+
}:${stripNamespace(element.name)}`
|
|
443
|
+
}
|
|
444
|
+
if (element.children) {
|
|
445
|
+
element.children.forEach(doReplace)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
doReplace(rootElement)
|
|
449
|
+
return rootElement
|
|
450
|
+
}
|