geonetwork-ui 2.3.0-dev.376e0e90 → 2.3.0-dev.f736344f

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.
Files changed (114) hide show
  1. package/esm2022/libs/api/metadata-converter/src/index.mjs +5 -5
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/atomic-operations.mjs +3 -3
  3. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +3 -3
  4. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.mjs +52 -0
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.mjs +14 -0
  6. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/role.mapper.mjs +48 -0
  7. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/status.mapper.mjs +18 -0
  8. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/update-frequency.mapper.mjs +64 -0
  9. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/converter.mjs +130 -0
  10. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +62 -58
  11. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +58 -75
  12. package/esm2022/libs/api/metadata-converter/src/lib/metadata-base.mapper.mjs +14 -0
  13. package/esm2022/libs/api/metadata-converter/src/lib/xml-utils.mjs +14 -76
  14. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +4 -4
  15. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  16. package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +8 -8
  17. package/fesm2022/geonetwork-ui.mjs +245 -822
  18. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  19. package/libs/api/metadata-converter/src/index.d.ts +4 -4
  20. package/libs/api/metadata-converter/src/index.d.ts.map +1 -1
  21. package/libs/api/metadata-converter/src/lib/gn4/{gn4.converter.d.ts → gn4.metadata.mapper.d.ts} +5 -5
  22. package/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.d.ts.map +1 -0
  23. package/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.d.ts.map +1 -0
  24. package/libs/api/metadata-converter/src/lib/iso19139/codelists/role.mapper.d.ts.map +1 -0
  25. package/libs/api/metadata-converter/src/lib/iso19139/codelists/status.mapper.d.ts.map +1 -0
  26. package/libs/api/metadata-converter/src/lib/iso19139/codelists/update-frequency.mapper.d.ts.map +1 -0
  27. package/libs/api/metadata-converter/src/lib/iso19139/converter.d.ts +4 -0
  28. package/libs/api/metadata-converter/src/lib/iso19139/converter.d.ts.map +1 -0
  29. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +6 -34
  30. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  31. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +3 -39
  32. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  33. package/libs/api/metadata-converter/src/lib/{base.converter.d.ts → metadata-base.mapper.d.ts} +3 -3
  34. package/libs/api/metadata-converter/src/lib/metadata-base.mapper.d.ts.map +1 -0
  35. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts +1 -14
  36. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts.map +1 -1
  37. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +2 -2
  38. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  39. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +4 -6
  40. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  41. package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/src/libs/api/metadata-converter/src/index.ts +4 -4
  44. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +5 -32
  45. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +4 -11
  46. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +7 -33
  47. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +2 -2
  48. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +2 -2
  49. package/src/libs/api/metadata-converter/src/lib/gn4/{gn4.converter.ts → gn4.metadata.mapper.ts} +2 -2
  50. package/src/libs/api/metadata-converter/src/lib/iso19139/converter.ts +196 -0
  51. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +82 -121
  52. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +95 -175
  53. package/src/libs/api/metadata-converter/src/lib/{base.converter.ts → metadata-base.mapper.ts} +2 -2
  54. package/src/libs/api/metadata-converter/src/lib/xml-utils.ts +16 -84
  55. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +2 -2
  56. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +4 -9
  57. package/src/libs/feature/editor/src/lib/services/editor.service.ts +16 -27
  58. package/esm2022/libs/api/metadata-converter/src/lib/base.converter.mjs +0 -14
  59. package/esm2022/libs/api/metadata-converter/src/lib/find-converter.mjs +0 -15
  60. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.converter.mjs +0 -52
  61. package/esm2022/libs/api/metadata-converter/src/lib/gn4/index.mjs +0 -4
  62. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/index.mjs +0 -2
  63. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.mjs +0 -123
  64. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.mjs +0 -116
  65. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.mjs +0 -138
  66. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/index.mjs +0 -2
  67. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +0 -242
  68. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.mjs +0 -18
  69. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.mjs +0 -14
  70. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/role.mapper.mjs +0 -48
  71. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.mjs +0 -18
  72. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.mjs +0 -64
  73. package/libs/api/metadata-converter/src/lib/base.converter.d.ts.map +0 -1
  74. package/libs/api/metadata-converter/src/lib/find-converter.d.ts +0 -3
  75. package/libs/api/metadata-converter/src/lib/find-converter.d.ts.map +0 -1
  76. package/libs/api/metadata-converter/src/lib/gn4/gn4.converter.d.ts.map +0 -1
  77. package/libs/api/metadata-converter/src/lib/gn4/index.d.ts +0 -4
  78. package/libs/api/metadata-converter/src/lib/gn4/index.d.ts.map +0 -1
  79. package/libs/api/metadata-converter/src/lib/iso19115-3/index.d.ts +0 -2
  80. package/libs/api/metadata-converter/src/lib/iso19115-3/index.d.ts.map +0 -1
  81. package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts +0 -9
  82. package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts.map +0 -1
  83. package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts +0 -20
  84. package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts.map +0 -1
  85. package/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.d.ts +0 -21
  86. package/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.d.ts.map +0 -1
  87. package/libs/api/metadata-converter/src/lib/iso19139/index.d.ts +0 -2
  88. package/libs/api/metadata-converter/src/lib/iso19139/index.d.ts.map +0 -1
  89. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts +0 -11
  90. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +0 -1
  91. package/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.d.ts +0 -8
  92. package/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.d.ts.map +0 -1
  93. package/libs/api/metadata-converter/src/lib/iso19139/utils/keyword.mapper.d.ts.map +0 -1
  94. package/libs/api/metadata-converter/src/lib/iso19139/utils/role.mapper.d.ts.map +0 -1
  95. package/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.d.ts.map +0 -1
  96. package/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.d.ts.map +0 -1
  97. package/src/libs/api/metadata-converter/src/lib/find-converter.ts +0 -16
  98. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +0 -580
  99. package/src/libs/api/metadata-converter/src/lib/gn4/index.ts +0 -3
  100. package/src/libs/api/metadata-converter/src/lib/iso19115-3/index.ts +0 -1
  101. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +0 -176
  102. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +0 -329
  103. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +0 -513
  104. package/src/libs/api/metadata-converter/src/lib/iso19139/index.ts +0 -1
  105. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +0 -327
  106. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/individual-name.ts +0 -20
  107. /package/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/keyword.mapper.d.ts +0 -0
  108. /package/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/role.mapper.d.ts +0 -0
  109. /package/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/status.mapper.d.ts +0 -0
  110. /package/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/update-frequency.mapper.d.ts +0 -0
  111. /package/src/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/keyword.mapper.ts +0 -0
  112. /package/src/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/role.mapper.ts +0 -0
  113. /package/src/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/status.mapper.ts +0 -0
  114. /package/src/libs/api/metadata-converter/src/lib/iso19139/{utils → codelists}/update-frequency.mapper.ts +0 -0
@@ -162,8 +162,6 @@ function createDocument(rootEl) {
162
162
  const namespace = extractNamespace(name);
163
163
  if (namespace === 'xmlns' || namespace === null)
164
164
  return;
165
- if (rootEl.attributes[`xmlns:${namespace}`])
166
- return;
167
165
  if (!NAMESPACES[namespace]) {
168
166
  throw new Error(`No known URI for namespace ${namespace}`);
169
167
  }
@@ -187,10 +185,6 @@ function stripNamespace(name) {
187
185
  const colon = name.indexOf(':');
188
186
  return colon > -1 ? name.substring(colon + 1) : name;
189
187
  }
190
- function getNamespace(name) {
191
- const colon = name.indexOf(':');
192
- return colon > -1 ? name.substring(0, colon) : '';
193
- }
194
188
  function getElementName(element) {
195
189
  return element.name || '';
196
190
  }
@@ -342,29 +336,6 @@ const NAMESPACES = {
342
336
  gsr: 'http://www.isotc211.org/2005/gsr',
343
337
  gmi: 'http://www.isotc211.org/2005/gmi',
344
338
  xlink: 'http://www.w3.org/1999/xlink',
345
- mdb: 'http://standards.iso.org/iso/19115/-3/mdb/2.0',
346
- mdq: 'http://standards.iso.org/iso/19157/-2/mdq/1.0',
347
- msr: 'http://standards.iso.org/iso/19115/-3/msr/2.0',
348
- mrs: 'http://standards.iso.org/iso/19115/-3/mrs/1.0',
349
- mmi: 'http://standards.iso.org/iso/19115/-3/mmi/1.0',
350
- mrl: 'http://standards.iso.org/iso/19115/-3/mrl/2.0',
351
- mdt: 'http://standards.iso.org/iso/19115/-3/mdt/2.0',
352
- mrd: 'http://standards.iso.org/iso/19115/-3/mrd/1.0',
353
- mds: 'http://standards.iso.org/iso/19115/-3/mds/2.0',
354
- mpc: 'http://standards.iso.org/iso/19115/-3/mpc/1.0',
355
- mcc: 'http://standards.iso.org/iso/19115/-3/mcc/1.0',
356
- mac: 'http://standards.iso.org/iso/19115/-3/mac/2.0',
357
- mco: 'http://standards.iso.org/iso/19115/-3/mco/1.0',
358
- mda: 'http://standards.iso.org/iso/19115/-3/mda/1.0',
359
- mex: 'http://standards.iso.org/iso/19115/-3/mex/1.0',
360
- gex: 'http://standards.iso.org/iso/19115/-3/gex/1.0',
361
- gcx: 'http://standards.iso.org/iso/19115/-3/gcx/1.0',
362
- mas: 'http://standards.iso.org/iso/19115/-3/mas/1.0',
363
- mri: 'http://standards.iso.org/iso/19115/-3/mri/1.0',
364
- cit: 'http://standards.iso.org/iso/19115/-3/cit/2.0',
365
- cat: 'http://standards.iso.org/iso/19115/-3/cat/1.0',
366
- lan: 'http://standards.iso.org/iso/19115/-3/lan/1.0',
367
- mrc: 'http://standards.iso.org/iso/19115/-3/mrc/2.0',
368
339
  };
369
340
  /**
370
341
  * @param name Full name with namespace, e.g.: gmd:MD_Metadata
@@ -378,36 +349,25 @@ function addAttribute(name, value) {
378
349
  return element;
379
350
  };
380
351
  }
381
- function getTreeRoot(element) {
382
- let root = element;
383
- while (root.parent instanceof XmlElement) {
384
- root = root.parent;
385
- }
386
- return root;
387
- }
388
352
  // stays on the parent element
389
353
  // if the given elements are part of a subtree, will add the root of subtree
390
354
  function appendChildren(...childrenFns) {
391
355
  return (element) => {
392
356
  if (!element)
393
357
  return null;
394
- element.children.push(...childrenFns.map((fn) => fn()).map(getTreeRoot));
358
+ element.children.push(...childrenFns
359
+ .map((fn) => fn())
360
+ .map((el) => {
361
+ let root = el;
362
+ while (root.parent instanceof XmlElement) {
363
+ root = root.parent;
364
+ }
365
+ return root;
366
+ }));
395
367
  element.children.forEach((el) => (el.parent = element));
396
368
  return element;
397
369
  };
398
370
  }
399
- // switch to the tip of the subtree
400
- function appendChildTree(childrenFn) {
401
- return (element) => {
402
- if (!element)
403
- return null;
404
- const treeTip = childrenFn();
405
- const treeRoot = getTreeRoot(treeTip);
406
- element.children.push(treeRoot);
407
- treeRoot.parent = element;
408
- return treeTip;
409
- };
410
- }
411
371
  // switches to the child element
412
372
  function createChild(childName) {
413
373
  return (element) => {
@@ -454,7 +414,6 @@ function removeAllChildren() {
454
414
  return element;
455
415
  };
456
416
  }
457
- // stays on the same element
458
417
  function removeChildrenByName(name) {
459
418
  return (element) => {
460
419
  if (!element)
@@ -469,33 +428,12 @@ function removeChildrenByName(name) {
469
428
  }
470
429
  function removeChildren(childrenFn) {
471
430
  return (element) => {
472
- const childrenToRemove = childrenFn(element);
473
- childrenToRemove.forEach((child) => (child.parent = null));
474
- element.children = element.children.filter((child) => child instanceof XmlElement && childrenToRemove.indexOf(child) === -1);
431
+ const children = childrenFn(element);
432
+ children.forEach((child) => (child.parent = null));
433
+ element.children = element.children.filter((child) => child instanceof XmlElement && children.indexOf(child) === -1);
475
434
  return element;
476
435
  };
477
436
  }
478
- /**
479
- * Renames elements in the XML tree according to the map
480
- * Either specify a full element name like 'gmd:MD_Metadata' or simply a namespace like 'gmd'
481
- * @param rootElement
482
- * @param replaceMap
483
- */
484
- function renameElements(rootElement, replaceMap) {
485
- function doReplace(element) {
486
- if (element.name in replaceMap) {
487
- element.name = replaceMap[element.name];
488
- }
489
- else if (element.name && getNamespace(element.name) in replaceMap) {
490
- element.name = `${replaceMap[getNamespace(element.name)]}:${stripNamespace(element.name)}`;
491
- }
492
- if (element.children) {
493
- element.children.forEach(doReplace);
494
- }
495
- }
496
- doReplace(rootElement);
497
- return rootElement;
498
- }
499
437
 
500
438
  function getStatusFromStatusCode(statusCode) {
501
439
  switch (statusCode) {
@@ -663,24 +601,6 @@ function getKeywordTypeFromKeywordTypeCode(typeCode) {
663
601
  }
664
602
  }
665
603
 
666
- /**
667
- * Parts are [firstName, lastName]
668
- * Second part will be null if no separation could be done
669
- * @param fullName
670
- */
671
- function fullNameToParts(fullName) {
672
- const parts = fullName.trim().split(/\s+/);
673
- const first = parts.shift();
674
- return [first, parts.join(' ').trim() || null];
675
- }
676
- function namePartsToFull(firstName, lastName) {
677
- const first = firstName?.trim();
678
- const last = lastName?.trim();
679
- if (!first && !last)
680
- return null;
681
- return last && first ? `${first} ${last}` : last || first;
682
- }
683
-
684
604
  function extractCharacterString() {
685
605
  return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false)), readText());
