@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-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 (545) hide show
  1. package/.github/workflows/melinda-node-tests.yml +1 -1
  2. package/dist/access-rights.js +63 -91
  3. package/dist/access-rights.js.map +7 -1
  4. package/dist/access-rights.test.js +137 -0
  5. package/dist/access-rights.test.js.map +7 -0
  6. package/dist/addMissingField041.js +21 -53
  7. package/dist/addMissingField041.js.map +7 -1
  8. package/dist/addMissingField041.test.js +39 -0
  9. package/dist/addMissingField041.test.js.map +7 -0
  10. package/dist/addMissingField336.js +99 -191
  11. package/dist/addMissingField336.js.map +7 -1
  12. package/dist/addMissingField336.test.js +39 -0
  13. package/dist/addMissingField336.test.js.map +7 -0
  14. package/dist/addMissingField337.js +63 -132
  15. package/dist/addMissingField337.js.map +7 -1
  16. package/dist/addMissingField337.test.js +39 -0
  17. package/dist/addMissingField337.test.js.map +7 -0
  18. package/dist/addMissingField338.js +147 -253
  19. package/dist/addMissingField338.js.map +7 -1
  20. package/dist/addMissingField338.test.js +39 -0
  21. package/dist/addMissingField338.test.js.map +7 -0
  22. package/dist/cyrillux-usemarcon-replacement.js +119 -272
  23. package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
  24. package/dist/cyrillux-usemarcon-replacement.test.js +46 -0
  25. package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
  26. package/dist/cyrillux.js +119 -223
  27. package/dist/cyrillux.js.map +7 -1
  28. package/dist/cyrillux.test.js +39 -0
  29. package/dist/cyrillux.test.js.map +7 -0
  30. package/dist/disambiguateSeriesStatements.js +40 -81
  31. package/dist/disambiguateSeriesStatements.js.map +7 -1
  32. package/dist/disambiguateSeriesStatements.test.js +44 -0
  33. package/dist/disambiguateSeriesStatements.test.js.map +7 -0
  34. package/dist/double-commas.js +7 -14
  35. package/dist/double-commas.js.map +7 -1
  36. package/dist/double-commas.test.js +48 -0
  37. package/dist/double-commas.test.js.map +7 -0
  38. package/dist/duplicates-ind1.js +10 -31
  39. package/dist/duplicates-ind1.js.map +7 -1
  40. package/dist/duplicates-ind1.test.js +40 -0
  41. package/dist/duplicates-ind1.test.js.map +7 -0
  42. package/dist/empty-fields.js +10 -22
  43. package/dist/empty-fields.js.map +7 -1
  44. package/dist/empty-fields.test.js +129 -0
  45. package/dist/empty-fields.test.js.map +7 -0
  46. package/dist/ending-punctuation-conf.js +871 -769
  47. package/dist/ending-punctuation-conf.js.map +7 -1
  48. package/dist/ending-punctuation.js +84 -167
  49. package/dist/ending-punctuation.js.map +7 -1
  50. package/dist/ending-punctuation.test.js +2290 -0
  51. package/dist/ending-punctuation.test.js.map +7 -0
  52. package/dist/ending-whitespace.js +10 -35
  53. package/dist/ending-whitespace.js.map +7 -1
  54. package/dist/ending-whitespace.test.js +38 -0
  55. package/dist/ending-whitespace.test.js.map +7 -0
  56. package/dist/field-008-18-34-character-groups.js +40 -125
  57. package/dist/field-008-18-34-character-groups.js.map +7 -1
  58. package/dist/field-008-18-34-character-groups.test.js +45 -0
  59. package/dist/field-008-18-34-character-groups.test.js.map +7 -0
  60. package/dist/field-505-separators.js +19 -39
  61. package/dist/field-505-separators.js.map +7 -1
  62. package/dist/field-505-separators.test.js +45 -0
  63. package/dist/field-505-separators.test.js.map +7 -0
  64. package/dist/field-521-fix.js +19 -47
  65. package/dist/field-521-fix.js.map +7 -1
  66. package/dist/field-521-fix.test.js +44 -0
  67. package/dist/field-521-fix.test.js.map +7 -0
  68. package/dist/field-exclusion.js +37 -91
  69. package/dist/field-exclusion.js.map +7 -1
  70. package/dist/field-exclusion.test.js +821 -0
  71. package/dist/field-exclusion.test.js.map +7 -0
  72. package/dist/field-structure.js +52 -104
  73. package/dist/field-structure.js.map +7 -1
  74. package/dist/field-structure.test.js +587 -0
  75. package/dist/field-structure.test.js.map +7 -0
  76. package/dist/field33XUtils.js +119 -503
  77. package/dist/field33XUtils.js.map +7 -1
  78. package/dist/fields-present.js +11 -23
  79. package/dist/fields-present.js.map +7 -1
  80. package/dist/fields-present.test.js +95 -0
  81. package/dist/fields-present.test.js.map +7 -0
  82. package/dist/fix-33X.js +393 -431
  83. package/dist/fix-33X.js.map +7 -1
  84. package/dist/fix-33X.test.js +39 -0
  85. package/dist/fix-33X.test.js.map +7 -0
  86. package/dist/fix-country-codes.js +20 -50
  87. package/dist/fix-country-codes.js.map +7 -1
  88. package/dist/fix-country-codes.test.js +44 -0
  89. package/dist/fix-country-codes.test.js.map +7 -0
  90. package/dist/fix-language-codes.js +23 -53
  91. package/dist/fix-language-codes.js.map +7 -1
  92. package/dist/fix-language-codes.test.js +38 -0
  93. package/dist/fix-language-codes.test.js.map +7 -0
  94. package/dist/fixRelatorTerms.js +82 -209
  95. package/dist/fixRelatorTerms.js.map +7 -1
  96. package/dist/fixRelatorTerms.test.js +44 -0
  97. package/dist/fixRelatorTerms.test.js.map +7 -0
  98. package/dist/fixed-fields.js +21 -30
  99. package/dist/fixed-fields.js.map +7 -1
  100. package/dist/fixed-fields.test.js +87 -0
  101. package/dist/fixed-fields.test.js.map +7 -0
  102. package/dist/identical-fields.js +8 -24
  103. package/dist/identical-fields.js.map +7 -1
  104. package/dist/identical-fields.test.js +119 -0
  105. package/dist/identical-fields.test.js.map +7 -0
  106. package/dist/index.js +119 -413
  107. package/dist/index.js.map +7 -1
  108. package/dist/indicator-fixes.js +57 -95
  109. package/dist/indicator-fixes.js.map +7 -1
  110. package/dist/indicator-fixes.test.js +42 -0
  111. package/dist/indicator-fixes.test.js.map +7 -0
  112. package/dist/isbn-issn.js +66 -126
  113. package/dist/isbn-issn.js.map +7 -1
  114. package/dist/isbn-issn.test.js +398 -0
  115. package/dist/isbn-issn.test.js.map +7 -0
  116. package/dist/item-language.js +32 -65
  117. package/dist/item-language.js.map +7 -1
  118. package/dist/item-language.test.js +322 -0
  119. package/dist/item-language.test.js.map +7 -0
  120. package/dist/melindaCustomMergeFields.js +5182 -11233
  121. package/dist/melindaCustomMergeFields.js.map +7 -1
  122. package/dist/merge-fields/controlSubfields.js +75 -142
  123. package/dist/merge-fields/controlSubfields.js.map +7 -1
  124. package/dist/merge-fields/counterpartField.js +182 -379
  125. package/dist/merge-fields/counterpartField.js.map +7 -1
  126. package/dist/merge-fields/index.js +15 -49
  127. package/dist/merge-fields/index.js.map +7 -1
  128. package/dist/merge-fields/mergableIndicator.js +18 -51
  129. package/dist/merge-fields/mergableIndicator.js.map +7 -1
  130. package/dist/merge-fields/mergableTag.js +78 -30
  131. package/dist/merge-fields/mergableTag.js.map +7 -1
  132. package/dist/merge-fields/mergeConfig.js +66 -171
  133. package/dist/merge-fields/mergeConfig.js.map +7 -1
  134. package/dist/merge-fields/mergeConstraints.js +323 -1214
  135. package/dist/merge-fields/mergeConstraints.js.map +7 -1
  136. package/dist/merge-fields/mergeField.js +47 -111
  137. package/dist/merge-fields/mergeField.js.map +7 -1
  138. package/dist/merge-fields/mergeIndicator.js +64 -118
  139. package/dist/merge-fields/mergeIndicator.js.map +7 -1
  140. package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
  141. package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
  142. package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
  143. package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
  144. package/dist/merge-fields/mergeSubfield.js +47 -95
  145. package/dist/merge-fields/mergeSubfield.js.map +7 -1
  146. package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
  147. package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
  148. package/dist/merge-fields/worldKnowledge.js +15 -40
  149. package/dist/merge-fields/worldKnowledge.js.map +7 -1
  150. package/dist/merge-fields.test.js +44 -0
  151. package/dist/merge-fields.test.js.map +7 -0
  152. package/dist/mergeField500Lisapainokset.js +28 -57
  153. package/dist/mergeField500Lisapainokset.js.map +7 -1
  154. package/dist/mergeField500Lisapainokset.test.js +44 -0
  155. package/dist/mergeField500Lisapainokset.test.js.map +7 -0
  156. package/dist/mergeRelatorTermFields.js +33 -69
  157. package/dist/mergeRelatorTermFields.js.map +7 -1
  158. package/dist/mergeRelatorTermFields.test.js +44 -0
  159. package/dist/mergeRelatorTermFields.test.js.map +7 -0
  160. package/dist/modernize-502.js +23 -55
  161. package/dist/modernize-502.js.map +7 -1
  162. package/dist/modernize-502.test.js +38 -0
  163. package/dist/modernize-502.test.js.map +7 -0
  164. package/dist/multiple-subfield-0.js +23 -48
  165. package/dist/multiple-subfield-0.js.map +7 -1
  166. package/dist/multiple-subfield-0.test.js +44 -0
  167. package/dist/multiple-subfield-0.test.js.map +7 -0
  168. package/dist/non-breaking-space.js +11 -32
  169. package/dist/non-breaking-space.js.map +7 -1
  170. package/dist/non-breaking-space.test.js +38 -0
  171. package/dist/non-breaking-space.test.js.map +7 -0
  172. package/dist/normalize-dashes.js +18 -37
  173. package/dist/normalize-dashes.js.map +7 -1
  174. package/dist/normalize-dashes.test.js +44 -0
  175. package/dist/normalize-dashes.test.js.map +7 -0
  176. package/dist/normalize-identifiers.js +54 -140
  177. package/dist/normalize-identifiers.js.map +7 -1
  178. package/dist/normalize-identifiers.test.js +44 -0
  179. package/dist/normalize-identifiers.test.js.map +7 -0
  180. package/dist/normalize-qualifying-information.js +23 -48
  181. package/dist/normalize-qualifying-information.js.map +7 -1
  182. package/dist/normalize-qualifying-information.test.js +44 -0
  183. package/dist/normalize-qualifying-information.test.js.map +7 -0
  184. package/dist/normalize-utf8-diacritics.js +19 -105
  185. package/dist/normalize-utf8-diacritics.js.map +7 -1
  186. package/dist/normalize-utf8-diacritics.test.js +44 -0
  187. package/dist/normalize-utf8-diacritics.test.js.map +7 -0
  188. package/dist/normalizeFieldForComparison.js +67 -158
  189. package/dist/normalizeFieldForComparison.js.map +7 -1
  190. package/dist/normalizeSubfieldValueForComparison.js +37 -77
  191. package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
  192. package/dist/prepublicationUtils.js +58 -111
  193. package/dist/prepublicationUtils.js.map +7 -1
  194. package/dist/punctuation/index.js +56 -72
  195. package/dist/punctuation/index.js.map +7 -1
  196. package/dist/punctuation/rules/aut.js +372 -331
  197. package/dist/punctuation/rules/aut.js.map +7 -1
  198. package/dist/punctuation/rules/bib.js +420 -373
  199. package/dist/punctuation/rules/bib.js.map +7 -1
  200. package/dist/punctuation/rules/index.js +7 -21
  201. package/dist/punctuation/rules/index.js.map +7 -1
  202. package/dist/punctuation.test.js +44 -0
  203. package/dist/punctuation.test.js.map +7 -0
  204. package/dist/punctuation2.js +251 -800
  205. package/dist/punctuation2.js.map +7 -1
  206. package/dist/punctuation2.test.js +44 -0
  207. package/dist/punctuation2.test.js.map +7 -0
  208. package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
  209. package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
  210. package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
  211. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
  212. package/dist/removeDuplicateDataFields.js +102 -202
  213. package/dist/removeDuplicateDataFields.js.map +7 -1
  214. package/dist/removeDuplicateDataFields.test.js +44 -0
  215. package/dist/removeDuplicateDataFields.test.js.map +7 -0
  216. package/dist/removeInferiorDataFields.js +103 -227
  217. package/dist/removeInferiorDataFields.js.map +7 -1
  218. package/dist/removeInferiorDataFields.test.js +44 -0
  219. package/dist/removeInferiorDataFields.test.js.map +7 -0
  220. package/dist/resolvable-ext-references-melinda.js +25 -60
  221. package/dist/resolvable-ext-references-melinda.js.map +7 -1
  222. package/dist/resolvable-ext-references-melinda.test.js +160 -0
  223. package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
  224. package/dist/resolveOrphanedSubfield6s.js +33 -64
  225. package/dist/resolveOrphanedSubfield6s.js.map +7 -1
  226. package/dist/resolveOrphanedSubfield6s.test.js +44 -0
  227. package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
  228. package/dist/sanitize-vocabulary-source-codes.js +27 -55
  229. package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
  230. package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
  231. package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
  232. package/dist/sort-tags.js +13 -25
  233. package/dist/sort-tags.js.map +7 -1
  234. package/dist/sort-tags.test.js +261 -0
  235. package/dist/sort-tags.test.js.map +7 -0
  236. package/dist/sortFields.js +152 -222
  237. package/dist/sortFields.js.map +7 -1
  238. package/dist/sortFields.test.js +44 -0
  239. package/dist/sortFields.test.js.map +7 -0
  240. package/dist/sortRelatorTerms.js +30 -68
  241. package/dist/sortRelatorTerms.js.map +7 -1
  242. package/dist/sortRelatorTerms.test.js +44 -0
  243. package/dist/sortRelatorTerms.test.js.map +7 -0
  244. package/dist/sortSubfields.js +102 -255
  245. package/dist/sortSubfields.js.map +7 -1
  246. package/dist/sortSubfields.test.js +44 -0
  247. package/dist/sortSubfields.test.js.map +7 -0
  248. package/dist/stripPunctuation.js +13 -36
  249. package/dist/stripPunctuation.js.map +7 -1
  250. package/dist/stripPunctuation.test.js +44 -0
  251. package/dist/stripPunctuation.test.js.map +7 -0
  252. package/dist/subfield-exclusion.js +28 -75
  253. package/dist/subfield-exclusion.js.map +7 -1
  254. package/dist/subfield-exclusion.test.js +471 -0
  255. package/dist/subfield-exclusion.test.js.map +7 -0
  256. package/dist/subfield6Utils.js +107 -269
  257. package/dist/subfield6Utils.js.map +7 -1
  258. package/dist/subfield8Utils.js +26 -50
  259. package/dist/subfield8Utils.js.map +7 -1
  260. package/dist/subfieldValueNormalizations.js +40 -74
  261. package/dist/subfieldValueNormalizations.js.map +7 -1
  262. package/dist/subfieldValueNormalizations.test.js +45 -0
  263. package/dist/subfieldValueNormalizations.test.js.map +7 -0
  264. package/dist/sync-007-and-300.js +22 -53
  265. package/dist/sync-007-and-300.js.map +7 -1
  266. package/dist/sync-007-and-300.test.js +44 -0
  267. package/dist/sync-007-and-300.test.js.map +7 -0
  268. package/dist/translate-terms.js +67 -155
  269. package/dist/translate-terms.js.map +7 -1
  270. package/dist/translate-terms.test.js +44 -0
  271. package/dist/translate-terms.test.js.map +7 -0
  272. package/dist/typeOfDate-008.js +10 -25
  273. package/dist/typeOfDate-008.js.map +7 -1
  274. package/dist/typeOfDate-008.test.js +40 -0
  275. package/dist/typeOfDate-008.test.js.map +7 -0
  276. package/dist/unicode-decomposition.js +94 -107
  277. package/dist/unicode-decomposition.js.map +7 -1
  278. package/dist/unicode-decomposition.test.js +94 -0
  279. package/dist/unicode-decomposition.test.js.map +7 -0
  280. package/dist/update-field-540.js +30 -75
  281. package/dist/update-field-540.js.map +7 -1
  282. package/dist/update-field-540.test.js +44 -0
  283. package/dist/update-field-540.test.js.map +7 -0
  284. package/dist/urn.js +55 -128
  285. package/dist/urn.js.map +7 -1
  286. package/dist/urn.test.js +44 -0
  287. package/dist/urn.test.js.map +7 -0
  288. package/dist/utils.js +72 -126
  289. package/dist/utils.js.map +7 -1
  290. package/eslint.config.mjs +1 -2
  291. package/package.json +21 -93
  292. package/src/access-rights.js +1 -1
  293. package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
  294. package/src/addMissingField041.js +1 -1
  295. package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
  296. package/src/addMissingField336.js +3 -3
  297. package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
  298. package/src/addMissingField337.js +2 -2
  299. package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
  300. package/src/addMissingField338.js +2 -2
  301. package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
  302. package/src/cyrillux-usemarcon-replacement.js +18 -18
  303. package/src/cyrillux-usemarcon-replacement.test.js +55 -0
  304. package/src/cyrillux.js +19 -12
  305. package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
  306. package/src/disambiguateSeriesStatements.js +2 -2
  307. package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
  308. package/src/double-commas.js +1 -1
  309. package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
  310. package/src/duplicates-ind1.js +1 -1
  311. package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
  312. package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
  313. package/src/ending-punctuation.js +1 -1
  314. package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +172 -173
  315. package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
  316. package/src/field-008-18-34-character-groups.js +2 -2
  317. package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
  318. package/src/field-505-separators.js +3 -3
  319. package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
  320. package/src/field-521-fix.js +2 -2
  321. package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
  322. package/src/field-exclusion.js +1 -1
  323. package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
  324. package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
  325. package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
  326. package/src/fix-33X.js +4 -4
  327. package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
  328. package/src/fix-country-codes.js +1 -1
  329. package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
  330. package/src/fix-language-codes.js +5 -5
  331. package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
  332. package/src/fixRelatorTerms.js +5 -5
  333. package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
  334. package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
  335. package/src/identical-fields.js +1 -1
  336. package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
  337. package/src/indicator-fixes.js +3 -3
  338. package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
  339. package/src/isbn-issn.js +1 -1
  340. package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
  341. package/src/{item-language.spec.js → item-language.test.js} +21 -22
  342. package/src/merge-fields/controlSubfields.js +1 -1
  343. package/src/merge-fields/counterpartField.js +8 -9
  344. package/src/merge-fields/index.js +1 -1
  345. package/src/merge-fields/mergableIndicator.js +1 -1
  346. package/src/merge-fields/mergeField.js +6 -6
  347. package/src/merge-fields/mergeIndicator.js +1 -1
  348. package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
  349. package/src/merge-fields/mergeOrAddSubfield.js +2 -2
  350. package/src/merge-fields/mergeSubfield.js +4 -4
  351. package/src/merge-fields/removeDuplicateSubfields.js +2 -2
  352. package/src/{merge-fields.spec.js → merge-fields.test.js} +12 -13
  353. package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
  354. package/src/mergeRelatorTermFields.js +5 -7
  355. package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
  356. package/src/modernize-502.js +1 -1
  357. package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
  358. package/src/multiple-subfield-0.js +3 -3
  359. package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
  360. package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
  361. package/src/normalize-dashes.js +2 -2
  362. package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
  363. package/src/normalize-identifiers.js +1 -1
  364. package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
  365. package/src/normalize-qualifying-information.js +2 -2
  366. package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
  367. package/src/normalize-utf8-diacritics.js +2 -2
  368. package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
  369. package/src/normalizeFieldForComparison.js +6 -6
  370. package/src/normalizeSubfieldValueForComparison.js +1 -1
  371. package/src/prepublicationUtils.js +4 -4
  372. package/src/punctuation/index.js +1 -1
  373. package/src/punctuation/rules/index.js +2 -2
  374. package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
  375. package/src/punctuation2.js +4 -4
  376. package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
  377. package/src/reindexSubfield6OccurenceNumbers.js +5 -7
  378. package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
  379. package/src/removeDuplicateDataFields.js +11 -19
  380. package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
  381. package/src/removeInferiorDataFields.js +11 -11
  382. package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
  383. package/src/resolvable-ext-references-melinda.js +1 -1
  384. package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
  385. package/src/resolveOrphanedSubfield6s.js +5 -5
  386. package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
  387. package/src/sanitize-vocabulary-source-codes.js +4 -4
  388. package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
  389. package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
  390. package/src/sortFields.js +4 -4
  391. package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
  392. package/src/sortRelatorTerms.js +3 -3
  393. package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
  394. package/src/sortSubfields.js +1 -1
  395. package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
  396. package/src/stripPunctuation.js +3 -3
  397. package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
  398. package/src/subfield-exclusion.js +1 -1
  399. package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
  400. package/src/subfield6Utils.js +6 -10
  401. package/src/subfield8Utils.js +4 -4
  402. package/src/subfieldValueNormalizations.js +3 -3
  403. package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
  404. package/src/sync-007-and-300.js +2 -2
  405. package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
  406. package/src/translate-terms.js +3 -3
  407. package/src/{translate-terms.spec.js → translate-terms.test.js} +13 -13
  408. package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
  409. package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
  410. package/src/update-field-540.js +2 -2
  411. package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
  412. package/src/urn.js +2 -2
  413. package/src/{urn.spec.js → urn.test.js} +12 -13
  414. package/src/utils.js +3 -3
  415. package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
  416. package/test-fixtures/field-505-separators/03/record.json +3 -0
  417. package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
  418. package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
  419. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
  420. package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
  421. package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
  422. package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
  423. package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
  424. package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
  425. package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
  426. package/dist/access-rights.spec.js +0 -195
  427. package/dist/access-rights.spec.js.map +0 -1
  428. package/dist/addMissingField041.spec.js +0 -45
  429. package/dist/addMissingField041.spec.js.map +0 -1
  430. package/dist/addMissingField336.spec.js +0 -45
  431. package/dist/addMissingField336.spec.js.map +0 -1
  432. package/dist/addMissingField337.spec.js +0 -43
  433. package/dist/addMissingField337.spec.js.map +0 -1
  434. package/dist/addMissingField338.spec.js +0 -45
  435. package/dist/addMissingField338.spec.js.map +0 -1
  436. package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
  437. package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
  438. package/dist/cyrillux.spec.js +0 -46
  439. package/dist/cyrillux.spec.js.map +0 -1
  440. package/dist/disambiguateSeriesStatements.spec.js +0 -51
  441. package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
  442. package/dist/double-commas.spec.js +0 -73
  443. package/dist/double-commas.spec.js.map +0 -1
  444. package/dist/duplicates-ind1.spec.js +0 -45
  445. package/dist/duplicates-ind1.spec.js.map +0 -1
  446. package/dist/empty-fields.spec.js +0 -118
  447. package/dist/empty-fields.spec.js.map +0 -1
  448. package/dist/ending-punctuation.spec.js +0 -2654
  449. package/dist/ending-punctuation.spec.js.map +0 -1
  450. package/dist/ending-whitespace.spec.js +0 -42
  451. package/dist/ending-whitespace.spec.js.map +0 -1
  452. package/dist/field-008-18-34-character-groups.spec.js +0 -51
  453. package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
  454. package/dist/field-505-separators.spec.js +0 -51
  455. package/dist/field-505-separators.spec.js.map +0 -1
  456. package/dist/field-521-fix.spec.js +0 -51
  457. package/dist/field-521-fix.spec.js.map +0 -1
  458. package/dist/field-exclusion.spec.js +0 -1054
  459. package/dist/field-exclusion.spec.js.map +0 -1
  460. package/dist/field-structure.spec.js +0 -535
  461. package/dist/field-structure.spec.js.map +0 -1
  462. package/dist/fields-present.spec.js +0 -121
  463. package/dist/fields-present.spec.js.map +0 -1
  464. package/dist/fix-33X.spec.js +0 -45
  465. package/dist/fix-33X.spec.js.map +0 -1
  466. package/dist/fix-country-codes.spec.js +0 -51
  467. package/dist/fix-country-codes.spec.js.map +0 -1
  468. package/dist/fix-language-codes.spec.js +0 -44
  469. package/dist/fix-language-codes.spec.js.map +0 -1
  470. package/dist/fixRelatorTerms.spec.js +0 -51
  471. package/dist/fixRelatorTerms.spec.js.map +0 -1
  472. package/dist/fixed-fields.spec.js +0 -140
  473. package/dist/fixed-fields.spec.js.map +0 -1
  474. package/dist/identical-fields.spec.js +0 -99
  475. package/dist/identical-fields.spec.js.map +0 -1
  476. package/dist/indicator-fixes.spec.js +0 -51
  477. package/dist/indicator-fixes.spec.js.map +0 -1
  478. package/dist/isbn-issn.spec.js +0 -595
  479. package/dist/isbn-issn.spec.js.map +0 -1
  480. package/dist/item-language.spec.js +0 -306
  481. package/dist/item-language.spec.js.map +0 -1
  482. package/dist/melindaCustomMergeFields.json +0 -5120
  483. package/dist/merge-fields.spec.js +0 -51
  484. package/dist/merge-fields.spec.js.map +0 -1
  485. package/dist/mergeField500Lisapainokset.spec.js +0 -51
  486. package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
  487. package/dist/mergeRelatorTermFields.spec.js +0 -51
  488. package/dist/mergeRelatorTermFields.spec.js.map +0 -1
  489. package/dist/modernize-502.spec.js +0 -49
  490. package/dist/modernize-502.spec.js.map +0 -1
  491. package/dist/multiple-subfield-0.spec.js +0 -51
  492. package/dist/multiple-subfield-0.spec.js.map +0 -1
  493. package/dist/non-breaking-space.spec.js +0 -42
  494. package/dist/non-breaking-space.spec.js.map +0 -1
  495. package/dist/normalize-dashes.spec.js +0 -51
  496. package/dist/normalize-dashes.spec.js.map +0 -1
  497. package/dist/normalize-identifiers.spec.js +0 -51
  498. package/dist/normalize-identifiers.spec.js.map +0 -1
  499. package/dist/normalize-qualifying-information.spec.js +0 -51
  500. package/dist/normalize-qualifying-information.spec.js.map +0 -1
  501. package/dist/normalize-utf8-diacritics.spec.js +0 -51
  502. package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
  503. package/dist/punctuation.spec.js +0 -51
  504. package/dist/punctuation.spec.js.map +0 -1
  505. package/dist/punctuation2.spec.js +0 -51
  506. package/dist/punctuation2.spec.js.map +0 -1
  507. package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
  508. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
  509. package/dist/removeDuplicateDataFields.spec.js +0 -51
  510. package/dist/removeDuplicateDataFields.spec.js.map +0 -1
  511. package/dist/removeInferiorDataFields.spec.js +0 -51
  512. package/dist/removeInferiorDataFields.spec.js.map +0 -1
  513. package/dist/resolvable-ext-references-melinda.spec.js +0 -166
  514. package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
  515. package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
  516. package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
  517. package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
  518. package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
  519. package/dist/sort-tags.spec.js +0 -207
  520. package/dist/sort-tags.spec.js.map +0 -1
  521. package/dist/sortFields.spec.js +0 -51
  522. package/dist/sortFields.spec.js.map +0 -1
  523. package/dist/sortRelatorTerms.spec.js +0 -51
  524. package/dist/sortRelatorTerms.spec.js.map +0 -1
  525. package/dist/sortSubfields.spec.js +0 -52
  526. package/dist/sortSubfields.spec.js.map +0 -1
  527. package/dist/stripPunctuation.spec.js +0 -51
  528. package/dist/stripPunctuation.spec.js.map +0 -1
  529. package/dist/subfield-exclusion.spec.js +0 -523
  530. package/dist/subfield-exclusion.spec.js.map +0 -1
  531. package/dist/subfieldValueNormalizations.spec.js +0 -51
  532. package/dist/subfieldValueNormalizations.spec.js.map +0 -1
  533. package/dist/sync-007-and-300.spec.js +0 -51
  534. package/dist/sync-007-and-300.spec.js.map +0 -1
  535. package/dist/translate-terms.spec.js +0 -51
  536. package/dist/translate-terms.spec.js.map +0 -1
  537. package/dist/typeOfDate-008.spec.js +0 -47
  538. package/dist/typeOfDate-008.spec.js.map +0 -1
  539. package/dist/unicode-decomposition.spec.js +0 -91
  540. package/dist/unicode-decomposition.spec.js.map +0 -1
  541. package/dist/update-field-540.spec.js +0 -51
  542. package/dist/update-field-540.spec.js.map +0 -1
  543. package/dist/urn.spec.js +0 -52
  544. package/dist/urn.spec.js.map +0 -1
  545. package/src/cyrillux-usemarcon-replacement.spec.js +0 -47
