@natlibfi/marc-record-validators-melinda 11.6.5 → 11.6.7-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/.github/workflows/melinda-node-tests.yml +1 -1
  2. package/dist/access-rights.js +1 -5
  3. package/dist/access-rights.js.map +1 -1
  4. package/dist/addMissingField336.js +1 -1
  5. package/dist/addMissingField336.js.map +1 -1
  6. package/dist/cyrillux-usemarcon-replacement.js +41 -45
  7. package/dist/cyrillux-usemarcon-replacement.js.map +1 -1
  8. package/dist/cyrillux.js +13 -17
  9. package/dist/cyrillux.js.map +1 -1
  10. package/dist/disambiguateSeriesStatements.js +3 -4
  11. package/dist/disambiguateSeriesStatements.js.map +1 -1
  12. package/dist/double-commas.js +2 -1
  13. package/dist/double-commas.js.map +1 -1
  14. package/dist/duplicates-ind1.js +1 -1
  15. package/dist/duplicates-ind1.js.map +1 -1
  16. package/dist/empty-fields.js +0 -4
  17. package/dist/empty-fields.js.map +1 -1
  18. package/dist/ending-punctuation.js +21 -49
  19. package/dist/ending-punctuation.js.map +1 -1
  20. package/dist/ending-whitespace.js +0 -4
  21. package/dist/ending-whitespace.js.map +1 -1
  22. package/dist/field-008-18-34-character-groups.js +4 -5
  23. package/dist/field-008-18-34-character-groups.js.map +1 -1
  24. package/dist/field-505-separators.js +8 -6
  25. package/dist/field-505-separators.js.map +1 -1
  26. package/dist/field-521-fix.js +5 -6
  27. package/dist/field-521-fix.js.map +1 -1
  28. package/dist/field-exclusion.js +5 -12
  29. package/dist/field-exclusion.js.map +1 -1
  30. package/dist/field-exclusion.spec.js +3 -5
  31. package/dist/field-exclusion.spec.js.map +1 -1
  32. package/dist/field-structure.js +2 -5
  33. package/dist/field-structure.js.map +1 -1
  34. package/dist/fields-present.js +1 -1
  35. package/dist/fields-present.js.map +1 -1
  36. package/dist/fields-present.spec.js +1 -1
  37. package/dist/fields-present.spec.js.map +1 -1
  38. package/dist/fix-33X.js +5 -6
  39. package/dist/fix-33X.js.map +1 -1
  40. package/dist/fix-country-codes.js +3 -4
  41. package/dist/fix-country-codes.js.map +1 -1
  42. package/dist/fix-language-codes.js +12 -9
  43. package/dist/fix-language-codes.js.map +1 -1
  44. package/dist/fixRelatorTerms.js +8 -8
  45. package/dist/fixRelatorTerms.js.map +1 -1
  46. package/dist/fixed-fields.js +1 -4
  47. package/dist/fixed-fields.js.map +1 -1
  48. package/dist/identical-fields.js +2 -3
  49. package/dist/identical-fields.js.map +1 -1
  50. package/dist/indicator-fixes.js +14 -15
  51. package/dist/indicator-fixes.js.map +1 -1
  52. package/dist/isbn-issn.js +8 -11
  53. package/dist/isbn-issn.js.map +1 -1
  54. package/dist/item-language.js +5 -12
  55. package/dist/item-language.js.map +1 -1
  56. package/dist/merge-fields/counterpartField.js +6 -8
  57. package/dist/merge-fields/counterpartField.js.map +1 -1
  58. package/dist/merge-fields/index.js +3 -3
  59. package/dist/merge-fields/index.js.map +1 -1
  60. package/dist/merge-fields/mergeConstraints.js +0 -1
  61. package/dist/merge-fields/mergeConstraints.js.map +1 -1
  62. package/dist/merge-fields/mergeField.js +12 -18
  63. package/dist/merge-fields/mergeField.js.map +1 -1
  64. package/dist/merge-fields/mergeIndicator.js +5 -5
  65. package/dist/merge-fields/mergeIndicator.js.map +1 -1
  66. package/dist/merge-fields/mergeOrAddPostprocess.js +6 -9
  67. package/dist/merge-fields/mergeOrAddPostprocess.js.map +1 -1
  68. package/dist/merge-fields/mergeOrAddSubfield.js +6 -8
  69. package/dist/merge-fields/mergeOrAddSubfield.js.map +1 -1
  70. package/dist/merge-fields/mergeSubfield.js +8 -8
  71. package/dist/merge-fields/mergeSubfield.js.map +1 -1
  72. package/dist/merge-fields/removeDuplicateSubfields.js +1 -2
  73. package/dist/merge-fields/removeDuplicateSubfields.js.map +1 -1
  74. package/dist/merge-fields/worldKnowledge.js +1 -1
  75. package/dist/merge-fields/worldKnowledge.js.map +1 -1
  76. package/dist/mergeField500Lisapainokset.js +0 -3
  77. package/dist/mergeField500Lisapainokset.js.map +1 -1
  78. package/dist/mergeRelatorTermFields.js +3 -3
  79. package/dist/mergeRelatorTermFields.js.map +1 -1
  80. package/dist/modernize-502.js +6 -6
  81. package/dist/modernize-502.js.map +1 -1
  82. package/dist/multiple-subfield-0.js +4 -4
  83. package/dist/multiple-subfield-0.js.map +1 -1
  84. package/dist/non-breaking-space.js +0 -4
  85. package/dist/non-breaking-space.js.map +1 -1
  86. package/dist/normalize-dashes.js +5 -4
  87. package/dist/normalize-dashes.js.map +1 -1
  88. package/dist/normalize-identifiers.js +6 -6
  89. package/dist/normalize-identifiers.js.map +1 -1
  90. package/dist/normalize-qualifying-information.js +4 -4
  91. package/dist/normalize-qualifying-information.js.map +1 -1
  92. package/dist/normalize-utf8-diacritics.js +7 -7
  93. package/dist/normalize-utf8-diacritics.js.map +1 -1
  94. package/dist/normalizeFieldForComparison.js +21 -20
  95. package/dist/normalizeFieldForComparison.js.map +1 -1
  96. package/dist/normalizeSubfieldValueForComparison.js +1 -2
  97. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  98. package/dist/prepublicationUtils.js +3 -3
  99. package/dist/prepublicationUtils.js.map +1 -1
  100. package/dist/punctuation/index.js +14 -31
  101. package/dist/punctuation/index.js.map +1 -1
  102. package/dist/punctuation2.js +9 -10
  103. package/dist/punctuation2.js.map +1 -1
  104. package/dist/reindexSubfield6OccurenceNumbers.js +8 -9
  105. package/dist/reindexSubfield6OccurenceNumbers.js.map +1 -1
  106. package/dist/removeDuplicateDataFields.js +18 -20
  107. package/dist/removeDuplicateDataFields.js.map +1 -1
  108. package/dist/removeInferiorDataFields.js +16 -19
  109. package/dist/removeInferiorDataFields.js.map +1 -1
  110. package/dist/resolvable-ext-references-melinda.js +4 -8
  111. package/dist/resolvable-ext-references-melinda.js.map +1 -1
  112. package/dist/resolveOrphanedSubfield6s.js +9 -9
  113. package/dist/resolveOrphanedSubfield6s.js.map +1 -1
  114. package/dist/sanitize-vocabulary-source-codes.js +9 -9
  115. package/dist/sanitize-vocabulary-source-codes.js.map +1 -1
  116. package/dist/sort-tags.js +2 -2
  117. package/dist/sort-tags.js.map +1 -1
  118. package/dist/sortFields.js +4 -9
  119. package/dist/sortFields.js.map +1 -1
  120. package/dist/sortRelatorTerms.js +4 -5
  121. package/dist/sortRelatorTerms.js.map +1 -1
  122. package/dist/sortSubfields.js +6 -7
  123. package/dist/sortSubfields.js.map +1 -1
  124. package/dist/stripPunctuation.js +2 -2
  125. package/dist/stripPunctuation.js.map +1 -1
  126. package/dist/subfield-exclusion.js +4 -11
  127. package/dist/subfield-exclusion.js.map +1 -1
  128. package/dist/subfield6Utils.js +12 -11
  129. package/dist/subfield6Utils.js.map +1 -1
  130. package/dist/subfield8Utils.js +8 -9
  131. package/dist/subfield8Utils.js.map +1 -1
  132. package/dist/subfieldValueNormalizations.js +5 -8
  133. package/dist/subfieldValueNormalizations.js.map +1 -1
  134. package/dist/sync-007-and-300.js +8 -8
  135. package/dist/sync-007-and-300.js.map +1 -1
  136. package/dist/translate-terms.js +5 -6
  137. package/dist/translate-terms.js.map +1 -1
  138. package/dist/typeOfDate-008.js +3 -4
  139. package/dist/typeOfDate-008.js.map +1 -1
  140. package/dist/unicode-decomposition.js +1 -1
  141. package/dist/unicode-decomposition.js.map +1 -1
  142. package/dist/update-field-540.js +5 -6
  143. package/dist/update-field-540.js.map +1 -1
  144. package/dist/urn.js +4 -9
  145. package/dist/urn.js.map +1 -1
  146. package/dist/utils.js +5 -9
  147. package/dist/utils.js.map +1 -1
  148. package/eslint.config.mjs +53 -0
  149. package/package.json +12 -13
  150. package/src/access-rights.js +4 -4
  151. package/src/addMissingField336.js +1 -1
  152. package/src/cyrillux-usemarcon-replacement.js +38 -38
  153. package/src/cyrillux.js +14 -14
  154. package/src/disambiguateSeriesStatements.js +3 -3
  155. package/src/double-commas.js +2 -2
  156. package/src/duplicates-ind1.js +1 -1
  157. package/src/empty-fields.js +4 -4
  158. package/src/ending-punctuation.js +46 -49
  159. package/src/ending-whitespace.js +0 -2
  160. package/src/field-008-18-34-character-groups.js +5 -5
  161. package/src/field-505-separators.js +6 -6
  162. package/src/field-521-fix.js +6 -6
  163. package/src/field-exclusion.js +12 -12
  164. package/src/field-exclusion.spec.js +4 -4
  165. package/src/field-structure.js +5 -5
  166. package/src/fields-present.js +1 -1
  167. package/src/fields-present.spec.js +1 -1
  168. package/src/fix-33X.js +5 -5
  169. package/src/fix-country-codes.js +3 -3
  170. package/src/fix-language-codes.js +10 -9
  171. package/src/fixRelatorTerms.js +8 -8
  172. package/src/fixed-fields.js +3 -3
  173. package/src/identical-fields.js +3 -3
  174. package/src/indicator-fixes.js +15 -15
  175. package/src/isbn-issn.js +11 -11
  176. package/src/item-language.js +10 -10
  177. package/src/merge-fields/counterpartField.js +7 -7
  178. package/src/merge-fields/index.js +3 -3
  179. package/src/merge-fields/mergeConstraints.js +1 -1
  180. package/src/merge-fields/mergeField.js +16 -17
  181. package/src/merge-fields/mergeIndicator.js +5 -5
  182. package/src/merge-fields/mergeOrAddPostprocess.js +9 -9
  183. package/src/merge-fields/mergeOrAddSubfield.js +6 -6
  184. package/src/merge-fields/mergeSubfield.js +8 -8
  185. package/src/merge-fields/removeDuplicateSubfields.js +1 -2
  186. package/src/merge-fields/worldKnowledge.js +1 -1
  187. package/src/mergeField500Lisapainokset.js +0 -2
  188. package/src/mergeRelatorTermFields.js +3 -3
  189. package/src/modernize-502.js +6 -6
  190. package/src/multiple-subfield-0.js +4 -4
  191. package/src/non-breaking-space.js +0 -2
  192. package/src/normalize-dashes.js +4 -4
  193. package/src/normalize-identifiers.js +6 -6
  194. package/src/normalize-qualifying-information.js +4 -4
  195. package/src/normalize-utf8-diacritics.js +7 -7
  196. package/src/normalizeFieldForComparison.js +20 -20
  197. package/src/normalizeSubfieldValueForComparison.js +1 -1
  198. package/src/prepublicationUtils.js +3 -3
  199. package/src/punctuation/index.js +29 -29
  200. package/src/punctuation2.js +10 -10
  201. package/src/reindexSubfield6OccurenceNumbers.js +9 -9
  202. package/src/removeDuplicateDataFields.js +21 -23
  203. package/src/removeInferiorDataFields.js +19 -19
  204. package/src/resolvable-ext-references-melinda.js +8 -8
  205. package/src/resolveOrphanedSubfield6s.js +9 -9
  206. package/src/sanitize-vocabulary-source-codes.js +8 -8
  207. package/src/sort-tags.js +2 -2
  208. package/src/sortFields.js +6 -6
  209. package/src/sortRelatorTerms.js +5 -5
  210. package/src/sortSubfields.js +7 -7
  211. package/src/stripPunctuation.js +2 -2
  212. package/src/subfield-exclusion.js +11 -11
  213. package/src/subfield6Utils.js +11 -11
  214. package/src/subfield8Utils.js +6 -9
  215. package/src/subfieldValueNormalizations.js +5 -7
  216. package/src/sync-007-and-300.js +8 -8
  217. package/src/translate-terms.js +3 -5
  218. package/src/typeOfDate-008.js +3 -3
  219. package/src/unicode-decomposition.js +1 -1
  220. package/src/update-field-540.js +6 -6
  221. package/src/urn.js +8 -6
  222. package/src/utils.js +8 -8
  223. package/.eslintignore +0 -1