686
606
  }
@@ -708,7 +628,7 @@ function extractRole() {
708
628
  return pipe(findChildElement('gmd:CI_RoleCode'), readAttribute('codeListValue'), map(getRoleFromRoleCode));
709
629
  }
710
630
  // from gmd:CI_ResponsibleParty
711
- function extractOrganization$1() {
631
+ function extractOrganization() {
712
632
  const getUrl = pipe(findNestedElements('gmd:contactInfo', 'gmd:CI_Contact', 'gmd:onlineResource', 'gmd:CI_OnlineResource', 'gmd:linkage'), getAtIndex(0), extractUrl());
713
633
  return pipe(combine(pipe(findChildElement('gmd:organisationName', false), extractCharacterString()), getUrl), map(([name, website]) => ({
714
634
  name,
@@ -716,29 +636,28 @@ function extractOrganization$1() {
716
636
  })));
717
637
  }
718
638
  // from gmd:CI_ResponsibleParty
719
- function extractIndividual$1() {
639
+ function extractIndividuals() {
720
640
  const getRole = pipe(findChildElement('gmd:role'), extractRole());
721
641
  const getPosition = pipe(findChildElement('gmd:positionName'), extractCharacterString());
722
642
  const getNameParts = pipe(findChildElement('gmd:individualName'), extractCharacterString(), map((fullName) => {
723
643
  if (!fullName)
724
644
  return [];
725
- return fullNameToParts(fullName);
645
+ const parts = fullName.split(/\s+/);
646
+ if (!parts.length)
647
+ return [fullName, null];
648
+ const first = parts.shift();
649
+ return [first, parts.join(' ')];
726
650
  }));
727
- const getOrganization = extractOrganization$1();
728
- const getContactRoot = findNestedElement('gmd:contactInfo', 'gmd:CI_Contact');
729
- const getEmail = pipe(getContactRoot, findChildElement('gmd:electronicMailAddress'), extractCharacterString(), map((email) => (email === null ? 'missing@missing.com' : email)));
730
- const getAddress = pipe(getContactRoot, findNestedElement('gmd:address', 'gmd:CI_Address'), combine(pipe(findChildElement('gmd:deliveryPoint', false), extractCharacterString()), pipe(findChildElement('gmd:city', false), extractCharacterString()), pipe(findChildElement('gmd:postalCode', false), extractCharacterString()), pipe(findChildElement('gmd:country', false), extractCharacterString())), map((parts) => parts.filter((p) => !!p).join(', ')));
731
- const getPhone = pipe(getContactRoot, findNestedElement('gmd:phone', 'gmd:CI_Telephone', 'gmd:voice'), extractCharacterString());
732
- return pipe(combine(getRole, getPosition, getNameParts, getOrganization, getEmail, getAddress, getPhone), map(([role, position, [firstName, lastName], organization, email, address, phone,]) => ({
651
+ const getOrganization = extractOrganization();
652
+ const getEmail = pipe(findChildElement('gmd:electronicMailAddress'), extractCharacterString(), map((email) => (email === null ? 'missing@missing.com' : email)));
653
+ return pipe(combine(getRole, getPosition, getNameParts, getOrganization, pipe(findChildrenElement('gmd:contactInfo'), mapArray(getEmail))), map(([role, position, [firstName, lastName], organization, emails]) => emails.map((email) => ({
733
654
  email,
734
655
  role,
735
656
  organization,
736
657
  ...(position && { position }),
737
658
  ...(firstName && { firstName }),
738
659
  ...(lastName && { lastName }),
739
- ...(address && { address }),
740
- ...(phone && { phone }),
741
- })));
660
+ }))));
742
661
  }
743
662
  function extractStatus() {
744
663
  return pipe(findChildElement('gmd:MD_ProgressCode'), readAttribute('codeListValue'), map(getStatusFromStatusCode));
@@ -771,12 +690,9 @@ function extractLicenses() {
771
690
  text,
772
691
  })));
773
692
  }