@@ -1,43 +1,29 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.mergeSubfield = mergeSubfield;
7
- var _debug = _interopRequireDefault(require("debug"));
8
- var _normalizeSubfieldValueForComparison = require("../normalizeSubfieldValueForComparison");
9
- var _worldKnowledge = require("./worldKnowledge");
10
- var _utils = require("../utils");
11
- var _normalizeFieldForComparison = require("../normalizeFieldForComparison.js");
12
- var _counterpartField = require("./counterpartField");
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');
15
- //const debugData = debug.extend('data');
16
- const debugDev = debug.extend('dev');
17
-
18
- // NB! These are X00 specific. Should we somehow parametrize them?
1
+ import createDebugLogger from "debug";
2
+ import { partsAgree, subfieldContainsPartData } from "../normalizeSubfieldValueForComparison.js";
3
+ import { valueCarriesMeaning } from "./worldKnowledge.js";
4
+ import { nvdebug } from "../utils.js";
5
+ import { tagAndSubfieldCodeReferToIsbn } from "../normalizeFieldForComparison.js";
6
+ import { canContainOptionalQualifier, splitToNameAndQualifier } from "./counterpartField.js";
7
+ const debug = createDebugLogger("@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield");
8
+ const debugDev = debug.extend("dev");
19
9
  const onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;