@@ -37,10 +37,10 @@ function debugFieldComparison(oldField, newField) {
37
37
  // NB: Debug-only function!
38
38
  /*
39
39
  // We may drop certain subfields:
40
- if (oldField.subfields.length === newField.subfields.length) { // eslint-disable-line functional/no-conditional-statements
40
+ if (oldField.subfields.length === newField.subfields.length) {
41
41
  oldField.subfields.forEach((subfield, index) => {
42
42
  const newValue = newField.subfields[index].value;
43
- if (subfield.value !== newValue) { // eslint-disable-line functional/no-conditional-statements
43
+ if (subfield.value !== newValue) {
44
44
  nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);
45
45
  }
46
46
  });
@@ -117,13 +117,14 @@ function subfieldValueLowercase(value, subfieldCode, tag) {
117
117
  return value;
118
118
  }
119
119
  function subfieldLowercase(sf, tag) {
120
- sf.value = subfieldValueLowercase(sf.value, sf.code, tag); // eslint-disable-line functional/immutable-data
120
+ sf.value = subfieldValueLowercase(sf.value, sf.code, tag);
121
121
  }
122
122
  function fieldLowercase(field) {
123
123
  if (skipFieldLowercase(field)) {
124
124
  return;
125
125
  }
126
- field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));
126
+ field.subfields.forEach(sf => subfieldLowercase(sf, field.tag)); // eslint-disable-line array-callback-return
127
+
127
128
  function skipFieldLowercase(field) {
128
129
  if (skipAllFieldNormalizations(field.tag)) {
129
130
  return true;
@@ -139,7 +140,7 @@ function hack490SubfieldA(field) {
139
140
  if (field.tag !== '490') {
140
141
  return;
141
142
  }
142
- field.subfields.forEach(sf => removeSarja(sf));
143
+ field.subfields.forEach(sf => removeSarja(sf)); // eslint-disable-line array-callback-return
143
144
 
144
145
  // NB! This won't work, if the punctuation has not been stripped beforehand!
145
146
  function removeSarja(subfield) {
@@ -148,7 +149,7 @@ function hack490SubfieldA(field) {
148
149
  }
149
150
  const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');
150
151
  if (tmp.length > 0) {
151
- subfield.value = tmp; // eslint-disable-line functional/immutable-data
152
+ subfield.value = tmp;
152
153
  return;
153
154
  }
154
155
  }
@@ -177,11 +178,12 @@ function normalizeISBN(field) {
177
178
 
178
179
  //nvdebug(`ISBN-field? ${fieldToString(field)}`);
179
180
  const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));
180
- relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf));
181
+ relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf)); // eslint-disable-line array-callback-return
182
+
181
183
  function normalizeIsbnSubfield(sf) {
182
184
  //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);
183
- sf.value = sf.value.replace(/-/ug, ''); // eslint-disable-line functional/immutable-data
184
- sf.value = sf.value.replace(/x/u, 'X'); // eslint-disable-line functional/immutable-data
185
+ sf.value = sf.value.replace(/-/ug, '');
186
+ sf.value = sf.value.replace(/x/u, 'X');
185
187
  }
186
188
  }
187
189
  function fieldSpecificHacks(field) {
@@ -190,16 +192,16 @@ function fieldSpecificHacks(field) {
190
192
  }
191
193
  function fieldTrimSubfieldValues(field) {
192
194
  field.subfields?.forEach(sf => {
193
- sf.value = sf.value.replace(/^[ \t\n]+/u, ''); // eslint-disable-line functional/immutable-data
194
- sf.value = sf.value.replace(/[ \t\n]+$/u, ''); // eslint-disable-line functional/immutable-data
195
- sf.value = sf.value.replace(/[ \t\n]+/gu, ' '); // eslint-disable-line functional/immutable-data
195
+ sf.value = sf.value.replace(/^[ \t\n]+/u, '');
196
+ sf.value = sf.value.replace(/[ \t\n]+$/u, '');
197
+ sf.value = sf.value.replace(/[ \t\n]+/gu, ' ');
196
198
  });
197
199
  }
198
200
  function fieldRemoveDecomposedDiacritics(field) {
199
201
  // Raison d'être/motivation: "Sirén" and diacriticless "Siren" might refer to a same surname, so this normalization
200
202
  // allows us to compare authors and avoid duplicate fields.
201
203
  field.subfields.forEach(sf => {
202
- sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data
204
+ sf.value = removeDecomposedDiacritics(sf.value);
203
205
  });
204
206
  }
205
207
  function removeDecomposedDiacritics(value = '') {
@@ -215,7 +217,7 @@ function normalizeSubfieldValue(value, subfieldCode, tag) {
215
217
 
216
218
  // Normalize: s. = sivut = pp.
217
219
  value = (0, _normalizeSubfieldValueForComparison.normalizePartData)(value, subfieldCode, tag);
218
- value = value.replace(/^\[([^[\]]+)\]/gu, '$1'); // eslint-disable-line functional/immutable-data, prefer-named-capture-group
220
+ value = value.replace(/^\[([^[\]]+)\]/gu, '$1'); // eslint-disable-line functional/immutable-data
219
221
 
220
222
  if (['130', '730'].includes(tag) && subfieldCode === 'a') {
221
223
  value = value.replace(' : ', ', '); // "Halloween ends (elokuva, 2022)" vs "Halloween ends (elokuva : 2023)"
@@ -250,7 +252,7 @@ function removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {
250
252
  if (tag === '080') {
251
253
  return value;
252
254
  }
253
- /* eslint-disable */
255
+
254
256
  // 3" refers to inches, but as this is for comparison only we don't mind...
255
257
  value = value.replace(/['‘’"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html
256
258
  // MRA-273: Handle X00$a name initials.
@@ -260,11 +262,10 @@ function removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {
260
262
  // 400 is used in auth records. It's not a bib field at all.
261
263
  value = value.replace(/([A-Z]|Å|Ä|Ö)\. +/ugi, '$1.');
262
264
  }
263
- /* eslint-enable */
264
265
  return value;
265
266
  }
266
267
  function normalizeField(field) {
267
- //sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data
268
+ //sf.value = removeDecomposedDiacritics(sf.value);
268
269
  (0, _punctuation.fieldStripPunctuation)(field);
269
270
  fieldLowercase(field);
270
271
  (0, _normalizeIdentifiers.fieldNormalizeControlNumbers)(field); // FIN11 vs FI-MELINDA etc.
@@ -279,10 +280,10 @@ function cloneAndNormalizeFieldForComparison(field) {
279
280
  }
280
281
  clonedField.subfields.forEach(sf => {
281
282
  // Do this for all fields or some fields?
282
- sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag); // eslint-disable-line functional/immutable-data
283
- sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code); // eslint-disable-line functional/immutable-data
283
+ sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag);
284
+ sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);
284
285
  });
285
- normalizeField(clonedField); // eslint-disable-line functional/immutable-data
286
+ normalizeField(clonedField);
286
287
  fieldRemoveDecomposedDiacritics(clonedField);
287
288
  fieldSpecificHacks(clonedField);
288
289
  fieldTrimSubfieldValues(clonedField);
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","e","__esModule","default","debug","createDebugLogger","debugDev","extend","isEnnakkotietoSubfieldG","subfield","code","value","match","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","normalizeISBN","relevantSubfields","filter","normalizeIsbnSubfield","fieldSpecificHacks","fieldTrimSubfieldValues","fieldRemoveDecomposedDiacritics","removeDecomposedDiacritics","String","normalizeSubfieldValue","normalizePartData","cloneAndRemovePunctuation","clonedField","clone","fieldSkipNormalization","fieldStripPunctuation","removeCharsThatDontCarryMeaning","normalizeField","fieldNormalizeControlNumbers","cloneAndNormalizeFieldForComparison"],"sources":["../src/normalizeFieldForComparison.js"],"sourcesContent":["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function isEnnakkotietoSubfieldG(subfield) {\n if (subfield.code !== 'g') {\n return false;\n }\n return subfield.value.match(/^ENNAKKOTIETO\\.?$/gui);\n}\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) { // eslint-disable-line functional/no-conditional-statements\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) { // eslint-disable-line functional/no-conditional-statements\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n if (isEnnakkotietoSubfieldG({'code': subfieldCode, value})) {\n return true;\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag); // eslint-disable-line functional/immutable-data\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf));\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp; // eslint-disable-line functional/immutable-data\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf));\n\n function normalizeIsbnSubfield(sf) {\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/x/u, 'X'); // eslint-disable-line functional/immutable-data\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' '); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data, prefer-named-capture-group\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?\n // Ø => Ö?\n // ß => ss\n // þ => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // ü => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n /* eslint-disable */\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['‘’\"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|Å|Ä|Ö)\\. +/ugi, '$1.');\n }\n /* eslint-enable */\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag); // eslint-disable-line functional/immutable-data\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);// eslint-disable-line functional/immutable-data\n });\n\n normalizeField(clonedField); // eslint-disable-line functional/immutable-data\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","e","__esModule","default","debug","createDebugLogger","debugDev","extend","isEnnakkotietoSubfieldG","subfield","code","value","match","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","normalizeISBN","relevantSubfields","filter","normalizeIsbnSubfield","fieldSpecificHacks","fieldTrimSubfieldValues","fieldRemoveDecomposedDiacritics","removeDecomposedDiacritics","String","normalizeSubfieldValue","normalizePartData","cloneAndRemovePunctuation","clonedField","clone","fieldSkipNormalization","fieldStripPunctuation","removeCharsThatDontCarryMeaning","normalizeField","fieldNormalizeControlNumbers","cloneAndNormalizeFieldForComparison"],"sources":["../src/normalizeFieldForComparison.js"],"sourcesContent":["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function isEnnakkotietoSubfieldG(subfield) {\n if (subfield.code !== 'g') {\n return false;\n }\n return subfield.value.match(/^ENNAKKOTIETO\\.?$/gui);\n}\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) {\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) {\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n if (isEnnakkotietoSubfieldG({'code': subfieldCode, value})) {\n return true;\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag);\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag)); // eslint-disable-line array-callback-return\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf)); // eslint-disable-line array-callback-return\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp;\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf)); // eslint-disable-line array-callback-return\n\n function normalizeIsbnSubfield(sf) {\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, '');\n sf.value = sf.value.replace(/x/u, 'X');\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' ');\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value);\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?\n // Ø => Ö?\n // ß => ss\n // þ => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // ü => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['‘’\"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|Å|Ä|Ö)\\. +/ugi, '$1.');\n }\n\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value);\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag);\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);\n });\n\n normalizeField(clonedField);\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -27,8 +27,7 @@ function subfieldContainsPartData(tag, subfieldCode) {
27
27
  function splitPartData(originalValue) {
28
28
  // This a very hacky function, but cand really help it, as the the data is very iffy as well...
29
29
  // Remove punctuation and brackets:
30
- const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\[([0-9]+)\]$/ui, '$1'); // eslint-disable-line prefer-named-capture-group
31
-
30
+ const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\[([0-9]+)\]$/ui, '$1');
32
31
  const [year, rest] = extractYear(value);
33
32
  const splitPoint = rest.lastIndexOf(' '); // MRA-627: "5, 2017" should be split here. Think of this later on...
34
33
  if (splitPoint === -1) {
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeSubfieldValueForComparison.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","subfieldContainsPartData","tag","subfieldCode","includes","splitPartData","originalValue","value","replace","year","rest","extractYear","splitPoint","lastIndexOf","undefined","lhs","substr","rhs","match","len","length","normalizePartType","toLowerCase","romanNumbers","normalizePartNumber","arabicValue","nvdebug","splitAndNormalizePartData","partType","partYear","partNumber","partsAgree","value1","value2","partType1","partYear1","partNumber1","partType2","partYear2","partNumber2","normalizePartData"],"sources":["../src/normalizeSubfieldValueForComparison.js"],"sourcesContent":["import {nvdebug} from './utils';\nimport createDebugLogger from 'debug';\n\n// Normalizes at least 490$v and 773$g which contain information such as \"Raita 5\" vs \"5\", and \"Osa 3\" vs \"Osa III\".\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeSubfieldValueForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function subfieldContainsPartData(tag, subfieldCode) {\n // NB! Used by reducers' mergeSubield.js\n if (subfieldCode === 'v' && ['490', '800', '810', '811', '830'].includes(tag)) {\n return true;\n }\n if (tag === '773' && subfieldCode === 'g') {\n return true;\n }\n return false;\n}\n\nfunction splitPartData(originalValue) {\n // This a very hacky function, but cand really help it, as the the data is very iffy as well...\n // Remove punctuation and brackets:\n const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\\[([0-9]+)\\]$/ui, '$1'); // eslint-disable-line prefer-named-capture-group\n\n const [year, rest] = extractYear(value);\n\n const splitPoint = rest.lastIndexOf(' '); // MRA-627: \"5, 2017\" should be split here. Think of this later on...\n if (splitPoint === -1) {\n return [undefined, year, rest];\n }\n const lhs = rest.substr(0, splitPoint);\n const rhs = rest.substr(splitPoint + 1);\n return [lhs, year, rhs];\n\n function extractYear(value) {\n // NB! Note that this is far for perfect. It cover just some very common cases...\n\n // \"2023, 3\" => [\"2023\", \"3\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9]), (?:nro |n:o)?[1-9][0-9]{0,2}$/ui)) {\n return [value.substr(0, 4), value.substr(6)];\n }\n // \"2023/12\" => [\"2023\", \"12\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9])[/:][1-9][0-9]{0,2}$/u)) {\n return [value.substr(0, 4), value.substr(5)];\n }\n // \"Vol. 3/2023\" => [\"2023\", \"Vol. 3\"]\n if (value.match(/^[^0-9]*[1-9][0-9]{0,2}\\/(?:1[89][0-9][0-9]|20[012][0-9])$/u)) {\n const len = value.length;\n return [value.substr(len - 4), value.substr(0, len - 5)];\n }\n\n\n return [undefined, value];\n }\n}\n\nfunction normalizePartType(originalValue) {\n if (originalValue === undefined) {\n return undefined;\n }\n const value = originalValue.toLowerCase();\n\n // Return Finnish singular nominative. Choise of language is arbitrary. This is best-ish for debug purposes...\n if (['n:o', 'no', 'nr', 'nro', 'number', 'numero', 'nummer'].includes(value)) {\n return 'numero';\n }\n if (['band', 'bd', 'häfte', 'nide', 'osa', 'part', 'teil', 'vol', 'vol.', 'volume'].includes(value)) {\n return 'osa';\n }\n\n if (['p.', 'page', 'pages', 'pp.', 's.', 'sidor', 'sivu', 'sivut'].includes(value)) {\n return 'sivu';\n }\n\n return value;\n}\n\nconst romanNumbers = {'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5', 'VI': '6', 'X': '10'};\n\nfunction normalizePartNumber(value) {\n // Should we handle all Roman numbers or some range of them?\n // There's probably a library for our purposes..\n if (value in romanNumbers) {\n const arabicValue = romanNumbers[value];\n nvdebug(` MAP ${value} to ${arabicValue}`, debugDev);\n return arabicValue;\n }\n return value.toLowerCase();\n}\n\nfunction splitAndNormalizePartData(value) {\n // This is just a stub. Does not handle eg. \"Levy 2, raita 15\"\n const [partType, partYear, partNumber] = splitPartData(value);\n //nvdebug(` LHS: '${lhs}'`, debugDev);\n //nvdebug(` RHS: '${rhs}'`, debugDev);\n return [normalizePartType(partType), partYear, normalizePartNumber(partNumber)];\n}\n\nexport function partsAgree(value1, value2, tag, subfieldCode) {\n // Note, that parts can not be normalized away, as \"2\" can agree with \"Part 2\" and \"Raita 2\" and \"Volume 2\"...\n // NB! Used by reducers' mergeSubield.js\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return false;\n }\n const [partType1, partYear1, partNumber1] = splitAndNormalizePartData(value1);\n const [partType2, partYear2, partNumber2] = splitAndNormalizePartData(value2);\n //nvdebug(`P1: ${partType1} | ${partYear1} | ${partNumber1}`);\n //nvdebug(`P2: ${partType2} | ${partYear2} | ${partNumber2}`);\n if (partNumber1 !== partNumber2) {\n return false;\n }\n if (partType1 !== undefined && partType2 !== undefined && partType1 !== partType2) {\n return false;\n }\n if (partYear1 !== undefined && partYear2 !== undefined && partYear1 !== partYear2) {\n return false;\n }\n\n\n return true;\n}\n\nexport function normalizePartData(value, subfieldCode, tag) {\n // This is for normalizing values for equality comparison only!\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return value;\n }\n\n const [partType, partYear, partNumber] = splitAndNormalizePartData(value);\n if (partType === undefined) {\n if (partYear === undefined) {\n return partNumber;\n }\n return `${partNumber}/${partYear}`;\n }\n if (partYear === undefined) {\n return `${partType} ${partNumber}`;\n }\n return `${partType} ${partNumber}/${partYear}`;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"normalizeSubfieldValueForComparison.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","subfieldContainsPartData","tag","subfieldCode","includes","splitPartData","originalValue","value","replace","year","rest","extractYear","splitPoint","lastIndexOf","undefined","lhs","substr","rhs","match","len","length","normalizePartType","toLowerCase","romanNumbers","normalizePartNumber","arabicValue","nvdebug","splitAndNormalizePartData","partType","partYear","partNumber","partsAgree","value1","value2","partType1","partYear1","partNumber1","partType2","partYear2","partNumber2","normalizePartData"],"sources":["../src/normalizeSubfieldValueForComparison.js"],"sourcesContent":["import {nvdebug} from './utils';\nimport createDebugLogger from 'debug';\n\n// Normalizes at least 490$v and 773$g which contain information such as \"Raita 5\" vs \"5\", and \"Osa 3\" vs \"Osa III\".\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeSubfieldValueForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function subfieldContainsPartData(tag, subfieldCode) {\n // NB! Used by reducers' mergeSubield.js\n if (subfieldCode === 'v' && ['490', '800', '810', '811', '830'].includes(tag)) {\n return true;\n }\n if (tag === '773' && subfieldCode === 'g') {\n return true;\n }\n return false;\n}\n\nfunction splitPartData(originalValue) {\n // This a very hacky function, but cand really help it, as the the data is very iffy as well...\n // Remove punctuation and brackets:\n const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\\[([0-9]+)\\]$/ui, '$1');\n\n const [year, rest] = extractYear(value);\n\n const splitPoint = rest.lastIndexOf(' '); // MRA-627: \"5, 2017\" should be split here. Think of this later on...\n if (splitPoint === -1) {\n return [undefined, year, rest];\n }\n const lhs = rest.substr(0, splitPoint);\n const rhs = rest.substr(splitPoint + 1);\n return [lhs, year, rhs];\n\n function extractYear(value) {\n // NB! Note that this is far for perfect. It cover just some very common cases...\n\n // \"2023, 3\" => [\"2023\", \"3\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9]), (?:nro |n:o)?[1-9][0-9]{0,2}$/ui)) {\n return [value.substr(0, 4), value.substr(6)];\n }\n // \"2023/12\" => [\"2023\", \"12\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9])[/:][1-9][0-9]{0,2}$/u)) {\n return [value.substr(0, 4), value.substr(5)];\n }\n // \"Vol. 3/2023\" => [\"2023\", \"Vol. 3\"]\n if (value.match(/^[^0-9]*[1-9][0-9]{0,2}\\/(?:1[89][0-9][0-9]|20[012][0-9])$/u)) {\n const len = value.length;\n return [value.substr(len - 4), value.substr(0, len - 5)];\n }\n\n\n return [undefined, value];\n }\n}\n\nfunction normalizePartType(originalValue) {\n if (originalValue === undefined) {\n return undefined;\n }\n const value = originalValue.toLowerCase();\n\n // Return Finnish singular nominative. Choise of language is arbitrary. This is best-ish for debug purposes...\n if (['n:o', 'no', 'nr', 'nro', 'number', 'numero', 'nummer'].includes(value)) {\n return 'numero';\n }\n if (['band', 'bd', 'häfte', 'nide', 'osa', 'part', 'teil', 'vol', 'vol.', 'volume'].includes(value)) {\n return 'osa';\n }\n\n if (['p.', 'page', 'pages', 'pp.', 's.', 'sidor', 'sivu', 'sivut'].includes(value)) {\n return 'sivu';\n }\n\n return value;\n}\n\nconst romanNumbers = {'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5', 'VI': '6', 'X': '10'};\n\nfunction normalizePartNumber(value) {\n // Should we handle all Roman numbers or some range of them?\n // There's probably a library for our purposes..\n if (value in romanNumbers) {\n const arabicValue = romanNumbers[value];\n nvdebug(` MAP ${value} to ${arabicValue}`, debugDev);\n return arabicValue;\n }\n return value.toLowerCase();\n}\n\nfunction splitAndNormalizePartData(value) {\n // This is just a stub. Does not handle eg. \"Levy 2, raita 15\"\n const [partType, partYear, partNumber] = splitPartData(value);\n //nvdebug(` LHS: '${lhs}'`, debugDev);\n //nvdebug(` RHS: '${rhs}'`, debugDev);\n return [normalizePartType(partType), partYear, normalizePartNumber(partNumber)];\n}\n\nexport function partsAgree(value1, value2, tag, subfieldCode) {\n // Note, that parts can not be normalized away, as \"2\" can agree with \"Part 2\" and \"Raita 2\" and \"Volume 2\"...\n // NB! Used by reducers' mergeSubield.js\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return false;\n }\n const [partType1, partYear1, partNumber1] = splitAndNormalizePartData(value1);\n const [partType2, partYear2, partNumber2] = splitAndNormalizePartData(value2);\n //nvdebug(`P1: ${partType1} | ${partYear1} | ${partNumber1}`);\n //nvdebug(`P2: ${partType2} | ${partYear2} | ${partNumber2}`);\n if (partNumber1 !== partNumber2) {\n return false;\n }\n if (partType1 !== undefined && partType2 !== undefined && partType1 !== partType2) {\n return false;\n }\n if (partYear1 !== undefined && partYear2 !== undefined && partYear1 !== partYear2) {\n return false;\n }\n\n\n return true;\n}\n\nexport function normalizePartData(value, subfieldCode, tag) {\n // This is for normalizing values for equality comparison only!\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return value;\n }\n\n const [partType, partYear, partNumber] = splitAndNormalizePartData(value);\n if (partType === undefined) {\n if (partYear === undefined) {\n return partNumber;\n }\n return `${partNumber}/${partYear}`;\n }\n if (partYear === undefined) {\n return `${partType} ${partNumber}`;\n }\n return `${partType} ${partNumber}/${partYear}`;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -167,7 +167,7 @@ function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {
167
167
  return;
168
168
  }
169
169
  (0, _utils.nvdebug)(`Delete all ${f500.length} instance(s) of field 500`, debugDev);
170
- f500.forEach(field => record.removeField(field));
170
+ f500.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return
171
171
  }
172
172
  function removeWorsePrepubField500s(record) {
173
173
  // Remove lower-level entries:
@@ -175,7 +175,7 @@ function removeWorsePrepubField500s(record) {
175
175
  (0, _utils.nvdebugFieldArray)(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);
176
176
  const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));
177
177
  (0, _utils.nvdebugFieldArray)(nonBest, ' Remove non-best 500: ', debugDev);
178
- nonBest.forEach(field => record.removeField(field));
178
+ nonBest.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return
179
179
  }
180
180
  function removeWorsePrepubField594s(record) {
181
181
  // Remove lower-level entries:
@@ -183,7 +183,7 @@ function removeWorsePrepubField594s(record) {
183
183
  (0, _utils.nvdebugFieldArray)(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);
184
184
  const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));
185
185
  (0, _utils.nvdebugFieldArray)(nonBest, ' Remove non-best 594: ', debugDev);
186
- nonBest.forEach(field => record.removeField(field));
186
+ nonBest.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return
187
187
  }
188
188
  function isEnnakkotietoSubfield(subfield) {
189
189
  if (subfield.code !== '9' && subfield.code !== 'g') {
@@ -1 +1 @@
1
- {"version":3,"file":"prepublicationUtils.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","KONEELLISESTI_TUOTETTU_TIETUE","TARKISTETTU_ENNAKKOTIETO","ENNAKKOTIETO","encodingLevelPreferenceArray","prepublicationLevelIndex","indexOf","prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto","prepublicationLevel","encodingLevelIsBetterThanPrepublication","encodingLevel","index","fieldRefersToKoneellisestiTuotettuTietue","field","subfields","some","sf","code","value","match","fieldRefersToTarkistettuEnnakkotieto","fieldRefersToEnnakkotieto","firstFieldHasBetterPrepubEncodingLevel","field1","field2","getRelevant5XXFields","record","f500","f594","cands","actualGetFields","filtered","filter","hasRelevantPrepubData","tag","every","includes","get","getPrepublicationLevel","fields","f","baseHasEqualOrHigherEncodingLevel","baseEncodingLevel","sourceEncodingLevel","baseIndex","sourceIndex","hasFikkaLOW","fieldHasSubfield","hasNatLibFi042","isFikkaRecord","getEncodingLevel","leader","substring","deleteAllPrepublicationNotesFromField500InNonPubRecord","length","nvdebug","forEach","removeField","removeWorsePrepubField500s","nvdebugFieldArray","nonBest","removeWorsePrepubField594s","fields594","isEnnakkotietoSubfield","subfield","coreString","substr","toLowerCase","isEnnakkotietoField","isKingOfTheHill","opposingFields","opposingField"],"sources":["../src/prepublicationUtils.js"],"sourcesContent":["import {fieldHasSubfield, nvdebug, nvdebugFieldArray} from './utils';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:prepublicationUtils');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best\nconst TARKISTETTU_ENNAKKOTIETO = 2;\nconst ENNAKKOTIETO = 3;\n//const EI_TASOA = 4;\n\nconst encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145\nconst prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');\n\nexport function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {\n return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;\n}\n\n\nexport function encodingLevelIsBetterThanPrepublication(encodingLevel) {\n const index = encodingLevelPreferenceArray.indexOf(encodingLevel);\n return index > -1 && index < prepublicationLevelIndex;\n}\n\n// These three functions below all refer to field 500:\nexport function fieldRefersToKoneellisestiTuotettuTietue(field) {\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^Koneellisesti tuotettu tietue/u));\n}\n\n\nexport function fieldRefersToTarkistettuEnnakkotieto(field) {\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^tarkistettu ennakkotieto/ui));\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?\n if (field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^ennakkotieto(?:$|[. ])/ui))) {\n return true;\n }\n\n // MRA-420: \"EI VIELÄ ILMESTYNYT\" is a Helmet note, that is semantically similar to ENNAKKOTIETO:\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^EI VIELÄ ILMESTYNYT/u));\n}\n\n\nexport function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return false;\n}\n\nexport function getRelevant5XXFields(record, f500 = false, f594 = false) {\n const cands = actualGetFields();\n //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);\n const filtered = cands.filter(field => hasRelevantPrepubData(field));\n //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);\n return filtered;\n\n //return actualGetFields().filter(field => hasRelevantPrepubData(field));\n\n function hasRelevantPrepubData(field) {\n // Check prepub ($a):\n if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToTarkistettuEnnakkotieto(field) && !fieldRefersToEnnakkotieto(field)) {\n return false;\n }\n // Check relevance (594$5):\n if (field.tag === '500') {\n return field.subfields.every(sf => sf.code !== '5'); //true;\n }\n return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));\n }\n\n function actualGetFields() {\n if (f500 && f594) {\n return record.get(/^(?:500|594)$/u);\n }\n if (f500) {\n return record.get(/^500$/u);\n }\n if (f594) {\n return record.get(/^594$/u);\n }\n return [];\n }\n\n}\n\n\n// Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...\n// We should use that and not have a copy here...\nexport function getPrepublicationLevel(record, f500 = false, f594 = false) {\n // Smaller return value is better\n const fields = getRelevant5XXFields(record, f500, f594);\n\n if (!fields) {\n return null;\n }\n if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {\n return KONEELLISESTI_TUOTETTU_TIETUE;\n }\n\n if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {\n return TARKISTETTU_ENNAKKOTIETO;\n }\n\n if (fields.some(f => fieldRefersToEnnakkotieto(f))) {\n return ENNAKKOTIETO;\n }\n\n return null;\n}\n\n\nexport function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {\n const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);\n const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);\n\n if (baseIndex === -1) {\n // Base wins if both are bad:\n return sourceIndex === -1;\n }\n return baseIndex <= sourceIndex;\n}\n\n\nfunction hasFikkaLOW(record) {\n return record.fields.some(field => field.tag === 'LOW' && fieldHasSubfield(field, 'a', 'FIKKA'));\n}\n\n\nfunction hasNatLibFi042(record) {\n return record.fields.some(field => field.tag === '042' && (fieldHasSubfield(field, 'a', 'finb') || fieldHasSubfield(field, 'a', 'finbd')));\n}\n\n\nexport function isFikkaRecord(record) {\n // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?\n return hasFikkaLOW(record) && hasNatLibFi042(record);\n}\n\n\nexport function getEncodingLevel(record) {\n return record.leader.substring(17, 18);\n}\n\n\nexport function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {\n const encodingLevel = getEncodingLevel(record);\n // Skip prepublication (or theoretically even worse) records:\n if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {\n //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here\n return;\n }\n\n // MET-306: keep \"koneellisesti tuotettu tietue\" if encoding level is '2':\n const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);\n if (f500.length === 0) {\n return;\n }\n\n\n nvdebug(`Delete all ${f500.length} instance(s) of field 500`, debugDev);\n f500.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField500s(record) {\n // Remove lower-level entries:\n const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true\n nvdebugFieldArray(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);\n const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 500: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField594s(record) {\n // Remove lower-level entries:\n const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true\n nvdebugFieldArray(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);\n const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 594: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function isEnnakkotietoSubfield(subfield) {\n if (subfield.code !== '9' && subfield.code !== 'g') {\n return false;\n }\n // Length <= 13 allows punctuation, but does not require it:\n if (subfield.value.length <= 13) {\n const coreString = subfield.value.substr(0, 12);\n if (coreString.toLowerCase() === 'ennakkotieto') { // Lowercase term first seen in MET-575\n return true;\n }\n }\n return false;\n}\n\nexport function isEnnakkotietoField(field) {\n return field.subfields.some(sf => isEnnakkotietoSubfield(sf));\n}\n\nexport function isKingOfTheHill(field, opposingFields) {\n // Field is no better than at least one of the opposing fields\n return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));\n}\n\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"prepublicationUtils.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","KONEELLISESTI_TUOTETTU_TIETUE","TARKISTETTU_ENNAKKOTIETO","ENNAKKOTIETO","encodingLevelPreferenceArray","prepublicationLevelIndex","indexOf","prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto","prepublicationLevel","encodingLevelIsBetterThanPrepublication","encodingLevel","index","fieldRefersToKoneellisestiTuotettuTietue","field","subfields","some","sf","code","value","match","fieldRefersToTarkistettuEnnakkotieto","fieldRefersToEnnakkotieto","firstFieldHasBetterPrepubEncodingLevel","field1","field2","getRelevant5XXFields","record","f500","f594","cands","actualGetFields","filtered","filter","hasRelevantPrepubData","tag","every","includes","get","getPrepublicationLevel","fields","f","baseHasEqualOrHigherEncodingLevel","baseEncodingLevel","sourceEncodingLevel","baseIndex","sourceIndex","hasFikkaLOW","fieldHasSubfield","hasNatLibFi042","isFikkaRecord","getEncodingLevel","leader","substring","deleteAllPrepublicationNotesFromField500InNonPubRecord","length","nvdebug","forEach","removeField","removeWorsePrepubField500s","nvdebugFieldArray","nonBest","removeWorsePrepubField594s","fields594","isEnnakkotietoSubfield","subfield","coreString","substr","toLowerCase","isEnnakkotietoField","isKingOfTheHill","opposingFields","opposingField"],"sources":["../src/prepublicationUtils.js"],"sourcesContent":["import {fieldHasSubfield, nvdebug, nvdebugFieldArray} from './utils';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:prepublicationUtils');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best\nconst TARKISTETTU_ENNAKKOTIETO = 2;\nconst ENNAKKOTIETO = 3;\n//const EI_TASOA = 4;\n\nconst encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145\nconst prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');\n\nexport function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {\n return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;\n}\n\n\nexport function encodingLevelIsBetterThanPrepublication(encodingLevel) {\n const index = encodingLevelPreferenceArray.indexOf(encodingLevel);\n return index > -1 && index < prepublicationLevelIndex;\n}\n\n// These three functions below all refer to field 500:\nexport function fieldRefersToKoneellisestiTuotettuTietue(field) {\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^Koneellisesti tuotettu tietue/u));\n}\n\n\nexport function fieldRefersToTarkistettuEnnakkotieto(field) {\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^tarkistettu ennakkotieto/ui));\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?\n if (field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^ennakkotieto(?:$|[. ])/ui))) {\n return true;\n }\n\n // MRA-420: \"EI VIELÄ ILMESTYNYT\" is a Helmet note, that is semantically similar to ENNAKKOTIETO:\n return field.subfields?.some(sf => sf.code === 'a' && sf.value.match(/^EI VIELÄ ILMESTYNYT/u));\n}\n\n\nexport function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return false;\n}\n\nexport function getRelevant5XXFields(record, f500 = false, f594 = false) {\n const cands = actualGetFields();\n //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);\n const filtered = cands.filter(field => hasRelevantPrepubData(field));\n //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);\n return filtered;\n\n //return actualGetFields().filter(field => hasRelevantPrepubData(field));\n\n function hasRelevantPrepubData(field) {\n // Check prepub ($a):\n if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToTarkistettuEnnakkotieto(field) && !fieldRefersToEnnakkotieto(field)) {\n return false;\n }\n // Check relevance (594$5):\n if (field.tag === '500') {\n return field.subfields.every(sf => sf.code !== '5'); //true;\n }\n return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));\n }\n\n function actualGetFields() {\n if (f500 && f594) {\n return record.get(/^(?:500|594)$/u);\n }\n if (f500) {\n return record.get(/^500$/u);\n }\n if (f594) {\n return record.get(/^594$/u);\n }\n return [];\n }\n\n}\n\n\n// Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...\n// We should use that and not have a copy here...\nexport function getPrepublicationLevel(record, f500 = false, f594 = false) {\n // Smaller return value is better\n const fields = getRelevant5XXFields(record, f500, f594);\n\n if (!fields) {\n return null;\n }\n if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {\n return KONEELLISESTI_TUOTETTU_TIETUE;\n }\n\n if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {\n return TARKISTETTU_ENNAKKOTIETO;\n }\n\n if (fields.some(f => fieldRefersToEnnakkotieto(f))) {\n return ENNAKKOTIETO;\n }\n\n return null;\n}\n\n\nexport function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {\n const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);\n const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);\n\n if (baseIndex === -1) {\n // Base wins if both are bad:\n return sourceIndex === -1;\n }\n return baseIndex <= sourceIndex;\n}\n\n\nfunction hasFikkaLOW(record) {\n return record.fields.some(field => field.tag === 'LOW' && fieldHasSubfield(field, 'a', 'FIKKA'));\n}\n\n\nfunction hasNatLibFi042(record) {\n return record.fields.some(field => field.tag === '042' && (fieldHasSubfield(field, 'a', 'finb') || fieldHasSubfield(field, 'a', 'finbd')));\n}\n\n\nexport function isFikkaRecord(record) {\n // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?\n return hasFikkaLOW(record) && hasNatLibFi042(record);\n}\n\n\nexport function getEncodingLevel(record) {\n return record.leader.substring(17, 18);\n}\n\n\nexport function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {\n const encodingLevel = getEncodingLevel(record);\n // Skip prepublication (or theoretically even worse) records:\n if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {\n //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here\n return;\n }\n\n // MET-306: keep \"koneellisesti tuotettu tietue\" if encoding level is '2':\n const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);\n if (f500.length === 0) {\n return;\n }\n\n\n nvdebug(`Delete all ${f500.length} instance(s) of field 500`, debugDev);\n f500.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return\n}\n\n\nexport function removeWorsePrepubField500s(record) {\n // Remove lower-level entries:\n const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true\n nvdebugFieldArray(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);\n const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 500: ', debugDev);\n nonBest.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return\n}\n\n\nexport function removeWorsePrepubField594s(record) {\n // Remove lower-level entries:\n const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true\n nvdebugFieldArray(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);\n const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 594: ', debugDev);\n nonBest.forEach(field => record.removeField(field)); // eslint-disable-line array-callback-return\n}\n\n\nexport function isEnnakkotietoSubfield(subfield) {\n if (subfield.code !== '9' && subfield.code !== 'g') {\n return false;\n }\n // Length <= 13 allows punctuation, but does not require it:\n if (subfield.value.length <= 13) {\n const coreString = subfield.value.substr(0, 12);\n if (coreString.toLowerCase() === 'ennakkotieto') { // Lowercase term first seen in MET-575\n return true;\n }\n }\n return false;\n}\n\nexport function isEnnakkotietoField(field) {\n return field.subfields.some(sf => isEnnakkotietoSubfield(sf));\n}\n\nexport function isKingOfTheHill(field, opposingFields) {\n // Field is no better than at least one of the opposing fields\n return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));\n}\n\n"],"mappings":"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","ignoreList":[]}
@@ -79,16 +79,14 @@ function _default() {
79
79
  debug(`No matching rules for field ${field.tag}`);
80
80
  return;
81
81
  }
82
- let currentPortion; // eslint-disable-line functional/no-let
83
- let preceedingField; // eslint-disable-line functional/no-let
84
- let inNamePortion = true; // eslint-disable-line functional/no-let
85
-
82
+ let currentPortion;
83
+ let preceedingField;
84
+ let inNamePortion = true;
86
85
  debug(`Field subfields: ${field.subfields.map(sub => sub.code)}`);
87
86
  debug(`Field portions: ${field.subfields.map(sub => getPortion(sub, rulesForField))}`);
88
87
  field.subfields.forEach(subfield => {
89
88
  debug(`Handling subfield ${subfield.code}`);
90
- let portion = getPortion(subfield, rulesForField); // eslint-disable-line functional/no-let
91
-
89
+ let portion = getPortion(subfield, rulesForField);
92
90
  if (portion === false) {
93
91
  return;
94
92
  }
@@ -96,28 +94,23 @@ function _default() {
96
94
  return;
97
95
  }
98
96
  if (inNamePortion && portion.includes('T', 'S')) {
99
- // eslint-disable-line functional/no-conditional-statements
100
97
  debug(`Portion changed to ${portion}. Not in name portion anymore`);
101
98
  inNamePortion = false;
102
99
  }
103
100
  if (inNamePortion && portion === 'NT') {
104
- // eslint-disable-line functional/no-conditional-statements
105
101
  portion = 'N';
106
102
  }
107
103
  if (!inNamePortion && portion === 'NT') {
108
- // eslint-disable-line functional/no-conditional-statements
109
104
  portion = 'T';
110
105
  }
111
106
  debug(`Current portion is ${portion}.`);
112
107
  if (currentPortion) {
113
108
  if (currentPortion === portion) {
114
- // eslint-disable-line functional/no-conditional-statements
115
109
  debug(`Current stayed as ${portion}. Adding punctuation for subfield.`);
116
110
  addSubfieldPunctuation(preceedingField, subfield, rulesForField);
117
111
  } else {
118
112
  debug(`Current portion changed to ${portion}.`);
119
113
  if (portion !== 'S') {
120
- // eslint-disable-line functional/no-conditional-statements
121
114
  debug('Adding punctuation for portion.');
122
115
  addNamePortionPunctuation(preceedingField);
123
116
  }
@@ -127,7 +120,6 @@ function _default() {
127
120
  preceedingField = subfield;
128
121
  });
129
122
  if (recordType !== 'z') {
130
- // eslint-disable-line functional/no-conditional-statements
131
123
  addNamePortionPunctuation(preceedingField);
132
124
  }
133
125
  debug(`After punctuation: ${fieldToString(field)}`);
@@ -147,10 +139,9 @@ function _default() {
147
139
  function addNamePortionPunctuation(preceedingSubfield) {
148
140
  const subfieldContainsPunctuation = /[?")\].\-!,]$/u.test(preceedingSubfield.value);
149
141
  if (!subfieldContainsPunctuation) {
150
- // eslint-disable-line functional/no-conditional-statements
151
142
  const nextValue = `${preceedingSubfield.value}.`;
152
143
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
153
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
144
+ preceedingSubfield.value = nextValue;
154
145
  }
155
146
  }
156
147
  function addSubfieldPunctuation(preceedingSubfield, currentSubfield, rules) {
@@ -164,42 +155,37 @@ function _default() {
164
155
  debug(`addSubfieldPunctuation -- punctType: ${punctType} endsInPunctuation: ${endsInPunctuation}`);
165
156
  if (!endsInPunctuation) {
166
157
  if (punctType === 'PERIOD' && !/\.$/u.test(preceedingSubfield.value)) {
167
- // eslint-disable-line functional/no-conditional-statements
168
158
  const nextValue = `${preceedingSubfield.value}.`;
169
159
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
170
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
160
+ preceedingSubfield.value = nextValue;
171
161
  }
172
162
  }
173
163
  if (punctType === 'COMMA') {
174
164
  if (!/,$/u.test(preceedingSubfield.value)) {
175
165
  if (!/^[[(]/u.test(currentSubfield.value)) {
176
- // eslint-disable-line functional/no-conditional-statements
177
166
  const nextValue = `${preceedingSubfield.value},`;
178
167
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
179
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
168
+ preceedingSubfield.value = nextValue;
180
169
  }
181
170
  }
182
171
  }
183
172
  if (punctType === 'COND_COMMA') {
184
173
  if (!/[-,]$/u.test(preceedingSubfield.value)) {
185
- // eslint-disable-line functional/no-conditional-statements
186
174
  const nextValue = `${preceedingSubfield.value},`;
187
175
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
188
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
176
+ preceedingSubfield.value = nextValue;
189
177
  }
190
178
  }
191
179
  if (punctType === 'SPACECOLON') {
192
180
  if (!/:$/u.test(preceedingSubfield.value)) {
193
- // eslint-disable-line functional/no-conditional-statements
194
181
  const nextValue = `${preceedingSubfield.value} :`;
195
182
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
196
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
183
+ preceedingSubfield.value = nextValue;
197
184
  }
198
185
  if (/[^ ]:$/u.test(preceedingSubfield.value)) {
199
- // eslint-disable-line functional/no-conditional-statements
200
186
  const nextValue = `${preceedingSubfield.value.slice(0, -1)} :`;
201
187
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
202
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
188
+ preceedingSubfield.value = nextValue;
203
189
  }
204
190
  }
205
191
  debug('addSubfieldPunctuation -- end');
@@ -222,13 +208,12 @@ function _default() {
222
208
  const exceptionRules = expectionsString.split('\n');
223
209
  const exceptionFuncs = [];
224
210
  exceptionRules.forEach(exceptionRule => {
225
- const match = /- (.*) if preceded by (.*)/u.exec(exceptionRule); // eslint-disable-line prefer-named-capture-group
211
+ const match = /- (.*) if preceded by (.*)/u.exec(exceptionRule);
226
212
  if (match) {
227
- // eslint-disable-line functional/no-conditional-statements
228
213
  const [, type, preceededCode] = match;
229
214
  const normalizedType = type.trim().toUpperCase().trim();
230
215
  const normalizedCode = preceededCode.replace(/\$/ug, '').trim();
231
- exceptionFuncs.push(ifPrecededByException(normalizedCode, normalizedType)); // eslint-disable-line functional/immutable-data
216
+ exceptionFuncs.push(ifPrecededByException(normalizedCode, normalizedType));
232
217
  }
233
218
  });
234
219
  return exceptionFuncs;
@@ -238,16 +223,14 @@ function _default() {
238
223
  if (code === preceedingSubfield.code) {
239
224
  debug(`Adding ${type} to ${preceedingSubfield.code}`);
240
225
  if (type === 'SEMICOLON' && !/;$/u.test(preceedingSubfield.value)) {
241
- // eslint-disable-line functional/no-conditional-statements
242
226
  const nextValue = `${preceedingSubfield.value} ;`;
243
227
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
244
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
228
+ preceedingSubfield.value = nextValue;
245
229
  }
246
230
  if (type === 'COLON' && !/:$/u.test(preceedingSubfield.value)) {
247
- // eslint-disable-line functional/no-conditional-statements
248
231
  const nextValue = `${preceedingSubfield.value} :`;
249
232
  debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
250
- preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
233
+ preceedingSubfield.value = nextValue;
251
234
  }
252
235
  return true;
253
236
  }