774
- const getMimeType$1 = pipe(findParent('gmd:MD_Distribution'), findNestedElement('gmd:distributionFormat', 'gmd:MD_Format', 'gmd:name'), extractCharacterString(), map(matchMimeType));
775
- /**
776
- * Extract distributions from a MD_Distribution element
777
- * @param getMimeTypeFn This function starts from a gmd:transferOptions element
778
- */
779
- function extractDatasetDistributions(getMimeTypeFn) {
693
+ // from gmd:MD_Distribution
694
+ function extractDatasetDistributions() {
695
+ const getFormat = pipe(findParent('gmd:MD_Distribution'), findNestedElement('gmd:distributionFormat', 'gmd:MD_Format', 'gmd:name'), extractCharacterString(), map(matchMimeType));
780
696
  const getUrl = pipe(findChildElement('gmd:linkage'), extractMandatoryUrl());
781
697
  const getProtocolStr = pipe(findChildElement('gmd:protocol'), extractCharacterString());
782
698
  const getProtocol = pipe(getProtocolStr, map(matchProtocol));
@@ -786,7 +702,7 @@ function extractDatasetDistributions(getMimeTypeFn) {
786
702
  /download/i.test(protocolStr)));
787
703
  const getName = pipe(findChildElement('gmd:name'), extractCharacterString());
788
704
  const getDescription = pipe(findChildElement('gmd:description'), extractCharacterString());
789
- return pipe(findNestedElements('gmd:transferOptions', 'gmd:MD_DigitalTransferOptions', 'gmd:onLine', 'gmd:CI_OnlineResource'), mapArray(combine(getIsService, getIsDownload, getProtocol, getUrl, getName, getDescription, getMimeTypeFn)), mapArray(([isService, isDownload, protocol, url, name, description, mimeType]) => {
705
+ return pipe(findNestedElements('gmd:transferOptions', 'gmd:MD_DigitalTransferOptions', 'gmd:onLine', 'gmd:CI_OnlineResource'), mapArray(combine(getIsService, getIsDownload, getProtocol, getUrl, getName, getDescription, getFormat)), mapArray(([isService, isDownload, protocol, url, name, description, format]) => {
790
706
  if (isService) {
791
707
  const hasIdentifier = protocol === 'wms' || protocol === 'wfs';
792
708
  return {
@@ -799,6 +715,7 @@ function extractDatasetDistributions(getMimeTypeFn) {
799
715
  };
800
716
  }
801
717
  else if (isDownload) {
718
+ const mimeType = format;
802
719
  return {
803
720
  type: 'download',
804
721
  url: url,
@@ -877,13 +794,18 @@ function extractUpdateFrequency() {
877
794
  }
878
795
  /**
879
796
  * Looks for srv:SV_ServiceIdentification or gmd:MD_DataIdentification element
880
- * Will find the first one that exists, not reading the type of the record
881
- * (this allows using this function in other similar schemas)
797
+ * depending on record type
882
798
  */
883
799
  function findIdentification() {
884
- return pipe(findChildElement('gmd:identificationInfo', false), combine(findChildElement('gmd:MD_DataIdentification', false), findChildElement('srv:SV_ServiceIdentification', false)), filterArray((el) => el !== null), getAtIndex(0));
800
+ return (rootEl) => {
801
+ const kind = readKind(rootEl);
802
+ let eltName = 'gmd:MD_DataIdentification';
803
+ if (kind === 'service')
804
+ eltName = 'srv:SV_ServiceIdentification';
805
+ return findNestedElement('gmd:identificationInfo', eltName)(rootEl);
806
+ };
885
807
  }
886
- function extractIdentificationDate(type) {
808
+ function extractCitationDate(type) {
887
809
  return pipe(findIdentification(), findNestedElements('gmd:citation', 'gmd:CI_Citation', 'gmd:date'), filterArray(pipe(findNestedElements('gmd:CI_Date', 'gmd:dateType', 'gmd:CI_DateTypeCode'), getAtIndex(0), readAttribute('codeListValue'), map((value) => value === type))), getAtIndex(0), findNestedElements('gmd:CI_Date', 'gmd:date'), getAtIndex(0), extractDateTime());
888
810
  }
889
811
  function getSpatialRepresentationFromCode(spatialRepresentationCode) {
@@ -898,25 +820,19 @@ function getSpatialRepresentationFromCode(spatialRepresentationCode) {
898
820
  return null;
899
821
  }
900
822
  }
901
- function readUniqueIdentifier$1(rootEl) {
823
+ function readUniqueIdentifier(rootEl) {
902
824
  return pipe(findChildElement('gmd:fileIdentifier', false), extractCharacterString())(rootEl);
903
825
  }
904
- function readKind$1(rootEl) {
826
+ function readKind(rootEl) {
905
827
  return pipe(findNestedElement('gmd:hierarchyLevel', 'gmd:MD_ScopeCode'), readAttribute('codeListValue'), map((scopeCode) => scopeCode === 'service' ? 'service' : 'dataset'))(rootEl);
906
828
  }
907
- function readOwnerOrganization$1(rootEl) {
908
- return pipe(findNestedElement('gmd:contact', 'gmd:CI_ResponsibleParty'), extractOrganization$1())(rootEl);
909
- }
910
- function readResourceUpdated(rootEl) {
911
- return extractIdentificationDate('revision')(rootEl);
912
- }
913
- function readResourceCreated(rootEl) {
914
- return extractIdentificationDate('creation')(rootEl);
829
+ function readOwnerOrganization(rootEl) {
830
+ return pipe(findNestedElement('gmd:contact', 'gmd:CI_ResponsibleParty'), extractOrganization())(rootEl);
915
831
  }
916
- function readResourcePublished(rootEl) {
917
- return extractIdentificationDate('publication')(rootEl);
832
+ function readRecordUpdated(rootEl) {
833
+ return pipe(findChildElement('gmd:dateStamp'), extractDateTime())(rootEl);
918
834
  }
919
- function readRecordUpdated$1(rootEl) {
835
+ function readRecordPublished(rootEl) {
920
836
  return pipe(findChildElement('gmd:dateStamp'), extractDateTime())(rootEl);
921
837
  }
922
838
  function readTitle(rootEl) {
@@ -925,11 +841,14 @@ function readTitle(rootEl) {
925
841
  function readAbstract(rootEl) {
926
842
  return pipe(findIdentification(), findChildElement('gmd:abstract', false), extractCharacterString())(rootEl);
927
843
  }
928
- function readContacts$1(rootEl) {
929
- return pipe(findChildrenElement('gmd:contact', false), mapArray(findChildElement('gmd:CI_ResponsibleParty', false)), mapArray(extractIndividual$1()))(rootEl);
844
+ function readDatasetCreated(rootEl) {
845
+ return extractCitationDate('creation')(rootEl);
930
846
  }
931
- function readContactsForResource(rootEl) {
932
- return pipe(findIdentification(), combine(findChildrenElement('gmd:contact', false), findChildrenElement('gmd:pointOfContact', false)), flattenArray(), mapArray(findChildElement('gmd:CI_ResponsibleParty', false)), mapArray(extractIndividual$1()))(rootEl);
847
+ function readDatasetUpdated(rootEl) {
848
+ return extractCitationDate('revision')(rootEl);
849
+ }
850
+ function readContacts(rootEl) {
851
+ return pipe(findIdentification(), combine(findChildrenElement('gmd:contact'), findChildrenElement('gmd:pointOfContact')), flattenArray(), mapArray(findChildElement('gmd:CI_ResponsibleParty', false)), mapArray(extractIndividuals()), flattenArray())(rootEl);
933
852
  }
934
853
  // from gmd:thesaurusName
935
854
  function readThesaurus(rootEl) {
@@ -990,11 +909,17 @@ function readOverviews(rootEl) {
990
909
  ...(description && { description }),
991
910
  })))(rootEl);
992
911
  }
993
- function readLineage$1(rootEl) {
912
+ function readSpatialExtents(rootEl) {
913
+ return []; // TODO
914
+ }
915
+ function readTemporalExtents(rootEl) {
916
+ return []; // TODO
917
+ }
918
+ function readLineage(rootEl) {
994
919
  return pipe(findNestedElement('gmd:dataQualityInfo', 'gmd:DQ_DataQuality', 'gmd:lineage', 'gmd:LI_Lineage', 'gmd:statement'), extractCharacterString())(rootEl);
995
920
  }
996
- function readDistributions$1(rootEl) {
997
- return pipe(findNestedElements('gmd:distributionInfo', 'gmd:MD_Distribution'), mapArray(extractDatasetDistributions(getMimeType$1)), flattenArray())(rootEl);
921
+ function readDistributions(rootEl) {
922
+ return pipe(findNestedElements('gmd:distributionInfo', 'gmd:MD_Distribution'), mapArray(extractDatasetDistributions()), flattenArray())(rootEl);
998
923
  }
999
924
  function readUpdateFrequency(rootEl) {
1000
925
  return pipe(findIdentification(), findNestedElement('gmd:resourceMaintenance', 'gmd:MD_MaintenanceInformation'), extractUpdateFrequency(), map((updateFrequency) => updateFrequency || 'unknown'))(rootEl);
@@ -1171,21 +1096,17 @@ function getISODuration(updateFrequency) {
1171
1096
  const hours = duration.hours > 0 ? `T${duration.hours}H` : '';
1172
1097
  return `P${duration.years}Y${duration.months}M${duration.days}D${hours}`;
1173
1098
  }
1174
- function appendResponsibleParty$1(contact) {
1175
- const fullName = namePartsToFull(contact.firstName, contact.lastName);
1176
- const createAddress = pipe(createElement('gmd:address'), createChild('gmd:CI_Address'), appendChildren(pipe(createElement('gmd:electronicMailAddress'), writeCharacterString(contact.email))), contact.address
1177
- ? appendChildren(pipe(createElement('gmd:deliveryPoint'), writeCharacterString(contact.address)))
1178
- : noop);
1179
- const createContact = pipe(createElement('gmd:contactInfo'), createChild('gmd:CI_Contact'), contact.phone
1180
- ? appendChildren(pipe(createElement('gmd:phone'), createChild('gmd:CI_Telephone'), createChild('gmd:voice'), writeCharacterString(contact.phone)))
1181
- : noop, appendChildren(createAddress), 'website' in contact.organization
1182
- ? appendChildren(pipe(createElement('gmd:onlineResource'), createChild('gmd:CI_OnlineResource'), writeLinkage(contact.organization.website)))
1183
- : noop);
1184
- return appendChildren(pipe(createElement('gmd:CI_ResponsibleParty'), fullName
1185
- ? appendChildren(pipe(createElement('gmd:individualName'), writeCharacterString(fullName)))
1099
+ function appendResponsibleParty(contact) {
1100
+ const name = contact.lastName && contact.firstName
1101
+ ? `${contact.firstName} ${contact.lastName}`
1102
+ : contact.lastName || contact.firstName || null;
1103
+ return appendChildren(pipe(createElement('gmd:CI_ResponsibleParty'), name
1104
+ ? appendChildren(pipe(createElement('gmd:individualName'), writeCharacterString(name)))
1186
1105
  : noop, contact.position
1187
1106
  ? appendChildren(pipe(createElement('gmd:positionName'), writeCharacterString(contact.position)))
1188
- : noop, appendChildren(pipe(createElement('gmd:organisationName'), writeCharacterString(contact.organization.name)), createContact, pipe(createElement('gmd:role'), createChild('gmd:CI_RoleCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_RoleCode'), addAttribute('codeListValue', getRoleCode(contact.role))))));
1107
+ : noop, appendChildren(pipe(createElement('gmd:organisationName'), writeCharacterString(contact.organization.name)), pipe(createElement('gmd:contactInfo'), createChild('gmd:CI_Contact'), appendChildren(pipe(createElement('gmd:address'), createChild('gmd:CI_Address'), createChild('gmd:electronicMailAddress'), writeCharacterString(contact.email))), 'website' in contact.organization
1108
+ ? appendChildren(pipe(createElement('gmd:onlineResource'), createChild('gmd:CI_OnlineResource'), writeLinkage(contact.organization.website)))
1109
+ : noop), pipe(createElement('gmd:role'), createChild('gmd:CI_RoleCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_RoleCode'), addAttribute('codeListValue', getRoleCode(contact.role))))));
1189
1110
  }
1190
1111
  function updateCitationDate(date, type) {
1191
1112
  return pipe(findNestedElements('gmd:date', 'gmd:CI_Date'), filterArray(pipe(findChildElement('gmd:CI_DateTypeCode'), readAttribute('codeListValue'), map((value) => value === type))), getAtIndex(0), findChildElement('gmd:date'), removeAllChildren(), writeDateTime(date));
@@ -1203,13 +1124,12 @@ function createThesaurus(thesaurus) {
1203
1124
  : writeCharacterString(thesaurus.id))))));
1204
1125
  }
1205
1126
  function appendKeywords(keywords) {
1206
- // keywords are grouped by thesaurus if they have one, otherwise by type
1207
1127
  const keywordsByThesaurus = keywords.reduce((acc, keyword) => {
1208
1128
  const thesaurusId = keyword.thesaurus?.id;
1209
1129
  const type = keyword.type;
1210
- let existingGroup = acc.find((group) => thesaurusId
1211
- ? group[0].thesaurus?.id === thesaurusId
1212
- : group[0].type === type && !group[0].thesaurus);
1130
+ let existingGroup = acc.find((group) => group[0].thesaurus
1131
+ ? group[0].thesaurus.id === thesaurusId
1132
+ : group[0].type === type);
1213
1133
  if (!existingGroup) {
1214
1134
  existingGroup = [];
1215
1135
  acc.push(existingGroup);
@@ -1250,39 +1170,36 @@ function createLicense(license) {
1250
1170
  function removeDistributions() {
1251
1171
  return pipe(removeChildrenByName('gmd:distributionInfo'));
1252
1172
  }
1253
- function appendDistributionFormat$1(mimeType) {
1254
- return appendChildren(pipe(createElement('gmd:distributionFormat'), createChild('gmd:MD_Format'), appendChildren(pipe(createElement('gmd:name'), writeCharacterString(mimeType)), pipe(createElement('gmd:version'), writeCharacterString('1.0') // hardcoding this as it most likely won't be used but is mandatory
1255
- ))));
1256
- }
1257
- function createDistributionInfo() {
1258
- return pipe(createElement('gmd:distributionInfo'), createChild('gmd:MD_Distribution'));
1259
- }
1260
- // apply to MD_Distribution
1261
- function appendDistribution(distribution, appendFormatFn) {
1262
- let name;
1263
- let functionCode;
1264
- let protocol;
1173
+ function createDistribution(distribution) {
1174
+ const appendDistributionFormat = 'mimeType' in distribution
1175
+ ? appendChildren(pipe(createElement('gmd:distributionFormat'), createChild('gmd:MD_Format'), appendChildren(pipe(createElement('gmd:name'), writeCharacterString(distribution.mimeType)), pipe(createElement('gmd:version'), writeCharacterString('1.0') // hardcoding this as it most likely won't be used but is mandatory
1176
+ ))))
1177
+ : noop;
1178
+ let linkageUrl, name, functionCode, protocol;
1265
1179
  if (distribution.type === 'service') {
1180
+ linkageUrl = distribution.url.toString();
1266
1181
  name = distribution.identifierInService; // this is for GeoNetwork to know the layer name
1267
1182
  functionCode = 'download';
1268
1183
  protocol = getDistributionProtocol(distribution);
1269
1184
  }
1270
1185
  else if (distribution.type === 'download') {
1186
+ linkageUrl = distribution.url.toString();
1271
1187
  name = distribution.name;
1272
1188
  functionCode = 'download';
1273
1189
  protocol = 'WWW:DOWNLOAD';
1274
1190
  }
1275
1191
  else {
1192
+ linkageUrl = distribution.url.toString();
1276
1193
  name = distribution.name;
1277
1194
  functionCode = 'information';
1278
1195
  protocol = 'WWW:LINK';
1279
1196
  }
1280
- const appendTransferOptions = appendChildren(pipe(createElement('gmd:transferOptions'), createChild('gmd:MD_DigitalTransferOptions'), createChild('gmd:onLine'), createChild('gmd:CI_OnlineResource'), writeLinkage(distribution.url), 'description' in distribution
1197
+ const appendTransferOptions = appendChildren(pipe(createElement('gmd:transferOptions'), createChild('gmd:MD_DigitalTransferOptions'), createChild('gmd:onLine'), createChild('gmd:CI_OnlineResource'), writeLinkage(linkageUrl), 'description' in distribution
1281
1198
  ? appendChildren(pipe(createElement('gmd:description'), writeCharacterString(distribution.description)))
1282
1199
  : noop, name !== undefined
1283
1200
  ? appendChildren(pipe(createElement('gmd:name'), writeCharacterString(name)))
1284
1201
  : noop, appendChildren(pipe(createElement('gmd:protocol'), writeCharacterString(protocol)), pipe(createElement('gmd:function'), createChild('gmd:CI_OnLineFunctionCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_OnLineFunctionCode'), addAttribute('codeListValue', functionCode)))));
1285
- return pipe('mimeType' in distribution ? appendFormatFn(distribution.mimeType) : noop, appendTransferOptions);
1202
+ return pipe(createElement('gmd:distributionInfo'), createChild('gmd:MD_Distribution'), appendDistributionFormat, appendTransferOptions);
1286
1203
  }
1287
1204
  /**
1288
1205
  * Looks for srv:SV_ServiceIdentification or gmd:MD_DataIdentification element
@@ -1290,7 +1207,7 @@ function appendDistribution(distribution, appendFormatFn) {
1290
1207
  */
1291
1208
  function findOrCreateIdentification() {
1292
1209
  return (rootEl) => {
1293
- const kind = readKind$1(rootEl);
1210
+ const kind = readKind(rootEl);
1294
1211
  let eltName = 'gmd:MD_DataIdentification';
1295
1212
  if (kind === 'service')
1296
1213
  eltName = 'srv:SV_ServiceIdentification';
@@ -1302,16 +1219,16 @@ function findOrCreateDistribution() {
1302
1219
  return findNestedChildOrCreate('gmd:distributionInfo', 'gmd:MD_Distribution')(rootEl);
1303
1220
  };
1304
1221
  }
1305
- function writeUniqueIdentifier$1(record, rootEl) {
1222
+ function writeUniqueIdentifier(record, rootEl) {
1306
1223
  pipe(findChildOrCreate('gmd:fileIdentifier'), writeCharacterString(record.uniqueIdentifier))(rootEl);
1307
1224
  }
1308
- function writeKind$1(record, rootEl) {
1225
+ function writeKind(record, rootEl) {
1309
1226
  pipe(findNestedChildOrCreate('gmd:hierarchyLevel', 'gmd:MD_ScopeCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_ScopeCode'), addAttribute('codeListValue', record.kind))(rootEl);
1310
1227
  }
1311
- function writeOwnerOrganization$1(record, rootEl) {
1228
+ function writeOwnerOrganization(record, rootEl) {
1312
1229
  // if no contact matches the owner org, create an empty one
1313
1230
  const ownerContact = record.contacts.find((contact) => contact.organization.name === record.ownerOrganization.name);
1314
- pipe(findChildOrCreate('gmd:contact'), removeAllChildren(), appendResponsibleParty$1(ownerContact
1231
+ pipe(findChildOrCreate('gmd:contact'), removeAllChildren(), appendResponsibleParty(ownerContact
1315
1232
  ? {
1316
1233
  ...ownerContact,
1317
1234
  // owner responsible party is always point of contact
@@ -1323,7 +1240,7 @@ function writeOwnerOrganization$1(record, rootEl) {
1323
1240
  role: 'point_of_contact',
1324
1241
  }))(rootEl);
1325
1242
  }
1326
- function writeRecordUpdated$1(record, rootEl) {
1243
+ function writeRecordUpdated(record, rootEl) {
1327
1244
  pipe(findChildOrCreate('gmd:dateStamp'), removeAllChildren(), writeDateTime(record.recordUpdated))(rootEl);
1328
1245
  }
1329
1246
  function writeTitle(record, rootEl) {
@@ -1332,16 +1249,13 @@ function writeTitle(record, rootEl) {
1332
1249
  function writeAbstract(record, rootEl) {
1333
1250
  pipe(findOrCreateIdentification(), findChildOrCreate('gmd:abstract'), writeCharacterString(record.abstract))(rootEl);
1334
1251
  }
1335
- function writeStatus$1(record, rootEl) {
1252
+ function writeStatus(record, rootEl) {
1336
1253
  pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:status', 'gmd:MD_ProgressCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_ProgressCode'), addAttribute('codeListValue', getProgressCode(record.status)))(rootEl);
1337
1254
  }
1338
- function writeContacts$1(record, rootEl) {
1339
- pipe(removeChildrenByName('gmd:contact'), appendChildren(...record.contacts.map((contact) => pipe(createElement('gmd:contact'), appendResponsibleParty$1(contact)))))(rootEl);
1340
- }
1341
- function writeContactsForResource$1(record, rootEl) {
1342
- pipe(findOrCreateIdentification(), removeChildrenByName('gmd:pointOfContact'), removeChildrenByName('gmd:contact'), appendChildren(...record.contactsForResource.map((contact) => pipe(createElement('gmd:pointOfContact'), appendResponsibleParty$1(contact)))))(rootEl);
1255
+ function writeContacts(record, rootEl) {
1256
+ pipe(findOrCreateIdentification(), removeChildrenByName('gmd:pointOfContact'), appendChildren(...record.contacts.map((contact) => pipe(createElement('gmd:pointOfContact'), appendResponsibleParty(contact)))))(rootEl);
1343
1257
  }
1344
- function writeKeywords$1(record, rootEl) {
1258
+ function writeKeywords(record, rootEl) {
1345
1259
  pipe(findOrCreateIdentification(), removeKeywords(), appendKeywords(record.keywords))(rootEl);
1346
1260
  }
1347
1261
  function writeTopics(record, rootEl) {
@@ -1364,22 +1278,17 @@ function writeUpdateFrequency(record, rootEl) {
1364
1278
  ? pipe(createChild('gmd:userDefinedMaintenanceFrequency'), createChild('gts:TM_PeriodDuration'), setTextContent(getISODuration(record.updateFrequency)))
1365
1279
  : pipe(createChild('gmd:maintenanceAndUpdateFrequency'), createChild('gmd:MD_MaintenanceFrequencyCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_MaintenanceFrequencyCode'), addAttribute('codeListValue', getMaintenanceFrequencyCode(record.updateFrequency))))(rootEl);
1366
1280
  }
1367
- function writeResourceCreated$1(record, rootEl) {
1368
- if (!('resourceCreated' in record))
1369
- return;
1370
- pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), fallback(updateCitationDate(record.resourceCreated, 'creation'), appendCitationDate(record.resourceCreated, 'creation')))(rootEl);
1371
- }
1372
- function writeResourceUpdated$1(record, rootEl) {
1373
- if (!('resourceUpdated' in record))
1281
+ function writeDatasetCreated(record, rootEl) {
1282
+ if (!('datasetCreated' in record))
1374
1283
  return;
1375
- pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), fallback(updateCitationDate(record.resourceUpdated, 'revision'), appendCitationDate(record.resourceUpdated, 'revision')))(rootEl);
1284
+ pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), fallback(updateCitationDate(record.datasetCreated, 'creation'), appendCitationDate(record.datasetCreated, 'creation')))(rootEl);
1376
1285
  }
1377
- function writeResourcePublished$1(record, rootEl) {
1378
- if (!('resourcePublished' in record))
1286
+ function writeDatasetUpdated(record, rootEl) {
1287
+ if (!('datasetUpdated' in record))
1379
1288
  return;
1380
- pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), fallback(updateCitationDate(record.resourcePublished, 'publication'), appendCitationDate(record.resourcePublished, 'publication')))(rootEl);
1289
+ pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), fallback(updateCitationDate(record.datasetUpdated, 'revision'), appendCitationDate(record.datasetUpdated, 'revision')))(rootEl);
1381
1290
  }
1382
- function writeSpatialRepresentation$1(record, rootEl) {
1291
+ function writeSpatialRepresentation(record, rootEl) {
1383
1292
  pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:spatialRepresentationType', 'gmd:MD_SpatialRepresentationTypeCode'), addAttribute('codeList', 'http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_SpatialRepresentationTypeCode'), addAttribute('codeListValue', record.spatialRepresentation))(rootEl);
1384
1293
  }
1385
1294
  function writeGraphicOverviews(record, rootEl) {
@@ -1387,10 +1296,10 @@ function writeGraphicOverviews(record, rootEl) {
1387
1296
  ? appendChildren(pipe(createElement('gmd:fileDescription'), writeCharacterString(overview.description)))
1388
1297
  : noop))))(rootEl);
1389
1298
  }
1390
- function writeDistributions$1(record, rootEl) {
1391
- pipe(removeDistributions(), appendChildren(...record.distributions.map((d) => pipe(createDistributionInfo(), appendDistribution(d, appendDistributionFormat$1)))))(rootEl);
1299
+ function writeDistributions(record, rootEl) {
1300
+ pipe(removeDistributions(), appendChildren(...record.distributions.map(createDistribution)))(rootEl);
1392
1301
  }
1393
- function writeLineage$1(record, rootEl) {
1302
+ function writeLineage(record, rootEl) {
1394
1303
  pipe(findNestedChildOrCreate('gmd:dataQualityInfo', 'gmd:DQ_DataQuality', 'gmd:lineage', 'gmd:LI_Lineage', 'gmd:statement'), writeCharacterString(record.lineage))(rootEl);
1395
1304
  }
1396
1305
  function getServiceEndpointProtocol(endpoint) {
@@ -1447,631 +1356,130 @@ function isEqual(a, b) {
1447
1356
  return a === b;
1448
1357
  }
1449
1358
 
1450
- class MetadataMapperContext {
1451
- }
1452
- class BaseConverter {
1453
- constructor(ctx = new MetadataMapperContext()) {
1454
- this.ctx = ctx;
1455
- }
1456
- readRecords(documents) {
1457
- return Promise.all(documents.map((doc) => this.readRecord(doc)));
1458
- }
1459
- writeRecords(records) {
1460
- return Promise.all(records.map((doc) => this.writeRecord(doc)));
1461
- }
1462
- }
1463
-
1464
- class Iso19139Converter extends BaseConverter {
1465
- constructor() {
1466
- super(...arguments);
1467
- this.readers = {
1468
- uniqueIdentifier: readUniqueIdentifier$1,
1469
- kind: readKind$1,
1470
- ownerOrganization: readOwnerOrganization$1,
1471
- recordUpdated: readRecordUpdated$1,
1472
- recordCreated: () => undefined,
1473
- recordPublished: () => undefined,
1474
- resourceUpdated: readResourceUpdated,
1475
- resourceCreated: readResourceCreated,
1476
- resourcePublished: readResourcePublished,
1477
- title: readTitle,
1478
- abstract: readAbstract,
1479
- contacts: readContacts$1,
1480
- contactsForResource: readContactsForResource,
1481
- keywords: readKeywords,
1482
- topics: readIsoTopics,
1483
- licenses: readLicenses,
1484
- legalConstraints: readLegalConstraints,
1485
- securityConstraints: readSecurityConstraints,
1486
- otherConstraints: readOtherConstraints,
1487
- status: readStatus,
1488
- updateFrequency: readUpdateFrequency,
1489
- spatialRepresentation: readSpatialRepresentation,
1490
- overviews: readOverviews,
1491
- lineage: readLineage$1,
1492
- distributions: readDistributions$1,
1493
- onlineResources: readOnlineResources,
1494
- // TODO
1495
- spatialExtents: () => [],
1496
- temporalExtents: () => [],
1497
- extras: () => undefined,
1498
- landingPage: () => undefined,
1499
- languages: () => [],
1500
- };
1501
- this.writers = {
1502
- uniqueIdentifier: writeUniqueIdentifier$1,
1503
- kind: writeKind$1,
1504
- ownerOrganization: writeOwnerOrganization$1,
1505
- recordUpdated: writeRecordUpdated$1,
1506
- recordCreated: () => undefined,
1507
- recordPublished: () => undefined,
1508
- resourceUpdated: writeResourceUpdated$1,
1509
- resourceCreated: writeResourceCreated$1,
1510
- resourcePublished: writeResourcePublished$1,
1511
- title: writeTitle,
1512
- abstract: writeAbstract,
1513
- contacts: writeContacts$1,
1514
- contactsForResource: writeContactsForResource$1,
1515
- keywords: writeKeywords$1,
1516
- topics: writeTopics,
1517
- licenses: writeLicenses,
1518
- legalConstraints: writeLegalConstraints,
1519
- securityConstraints: writeSecurityConstraints,
1520
- otherConstraints: writeOtherConstraints,
1521
- status: writeStatus$1,
1522
- updateFrequency: writeUpdateFrequency,
1523
- spatialRepresentation: writeSpatialRepresentation$1,
1524
- overviews: writeGraphicOverviews,
1525
- lineage: writeLineage$1,
1526
- distributions: writeDistributions$1,
1527
- onlineResources: writeOnlineResources,
1528
- // TODO
1529
- spatialExtents: () => undefined,
1530
- temporalExtents: () => undefined,
1531
- extras: () => undefined,
1532
- landingPage: () => undefined,
1533
- languages: () => undefined,
1359
+ function toModel(xml) {
1360
+ const doc = parseXmlString(xml);
1361
+ const rootEl = getRootElement(doc);
1362
+ const uniqueIdentifier = readUniqueIdentifier(rootEl);
1363
+ const kind = readKind(rootEl);
1364
+ const ownerOrganization = readOwnerOrganization(rootEl);
1365
+ const title = readTitle(rootEl);
1366
+ const abstract = readAbstract(rootEl);
1367
+ const contacts = readContacts(rootEl);
1368
+ const recordUpdated = readRecordUpdated(rootEl);
1369
+ const recordCreated = recordUpdated;
1370
+ const recordPublished = readRecordPublished(rootEl);
1371
+ const keywords = readKeywords(rootEl);
1372
+ const topics = readIsoTopics(rootEl);
1373
+ const legalConstraints = readLegalConstraints(rootEl);
1374
+ const otherConstraints = readOtherConstraints(rootEl);
1375
+ const securityConstraints = readSecurityConstraints(rootEl);
1376
+ const licenses = readLicenses(rootEl);
1377
+ const overviews = readOverviews(rootEl);
1378
+ if (kind === 'dataset') {
1379
+ const status = readStatus(rootEl);
1380
+ const datasetCreated = readDatasetCreated(rootEl);
1381
+ const datasetUpdated = readDatasetUpdated(rootEl);
1382
+ const spatialRepresentation = readSpatialRepresentation(rootEl);
1383
+ const spatialExtents = readSpatialExtents(rootEl);
1384
+ const temporalExtents = readTemporalExtents(rootEl);
1385
+ const lineage = readLineage(rootEl);
1386
+ const distributions = readDistributions(rootEl);
1387
+ const updateFrequency = readUpdateFrequency(rootEl);
1388
+ return {
1389
+ uniqueIdentifier,
1390
+ kind,
1391
+ languages: [],
1392
+ recordCreated,
1393
+ recordUpdated,
1394
+ recordPublished,
1395
+ status,
1396
+ title,
1397
+ abstract,
1398
+ ownerOrganization,
1399
+ contacts,
1400
+ contactsForResource: [],
1401
+ keywords,
1402
+ topics,
1403
+ licenses,
1404
+ legalConstraints,
1405
+ securityConstraints,
1406
+ otherConstraints,
1407
+ ...(datasetCreated && { datasetCreated }),
1408
+ ...(datasetUpdated && { datasetUpdated }),
1409
+ lineage,
1410
+ ...(spatialRepresentation && { spatialRepresentation }),
1411
+ overviews,
1412
+ spatialExtents,
1413
+ temporalExtents,
1414
+ distributions,
1415
+ updateFrequency,
1534
1416
  };
1535
1417
  }
1536
- beforeDocumentCreation(rootElement) {
1537
- // to override
1538
- }
1539
- async readRecord(document) {
1540
- const doc = parseXmlString(document);
1541
- const rootEl = getRootElement(doc);
1542
- const uniqueIdentifier = this.readers['uniqueIdentifier'](rootEl);
1543
- const kind = this.readers['kind'](rootEl);
1544
- const ownerOrganization = this.readers['ownerOrganization'](rootEl);
1545
- const title = this.readers['title'](rootEl);
1546
- const abstract = this.readers['abstract'](rootEl);
1547
- const contacts = this.readers['contacts'](rootEl);
1548
- const contactsForResource = this.readers['contactsForResource'](rootEl);
1549
- const recordUpdated = this.readers['recordUpdated'](rootEl);
1550
- const recordCreated = this.readers['recordCreated'](rootEl);
1551
- const recordPublished = this.readers['recordPublished'](rootEl);
1552
- const resourceCreated = this.readers['resourceCreated'](rootEl);
1553
- const resourceUpdated = this.readers['resourceUpdated'](rootEl);
1554
- const resourcePublished = this.readers['resourcePublished'](rootEl);
1555
- const keywords = this.readers['keywords'](rootEl);
1556
- const topics = this.readers['topics'](rootEl);
1557
- const legalConstraints = this.readers['legalConstraints'](rootEl);
1558
- const otherConstraints = this.readers['otherConstraints'](rootEl);
1559
- const securityConstraints = this.readers['securityConstraints'](rootEl);
1560
- const licenses = this.readers['licenses'](rootEl);
1561
- const overviews = this.readers['overviews'](rootEl);
1562
- const landingPage = this.readers['landingPage'](rootEl);
1563
- if (kind === 'dataset') {
1564
- const status = this.readers['status'](rootEl);
1565
- const spatialRepresentation = this.readers['spatialRepresentation'](rootEl);
1566
- const spatialExtents = this.readers['spatialExtents'](rootEl);
1567
- const temporalExtents = this.readers['temporalExtents'](rootEl);
1568
- const lineage = this.readers['lineage'](rootEl);
1569
- const distributions = this.readers['distributions'](rootEl);
1570
- const updateFrequency = this.readers['updateFrequency'](rootEl);
1571
- return {
1572
- uniqueIdentifier,
1573
- kind,
1574
- languages: [],
1575
- ...(recordCreated && { recordCreated }),
1576
- ...(recordPublished && { recordPublished }),
1577
- recordUpdated,
1578
- ...(resourceCreated && { resourceCreated }),
1579
- ...(resourceUpdated && { resourceUpdated }),
1580
- ...(resourcePublished && { resourcePublished }),
1581
- status,
1582
- title,
1583
- abstract,
1584
- ownerOrganization,
1585
- contacts,
1586
- contactsForResource,
1587
- keywords,
1588
- topics,
1589
- licenses,
1590
- legalConstraints,
1591
- securityConstraints,
1592
- otherConstraints,
1593
- lineage,
1594
- ...(spatialRepresentation && { spatialRepresentation }),
1595
- overviews,
1596
- spatialExtents,
1597
- temporalExtents,
1598
- distributions,
1599
- updateFrequency,
1600
- ...(landingPage && { landingPage }),
1601
- };
1602
- }
1603
- else {
1604
- const onlineResources = this.readers['onlineResources'](rootEl);
1605
- return {
1606
- uniqueIdentifier,
1607
- kind,
1608
- languages: [],
1609
- ...(recordCreated && { recordCreated }),
1610
- ...(recordPublished && { recordPublished }),
1611
- recordUpdated,
1612
- ...(resourceCreated && { resourceCreated }),
1613
- ...(resourceUpdated && { resourceUpdated }),
1614
- ...(resourcePublished && { resourcePublished }),
1615
- title,
1616
- abstract,
1617
- ownerOrganization,
1618
- contacts,
1619
- contactsForResource,
1620
- keywords,
1621
- topics,
1622
- licenses,
1623
- legalConstraints,
1624
- securityConstraints,
1625
- otherConstraints,
1626
- overviews,
1627
- onlineResources,
1628
- ...(landingPage && { landingPage }),
1629
- };
1630
- }
1631
- }
1632
- async writeRecord(record, reference) {
1633
- let rootEl;
1634
- let fieldChanged;
1635
- if (reference) {
1636
- const originalDoc = parseXmlString(reference);
1637
- const originalRecord = await this.readRecord(reference);
1638
- rootEl = getRootElement(originalDoc);
1639
- fieldChanged = (name) => {
1640
- return originalRecord !== null
1641
- ? !isEqual(record[name], originalRecord[name])
1642
- : true;
1643
- };
1644
- }
1645
- else {
1646
- rootEl = createElement('gmd:MD_Metadata')();
1647
- fieldChanged = () => true;
1648
- }
1649
- fieldChanged('uniqueIdentifier') &&
1650
- this.writers['uniqueIdentifier'](record, rootEl);
1651
- fieldChanged('kind') && this.writers['kind'](record, rootEl);
1652
- fieldChanged('contacts') && this.writers['contacts'](record, rootEl);
1653
- fieldChanged('ownerOrganization') &&
1654
- this.writers['ownerOrganization'](record, rootEl);
1655
- fieldChanged('recordUpdated') &&
1656
- this.writers['recordUpdated'](record, rootEl);
1657
- fieldChanged('recordCreated') &&
1658
- this.writers['recordCreated'](record, rootEl);
1659
- fieldChanged('recordPublished') &&
1660
- this.writers['recordPublished'](record, rootEl);
1661
- fieldChanged('title') && this.writers['title'](record, rootEl);
1662
- fieldChanged('abstract') && this.writers['abstract'](record, rootEl);
1663
- fieldChanged('resourceCreated') &&
1664
- this.writers['resourceCreated'](record, rootEl);
1665
- fieldChanged('resourcePublished') &&
1666
- this.writers['resourcePublished'](record, rootEl);
1667
- fieldChanged('resourceUpdated') &&
1668
- this.writers['resourceUpdated'](record, rootEl);
1669
- fieldChanged('contactsForResource') &&
1670
- this.writers['contactsForResource'](record, rootEl);
1671
- fieldChanged('keywords') && this.writers['keywords'](record, rootEl);
1672
- fieldChanged('topics') && this.writers['topics'](record, rootEl);
1673
- fieldChanged('legalConstraints') &&
1674
- this.writers['legalConstraints'](record, rootEl);
1675
- fieldChanged('securityConstraints') &&
1676
- this.writers['securityConstraints'](record, rootEl);
1677
- fieldChanged('licenses') && this.writers['licenses'](record, rootEl);
1678
- fieldChanged('otherConstraints') &&
1679
- this.writers['otherConstraints'](record, rootEl);
1680
- if (record.kind === 'dataset') {
1681
- fieldChanged('status') && this.writers['status'](record, rootEl);
1682
- fieldChanged('updateFrequency') &&
1683
- this.writers['updateFrequency'](record, rootEl);
1684
- fieldChanged('spatialRepresentation') &&
1685
- this.writers['spatialRepresentation'](record, rootEl);
1686
- fieldChanged('overviews') && this.writers['overviews'](record, rootEl);
1687
- fieldChanged('distributions') &&
1688
- this.writers['distributions'](record, rootEl);
1689
- fieldChanged('lineage') && this.writers['lineage'](record, rootEl);
1690
- }
1691
- else {
1692
- fieldChanged('onlineResources') &&
1693
- this.writers['onlineResources'](record, rootEl);
1694
- }
1695
- this.beforeDocumentCreation(rootEl);
1696
- const newDocument = createDocument(rootEl);
1697
- return xmlToString(newDocument);
1698
- }
1699
- }
1700
-
1701
- function readKind(rootEl) {
1702
- return pipe(findNestedElement('mdb:metadataScope', 'mdb:MD_MetadataScope', 'mdb:resourceScope', 'mcc:MD_ScopeCode'), readAttribute('codeListValue'), map((scopeCode) => scopeCode === 'service' ? 'service' : 'dataset'))(rootEl);
1703
- }
1704
- function findDistribution() {
1705
- return findNestedElement('mdb:distributionInfo', 'mrd:MD_Distribution');
1706
- }
1707
- // from cit:CI_Organisation
1708
- function extractOrganization() {
1709
- const getUrl = pipe(findNestedElements('cit:contactInfo', 'cit:CI_Contact', 'cit:onlineResource', 'cit:CI_OnlineResource', 'cit:linkage'), getAtIndex(0), extractUrl());
1710
- return pipe(combine(pipe(findChildElement('cit:name', false), extractCharacterString()), getUrl), map(([name, website]) => ({
1711
- name,
1712
- ...(website && { website }),
1713
- })));
1714
- }
1715
- // from cit:CI_Individual or cit:CI_Organisation
1716
- function extractIndividual(role, organization, orgContact) {
1717
- const getPosition = pipe(findChildElement('cit:positionName'), extractCharacterString());
1718
- const getNameParts = pipe(findChildElement('cit:name'), extractCharacterString(), map((fullName) => {
1719
- if (!fullName)
1720
- return [];
1721
- return fullNameToParts(fullName);
1722
- }));
1723
- const getContact = findNestedElement('cit:contactInfo', 'cit:CI_Contact');
1724
- const getAddressRoot = pipe(getContact, findNestedElement('cit:address', 'cit:CI_Address'));
1725
- const getAddress = pipe(getAddressRoot, combine(pipe(findChildElement('cit:deliveryPoint', false), extractCharacterString()), pipe(findChildElement('cit:city', false), extractCharacterString()), pipe(findChildElement('cit:postalCode', false), extractCharacterString()), pipe(findChildElement('cit:country', false), extractCharacterString())), map((parts) => parts.filter((p) => !!p).join(', ')));
1726
- const getPhone = pipe(getContact, findNestedElement('cit:phone', 'cit:CI_Telephone', 'cit:number'), extractCharacterString());
1727
- const getEmail = pipe(getAddressRoot, findChildElement('cit:electronicMailAddress', false), extractCharacterString());
1728
- const defaultOrg = {
1729
- name: 'Missing Organization',
1730
- };
1731
- let defaultIndividual = {};
1732
- if (orgContact) {
1733
- defaultIndividual = {
1734
- email: orgContact.email,
1735
- ...(orgContact.address && { address: orgContact.address }),
1736
- ...(orgContact.phone && { phone: orgContact.phone }),
1737
- ...(orgContact.position && { position: orgContact.position }),
1738
- organization,
1418
+ else {
1419
+ const onlineResources = readOnlineResources(rootEl);
1420
+ return {
1421
+ uniqueIdentifier,
1422
+ kind,
1423
+ languages: [],
1424
+ recordCreated,
1425
+ recordUpdated,
1426
+ recordPublished,
1427
+ title,
1428
+ abstract,
1429
+ ownerOrganization,
1430
+ contacts,
1431
+ keywords,
1432
+ topics,
1433
+ licenses,
1434
+ legalConstraints,
1435
+ securityConstraints,
1436
+ otherConstraints,
1437
+ overviews,
1438
+ onlineResources,
1739
1439
  };
1740
1440
  }
1741
- return pipe(combine(getPosition, getNameParts, getEmail, getAddress, getPhone), map(([position, [firstName, lastName], email, address, phone]) => ({
1742
- ...defaultIndividual,
1743
- email: email || defaultIndividual.email || 'missing@missing.com',
1744
- role,
1745
- organization: organization || defaultOrg,
1746
- ...(position && { position }),
1747
- ...(firstName && { firstName }),
1748
- ...(lastName && { lastName }),
1749
- ...(address && { address }),
1750
- ...(phone && { phone }),
1751
- })));
1752
- }
1753
- // from cit:CI_Organisation
1754
- function extractOrganizationIndividuals(role) {
1755
- return pipe(combine(extractOrganization(), extractIndividual(role), findNestedElements('cit:individual', 'cit:CI_Individual')), map(([org, orgContact, els]) => els.length
1756
- ? els.map((el) => extractIndividual(role, org, orgContact)(el))
1757
- : [
1758
- {
1759
- email: orgContact.email,
1760
- ...(orgContact.address && { address: orgContact.address }),
1761
- ...(orgContact.phone && { phone: orgContact.phone }),
1762
- ...(orgContact.position && { position: orgContact.position }),
1763
- organization: org,
1764
- role,
1765
- },
1766
- ]));
1767
- }
1768
- // from cit:CI_Responsibility
1769
- function extractIndividuals() {
1770
- const getRole = pipe(findChildElement('cit:role'), extractRole());
1771
- const getIndividuals = pipe(combine(getRole, findNestedElements('cit:party', 'cit:CI_Individual')), ([role, els]) => els.map((el) => extractIndividual(role)(el)));
1772
- const getOrgIndividuals = pipe(combine(getRole, findNestedElements('cit:party', 'cit:CI_Organisation')), map(([role, els]) => els.map((el) => extractOrganizationIndividuals(role)(el))), flattenArray());
1773
- return pipe(combine(getIndividuals, getOrgIndividuals), flattenArray());
1774
- }
1775
- function readUniqueIdentifier(rootEl) {
1776
- return pipe(findNestedElement('mdb:metadataIdentifier', 'mcc:MD_Identifier', 'mcc:code'), extractCharacterString())(rootEl);
1777
- }
1778
- function readOwnerOrganization(rootEl) {
1779
- const contacts = readContacts(rootEl);
1780
- const pointOfContact = contacts.filter((c) => c.role === 'point_of_contact')[0];
1781
- return (pointOfContact || contacts[0]).organization;
1782
- }
1783
- function readContacts(rootEl) {
1784
- return pipe(findNestedElements('mdb:contact', 'cit:CI_Responsibility'), mapArray(extractIndividuals()), flattenArray())(rootEl);
1785
- }
1786
- function readResourceContacts(rootEl) {
1787
- return pipe(combine(pipe(findIdentification(), findNestedElements('mri:citation', 'cit:CI_Citation', 'cit:citedResponsibleParty')), pipe(findIdentification(), findChildrenElement('mri:pointOfContact', false)), pipe(findDistribution(), findChildrenElement('mrd:distributorContact'))), flattenArray(), mapArray(findChildElement('cit:CI_Responsibility', false)), mapArray(extractIndividuals()), flattenArray())(rootEl);
1788
- }
1789
- function readLandingPage(rootEl) {
1790
- return pipe(findNestedElement('mdb:metadataLinkage', 'cit:CI_OnlineResource', 'cit:linkage'), extractUrl())(rootEl);
1791
- }
1792
- function readLineage(rootEl) {
1793
- return pipe(findNestedElement('mdb:resourceLineage', 'mrl:LI_Lineage', 'mrl:statement'), extractCharacterString())(rootEl);
1794
- }
1795
- function extractDateInfo(type) {
1796
- return pipe(findChildrenElement('mdb:dateInfo', false), filterArray((el) => pipe(findChildElement('cit:CI_DateTypeCode'), readAttribute('codeListValue'))(el) === type), getAtIndex(0), findChildElement('cit:date'), extractDateTime());
1797
1441
  }
1798
- function readRecordUpdated(rootEl) {
1799
- return extractDateInfo('revision')(rootEl);
1800
- }
1801
- function readRecordCreated(rootEl) {
1802
- return extractDateInfo('creation')(rootEl);
1803
- }
1804
- function readRecordPublished(rootEl) {
1805
- return extractDateInfo('publication')(rootEl);
1806
- }
1807
- const getMimeType = pipe(findParent('mrd:MD_Distribution'), findNestedElement('mrd:distributionFormat', 'mrd:MD_Format', 'mrd:formatSpecificationCitation', 'cit:CI_Citation', 'cit:title'), extractCharacterString(), map(matchMimeType));
1808
- function readDistributions(rootEl) {
1809
- return pipe(findNestedElements('mrd:distributionInfo', 'mrd:MD_Distribution'), mapArray(extractDatasetDistributions(getMimeType)), flattenArray())(rootEl);
1810
- }
1811
-
1812
- function writeUniqueIdentifier(record, rootEl) {
1813
- pipe(findChildOrCreate('mdb:metadataIdentifier'), findChildOrCreate('mcc:MD_Identifier'), findChildOrCreate('mcc:code'), writeCharacterString(record.uniqueIdentifier))(rootEl);
1814
- }
1815
- function writeKind(record, rootEl) {
1816
- pipe(findNestedChildOrCreate('mdb:metadataScope', 'mdb:MD_MetadataScope', 'mdb:resourceScope', 'mcc:MD_ScopeCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#MD_ScopeCode'), addAttribute('codeListValue', record.kind), setTextContent(record.kind))(rootEl);
1817
- }
1818
- function removeRecordDate(type) {
1819
- return removeChildren(pipe(findChildrenElement('mdb:dateInfo', false), filterArray(pipe(findChildElement('cit:CI_DateTypeCode'), readAttribute('codeListValue'), map((value) => value === type)))));
1820
- }
1821
- function appendRecordDate(date, type) {
1822
- return appendChildren(pipe(createElement('mdb:dateInfo'), createChild('cit:CI_Date'), appendChildren(pipe(createElement('cit:date'), writeDateTime(date)), pipe(createElement('cit:dateType'), createChild('cit:CI_DateTypeCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#CI_DateTypeCode'), addAttribute('codeListValue', type), setTextContent(type)))));
1823
- }
1824
- function writeRecordUpdated(record, rootEl) {
1825
- removeRecordDate('revision')(rootEl);
1826
- appendRecordDate(record.recordUpdated, 'revision')(rootEl);
1827
- }
1828
- function writeRecordCreated(record, rootEl) {
1829
- removeRecordDate('creation')(rootEl);
1830
- if (!('recordCreated' in record))
1831
- return;
1832
- appendRecordDate(record.recordCreated, 'creation')(rootEl);
1833
- }
1834
- function writeRecordPublished(record, rootEl) {
1835
- removeRecordDate('publication')(rootEl);
1836
- if (!('recordPublished' in record))
1837
- return;
1838
- appendRecordDate(record.recordPublished, 'publication')(rootEl);
1839
- }
1840
- function removeResourceDate(type) {
1841
- return pipe(findIdentification(), findNestedElement('mri:citation', 'cit:CI_Citation'), removeChildren(pipe(findChildrenElement('cit:date', false), filterArray(pipe(findChildElement('cit:CI_DateTypeCode'), readAttribute('codeListValue'), map((value) => value === type))))));
1842
- }
1843
- function appendResourceDate(date, type) {
1844
- return pipe(findIdentification(), findNestedElement('mri:citation', 'cit:CI_Citation'), appendChildren(pipe(createElement('cit:date'), createChild('cit:CI_Date'), appendChildren(pipe(createElement('cit:date'), writeDateTime(date)), pipe(createElement('cit:dateType'), createChild('cit:CI_DateTypeCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#CI_DateTypeCode'), addAttribute('codeListValue', type), setTextContent(type))))));
1845
- }
1846
- function writeResourceUpdated(record, rootEl) {
1847
- removeResourceDate('revision')(rootEl);
1848
- if (!('resourceUpdated' in record))
1849
- return;
1850
- appendResourceDate(record.resourceUpdated, 'revision')(rootEl);
1851
- }
1852
- function writeResourceCreated(record, rootEl) {
1853
- removeResourceDate('creation')(rootEl);
1854
- if (!('resourceCreated' in record))
1855
- return;
1856
- appendResourceDate(record.resourceCreated, 'creation')(rootEl);
1857
- }
1858
- function writeResourcePublished(record, rootEl) {
1859
- removeResourceDate('publication')(rootEl);
1860
- if (!('resourcePublished' in record))
1861
- return;
1862
- appendResourceDate(record.resourcePublished, 'publication')(rootEl);
1863
- }
1864
- function writeOwnerOrganization(record, rootEl) {
1865
- // if no contact matches the owner org, create an empty one
1866
- const ownerContact = record.contacts.find((contact) => contact.organization.name === record.ownerOrganization.name);
1867
- pipe(findChildOrCreate('mdb:contact'), removeAllChildren(), appendResponsibleParty(ownerContact
1868
- ? {
1869
- ...ownerContact,
1870
- // owner responsible party is always point of contact
1871
- role: 'point_of_contact',
1872
- }
1873
- : {
1874
- organization: record.ownerOrganization,
1875
- email: 'missing@missing.com',
1876
- role: 'point_of_contact',
1877
- }))(rootEl);
1878
- }
1879
- function appendResponsibleParty(contact) {
1880
- const fullName = namePartsToFull(contact.firstName, contact.lastName);
1881
- const createIndividual = pipe(createElement('cit:individual'), createChild('cit:CI_Individual'), fullName
1882
- ? appendChildren(pipe(createElement('cit:name'), writeCharacterString(fullName)))
1883
- : noop, contact.position
1884
- ? appendChildren(pipe(createElement('cit:positionName'), writeCharacterString(contact.position)))
1885
- : noop);
1886
- const createContactInfo = pipe(createElement('cit:contactInfo'), createChild('cit:CI_Contact'), appendChildren(pipe(createElement('cit:address'), createChild('cit:CI_Address'), appendChildren(pipe(createElement('cit:electronicMailAddress'), writeCharacterString(contact.email))), contact.address
1887
- ? appendChildren(pipe(createElement('cit:deliveryPoint'), writeCharacterString(contact.address)))
1888
- : noop)), contact.organization?.website
1889
- ? appendChildren(pipe(createElement('cit:onlineResource'), createChild('cit:CI_OnlineResource'), createChild('cit:linkage'), writeCharacterString(contact.organization.website.toString())))
1890
- : noop, contact.phone
1891
- ? appendChildren(pipe(createElement('cit:phone'), createChild('cit:CI_Telephone'), createChild('cit:number'), writeCharacterString(contact.phone)))
1892
- : noop);
1893
- const createRole = pipe(createElement('cit:role'), createChild('cit:CI_RoleCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#CI_RoleCode'), addAttribute('codeListValue', getRoleCode(contact.role)), setTextContent(getRoleCode(contact.role)));
1894
- const createParty = pipe(createElement('cit:party'), createChild('cit:CI_Organisation'), contact.organization?.name
1895
- ? appendChildren(pipe(createElement('cit:name'), writeCharacterString(contact.organization?.name)))
1896
- : noop, appendChildren(createContactInfo, createIndividual));
1897
- return appendChildren(pipe(createElement('cit:CI_Responsibility'), appendChildren(createRole, createParty)));
1898
- }
1899
- function writeContacts(record, rootEl) {
1900
- pipe(removeChildrenByName('mdb:contact'), appendChildren(...record.contacts.map((contact) => pipe(createElement('gmd:contact'), appendResponsibleParty(contact)))))(rootEl);
1901
- }
1902
- function writeContactsForResource(record, rootEl) {
1903
- const withoutDistributors = record.contactsForResource.filter((c) => c.role !== 'distributor');
1904
- const distributors = record.contactsForResource.filter((c) => c.role === 'distributor');
1905
- pipe(findOrCreateIdentification(), removeChildrenByName('mri:pointOfContact'), appendChildren(...withoutDistributors.map((contact) => pipe(createElement('mri:pointOfContact'), appendResponsibleParty(contact)))))(rootEl);
1906
- if (!distributors.length)
1907
- return;
1908
- pipe(findOrCreateDistribution(), removeChildrenByName('mrd:distributor'), createChild('mrd:distributor'), createChild('mrd:MD_Distributor'), appendChildren(...distributors.map((contact) => pipe(createElement('mrd:distributorContact'), appendResponsibleParty(contact)))))(rootEl);
1909
- }
1910
- function writeKeywords(record, rootEl) {
1911
- pipe(findOrCreateIdentification(), removeKeywords(), appendKeywords(record.keywords))(rootEl);
1912
- }
1913
- function writeLandingPage(record, rootEl) {
1914
- pipe(findNestedChildOrCreate('mdb:metadataLinkage', 'cit:CI_OnlineResource', 'cit:linkage'), writeLinkage(record.landingPage))(rootEl);
1915
- }
1916
- function writeLineage(record, rootEl) {
1917
- pipe(findNestedChildOrCreate('mdb:resourceLineage', 'mrl:LI_Lineage', 'mrl:statement'), writeCharacterString(record.lineage))(rootEl);
1918
- }
1919
- function writeStatus(record, rootEl) {
1920
- const progressCode = getProgressCode(record.status);
1921
- pipe(findOrCreateIdentification(), findNestedChildOrCreate('mri:status', 'mcc:MD_ProgressCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#MD_ProgressCode'), addAttribute('codeListValue', progressCode), setTextContent(progressCode))(rootEl);
1922
- }
1923
- function writeSpatialRepresentation(record, rootEl) {
1924
- pipe(findOrCreateIdentification(), findNestedChildOrCreate('mri:spatialRepresentationType', 'mcc:MD_SpatialRepresentationTypeCode'), addAttribute('codeList', 'https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#MD_SpatialRepresentationTypeCode'), addAttribute('codeListValue', record.spatialRepresentation), setTextContent(record.spatialRepresentation))(rootEl);
1925
- }
1926
- // this will remove all transfer options and formats from distribution info
1927
- // and remove empty distribution info
1928
- function removeTransferOptions(rootEl) {
1929
- // remove transfer options & formats
1930
- pipe(findNestedElements('mdb:distributionInfo', 'mrd:MD_Distribution'), mapArray(pipe(removeChildren(findChildrenElement('mrd:distributionFormat', false)), removeChildren(findChildrenElement('mrd:transferOptions', false)))))(rootEl);
1931
- // remove empty distributions
1932
- removeChildren(pipe(findChildrenElement('mdb:distributionInfo', false), filterArray(pipe(findChildElement('mrd:MD_Distribution'), allChildrenElement, map((children) => children.length === 0)))))(rootEl);
1933
- }
1934
- function appendDistributionFormat(mimeType) {
1935
- return appendChildren(pipe(createElement('mrd:distributionFormat'), createChild('mrd:MD_Format'), createChild('mrd:formatSpecificationCitation'), createChild('cit:CI_Citation'), createChild('cit:title'), writeCharacterString(mimeType)));
1936
- }
1937
- function writeDistributions(record, rootEl) {
1938
- removeTransferOptions(rootEl);
1939
- // for each distribution, either find an existing distribution info or create a new one
1940
- record.distributions.forEach((distribution, index) => {
1941
- pipe(fallback(pipe(findNestedElements('gmd:distributionInfo', 'gmd:MD_Distribution'), getAtIndex(index)), appendChildTree(createDistributionInfo())), appendDistribution(distribution, appendDistributionFormat))(rootEl);
1942
- });
1943
- }
1944
-
1945
- class Iso191153Converter extends Iso19139Converter {
1946
- constructor() {
1947
- super();
1948
- this.readers['uniqueIdentifier'] = readUniqueIdentifier;
1949
- this.readers['kind'] = readKind;
1950
- this.readers['recordUpdated'] = readRecordUpdated;
1951
- this.readers['recordCreated'] = readRecordCreated;
1952
- this.readers['recordPublished'] = readRecordPublished;
1953
- this.readers['contacts'] = readContacts;
1954
- this.readers['contactsForResource'] = readResourceContacts;
1955
- this.readers['ownerOrganization'] = readOwnerOrganization;
1956
- this.readers['landingPage'] = readLandingPage;
1957
- this.readers['lineage'] = readLineage;
1958
- this.readers['distributions'] = readDistributions;
1959
- this.writers['uniqueIdentifier'] = writeUniqueIdentifier;
1960
- this.writers['kind'] = writeKind;
1961
- this.writers['recordUpdated'] = writeRecordUpdated;
1962
- this.writers['recordCreated'] = writeRecordCreated;
1963
- this.writers['recordPublished'] = writeRecordPublished;
1964
- this.writers['resourceUpdated'] = writeResourceUpdated;
1965
- this.writers['resourceCreated'] = writeResourceCreated;
1966
- this.writers['resourcePublished'] = writeResourcePublished;
1967
- this.writers['contacts'] = writeContacts;
1968
- this.writers['contactsForResource'] = writeContactsForResource;
1969
- this.writers['ownerOrganization'] = writeOwnerOrganization;
1970
- this.writers['landingPage'] = writeLandingPage;
1971
- this.writers['lineage'] = writeLineage;
1972
- this.writers['distributions'] = writeDistributions;
1973
- this.writers['status'] = writeStatus;
1974
- this.writers['spatialRepresentation'] = writeSpatialRepresentation;
1975
- }
1976
- beforeDocumentCreation(rootEl) {
1977
- renameElements(rootEl, {
1978
- gmd: 'mdb',
1979
- 'gmd:characterEncoding': 'lan:characterEncoding',
1980
- 'gmd:MD_CharacterSetCode': 'lan:MD_CharacterSetCode',
1981
- 'gmd:MD_DataIdentification': 'mri:MD_DataIdentification',
1982
- 'gmd:citation': 'mri:citation',
1983
- 'gmd:abstract': 'mri:abstract',
1984
- 'gmd:title': 'cit:title',
1985
- 'gmd:CI_Citation': 'cit:CI_Citation',
1986
- 'gmx:Anchor': 'gcx:Anchor',
1987
- // languages
1988
- 'gmd:PT_Locale': 'lan:PT_Locale',
1989
- 'gmd:languageCode': 'lan:languageCode',
1990
- 'gmd:LanguageCode': 'lan:LanguageCode',
1991
- // status
1992
- 'gmd:status': 'mri:status',
1993
- 'gmd:MD_ProgressCode': 'mri:MD_ProgressCode',
1994
- // dates
1995
- 'gmd:date': 'cit:date',
1996
- 'gmd:CI_Date': 'cit:CI_Date',
1997
- 'gmd:dateType': 'cit:dateType',
1998
- 'gmd:CI_DateTypeCode': 'cit:CI_DateTypeCode',
1999
- // contacts
2000
- 'gmd:CI_Responsibility': 'cit:CI_Responsibility',
2001
- 'gmd:role': 'cit:role',
2002
- 'gmd:CI_RoleCode': 'cit:CI_RoleCode',
2003
- // keywords
2004
- 'gmd:descriptiveKeywords': 'mri:descriptiveKeywords',
2005
- 'gmd:MD_Keywords': 'mri:MD_Keywords',
2006
- 'gmd:type': 'mri:type',
2007
- 'gmd:MD_KeywordTypeCode': 'mri:MD_KeywordTypeCode',
2008
- 'gmd:thesaurusName': 'mri:thesaurusName',
2009
- 'gmd:keyword': 'mri:keyword',
2010
- 'gmd:identifier': 'cit:identifier',
2011
- 'gmd:MD_Identifier': 'mcc:MD_Identifier',
2012
- 'gmd:code': 'mcc:code',
2013
- // distributions
2014
- 'gmd:MD_Distribution': 'mrd:MD_Distribution',
2015
- 'gmd:transferOptions': 'mrd:transferOptions',
2016
- 'gmd:MD_DigitalTransferOptions': 'mrd:MD_DigitalTransferOptions',
2017
- 'gmd:onLine': 'mrd:onLine',
2018
- 'gmd:distributionFormat': 'mrd:distributionFormat',
2019
- 'gmd:MD_Format': 'mrd:MD_Format',
2020
- 'gmd:CI_OnlineResource': 'cit:CI_OnlineResource',
2021
- 'gmd:linkage': 'cit:linkage',
2022
- 'gmd:name': 'cit:name',
2023
- 'gmd:description': 'cit:description',
2024
- 'gmd:CI_OnLineFunctionCode': 'cit:CI_OnLineFunctionCode',
2025
- 'gmd:function': 'cit:function',
2026
- 'gmd:protocol': 'cit:protocol',
2027
- // topic
2028
- 'gmd:topicCategory': 'mri:topicCategory',
2029
- 'gmd:MD_TopicCategoryCode': 'mri:MD_TopicCategoryCode',
2030
- // update frequency
2031
- 'gmd:resourceMaintenance': 'mri:resourceMaintenance',
2032
- 'gmd:MD_MaintenanceInformation': 'mmi:MD_MaintenanceInformation',
2033
- 'gmd:userDefinedMaintenanceFrequency': 'mmi:userDefinedMaintenanceFrequency',
2034
- 'gts:TM_PeriodDuration': 'gco:TM_PeriodDuration',
2035
- // constraints
2036
- 'gmd:resourceConstraints': 'mri:resourceConstraints',
2037
- 'gmd:MD_Constraints': 'mco:MD_Constraints',
2038
- 'gmd:MD_LegalConstraints': 'mco:MD_LegalConstraints',
2039
- 'gmd:MD_SecurityConstraints': 'mco:MD_SecurityConstraints',
2040
- 'gmd:useLimitation': 'mco:useLimitation',
2041
- 'gmd:useConstraints': 'mco:useConstraints',
2042
- 'gmd:accessConstraints': 'mco:accessConstraints',
2043
- 'gmd:otherConstraints': 'mco:otherConstraints',
2044
- 'gmd:MD_RestrictionCode': 'mco:MD_RestrictionCode',
2045
- 'gmd:classification': 'mco:classification',
2046
- 'gmd:MD_ClassificationCode': 'mco:MD_ClassificationCode',
2047
- // overviews
2048
- 'gmd:graphicOverview': 'mri:graphicOverview',
2049
- 'gmd:MD_BrowseGraphic': 'mcc:MD_BrowseGraphic',
2050
- 'gmd:fileName': 'mcc:fileName',
2051
- 'gmd:fileDescription': 'mcc:fileDescription',
2052
- // no more URL elements
2053
- 'gmd:URL': 'gco:CharacterString',
2054
- });
2055
- }
2056
- async writeRecord(record, reference) {
2057
- let result = await super.writeRecord(record, reference);
2058
- // fix gco namespace definition (changes between iso19139 and iso19115-3
2059
- result = result.replace('"http://www.isotc211.org/2005/gco"', '"http://standards.iso.org/iso/19115/-3/gco/1.0"');
2060
- return result;
2061
- }
2062
- }
2063
-
2064
- function findConverterForDocument(document) {
2065
- if (document.indexOf('mdb:MD_Metadata') > 0) {
2066
- return new Iso191153Converter();
2067
- }
2068
- else if (document.indexOf('gmd:MD_Metadata') > 0) {
2069
- return new Iso19139Converter();
1442
+ function toXml(record, originalXml) {
1443
+ const originalDoc = originalXml ? parseXmlString(originalXml) : null;
1444
+ const originalRecord = originalXml ? toModel(originalXml) : null;
1445
+ const rootEl = originalDoc
1446
+ ? getRootElement(originalDoc)
1447
+ : createElement('gmd:MD_Metadata')();
1448
+ function fieldChanged(name) {
1449
+ return originalRecord !== null
1450
+ ? !isEqual(record[name], originalRecord[name])
1451
+ : true;
1452
+ }
1453
+ writeUniqueIdentifier(record, rootEl);
1454
+ writeKind(record, rootEl);
1455
+ fieldChanged('ownerOrganization') && writeOwnerOrganization(record, rootEl);
1456
+ fieldChanged('recordUpdated') && writeRecordUpdated(record, rootEl);
1457
+ writeTitle(record, rootEl);
1458
+ writeAbstract(record, rootEl);
1459
+ fieldChanged('contacts') && writeContacts(record, rootEl);
1460
+ fieldChanged('keywords') && writeKeywords(record, rootEl);
1461
+ fieldChanged('topics') && writeTopics(record, rootEl);
1462
+ fieldChanged('legalConstraints') && writeLegalConstraints(record, rootEl);
1463
+ fieldChanged('securityConstraints') &&
1464
+ writeSecurityConstraints(record, rootEl);
1465
+ fieldChanged('licenses') && writeLicenses(record, rootEl);
1466
+ fieldChanged('otherConstraints') && writeOtherConstraints(record, rootEl);
1467
+ if (record.kind === 'dataset') {
1468
+ writeStatus(record, rootEl);
1469
+ fieldChanged('updateFrequency') && writeUpdateFrequency(record, rootEl);
1470
+ fieldChanged('datasetCreated') && writeDatasetCreated(record, rootEl);
1471
+ fieldChanged('datasetUpdated') && writeDatasetUpdated(record, rootEl);
1472
+ fieldChanged('spatialRepresentation') &&
1473
+ writeSpatialRepresentation(record, rootEl);
1474
+ fieldChanged('overviews') && writeGraphicOverviews(record, rootEl);
1475
+ fieldChanged('distributions') && writeDistributions(record, rootEl);
1476
+ writeLineage(record, rootEl);
2070
1477
  }
2071
1478
  else {
2072
- throw new Error(`No suitable converter found for the following document:
2073
- ${document.substring(0, 400)}...`);
1479
+ fieldChanged('onlineResources') && writeOnlineResources(record, rootEl);
2074
1480
  }
1481
+ const newDocument = createDocument(rootEl);
1482
+ return xmlToString(newDocument);
2075
1483
  }
2076
1484
 
2077
1485
  const selectField = (source, fieldName) => source !== null && fieldName in source ? source[fieldName] : null;
@@ -20026,7 +19434,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
20026
19434
  class OrganizationsServiceInterface {
20027
19435
  }
20028
19436
 
20029
- class Gn4Converter extends BaseConverter {
19437
+ class MetadataMapperContext {
19438
+ }
19439
+ class MetadataBaseMapper {
19440
+ constructor(ctx = new MetadataMapperContext()) {
19441
+ this.ctx = ctx;
19442
+ }
19443
+ readRecords(documents) {
19444
+ return Promise.all(documents.map((doc) => this.readRecord(doc)));
19445
+ }
19446
+ writeRecords(records) {
19447
+ return Promise.all(records.map((doc) => this.writeRecord(doc)));
19448
+ }
19449
+ }
19450
+
19451
+ class Gn4MetadataMapper extends MetadataBaseMapper {
20030
19452
  constructor(fieldMapper, orgsService) {
20031
19453
  super();
20032
19454
  this.fieldMapper = fieldMapper;
@@ -20060,10 +19482,10 @@ class Gn4Converter extends BaseConverter {
20060
19482
  writeRecord(record) {
20061
19483
  throw new Error('not implemented');
20062
19484
  }
20063
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Converter, deps: [{ token: Gn4FieldMapper }, { token: OrganizationsServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
20064
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Converter, providedIn: 'root' }); }
19485
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4MetadataMapper, deps: [{ token: Gn4FieldMapper }, { token: OrganizationsServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
19486
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4MetadataMapper, providedIn: 'root' }); }
20065
19487
  }
20066
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Converter, decorators: [{
19488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4MetadataMapper, decorators: [{
20067
19489
  type: Injectable,
20068
19490
  args: [{
20069
19491
  providedIn: 'root',
@@ -20653,12 +20075,12 @@ class Gn4Repository {
20653
20075
  records,
20654
20076
  }))));
20655
20077
  }
20656
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Repository, deps: [{ token: SearchApiService }, { token: ElasticsearchService }, { token: Gn4Converter }], target: i0.ɵɵFactoryTarget.Injectable }); }
20078
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Repository, deps: [{ token: SearchApiService }, { token: ElasticsearchService }, { token: Gn4MetadataMapper }], target: i0.ɵɵFactoryTarget.Injectable }); }
20657
20079
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Repository }); }
20658
20080
  }
20659
20081
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4Repository, decorators: [{
20660
20082
  type: Injectable
20661
- }], ctorParameters: function () { return [{ type: SearchApiService }, { type: ElasticsearchService }, { type: Gn4Converter }]; } });
20083
+ }], ctorParameters: function () { return [{ type: SearchApiService }, { type: ElasticsearchService }, { type: Gn4MetadataMapper }]; } });
20662
20084
 
20663
20085
  class PlatformServiceInterface {
20664
20086
  }
@@ -32734,7 +32156,7 @@ class EditorService {
32734
32156
  Accept: 'application/xml',
32735
32157
  },
32736
32158
  })
32737
- .pipe(switchMap$1((response) => findConverterForDocument(response).readRecord(response.toString())));
32159
+ .pipe(map$1((response) => toModel(response.toString())));
32738
32160
  }
32739
32161
  // returns the record as it was when saved
32740
32162
  saveRecord(record, fieldsConfig) {
@@ -32750,13 +32172,14 @@ class EditorService {
32750
32172
  }
32751
32173
  }
32752
32174
  // TODO: use the catalog repository instead
32753
- // TODO: use converter based on the format of the record before change
32754
- return from(new Iso19139Converter().writeRecord(savedRecord)).pipe(switchMap$1((recordXml) => this.http.put(`${this.apiUrl}/records?metadataType=METADATA&uuidProcessing=OVERWRITE&transformWith=_none_&publishToAll=on`, recordXml, {
32175
+ return this.http
32176
+ .put(`${this.apiUrl}/records?metadataType=METADATA&uuidProcessing=OVERWRITE&transformWith=_none_&publishToAll=on`, toXml(savedRecord), {
32755
32177
  headers: {
32756
32178
  'Content-Type': 'application/xml',
32757
32179
  },
32758
32180
  withCredentials: true,
32759
- })), map$1(() => savedRecord));
32181
+ })
32182
+ .pipe(map$1(() => savedRecord));
32760
32183
  }
32761
32184
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
32762
32185
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, providedIn: 'root' }); }
@@ -33226,5 +32649,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33226
32649
  * Generated bundle index. Do not edit.
33227
32650
  */
33228
32651
 
33229
- export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldFileComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
32652
+ export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldFileComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4MetadataMapper, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, dragPanCondition, dropEmptyTranslations, editorReducer, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, toModel, toXml, totalPages, updateLayer, updateRecordField };
33230
32653
  //# sourceMappingURL=geonetwork-ui.mjs.map