20
10
  const onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;
21
11
  const birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;
22
12
  function getDeathYear(str) {
23
- return parseInt(str.substring(str.indexOf('-') + 1), 10);
13
+ return parseInt(str.substring(str.indexOf("-") + 1), 10);
24
14
  }
25
15
  function isValidBirthYearAndDeathYear(str) {
26
16
  if (!birthYearAndDeathYear.test(str)) {
27
17
  return false;
28
18
  }
29
- // We have two years
30
19
  const b = parseInt(str, 10);
31
20
  const d = getDeathYear(str);
32
21
  if (b > d) {
33
- // died before birth! Rather unlikely.
34
22
  return false;
35
23
  }
36
24
  if (d - b > 125) {
37
- // Over 125 years old. Rather unlikely.
38
25
  return false;
39
26
  }
40
- // Possible sanity check: Died after current year?
41
27
  return true;
42
28
  }
43
29
  function anyYear(str) {
@@ -60,10 +46,7 @@ function replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfi
60
46
  return false;
61
47
  }
62
48
  function replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {
63
- // Add also the death year, if the original value only contains birth year.
64
- // This function treats only with X00$d subfields:
65
- if (candSubfield.code !== 'd' || !/^[1678]00$/u.test(targetField.tag)) {
66
- // njsscan-ignore: regex_dos
49
+ if (candSubfield.code !== "d" || !/^[1678]00$/u.test(targetField.tag)) {
67
50
  return false;
68
51
  }
69
52
  if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {
@@ -75,16 +58,14 @@ function replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfi
75
58
  }
76
59
  return false;
77
60
  }
78
-
79
- // use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()
80
61
  function isKierreselka(value) {
81
- return ['kierreselkä', 'spiral bound', 'spiral-bound', 'spiralrygg'].includes(value);
62
+ return ["kierreselk\xE4", "spiral bound", "spiral-bound", "spiralrygg"].includes(value);
82
63
  }
83
64
  function isKovakantinen(value) {
84
- return ['hardback', 'hardcover', 'hårda pärmar', 'kovakantinen'].includes(value);
65
+ return ["hardback", "hardcover", "h\xE5rda p\xE4rmar", "kovakantinen"].includes(value);
85
66
  }
86
67
  function isPehmeakantinen(value) {
87
- return ['mjuka pärmar', 'paperback', 'pehmeäkantinen', 'softcover'].includes(value);
68
+ return ["mjuka p\xE4rmar", "paperback", "pehme\xE4kantinen", "softcover"].includes(value);
88
69
  }
89
70
  function isItsenainenJatkoOsa(value) {
90
71
  if (value.match(/^Fristående fortsättning på verket[^a-z]*$/ui)) {
@@ -105,41 +86,38 @@ function isSisaltaaTeos(value) {
105
86
  return false;
106
87
  }
107
88
  function relationInformationMatches(candSubfield, relevantSubfields) {
108
- if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {
89
+ if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some((sf) => isSisaltaaTeos(sf.value))) {
109
90
  return true;
110
91
  }
111
- if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {
92
+ if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some((sf) => isItsenainenJatkoOsa(sf.value))) {
112
93
  return true;
113
94
  }
114
95
  return false;
115
96
  }
116
97
  function coverTypesMatch(candSubfield, relevantSubfields) {
117
- if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {
98
+ if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some((sf) => isPehmeakantinen(sf.value))) {
118
99
  return true;
119
100
  }
120
- if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {
101
+ if (isKovakantinen(candSubfield.value) && relevantSubfields.some((sf) => isKovakantinen(sf.value))) {
121
102
  return true;
122
103
  }
123
- if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {
104
+ if (isKierreselka(candSubfield.value) && relevantSubfields.some((sf) => isKierreselka(sf.value))) {
124
105
  return true;
125
106
  }
126
107
  return false;
127
108
  }
128
109
  function httpToHttps(val) {
129
- return val.replace(/http:\/\//ug, 'https://');
110
+ return val.replace(/http:\/\//ug, "https://");
130
111
  }
131
112
  function pairHttpAndHttps(candSubfield, relevantSubfields) {
132
113
  const a = httpToHttps(candSubfield.value);
133
- const bs = relevantSubfields.map(sf => httpToHttps(sf.value));
114
+ const bs = relevantSubfields.map((sf) => httpToHttps(sf.value));
134
115
  return bs.includes(a);
135
116
  }
136
117
  function isSynonym(field, candSubfield, relevantSubfields) {
137
- if (candSubfield.code === 'q' && ['015', '020', '024', '028'].includes(field.tag)) {
118
+ if (candSubfield.code === "q" && ["015", "020", "024", "028"].includes(field.tag)) {
138
119
  return coverTypesMatch(candSubfield, relevantSubfields);
139
120
  }
140
-
141
- //nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);
142
-
143
121
  if (relationInformationMatches(candSubfield, relevantSubfields)) {
144
122
  return true;
145
123
  }
@@ -149,16 +127,14 @@ function isSynonym(field, candSubfield, relevantSubfields) {
149
127
  return false;
150
128
  }
151
129
  function preferHyphenatedISBN(field, candSubfield, relevantSubfields) {
152
- if (!(0, _normalizeFieldForComparison.tagAndSubfieldCodeReferToIsbn)(field.tag, candSubfield.code) || candSubfield.value.includes('-') === -1) {
130
+ if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes("-") === -1) {
153
131
  return false;
154
132
  }
155
-
156
- // Must not already exist:
157
- if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {
133
+ if (relevantSubfields.some((sf) => sf.value === candSubfield.value)) {
158
134
  return false;
159
135
  }
160
- const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes('-') > -1);
161
- const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu, ''));
136
+ const hyphenlessSubfields = relevantSubfields.filter((sf) => sf.value.includes("-") > -1);
137
+ const pair = hyphenlessSubfields.find((sf) => sf.value === candSubfield.value.replace(/-/gu, ""));
162
138
  if (!pair) {
163
139
  return false;
164
140
  }
@@ -166,11 +142,11 @@ function preferHyphenatedISBN(field, candSubfield, relevantSubfields) {
166
142
  return true;
167
143
  }
168
144
  function preferHttpsOverHttp(candSubfield, relevantSubfields) {
169
- if (candSubfield.value.substring(0, 8) !== 'https://') {
145
+ if (candSubfield.value.substring(0, 8) !== "https://") {
170
146
  return false;
171
147
  }
172
148
  const httpVersion = `http://${candSubfield.value.substring(8)}`;
173
- const pair = relevantSubfields.find(sf => sf.value === httpVersion);
149
+ const pair = relevantSubfields.find((sf) => sf.value === httpVersion);
174
150
  if (!pair) {
175
151
  return false;
176
152
  }
@@ -178,23 +154,21 @@ function preferHttpsOverHttp(candSubfield, relevantSubfields) {
178
154
  return true;
179
155
  }
180
156
  function preferQualifierVersion(field, candSubfield, relevantSubfields) {
181
- if (!(0, _counterpartField.canContainOptionalQualifier)(field.tag, candSubfield.code)) {
182
- // currently only 300$a and 776$i can prefer source...
157
+ if (!canContainOptionalQualifier(field.tag, candSubfield.code)) {
183
158
  return false;
184
159
  }
185
- const [name1, qualifier1] = (0, _counterpartField.splitToNameAndQualifier)(candSubfield.value);
186
- const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));
160
+ const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);
161
+ const pair = relevantSubfields.find((sf) => subfieldQualifierCheck(sf, name1, qualifier1));
187
162
  if (!pair) {
188
163
  return false;
189
164
  }
190
- // SN: "Kuvailuohjeiden näkökulmasta epubille ei pitäisi koskaan merkitä sivumäärää"
191
- if (field.tag === '300' && candSubfield.code === 'a' && candSubfield.value.match(/(?:online|verkko)/iu)) {
192
- return true; // True, but don't prefer the source value
165
+ if (field.tag === "300" && candSubfield.code === "a" && candSubfield.value.match(/(?:online|verkko)/iu)) {
166
+ return true;
193
167
  }
194
168
  pair.value = candSubfield.value;
195
169
  return true;
196
170
  function subfieldQualifierCheck(subfield, name, qualifier) {
197
- const [name2, qualifier2] = (0, _counterpartField.splitToNameAndQualifier)(candSubfield.value);
171
+ const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);
198
172
  if (name !== name2) {
199
173
  return false;
200
174
  }
@@ -205,10 +179,10 @@ function preferQualifierVersion(field, candSubfield, relevantSubfields) {
205
179
  }
206
180
  }
207
181
  function preferSourceCorporateName(field, candSubfield, pair) {
208
- if (candSubfield.code !== 'a' || !['110', '610', '710', '810'].includes(field.tag)) {
182
+ if (candSubfield.code !== "a" || !["110", "610", "710", "810"].includes(field.tag)) {
209
183
  return false;
210
184
  }
211
- (0, _utils.nvdebug)(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);
185
+ nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);
212
186
  const prefer = actualPrefenceCheck();
213
187
  if (prefer) {
214
188
  pair.value = candSubfield.value;
@@ -222,56 +196,34 @@ function preferSourceCorporateName(field, candSubfield, pair) {
222
196
  if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {
223
197
  return true;
224
198
  }
225
- // Prefer (qualifier):
226
- const [sourceName, sourceQualifier] = (0, _counterpartField.splitToNameAndQualifier)(candSubfield.value);
227
- const [baseName, baseQualifier] = (0, _counterpartField.splitToNameAndQualifier)(pair.value);
228
- if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {
199
+ const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);
200
+ const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);
201
+ if (sourceName === baseName && baseQualifier === void 0 && sourceQualifier !== void 0) {
229
202
  return true;
230
203
  }
231
- // Not taking prefix and suffix into account here...
232
204
  return false;
233
205
  }
234
206
  }
235
- function mergeSubfield(targetField, candSubfield) {
236
- // Replace existing subfield with the incoming field. These replacements are by name rather hacky...
237
- // Currenty we only select the better X00$d.
238
- // In future we might do more things here. Examples:
239
- // - "FOO" gets replaced by "Foo" in certain fields.
240
- // - "Etunimi Sukunimi" might lose to "Sukunimi, Etunimi" in X00 fields.
241
- // - [put your ideas here]
242
- // Return true, if replace is done.
243
- // However, replacing/succeeding requires a sanity check, that the new value is a better one...
244
- // Thus, typically this function fails...
245
-
246
- const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);
247
-
248
- // There's nothing to replace the incoming subfield with. Thus abort:
207
+ export function mergeSubfield(targetField, candSubfield) {
208
+ const relevantSubfields = targetField.subfields.filter((subfield) => subfield.code === candSubfield.code);
249
209
  if (relevantSubfields.length === 0) {
250
210
  return false;
251
211
  }
252
- (0, _utils.nvdebug)(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}‡${candSubfield.code}`, debugDev);
253
- if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) || preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) || preferHttpsOverHttp(candSubfield, relevantSubfields) || preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) ||
254
- // SF is non-repeat
212
+ nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}\u2021${candSubfield.code}`, debugDev);
213
+ if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) || preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) || preferHttpsOverHttp(candSubfield, relevantSubfields) || preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat
255
214
  preferQualifierVersion(targetField, candSubfield, relevantSubfields) || isSynonym(targetField, candSubfield, relevantSubfields)) {
256
215
  return true;
257
216
  }
258
-
259
- // We found a crappy empty subfield: replace that with a meaningful one.
260
- // 260 $a value "[S.l]" is the main type for this.
261
- const meaninglessSubfields = relevantSubfields.filter(sf => !(0, _worldKnowledge.valueCarriesMeaning)(targetField.tag, sf.code, sf.value));
217
+ const meaninglessSubfields = relevantSubfields.filter((sf) => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));
262
218
  if (meaninglessSubfields.length > 0) {
263
219
  meaninglessSubfields[0].value = candSubfield.value;
264
220
  return true;
265
221
  }
266
-
267
- // Mark 490$v "osa 1" vs "1" as merged (2nd part of MET-53).
268
- // NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)
269
- // NB! We could improve this and choose the longer value later on.
270
- if ((0, _normalizeSubfieldValueForComparison.subfieldContainsPartData)(targetField.tag, candSubfield.code)) {
271
- if (relevantSubfields.some(sf => (0, _normalizeSubfieldValueForComparison.partsAgree)(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {
222
+ if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {
223
+ if (relevantSubfields.some((sf) => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {
272
224
  return true;
273
225
  }
274
226
  }
275
- return false; // default to failure
227
+ return false;
276
228
  }
277
- //# sourceMappingURL=mergeSubfield.js.map
229
+ //# sourceMappingURL=mergeSubfield.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"mergeSubfield.js","names":["_debug","_interopRequireDefault","require","_normalizeSubfieldValueForComparison","_worldKnowledge","_utils","_normalizeFieldForComparison","_counterpartField","e","__esModule","default","debug","createDebugLogger","debugDev","extend","onlyBirthYear","onlyDeathYear","birthYearAndDeathYear","getDeathYear","str","parseInt","substring","indexOf","isValidBirthYearAndDeathYear","test","b","d","anyYear","replaceEntrysBirthAndDeathYear","targetField","candSubfield","relevantSubfields","value","replaceDatesAssociatedWithName","code","tag","isKierreselka","includes","isKovakantinen","isPehmeakantinen","isItsenainenJatkoOsa","match","isSisaltaaTeos","relationInformationMatches","some","sf","coverTypesMatch","httpToHttps","val","replace","pairHttpAndHttps","a","bs","map","isSynonym","field","preferHyphenatedISBN","tagAndSubfieldCodeReferToIsbn","hyphenlessSubfields","filter","pair","find","preferHttpsOverHttp","httpVersion","preferQualifierVersion","canContainOptionalQualifier","name1","qualifier1","splitToNameAndQualifier","subfieldQualifierCheck","subfield","name","qualifier","name2","qualifier2","preferSourceCorporateName","nvdebug","prefer","actualPrefenceCheck","sourceName","sourceQualifier","baseName","baseQualifier","undefined","mergeSubfield","subfields","length","meaninglessSubfields","valueCarriesMeaning","subfieldContainsPartData","partsAgree"],"sources":["../../src/merge-fields/mergeSubfield.js"],"sourcesContent":["import createDebugLogger from 'debug';\nimport {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison';\nimport {valueCarriesMeaning} from './worldKnowledge';\nimport {nvdebug} from '../utils';\nimport {tagAndSubfieldCodeReferToIsbn} from '../normalizeFieldForComparison.js';\nimport {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n// NB! These are X00 specific. Should we somehow parametrize them?\nconst onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;\nconst onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;\nconst birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;\n\nfunction getDeathYear(str) {\n return parseInt(str.substring(str.indexOf('-') + 1), 10);\n}\n\nfunction isValidBirthYearAndDeathYear(str) {\n if (!birthYearAndDeathYear.test(str)) {\n return false;\n }\n // We have two years\n const b = parseInt(str, 10);\n const d = getDeathYear(str);\n if (b > d) { // died before birth! Rather unlikely.\n return false;\n }\n if (d - b > 125) { // Over 125 years old. Rather unlikely.\n return false;\n }\n // Possible sanity check: Died after current year?\n return true;\n}\n\nfunction anyYear(str) {\n if (onlyBirthYear.test(str) || onlyDeathYear.test(str) || isValidBirthYearAndDeathYear(str)) {\n return true;\n }\n return false;\n}\n\nfunction replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields) {\n if (birthYearAndDeathYear.test(candSubfield.value)) {\n if (onlyBirthYear.test(relevantSubfields[0].value) && parseInt(relevantSubfields[0].value, 10) === parseInt(candSubfield.value, 10)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (onlyDeathYear.test(relevantSubfields[0].value) && getDeathYear(relevantSubfields[0].value) === getDeathYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n }\n return false;\n}\n\nfunction replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {\n // Add also the death year, if the original value only contains birth year.\n // This function treats only with X00$d subfields:\n if (candSubfield.code !== 'd' || !(/^[1678]00$/u).test(targetField.tag)) { // njsscan-ignore: regex_dos\n return false;\n }\n\n if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n return false;\n}\n\n// use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()\nfunction isKierreselka(value) {\n return ['kierreselkä', 'spiral bound', 'spiral-bound', 'spiralrygg'].includes(value);\n}\n\nfunction isKovakantinen(value) {\n return ['hardback', 'hardcover', 'hårda pärmar', 'kovakantinen'].includes(value);\n}\n\nfunction isPehmeakantinen(value) {\n return ['mjuka pärmar', 'paperback', 'pehmeäkantinen', 'softcover'].includes(value);\n}\n\nfunction isItsenainenJatkoOsa(value) {\n if (value.match(/^Fristående fortsättning på verket[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Itsenäinen jatko-osa teokselle[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\n\nfunction isSisaltaaTeos(value) {\n if (value.match(/^Innehåller \\(verk\\)[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Sisältää \\(teos\\)[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\nfunction relationInformationMatches(candSubfield, relevantSubfields) {\n if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {\n return true;\n }\n if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {\n return true;\n }\n\n return false;\n}\n\nfunction coverTypesMatch(candSubfield, relevantSubfields) {\n if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {\n return true;\n }\n if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {\n return true;\n }\n if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {\n return true;\n }\n return false;\n}\n\nfunction httpToHttps(val) {\n return val.replace(/http:\\/\\//ug, 'https://');\n}\n\nfunction pairHttpAndHttps(candSubfield, relevantSubfields) {\n const a = httpToHttps(candSubfield.value);\n const bs = relevantSubfields.map(sf => httpToHttps(sf.value));\n return bs.includes(a);\n}\n\nfunction isSynonym(field, candSubfield, relevantSubfields) {\n if (candSubfield.code === 'q' && ['015', '020', '024', '028'].includes(field.tag)) {\n return coverTypesMatch(candSubfield, relevantSubfields);\n }\n\n //nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);\n\n if (relationInformationMatches(candSubfield, relevantSubfields)) {\n return true;\n }\n\n if (pairHttpAndHttps(candSubfield, relevantSubfields)) {\n return true;\n }\n\n return false;\n}\n\nfunction preferHyphenatedISBN(field, candSubfield, relevantSubfields) {\n if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes('-') === -1) {\n return false;\n }\n\n // Must not already exist:\n if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {\n return false;\n }\n\n const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes('-') > -1);\n const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu, ''));\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\nfunction preferHttpsOverHttp(candSubfield, relevantSubfields) {\n if (candSubfield.value.substring(0, 8) !== 'https://') {\n return false;\n }\n\n const httpVersion = `http://${candSubfield.value.substring(8)}`;\n const pair = relevantSubfields.find(sf => sf.value === httpVersion);\n\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\n\nfunction preferQualifierVersion(field, candSubfield, relevantSubfields) {\n if (!canContainOptionalQualifier(field.tag, candSubfield.code)) { // currently only 300$a and 776$i can prefer source...\n return false;\n }\n\n const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);\n const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));\n if (!pair) {\n return false;\n }\n // SN: \"Kuvailuohjeiden näkökulmasta epubille ei pitäisi koskaan merkitä sivumäärää\"\n if (field.tag === '300' && candSubfield.code === 'a' && candSubfield.value.match(/(?:online|verkko)/iu)) {\n return true; // True, but don't prefer the source value\n }\n\n pair.value = candSubfield.value;\n return true;\n\n function subfieldQualifierCheck(subfield, name, qualifier) {\n const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);\n if (name !== name2) {\n return false;\n }\n if (!qualifier || !qualifier2 || qualifier === qualifier2) {\n return true;\n }\n return false;\n }\n\n}\n\nfunction preferSourceCorporateName(field, candSubfield, pair) {\n if (candSubfield.code !== 'a' || !['110', '610', '710', '810'].includes(field.tag)) {\n return false;\n }\n nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);\n const prefer = actualPrefenceCheck();\n if (prefer) {\n pair.value = candSubfield.value;\n return true;\n }\n return false;\n\n function actualPrefenceCheck() {\n if (candSubfield.value.match(/^Werner Söderström/u) && pair.value.match(/^WSOY/ui)) {\n return true;\n }\n if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {\n return true;\n }\n // Prefer (qualifier):\n const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);\n const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);\n if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {\n return true;\n }\n // Not taking prefix and suffix into account here...\n return false;\n }\n\n}\n\nexport function mergeSubfield(targetField, candSubfield) {\n // Replace existing subfield with the incoming field. These replacements are by name rather hacky...\n // Currenty we only select the better X00$d.\n // In future we might do more things here. Examples:\n // - \"FOO\" gets replaced by \"Foo\" in certain fields.\n // - \"Etunimi Sukunimi\" might lose to \"Sukunimi, Etunimi\" in X00 fields.\n // - [put your ideas here]\n // Return true, if replace is done.\n // However, replacing/succeeding requires a sanity check, that the new value is a better one...\n // Thus, typically this function fails...\n\n const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);\n\n // There's nothing to replace the incoming subfield with. Thus abort:\n if (relevantSubfields.length === 0) {\n return false;\n }\n\n nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}‡${candSubfield.code}`, debugDev);\n\n\n if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) ||\n preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) ||\n preferHttpsOverHttp(candSubfield, relevantSubfields) ||\n preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat\n preferQualifierVersion(targetField, candSubfield, relevantSubfields) ||\n isSynonym(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n\n // We found a crappy empty subfield: replace that with a meaningful one.\n // 260 $a value \"[S.l]\" is the main type for this.\n const meaninglessSubfields = relevantSubfields.filter(sf => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));\n if (meaninglessSubfields.length > 0) {\n meaninglessSubfields[0].value = candSubfield.value;\n return true;\n }\n\n // Mark 490$v \"osa 1\" vs \"1\" as merged (2nd part of MET-53).\n // NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)\n // NB! We could improve this and choose the longer value later on.\n if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {\n if (relevantSubfields.some(sf => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {\n return true;\n }\n }\n return false; // default to failure\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/merge-fields/mergeSubfield.js"],
4
+ "sourcesContent": ["import createDebugLogger from 'debug';\nimport {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison.js';\nimport {valueCarriesMeaning} from './worldKnowledge.js';\nimport {nvdebug} from '../utils.js';\nimport {tagAndSubfieldCodeReferToIsbn} from '../normalizeFieldForComparison.js';\nimport {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField.js';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n// NB! These are X00 specific. Should we somehow parametrize them?\nconst onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;\nconst onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;\nconst birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;\n\nfunction getDeathYear(str) {\n return parseInt(str.substring(str.indexOf('-') + 1), 10);\n}\n\nfunction isValidBirthYearAndDeathYear(str) {\n if (!birthYearAndDeathYear.test(str)) {\n return false;\n }\n // We have two years\n const b = parseInt(str, 10);\n const d = getDeathYear(str);\n if (b > d) { // died before birth! Rather unlikely.\n return false;\n }\n if (d - b > 125) { // Over 125 years old. Rather unlikely.\n return false;\n }\n // Possible sanity check: Died after current year?\n return true;\n}\n\nfunction anyYear(str) {\n if (onlyBirthYear.test(str) || onlyDeathYear.test(str) || isValidBirthYearAndDeathYear(str)) {\n return true;\n }\n return false;\n}\n\nfunction replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields) {\n if (birthYearAndDeathYear.test(candSubfield.value)) {\n if (onlyBirthYear.test(relevantSubfields[0].value) && parseInt(relevantSubfields[0].value, 10) === parseInt(candSubfield.value, 10)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (onlyDeathYear.test(relevantSubfields[0].value) && getDeathYear(relevantSubfields[0].value) === getDeathYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n }\n return false;\n}\n\nfunction replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {\n // Add also the death year, if the original value only contains birth year.\n // This function treats only with X00$d subfields:\n if (candSubfield.code !== 'd' || !(/^[1678]00$/u).test(targetField.tag)) { // njsscan-ignore: regex_dos\n return false;\n }\n\n if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n return false;\n}\n\n// use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()\nfunction isKierreselka(value) {\n return ['kierreselk\u00E4', 'spiral bound', 'spiral-bound', 'spiralrygg'].includes(value);\n}\n\nfunction isKovakantinen(value) {\n return ['hardback', 'hardcover', 'h\u00E5rda p\u00E4rmar', 'kovakantinen'].includes(value);\n}\n\nfunction isPehmeakantinen(value) {\n return ['mjuka p\u00E4rmar', 'paperback', 'pehme\u00E4kantinen', 'softcover'].includes(value);\n}\n\nfunction isItsenainenJatkoOsa(value) {\n if (value.match(/^Frist\u00E5ende forts\u00E4ttning p\u00E5 verket[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Itsen\u00E4inen jatko-osa teokselle[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\n\nfunction isSisaltaaTeos(value) {\n if (value.match(/^Inneh\u00E5ller \\(verk\\)[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Sis\u00E4lt\u00E4\u00E4 \\(teos\\)[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\nfunction relationInformationMatches(candSubfield, relevantSubfields) {\n if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {\n return true;\n }\n if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {\n return true;\n }\n\n return false;\n}\n\nfunction coverTypesMatch(candSubfield, relevantSubfields) {\n if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {\n return true;\n }\n if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {\n return true;\n }\n if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {\n return true;\n }\n return false;\n}\n\nfunction httpToHttps(val) {\n return val.replace(/http:\\/\\//ug, 'https://');\n}\n\nfunction pairHttpAndHttps(candSubfield, relevantSubfields) {\n const a = httpToHttps(candSubfield.value);\n const bs = relevantSubfields.map(sf => httpToHttps(sf.value));\n return bs.includes(a);\n}\n\nfunction isSynonym(field, candSubfield, relevantSubfields) {\n if (candSubfield.code === 'q' && ['015', '020', '024', '028'].includes(field.tag)) {\n return coverTypesMatch(candSubfield, relevantSubfields);\n }\n\n //nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);\n\n if (relationInformationMatches(candSubfield, relevantSubfields)) {\n return true;\n }\n\n if (pairHttpAndHttps(candSubfield, relevantSubfields)) {\n return true;\n }\n\n return false;\n}\n\nfunction preferHyphenatedISBN(field, candSubfield, relevantSubfields) {\n if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes('-') === -1) {\n return false;\n }\n\n // Must not already exist:\n if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {\n return false;\n }\n\n const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes('-') > -1);\n const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu, ''));\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\nfunction preferHttpsOverHttp(candSubfield, relevantSubfields) {\n if (candSubfield.value.substring(0, 8) !== 'https://') {\n return false;\n }\n\n const httpVersion = `http://${candSubfield.value.substring(8)}`;\n const pair = relevantSubfields.find(sf => sf.value === httpVersion);\n\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\n\nfunction preferQualifierVersion(field, candSubfield, relevantSubfields) {\n if (!canContainOptionalQualifier(field.tag, candSubfield.code)) { // currently only 300$a and 776$i can prefer source...\n return false;\n }\n\n const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);\n const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));\n if (!pair) {\n return false;\n }\n // SN: \"Kuvailuohjeiden n\u00E4k\u00F6kulmasta epubille ei pit\u00E4isi koskaan merkit\u00E4 sivum\u00E4\u00E4r\u00E4\u00E4\"\n if (field.tag === '300' && candSubfield.code === 'a' && candSubfield.value.match(/(?:online|verkko)/iu)) {\n return true; // True, but don't prefer the source value\n }\n\n pair.value = candSubfield.value;\n return true;\n\n function subfieldQualifierCheck(subfield, name, qualifier) {\n const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);\n if (name !== name2) {\n return false;\n }\n if (!qualifier || !qualifier2 || qualifier === qualifier2) {\n return true;\n }\n return false;\n }\n\n}\n\nfunction preferSourceCorporateName(field, candSubfield, pair) {\n if (candSubfield.code !== 'a' || !['110', '610', '710', '810'].includes(field.tag)) {\n return false;\n }\n nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);\n const prefer = actualPrefenceCheck();\n if (prefer) {\n pair.value = candSubfield.value;\n return true;\n }\n return false;\n\n function actualPrefenceCheck() {\n if (candSubfield.value.match(/^Werner S\u00F6derstr\u00F6m/u) && pair.value.match(/^WSOY/ui)) {\n return true;\n }\n if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {\n return true;\n }\n // Prefer (qualifier):\n const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);\n const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);\n if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {\n return true;\n }\n // Not taking prefix and suffix into account here...\n return false;\n }\n\n}\n\nexport function mergeSubfield(targetField, candSubfield) {\n // Replace existing subfield with the incoming field. These replacements are by name rather hacky...\n // Currenty we only select the better X00$d.\n // In future we might do more things here. Examples:\n // - \"FOO\" gets replaced by \"Foo\" in certain fields.\n // - \"Etunimi Sukunimi\" might lose to \"Sukunimi, Etunimi\" in X00 fields.\n // - [put your ideas here]\n // Return true, if replace is done.\n // However, replacing/succeeding requires a sanity check, that the new value is a better one...\n // Thus, typically this function fails...\n\n const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);\n\n // There's nothing to replace the incoming subfield with. Thus abort:\n if (relevantSubfields.length === 0) {\n return false;\n }\n\n nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}\u2021${candSubfield.code}`, debugDev);\n\n\n if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) ||\n preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) ||\n preferHttpsOverHttp(candSubfield, relevantSubfields) ||\n preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat\n preferQualifierVersion(targetField, candSubfield, relevantSubfields) ||\n isSynonym(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n\n // We found a crappy empty subfield: replace that with a meaningful one.\n // 260 $a value \"[S.l]\" is the main type for this.\n const meaninglessSubfields = relevantSubfields.filter(sf => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));\n if (meaninglessSubfields.length > 0) {\n meaninglessSubfields[0].value = candSubfield.value;\n return true;\n }\n\n // Mark 490$v \"osa 1\" vs \"1\" as merged (2nd part of MET-53).\n // NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)\n // NB! We could improve this and choose the longer value later on.\n if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {\n if (relevantSubfields.some(sf => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {\n return true;\n }\n }\n return false; // default to failure\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,47 +1,34 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.fieldRemoveDuplicateSubfields = fieldRemoveDuplicateSubfields;
7
- exports.recordRemoveDuplicateSubfieldsFromFields = recordRemoveDuplicateSubfieldsFromFields;
8
- var _utils = require("../utils.js");
9
- var _debug = _interopRequireDefault(require("debug"));
10
- var _normalizeFieldForComparison = require("../normalizeFieldForComparison.js");
11
- var _sortSubfields = require("../sortSubfields");
12
- var _punctuation = require("../punctuation2");
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- // NB This should be moved and converted to a validator/fixer as well...
15
- const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields');
16
- //const debugData = debug.extend('data');
17
- const debugDev = debug.extend('dev');
18
- function recordRemoveDuplicateSubfieldsFromFields(record) {
19
- record.fields.forEach(field => fieldRemoveDuplicateSubfields(field));
1
+ import { nvdebug, subfieldToString } from "../utils.js";
2
+ import createDebugLogger from "debug";
3
+ import { cloneAndRemovePunctuation } from "../normalizeFieldForComparison.js";
4
+ import { sortAdjacentSubfields } from "../sortSubfields.js";
5
+ import { fieldFixPunctuation } from "../punctuation2.js";
6
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields");
7
+ const debugDev = debug.extend("dev");
8
+ export function recordRemoveDuplicateSubfieldsFromFields(record) {
9
+ record.fields.forEach((field) => fieldRemoveDuplicateSubfields(field));
20
10
  }
21
- function fieldRemoveDuplicateSubfields(field) {
22
- // Skip bad (382, 505) and risky (264 ...) stuff: 382$n, 505$r, others...
23
- if (!field.subfields || ['264', '300', '382', '505'].includes(field.tag)) {
11
+ export function fieldRemoveDuplicateSubfields(field) {
12
+ if (!field.subfields || ["264", "300", "382", "505"].includes(field.tag)) {
24
13
  return;
25
14
  }
26
- const strippedField = (0, _normalizeFieldForComparison.cloneAndRemovePunctuation)(field); // make punctuation-less version
27
-
15
+ const strippedField = cloneAndRemovePunctuation(field);
28
16
  let seen = {};
29
17
  field.subfields = field.subfields.filter((sf, i) => notSeenBefore(sf, i));
30
18
  if (field.collapsed) {
31
- (0, _sortSubfields.sortAdjacentSubfields)(field);
32
- (0, _punctuation.fieldFixPunctuation)(field);
19
+ sortAdjacentSubfields(field);
20
+ fieldFixPunctuation(field);
33
21
  delete field.collapsed;
34
22
  }
35
23
  function notSeenBefore(sf, index) {
36
- const subfieldAsString = (0, _utils.subfieldToString)(strippedField.subfields[index]); // use normalized form
24
+ const subfieldAsString = subfieldToString(strippedField.subfields[index]);
37
25
  if (seen[subfieldAsString]) {
38
- (0, _utils.nvdebug)(`Remove field-internal duplicate subfield ${(0, _utils.subfieldToString)(sf)}`, debugDev);
39
- field.collapsed = 1; // trigger punctuation reset
26
+ nvdebug(`Remove field-internal duplicate subfield ${subfieldToString(sf)}`, debugDev);
27
+ field.collapsed = 1;
40
28
  return false;
41
29
  }
42
- //nvdebug(`identical subfield removal: Add ${subfieldAsString} to seen[]`, debugDev);
43
30
  seen[subfieldAsString] = subfieldAsString;
44
31
  return true;
45
32
  }
46
33
  }
47
- //# sourceMappingURL=removeDuplicateSubfields.js.map
34
+ //# sourceMappingURL=removeDuplicateSubfields.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"removeDuplicateSubfields.js","names":["_utils","require","_debug","_interopRequireDefault","_normalizeFieldForComparison","_sortSubfields","_punctuation","e","__esModule","default","debug","createDebugLogger","debugDev","extend","recordRemoveDuplicateSubfieldsFromFields","record","fields","forEach","field","fieldRemoveDuplicateSubfields","subfields","includes","tag","strippedField","cloneAndRemovePunctuation","seen","filter","sf","i","notSeenBefore","collapsed","sortAdjacentSubfields","fieldFixPunctuation","index","subfieldAsString","subfieldToString","nvdebug"],"sources":["../../src/merge-fields/removeDuplicateSubfields.js"],"sourcesContent":["\nimport {nvdebug, subfieldToString} from '../utils.js';\nimport createDebugLogger from 'debug';\nimport {cloneAndRemovePunctuation} from '../normalizeFieldForComparison.js';\nimport {sortAdjacentSubfields} from '../sortSubfields';\nimport {fieldFixPunctuation} from '../punctuation2';\n\n\n// NB This should be moved and converted to a validator/fixer as well...\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function recordRemoveDuplicateSubfieldsFromFields(record) {\n record.fields.forEach(field => fieldRemoveDuplicateSubfields(field));\n}\n\nexport function fieldRemoveDuplicateSubfields(field) {\n // Skip bad (382, 505) and risky (264 ...) stuff: 382$n, 505$r, others...\n if (!field.subfields || ['264', '300', '382', '505'].includes(field.tag)) {\n return;\n }\n\n const strippedField = cloneAndRemovePunctuation(field); // make punctuation-less version\n\n let seen = {};\n\n field.subfields = field.subfields.filter((sf, i) => notSeenBefore(sf, i));\n\n if (field.collapsed) {\n sortAdjacentSubfields(field);\n fieldFixPunctuation(field);\n delete field.collapsed;\n }\n\n\n function notSeenBefore(sf, index) {\n const subfieldAsString = subfieldToString(strippedField.subfields[index]); // use normalized form\n if (seen[subfieldAsString]) {\n nvdebug(`Remove field-internal duplicate subfield ${subfieldToString(sf)}`, debugDev);\n field.collapsed = 1; // trigger punctuation reset\n return false;\n }\n //nvdebug(`identical subfield removal: Add ${subfieldAsString} to seen[]`, debugDev);\n seen[subfieldAsString] = subfieldAsString;\n return true;\n }\n\n}\n"],"mappings":";;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,4BAAA,GAAAH,OAAA;AACA,IAAAI,cAAA,GAAAJ,OAAA;AACA,IAAAK,YAAA,GAAAL,OAAA;AAAoD,SAAAE,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAGpD;AACA,MAAMG,KAAK,GAAG,IAAAC,cAAiB,EAAC,gFAAgF,CAAC;AACjH;AACA,MAAMC,QAAQ,GAAGF,KAAK,CAACG,MAAM,CAAC,KAAK,CAAC;AAE7B,SAASC,wCAAwCA,CAACC,MAAM,EAAE;EAC/DA,MAAM,CAACC,MAAM,CAACC,OAAO,CAACC,KAAK,IAAIC,6BAA6B,CAACD,KAAK,CAAC,CAAC;AACtE;AAEO,SAASC,6BAA6BA,CAACD,KAAK,EAAE;EACnD;EACA,IAAI,CAACA,KAAK,CAACE,SAAS,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAACC,QAAQ,CAACH,KAAK,CAACI,GAAG,CAAC,EAAE;IACxE;EACF;EAEA,MAAMC,aAAa,GAAG,IAAAC,sDAAyB,EAACN,KAAK,CAAC,CAAC,CAAC;;EAExD,IAAIO,IAAI,GAAG,CAAC,CAAC;EAEbP,KAAK,CAACE,SAAS,GAAGF,KAAK,CAACE,SAAS,CAACM,MAAM,CAAC,CAACC,EAAE,EAAEC,CAAC,KAAKC,aAAa,CAACF,EAAE,EAAEC,CAAC,CAAC,CAAC;EAEzE,IAAIV,KAAK,CAACY,SAAS,EAAE;IACnB,IAAAC,oCAAqB,EAACb,KAAK,CAAC;IAC5B,IAAAc,gCAAmB,EAACd,KAAK,CAAC;IAC1B,OAAOA,KAAK,CAACY,SAAS;EACxB;EAGA,SAASD,aAAaA,CAACF,EAAE,EAAEM,KAAK,EAAE;IAChC,MAAMC,gBAAgB,GAAG,IAAAC,uBAAgB,EAACZ,aAAa,CAACH,SAAS,CAACa,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAIR,IAAI,CAACS,gBAAgB,CAAC,EAAE;MAC1B,IAAAE,cAAO,EAAC,4CAA4C,IAAAD,uBAAgB,EAACR,EAAE,CAAC,EAAE,EAAEf,QAAQ,CAAC;MACrFM,KAAK,CAACY,SAAS,GAAG,CAAC,CAAC,CAAC;MACrB,OAAO,KAAK;IACd;IACA;IACAL,IAAI,CAACS,gBAAgB,CAAC,GAAGA,gBAAgB;IACzC,OAAO,IAAI;EACb;AAEF","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/merge-fields/removeDuplicateSubfields.js"],
4
+ "sourcesContent": ["\nimport {nvdebug, subfieldToString} from '../utils.js';\nimport createDebugLogger from 'debug';\nimport {cloneAndRemovePunctuation} from '../normalizeFieldForComparison.js';\nimport {sortAdjacentSubfields} from '../sortSubfields.js';\nimport {fieldFixPunctuation} from '../punctuation2.js';\n\n\n// NB This should be moved and converted to a validator/fixer as well...\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function recordRemoveDuplicateSubfieldsFromFields(record) {\n record.fields.forEach(field => fieldRemoveDuplicateSubfields(field));\n}\n\nexport function fieldRemoveDuplicateSubfields(field) {\n // Skip bad (382, 505) and risky (264 ...) stuff: 382$n, 505$r, others...\n if (!field.subfields || ['264', '300', '382', '505'].includes(field.tag)) {\n return;\n }\n\n const strippedField = cloneAndRemovePunctuation(field); // make punctuation-less version\n\n let seen = {};\n\n field.subfields = field.subfields.filter((sf, i) => notSeenBefore(sf, i));\n\n if (field.collapsed) {\n sortAdjacentSubfields(field);\n fieldFixPunctuation(field);\n delete field.collapsed;\n }\n\n\n function notSeenBefore(sf, index) {\n const subfieldAsString = subfieldToString(strippedField.subfields[index]); // use normalized form\n if (seen[subfieldAsString]) {\n nvdebug(`Remove field-internal duplicate subfield ${subfieldToString(sf)}`, debugDev);\n field.collapsed = 1; // trigger punctuation reset\n return false;\n }\n //nvdebug(`identical subfield removal: Add ${subfieldAsString} to seen[]`, debugDev);\n seen[subfieldAsString] = subfieldAsString;\n return true;\n }\n\n}\n"],
5
+ "mappings": "AACA,SAAQ,SAAS,wBAAuB;AACxC,OAAO,uBAAuB;AAC9B,SAAQ,iCAAgC;AACxC,SAAQ,6BAA4B;AACpC,SAAQ,2BAA0B;AAIlC,MAAM,QAAQ,kBAAkB,gFAAgF;AAEhH,MAAM,WAAW,MAAM,OAAO,KAAK;AAE5B,gBAAS,yCAAyC,QAAQ;AAC/D,SAAO,OAAO,QAAQ,WAAS,8BAA8B,KAAK,CAAC;AACrE;AAEO,gBAAS,8BAA8B,OAAO;AAEnD,MAAI,CAAC,MAAM,aAAa,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,MAAM,GAAG,GAAG;AACxE;AAAA,EACF;AAEA,QAAM,gBAAgB,0BAA0B,KAAK;AAErD,MAAI,OAAO,CAAC;AAEZ,QAAM,YAAY,MAAM,UAAU,OAAO,CAAC,IAAI,MAAM,cAAc,IAAI,CAAC,CAAC;AAExE,MAAI,MAAM,WAAW;AACnB,0BAAsB,KAAK;AAC3B,wBAAoB,KAAK;AACzB,WAAO,MAAM;AAAA,EACf;AAGA,WAAS,cAAc,IAAI,OAAO;AAChC,UAAM,mBAAmB,iBAAiB,cAAc,UAAU,KAAK,CAAC;AACxE,QAAI,KAAK,gBAAgB,GAAG;AAC1B,cAAQ,4CAA4C,iBAAiB,EAAE,CAAC,IAAI,QAAQ;AACpF,YAAM,YAAY;AAClB,aAAO;AAAA,IACT;AAEA,SAAK,gBAAgB,IAAI;AACzB,WAAO;AAAA,EACT;AAEF;",
6
+ "names": []
7
+ }
@@ -1,23 +1,11 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.normalizeForSamenessCheck = normalizeForSamenessCheck;
7
- exports.valueCarriesMeaning = valueCarriesMeaning;
8
- //import {nvdebug} from '../utils';
9
-
10
- function valueCarriesMeaning(tag, subfieldCode, value) {
11
- // Some data is pretty meaningless and as meaningless is pretty close to nothing, this meaningless data should no prevent merge.
12
- // The list below is incomples (swedish translations etc)
13
- if (tag === '260' || tag === '264') {
14
- // We drop these, instead of normalizing, as KV does not put this information in place...
15
- if (subfieldCode === 'a') {
1
+ export function valueCarriesMeaning(tag, subfieldCode, value) {
2
+ if (tag === "260" || tag === "264") {
3
+ if (subfieldCode === "a") {
16
4
  if (value.match(/^[^a-z]*(?:Kustannuspaikka tuntematon|S\.l)[^a-z]*$/ui)) {
17
5
  return false;
18
6
  }
19
7
  }
20
- if (subfieldCode === 'b') {
8
+ if (subfieldCode === "b") {
21
9
  if (value.match(/^[^a-z]*(?:Kustantaja tuntematon|S\.n)[^a-z]*$/ui)) {
22
10
  return false;
23
11
  }
@@ -26,42 +14,33 @@ function valueCarriesMeaning(tag, subfieldCode, value) {
26
14
  }
27
15
  return true;
28
16
  }
29
- function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {
30
- // NB! These work only for non-repeatable subfields!
31
- // Repeatable subfields are currently handled in mergeSubfields.js. Only non-repeatable subfields block field merge,
32
- // (This split is suboptiomal... Minimum fix: make this disctinction cleaner...)
33
- if (subfieldCode === 'a' && ['100', '600', '700', '800'].includes(tag)) {
17
+ export function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {
18
+ if (subfieldCode === "a" && ["100", "600", "700", "800"].includes(tag)) {
34
19
  return normalizePersonalName(originalValue);
35
20
  }
36
-
37
- // NB! originalValue should already be lowercased, stripped on initial '[' chars and postpunctuation.
38
- if (tag === '250' && subfieldCode === 'a') {
21
+ if (tag === "250" && subfieldCode === "a") {
39
22
  return normalizeEditionStatement(originalValue);
40
23
  }
41
-
42
- // 506 - Restrictions on Access Note (R), $a - Terms governing access (NR)
43
- if (tag === '506' && subfieldCode === 'a') {
24
+ if (tag === "506" && subfieldCode === "a") {
44
25
  return normalize506a(originalValue);
45
26
  }
46
- if (tag === '534' && subfieldCode === 'p') {
27
+ if (tag === "534" && subfieldCode === "p") {
47
28
  return normalizeOriginalVersionNoteIntroductoryPhrase(originalValue);
48
29
  }
49
30
  return originalValue;
50
31
  }
51
32
  function normalizePersonalName(originalValue) {
52
- // Use more readable "Forename Surname" format in comparisons:
53
- return originalValue.replace(/^([^,]+), ([^,]+)$/u, '$2 $1');
33
+ return originalValue.replace(/^([^,]+), ([^,]+)$/u, "$2 $1");
54
34
  }
55
- const sallittu506a = ['sallittu kaikenikäisille', 'sallittu', 's']; // downcased, without punctuation
35
+ const sallittu506a = ["sallittu kaikenik\xE4isille", "sallittu", "s"];
56
36
  function normalize506a(originalValue) {
57
37
  if (sallittu506a.includes(originalValue)) {
58
38
  return sallittu506a[0];
59
39
  }
60
40
  return originalValue;
61
41
  }
62
- const introductoryPhrasesMeaning1 = ['alkuperäinen', 'alkuperäisen julkaisutiedot', 'alun perin julkaistu', 'alunperin julkaistu'];
42
+ const introductoryPhrasesMeaning1 = ["alkuper\xE4inen", "alkuper\xE4isen julkaisutiedot", "alun perin julkaistu", "alunperin julkaistu"];
63
43
  function normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {
64
- // MELKEHITYS-1935-ish:
65
44
  if (introductoryPhrasesMeaning1.includes(originalValue)) {
66
45
  return introductoryPhrasesMeaning1[0];
67
46
  }
@@ -69,16 +48,12 @@ function normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {
69
48
  }
70
49
  function normalizeEditionStatement(originalValue) {
71
50
  const value = originalValue;
72
-
73
- // As normalization tries to translate things info Finnish, use this for similarity check only!
74
51
  if (value.match(/^[1-9][0-9]*(?:\.|:a|nd|rd|st|th) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
75
- const nth = value.replace(/[^0-9].*$/u, '');
52
+ const nth = value.replace(/[^0-9].*$/u, "");
76
53
  return `${nth}. painos`;
77
54
  }
78
-
79
- // Quick and dirty fix for
80
55
  if (value.match(/^[1-9][0-9]*(?:\.|:a|nd|rd|st|th)(?: förnyade|,? rev\.| uud\.| uudistettu) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
81
- const nth = value.replace(/[^0-9].*$/u, '');
56
+ const nth = value.replace(/[^0-9].*$/u, "");
82
57
  return `${nth}. uudistettu painos`;
83
58
  }
84
59
  if (value.match(/^(?:First|Första|Ensimmäinen) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
@@ -95,4 +70,4 @@ function normalizeEditionStatement(originalValue) {
95
70
  }
96
71
  return originalValue;
97
72
  }
98
- //# sourceMappingURL=worldKnowledge.js.map
73
+ //# sourceMappingURL=worldKnowledge.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"worldKnowledge.js","names":["valueCarriesMeaning","tag","subfieldCode","value","match","normalizeForSamenessCheck","originalValue","includes","normalizePersonalName","normalizeEditionStatement","normalize506a","normalizeOriginalVersionNoteIntroductoryPhrase","replace","sallittu506a","introductoryPhrasesMeaning1","nth"],"sources":["../../src/merge-fields/worldKnowledge.js"],"sourcesContent":["//import {nvdebug} from '../utils';\n\nexport function valueCarriesMeaning(tag, subfieldCode, value) {\n // Some data is pretty meaningless and as meaningless is pretty close to nothing, this meaningless data should no prevent merge.\n // The list below is incomples (swedish translations etc)\n if (tag === '260' || tag === '264') {\n // We drop these, instead of normalizing, as KV does not put this information in place...\n if (subfieldCode === 'a') {\n if (value.match(/^[^a-z]*(?:Kustannuspaikka tuntematon|S\\.l)[^a-z]*$/ui)) {\n return false;\n }\n }\n if (subfieldCode === 'b') {\n if (value.match(/^[^a-z]*(?:Kustantaja tuntematon|S\\.n)[^a-z]*$/ui)) {\n return false;\n }\n }\n return true;\n }\n return true;\n}\n\nexport function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {\n // NB! These work only for non-repeatable subfields!\n // Repeatable subfields are currently handled in mergeSubfields.js. Only non-repeatable subfields block field merge,\n // (This split is suboptiomal... Minimum fix: make this disctinction cleaner...)\n if (subfieldCode === 'a' && ['100', '600', '700', '800'].includes(tag)) {\n return normalizePersonalName(originalValue);\n }\n\n // NB! originalValue should already be lowercased, stripped on initial '[' chars and postpunctuation.\n if (tag === '250' && subfieldCode === 'a') {\n return normalizeEditionStatement(originalValue);\n }\n\n // 506 - Restrictions on Access Note (R), $a - Terms governing access (NR)\n if (tag === '506' && subfieldCode === 'a') {\n return normalize506a(originalValue);\n }\n\n if (tag === '534' && subfieldCode === 'p') {\n return normalizeOriginalVersionNoteIntroductoryPhrase(originalValue);\n }\n\n return originalValue;\n}\n\n\nfunction normalizePersonalName(originalValue) {\n // Use more readable \"Forename Surname\" format in comparisons:\n return originalValue.replace(/^([^,]+), ([^,]+)$/u, '$2 $1');\n}\n\nconst sallittu506a = ['sallittu kaikenikäisille', 'sallittu', 's']; // downcased, without punctuation\nfunction normalize506a(originalValue) {\n if (sallittu506a.includes(originalValue)) {\n return sallittu506a[0];\n }\n return originalValue;\n}\n\nconst introductoryPhrasesMeaning1 = ['alkuperäinen', 'alkuperäisen julkaisutiedot', 'alun perin julkaistu', 'alunperin julkaistu'];\nfunction normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {\n // MELKEHITYS-1935-ish:\n if (introductoryPhrasesMeaning1.includes(originalValue)) {\n return introductoryPhrasesMeaning1[0];\n }\n\n return originalValue;\n}\n\nfunction normalizeEditionStatement(originalValue) {\n const value = originalValue;\n\n // As normalization tries to translate things info Finnish, use this for similarity check only!\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. painos`;\n }\n\n // Quick and dirty fix for\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th)(?: förnyade|,? rev\\.| uud\\.| uudistettu) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. uudistettu painos`;\n }\n\n if (value.match(/^(?:First|Första|Ensimmäinen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `1. painos`;\n }\n\n if (value.match(/^(?:Andra|Second|Toinen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `2. painos`;\n }\n\n if (value.match(/^(?:Kolmas|Third|Tredje) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `3. painos`;\n }\n\n if (value.match(/^(?:Fourth|Fjärde|Neljäs) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `4. painos`;\n }\n\n return originalValue;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/merge-fields/worldKnowledge.js"],
4
+ "sourcesContent": ["//import {nvdebug} from '../utils';\n\nexport function valueCarriesMeaning(tag, subfieldCode, value) {\n // Some data is pretty meaningless and as meaningless is pretty close to nothing, this meaningless data should no prevent merge.\n // The list below is incomples (swedish translations etc)\n if (tag === '260' || tag === '264') {\n // We drop these, instead of normalizing, as KV does not put this information in place...\n if (subfieldCode === 'a') {\n if (value.match(/^[^a-z]*(?:Kustannuspaikka tuntematon|S\\.l)[^a-z]*$/ui)) {\n return false;\n }\n }\n if (subfieldCode === 'b') {\n if (value.match(/^[^a-z]*(?:Kustantaja tuntematon|S\\.n)[^a-z]*$/ui)) {\n return false;\n }\n }\n return true;\n }\n return true;\n}\n\nexport function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {\n // NB! These work only for non-repeatable subfields!\n // Repeatable subfields are currently handled in mergeSubfields.js. Only non-repeatable subfields block field merge,\n // (This split is suboptiomal... Minimum fix: make this disctinction cleaner...)\n if (subfieldCode === 'a' && ['100', '600', '700', '800'].includes(tag)) {\n return normalizePersonalName(originalValue);\n }\n\n // NB! originalValue should already be lowercased, stripped on initial '[' chars and postpunctuation.\n if (tag === '250' && subfieldCode === 'a') {\n return normalizeEditionStatement(originalValue);\n }\n\n // 506 - Restrictions on Access Note (R), $a - Terms governing access (NR)\n if (tag === '506' && subfieldCode === 'a') {\n return normalize506a(originalValue);\n }\n\n if (tag === '534' && subfieldCode === 'p') {\n return normalizeOriginalVersionNoteIntroductoryPhrase(originalValue);\n }\n\n return originalValue;\n}\n\n\nfunction normalizePersonalName(originalValue) {\n // Use more readable \"Forename Surname\" format in comparisons:\n return originalValue.replace(/^([^,]+), ([^,]+)$/u, '$2 $1');\n}\n\nconst sallittu506a = ['sallittu kaikenik\u00E4isille', 'sallittu', 's']; // downcased, without punctuation\nfunction normalize506a(originalValue) {\n if (sallittu506a.includes(originalValue)) {\n return sallittu506a[0];\n }\n return originalValue;\n}\n\nconst introductoryPhrasesMeaning1 = ['alkuper\u00E4inen', 'alkuper\u00E4isen julkaisutiedot', 'alun perin julkaistu', 'alunperin julkaistu'];\nfunction normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {\n // MELKEHITYS-1935-ish:\n if (introductoryPhrasesMeaning1.includes(originalValue)) {\n return introductoryPhrasesMeaning1[0];\n }\n\n return originalValue;\n}\n\nfunction normalizeEditionStatement(originalValue) {\n const value = originalValue;\n\n // As normalization tries to translate things info Finnish, use this for similarity check only!\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. painos`;\n }\n\n // Quick and dirty fix for\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th)(?: f\u00F6rnyade|,? rev\\.| uud\\.| uudistettu) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. uudistettu painos`;\n }\n\n if (value.match(/^(?:First|F\u00F6rsta|Ensimm\u00E4inen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `1. painos`;\n }\n\n if (value.match(/^(?:Andra|Second|Toinen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `2. painos`;\n }\n\n if (value.match(/^(?:Kolmas|Third|Tredje) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `3. painos`;\n }\n\n if (value.match(/^(?:Fourth|Fj\u00E4rde|Nelj\u00E4s) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `4. painos`;\n }\n\n return originalValue;\n}\n"],
5
+ "mappings": "AAEO,gBAAS,oBAAoB,KAAK,cAAc,OAAO;AAG5D,MAAI,QAAQ,SAAS,QAAQ,OAAO;AAElC,QAAI,iBAAiB,KAAK;AACxB,UAAI,MAAM,MAAM,uDAAuD,GAAG;AACxE,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,iBAAiB,KAAK;AACxB,UAAI,MAAM,MAAM,kDAAkD,GAAG;AACnE,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,gBAAS,0BAA0B,KAAK,cAAc,eAAe;AAI1E,MAAI,iBAAiB,OAAO,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACtE,WAAO,sBAAsB,aAAa;AAAA,EAC5C;AAGA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,0BAA0B,aAAa;AAAA,EAChD;AAGA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,cAAc,aAAa;AAAA,EACpC;AAEA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,+CAA+C,aAAa;AAAA,EACrE;AAEA,SAAO;AACT;AAGA,SAAS,sBAAsB,eAAe;AAE5C,SAAO,cAAc,QAAQ,uBAAuB,OAAO;AAC7D;AAEA,MAAM,eAAe,CAAC,+BAA4B,YAAY,GAAG;AACjE,SAAS,cAAc,eAAe;AACpC,MAAI,aAAa,SAAS,aAAa,GAAG;AACxC,WAAO,aAAa,CAAC;AAAA,EACvB;AACA,SAAO;AACT;AAEA,MAAM,8BAA8B,CAAC,mBAAgB,kCAA+B,wBAAwB,qBAAqB;AACjI,SAAS,+CAA+C,eAAe;AAErE,MAAI,4BAA4B,SAAS,aAAa,GAAG;AACvD,WAAO,4BAA4B,CAAC;AAAA,EACtC;AAEA,SAAO;AACT;AAEA,SAAS,0BAA0B,eAAe;AAChD,QAAM,QAAQ;AAGd,MAAI,MAAM,MAAM,2FAA2F,GAAG;AAC5G,UAAM,MAAM,MAAM,QAAQ,cAAc,EAAE;AAC1C,WAAO,GAAG,GAAG;AAAA,EACf;AAGA,MAAI,MAAM,MAAM,oIAAoI,GAAG;AACrJ,UAAM,MAAM,MAAM,QAAQ,cAAc,EAAE;AAC1C,WAAO,GAAG,GAAG;AAAA,EACf;AAEA,MAAI,MAAM,MAAM,uFAAuF,GAAG;AACxG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,kFAAkF,GAAG;AACnG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,kFAAkF,GAAG;AACnG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,mFAAmF,GAAG;AACpG,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }