@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-alpha.12

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 (563) hide show
  1. package/.github/workflows/{melinda-node-tests.yml → melinda-node-tests-and-publish.yml} +37 -12
  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 +43 -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 +873 -769
  47. package/dist/ending-punctuation-conf.js.map +7 -1
  48. package/dist/ending-punctuation.js +156 -169
  49. package/dist/ending-punctuation.js.map +7 -1
  50. package/dist/ending-punctuation.test.js +2385 -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 +182 -413
  107. package/dist/index.js.map +7 -1
  108. package/dist/indicator-fixes.js +66 -94
  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 +71 -128
  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 +187 -379
  125. package/dist/merge-fields/counterpartField.js.map +7 -1
  126. package/dist/merge-fields/dataProvenance.js +29 -0
  127. package/dist/merge-fields/dataProvenance.js.map +7 -0
  128. package/dist/merge-fields/index.js +25 -50
  129. package/dist/merge-fields/index.js.map +7 -1
  130. package/dist/merge-fields/mergableIndicator.js +18 -51
  131. package/dist/merge-fields/mergableIndicator.js.map +7 -1
  132. package/dist/merge-fields/mergableTag.js +78 -30
  133. package/dist/merge-fields/mergableTag.js.map +7 -1
  134. package/dist/merge-fields/mergeConfig.js +66 -171
  135. package/dist/merge-fields/mergeConfig.js.map +7 -1
  136. package/dist/merge-fields/mergeConstraints.js +323 -1214
  137. package/dist/merge-fields/mergeConstraints.js.map +7 -1
  138. package/dist/merge-fields/mergeField.js +47 -111
  139. package/dist/merge-fields/mergeField.js.map +7 -1
  140. package/dist/merge-fields/mergeIndicator.js +64 -118
  141. package/dist/merge-fields/mergeIndicator.js.map +7 -1
  142. package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
  143. package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
  144. package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
  145. package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
  146. package/dist/merge-fields/mergeSubfield.js +47 -95
  147. package/dist/merge-fields/mergeSubfield.js.map +7 -1
  148. package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
  149. package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
  150. package/dist/merge-fields/worldKnowledge.js +15 -40
  151. package/dist/merge-fields/worldKnowledge.js.map +7 -1
  152. package/dist/merge-fields.test.js +46 -0
  153. package/dist/merge-fields.test.js.map +7 -0
  154. package/dist/mergeField500Lisapainokset.js +27 -56
  155. package/dist/mergeField500Lisapainokset.js.map +7 -1
  156. package/dist/mergeField500Lisapainokset.test.js +44 -0
  157. package/dist/mergeField500Lisapainokset.test.js.map +7 -0
  158. package/dist/mergeRelatorTermFields.js +33 -69
  159. package/dist/mergeRelatorTermFields.js.map +7 -1
  160. package/dist/mergeRelatorTermFields.test.js +44 -0
  161. package/dist/mergeRelatorTermFields.test.js.map +7 -0
  162. package/dist/modernize-502.js +23 -55
  163. package/dist/modernize-502.js.map +7 -1
  164. package/dist/modernize-502.test.js +38 -0
  165. package/dist/modernize-502.test.js.map +7 -0
  166. package/dist/multiple-subfield-0.js +23 -48
  167. package/dist/multiple-subfield-0.js.map +7 -1
  168. package/dist/multiple-subfield-0.test.js +44 -0
  169. package/dist/multiple-subfield-0.test.js.map +7 -0
  170. package/dist/non-breaking-space.js +11 -32
  171. package/dist/non-breaking-space.js.map +7 -1
  172. package/dist/non-breaking-space.test.js +38 -0
  173. package/dist/non-breaking-space.test.js.map +7 -0
  174. package/dist/normalize-dashes.js +18 -37
  175. package/dist/normalize-dashes.js.map +7 -1
  176. package/dist/normalize-dashes.test.js +44 -0
  177. package/dist/normalize-dashes.test.js.map +7 -0
  178. package/dist/normalize-identifiers.js +54 -140
  179. package/dist/normalize-identifiers.js.map +7 -1
  180. package/dist/normalize-identifiers.test.js +44 -0
  181. package/dist/normalize-identifiers.test.js.map +7 -0
  182. package/dist/normalize-qualifying-information.js +23 -48
  183. package/dist/normalize-qualifying-information.js.map +7 -1
  184. package/dist/normalize-qualifying-information.test.js +44 -0
  185. package/dist/normalize-qualifying-information.test.js.map +7 -0
  186. package/dist/normalize-utf8-diacritics.js +19 -105
  187. package/dist/normalize-utf8-diacritics.js.map +7 -1
  188. package/dist/normalize-utf8-diacritics.test.js +44 -0
  189. package/dist/normalize-utf8-diacritics.test.js.map +7 -0
  190. package/dist/normalizeFieldForComparison.js +91 -158
  191. package/dist/normalizeFieldForComparison.js.map +7 -1
  192. package/dist/normalizeSubfieldValueForComparison.js +37 -77
  193. package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
  194. package/dist/prepublicationUtils.js +58 -111
  195. package/dist/prepublicationUtils.js.map +7 -1
  196. package/dist/punctuation/index.js +56 -72
  197. package/dist/punctuation/index.js.map +7 -1
  198. package/dist/punctuation/rules/aut.js +372 -331
  199. package/dist/punctuation/rules/aut.js.map +7 -1
  200. package/dist/punctuation/rules/bib.js +420 -373
  201. package/dist/punctuation/rules/bib.js.map +7 -1
  202. package/dist/punctuation/rules/index.js +7 -21
  203. package/dist/punctuation/rules/index.js.map +7 -1
  204. package/dist/punctuation.test.js +44 -0
  205. package/dist/punctuation.test.js.map +7 -0
  206. package/dist/punctuation2.js +259 -802
  207. package/dist/punctuation2.js.map +7 -1
  208. package/dist/punctuation2.test.js +44 -0
  209. package/dist/punctuation2.test.js.map +7 -0
  210. package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
  211. package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
  212. package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
  213. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
  214. package/dist/removeDuplicateDataFields.js +102 -202
  215. package/dist/removeDuplicateDataFields.js.map +7 -1
  216. package/dist/removeDuplicateDataFields.test.js +44 -0
  217. package/dist/removeDuplicateDataFields.test.js.map +7 -0
  218. package/dist/removeInferiorDataFields.js +104 -227
  219. package/dist/removeInferiorDataFields.js.map +7 -1
  220. package/dist/removeInferiorDataFields.test.js +44 -0
  221. package/dist/removeInferiorDataFields.test.js.map +7 -0
  222. package/dist/resolvable-ext-references-melinda.js +25 -60
  223. package/dist/resolvable-ext-references-melinda.js.map +7 -1
  224. package/dist/resolvable-ext-references-melinda.test.js +160 -0
  225. package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
  226. package/dist/resolveOrphanedSubfield6s.js +32 -63
  227. package/dist/resolveOrphanedSubfield6s.js.map +7 -1
  228. package/dist/resolveOrphanedSubfield6s.test.js +44 -0
  229. package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
  230. package/dist/sanitize-vocabulary-source-codes.js +27 -55
  231. package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
  232. package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
  233. package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
  234. package/dist/sort-tags.js +13 -25
  235. package/dist/sort-tags.js.map +7 -1
  236. package/dist/sort-tags.test.js +261 -0
  237. package/dist/sort-tags.test.js.map +7 -0
  238. package/dist/sortFields.js +152 -222
  239. package/dist/sortFields.js.map +7 -1
  240. package/dist/sortFields.test.js +44 -0
  241. package/dist/sortFields.test.js.map +7 -0
  242. package/dist/sortRelatorTerms.js +30 -68
  243. package/dist/sortRelatorTerms.js.map +7 -1
  244. package/dist/sortRelatorTerms.test.js +44 -0
  245. package/dist/sortRelatorTerms.test.js.map +7 -0
  246. package/dist/sortSubfields.js +102 -255
  247. package/dist/sortSubfields.js.map +7 -1
  248. package/dist/sortSubfields.test.js +44 -0
  249. package/dist/sortSubfields.test.js.map +7 -0
  250. package/dist/stripPunctuation.js +13 -36
  251. package/dist/stripPunctuation.js.map +7 -1
  252. package/dist/stripPunctuation.test.js +44 -0
  253. package/dist/stripPunctuation.test.js.map +7 -0
  254. package/dist/subfield-exclusion.js +28 -75
  255. package/dist/subfield-exclusion.js.map +7 -1
  256. package/dist/subfield-exclusion.test.js +471 -0
  257. package/dist/subfield-exclusion.test.js.map +7 -0
  258. package/dist/subfield6Utils.js +107 -269
  259. package/dist/subfield6Utils.js.map +7 -1
  260. package/dist/subfield8Utils.js +26 -50
  261. package/dist/subfield8Utils.js.map +7 -1
  262. package/dist/subfieldValueNormalizations.js +40 -74
  263. package/dist/subfieldValueNormalizations.js.map +7 -1
  264. package/dist/subfieldValueNormalizations.test.js +45 -0
  265. package/dist/subfieldValueNormalizations.test.js.map +7 -0
  266. package/dist/sync-007-and-300.js +22 -53
  267. package/dist/sync-007-and-300.js.map +7 -1
  268. package/dist/sync-007-and-300.test.js +44 -0
  269. package/dist/sync-007-and-300.test.js.map +7 -0
  270. package/dist/translate-terms.js +67 -155
  271. package/dist/translate-terms.js.map +7 -1
  272. package/dist/translate-terms.test.js +54 -0
  273. package/dist/translate-terms.test.js.map +7 -0
  274. package/dist/typeOfDate-008.js +10 -25
  275. package/dist/typeOfDate-008.js.map +7 -1
  276. package/dist/typeOfDate-008.test.js +40 -0
  277. package/dist/typeOfDate-008.test.js.map +7 -0
  278. package/dist/unicode-decomposition.js +94 -107
  279. package/dist/unicode-decomposition.js.map +7 -1
  280. package/dist/unicode-decomposition.test.js +94 -0
  281. package/dist/unicode-decomposition.test.js.map +7 -0
  282. package/dist/update-field-540.js +30 -75
  283. package/dist/update-field-540.js.map +7 -1
  284. package/dist/update-field-540.test.js +44 -0
  285. package/dist/update-field-540.test.js.map +7 -0
  286. package/dist/urn.js +55 -128
  287. package/dist/urn.js.map +7 -1
  288. package/dist/urn.test.js +44 -0
  289. package/dist/urn.test.js.map +7 -0
  290. package/dist/utils.js +78 -126
  291. package/dist/utils.js.map +7 -1
  292. package/eslint.config.mjs +1 -2
  293. package/package.json +28 -101
  294. package/src/access-rights.js +1 -1
  295. package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
  296. package/src/addMissingField041.js +1 -1
  297. package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
  298. package/src/addMissingField336.js +3 -3
  299. package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
  300. package/src/addMissingField337.js +2 -2
  301. package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
  302. package/src/addMissingField338.js +2 -2
  303. package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
  304. package/src/cyrillux-usemarcon-replacement.js +18 -18
  305. package/src/{cyrillux-usemarcon-replacement.spec.js → cyrillux-usemarcon-replacement.test.js} +17 -14
  306. package/src/cyrillux.js +19 -12
  307. package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
  308. package/src/disambiguateSeriesStatements.js +2 -2
  309. package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
  310. package/src/double-commas.js +1 -1
  311. package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
  312. package/src/duplicates-ind1.js +1 -1
  313. package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
  314. package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
  315. package/src/ending-punctuation-conf.js +6 -5
  316. package/src/ending-punctuation.js +115 -24
  317. package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +357 -275
  318. package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
  319. package/src/field-008-18-34-character-groups.js +2 -2
  320. package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
  321. package/src/field-505-separators.js +3 -3
  322. package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
  323. package/src/field-521-fix.js +2 -2
  324. package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
  325. package/src/field-exclusion.js +1 -1
  326. package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
  327. package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
  328. package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
  329. package/src/fix-33X.js +4 -4
  330. package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
  331. package/src/fix-country-codes.js +1 -1
  332. package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
  333. package/src/fix-language-codes.js +5 -5
  334. package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
  335. package/src/fixRelatorTerms.js +5 -5
  336. package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
  337. package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
  338. package/src/identical-fields.js +1 -1
  339. package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
  340. package/src/index.js +132 -59
  341. package/src/indicator-fixes.js +17 -4
  342. package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
  343. package/src/isbn-issn.js +12 -7
  344. package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
  345. package/src/{item-language.spec.js → item-language.test.js} +21 -22
  346. package/src/melindaCustomMergeFields.js +1 -1
  347. package/src/merge-fields/controlSubfields.js +1 -1
  348. package/src/merge-fields/counterpartField.js +14 -9
  349. package/src/merge-fields/dataProvenance.js +41 -0
  350. package/src/merge-fields/index.js +12 -3
  351. package/src/merge-fields/mergableIndicator.js +1 -1
  352. package/src/merge-fields/mergeField.js +8 -8
  353. package/src/merge-fields/mergeIndicator.js +1 -1
  354. package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
  355. package/src/merge-fields/mergeOrAddSubfield.js +2 -2
  356. package/src/merge-fields/mergeSubfield.js +4 -4
  357. package/src/merge-fields/removeDuplicateSubfields.js +2 -2
  358. package/src/{merge-fields.spec.js → merge-fields.test.js} +18 -15
  359. package/src/mergeField500Lisapainokset.js +1 -1
  360. package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
  361. package/src/mergeRelatorTermFields.js +5 -7
  362. package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
  363. package/src/modernize-502.js +1 -1
  364. package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
  365. package/src/multiple-subfield-0.js +3 -3
  366. package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
  367. package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
  368. package/src/normalize-dashes.js +2 -2
  369. package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
  370. package/src/normalize-identifiers.js +1 -1
  371. package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
  372. package/src/normalize-qualifying-information.js +2 -2
  373. package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
  374. package/src/normalize-utf8-diacritics.js +2 -2
  375. package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
  376. package/src/normalizeFieldForComparison.js +32 -6
  377. package/src/normalizeSubfieldValueForComparison.js +1 -1
  378. package/src/prepublicationUtils.js +4 -4
  379. package/src/punctuation/index.js +1 -1
  380. package/src/punctuation/rules/index.js +2 -2
  381. package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
  382. package/src/punctuation2.js +17 -8
  383. package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
  384. package/src/reindexSubfield6OccurenceNumbers.js +5 -7
  385. package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
  386. package/src/removeDuplicateDataFields.js +11 -19
  387. package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
  388. package/src/removeInferiorDataFields.js +15 -12
  389. package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
  390. package/src/resolvable-ext-references-melinda.js +1 -1
  391. package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
  392. package/src/resolveOrphanedSubfield6s.js +6 -6
  393. package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
  394. package/src/sanitize-vocabulary-source-codes.js +4 -4
  395. package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
  396. package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
  397. package/src/sortFields.js +4 -4
  398. package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
  399. package/src/sortRelatorTerms.js +3 -3
  400. package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
  401. package/src/sortSubfields.js +8 -6
  402. package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
  403. package/src/stripPunctuation.js +3 -3
  404. package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
  405. package/src/subfield-exclusion.js +1 -1
  406. package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
  407. package/src/subfield6Utils.js +6 -10
  408. package/src/subfield8Utils.js +4 -4
  409. package/src/subfieldValueNormalizations.js +3 -3
  410. package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
  411. package/src/sync-007-and-300.js +2 -2
  412. package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
  413. package/src/translate-terms.js +3 -3
  414. package/src/translate-terms.test.js +75 -0
  415. package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
  416. package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
  417. package/src/update-field-540.js +2 -2
  418. package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
  419. package/src/urn.js +2 -2
  420. package/src/{urn.spec.js → urn.test.js} +12 -13
  421. package/src/utils.js +21 -5
  422. package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
  423. package/test-fixtures/field-505-separators/03/record.json +3 -0
  424. package/test-fixtures/indicator-fixes/10/expectedResult.json +11 -0
  425. package/test-fixtures/indicator-fixes/10/metadata.json +4 -0
  426. package/test-fixtures/indicator-fixes/10/record.json +11 -0
  427. package/test-fixtures/merge-fields/f05/expectedResult.json +24 -0
  428. package/test-fixtures/merge-fields/f05/metadata.json +6 -0
  429. package/test-fixtures/merge-fields/f05/record.json +30 -0
  430. package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
  431. package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
  432. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
  433. package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
  434. package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
  435. package/test-fixtures/remove-inferior-datafields/f16/expectedResult.json +12 -0
  436. package/test-fixtures/remove-inferior-datafields/f16/metadata.json +5 -0
  437. package/test-fixtures/remove-inferior-datafields/f16/record.json +14 -0
  438. package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
  439. package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
  440. package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
  441. package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
  442. package/test-fixtures/translate-terms-data.js +42 -0
  443. package/dist/access-rights.spec.js +0 -195
  444. package/dist/access-rights.spec.js.map +0 -1
  445. package/dist/addMissingField041.spec.js +0 -45
  446. package/dist/addMissingField041.spec.js.map +0 -1
  447. package/dist/addMissingField336.spec.js +0 -45
  448. package/dist/addMissingField336.spec.js.map +0 -1
  449. package/dist/addMissingField337.spec.js +0 -43
  450. package/dist/addMissingField337.spec.js.map +0 -1
  451. package/dist/addMissingField338.spec.js +0 -45
  452. package/dist/addMissingField338.spec.js.map +0 -1
  453. package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
  454. package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
  455. package/dist/cyrillux.spec.js +0 -46
  456. package/dist/cyrillux.spec.js.map +0 -1
  457. package/dist/disambiguateSeriesStatements.spec.js +0 -51
  458. package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
  459. package/dist/double-commas.spec.js +0 -73
  460. package/dist/double-commas.spec.js.map +0 -1
  461. package/dist/duplicates-ind1.spec.js +0 -45
  462. package/dist/duplicates-ind1.spec.js.map +0 -1
  463. package/dist/empty-fields.spec.js +0 -118
  464. package/dist/empty-fields.spec.js.map +0 -1
  465. package/dist/ending-punctuation.spec.js +0 -2654
  466. package/dist/ending-punctuation.spec.js.map +0 -1
  467. package/dist/ending-whitespace.spec.js +0 -42
  468. package/dist/ending-whitespace.spec.js.map +0 -1
  469. package/dist/field-008-18-34-character-groups.spec.js +0 -51
  470. package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
  471. package/dist/field-505-separators.spec.js +0 -51
  472. package/dist/field-505-separators.spec.js.map +0 -1
  473. package/dist/field-521-fix.spec.js +0 -51
  474. package/dist/field-521-fix.spec.js.map +0 -1
  475. package/dist/field-exclusion.spec.js +0 -1054
  476. package/dist/field-exclusion.spec.js.map +0 -1
  477. package/dist/field-structure.spec.js +0 -535
  478. package/dist/field-structure.spec.js.map +0 -1
  479. package/dist/fields-present.spec.js +0 -121
  480. package/dist/fields-present.spec.js.map +0 -1
  481. package/dist/fix-33X.spec.js +0 -45
  482. package/dist/fix-33X.spec.js.map +0 -1
  483. package/dist/fix-country-codes.spec.js +0 -51
  484. package/dist/fix-country-codes.spec.js.map +0 -1
  485. package/dist/fix-language-codes.spec.js +0 -44
  486. package/dist/fix-language-codes.spec.js.map +0 -1
  487. package/dist/fixRelatorTerms.spec.js +0 -51
  488. package/dist/fixRelatorTerms.spec.js.map +0 -1
  489. package/dist/fixed-fields.spec.js +0 -140
  490. package/dist/fixed-fields.spec.js.map +0 -1
  491. package/dist/identical-fields.spec.js +0 -99
  492. package/dist/identical-fields.spec.js.map +0 -1
  493. package/dist/indicator-fixes.spec.js +0 -51
  494. package/dist/indicator-fixes.spec.js.map +0 -1
  495. package/dist/isbn-issn.spec.js +0 -595
  496. package/dist/isbn-issn.spec.js.map +0 -1
  497. package/dist/item-language.spec.js +0 -306
  498. package/dist/item-language.spec.js.map +0 -1
  499. package/dist/melindaCustomMergeFields.json +0 -5120
  500. package/dist/merge-fields.spec.js +0 -51
  501. package/dist/merge-fields.spec.js.map +0 -1
  502. package/dist/mergeField500Lisapainokset.spec.js +0 -51
  503. package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
  504. package/dist/mergeRelatorTermFields.spec.js +0 -51
  505. package/dist/mergeRelatorTermFields.spec.js.map +0 -1
  506. package/dist/modernize-502.spec.js +0 -49
  507. package/dist/modernize-502.spec.js.map +0 -1
  508. package/dist/multiple-subfield-0.spec.js +0 -51
  509. package/dist/multiple-subfield-0.spec.js.map +0 -1
  510. package/dist/non-breaking-space.spec.js +0 -42
  511. package/dist/non-breaking-space.spec.js.map +0 -1
  512. package/dist/normalize-dashes.spec.js +0 -51
  513. package/dist/normalize-dashes.spec.js.map +0 -1
  514. package/dist/normalize-identifiers.spec.js +0 -51
  515. package/dist/normalize-identifiers.spec.js.map +0 -1
  516. package/dist/normalize-qualifying-information.spec.js +0 -51
  517. package/dist/normalize-qualifying-information.spec.js.map +0 -1
  518. package/dist/normalize-utf8-diacritics.spec.js +0 -51
  519. package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
  520. package/dist/punctuation.spec.js +0 -51
  521. package/dist/punctuation.spec.js.map +0 -1
  522. package/dist/punctuation2.spec.js +0 -51
  523. package/dist/punctuation2.spec.js.map +0 -1
  524. package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
  525. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
  526. package/dist/removeDuplicateDataFields.spec.js +0 -51
  527. package/dist/removeDuplicateDataFields.spec.js.map +0 -1
  528. package/dist/removeInferiorDataFields.spec.js +0 -51
  529. package/dist/removeInferiorDataFields.spec.js.map +0 -1
  530. package/dist/resolvable-ext-references-melinda.spec.js +0 -166
  531. package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
  532. package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
  533. package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
  534. package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
  535. package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
  536. package/dist/sort-tags.spec.js +0 -207
  537. package/dist/sort-tags.spec.js.map +0 -1
  538. package/dist/sortFields.spec.js +0 -51
  539. package/dist/sortFields.spec.js.map +0 -1
  540. package/dist/sortRelatorTerms.spec.js +0 -51
  541. package/dist/sortRelatorTerms.spec.js.map +0 -1
  542. package/dist/sortSubfields.spec.js +0 -52
  543. package/dist/sortSubfields.spec.js.map +0 -1
  544. package/dist/stripPunctuation.spec.js +0 -51
  545. package/dist/stripPunctuation.spec.js.map +0 -1
  546. package/dist/subfield-exclusion.spec.js +0 -523
  547. package/dist/subfield-exclusion.spec.js.map +0 -1
  548. package/dist/subfieldValueNormalizations.spec.js +0 -51
  549. package/dist/subfieldValueNormalizations.spec.js.map +0 -1
  550. package/dist/sync-007-and-300.spec.js +0 -51
  551. package/dist/sync-007-and-300.spec.js.map +0 -1
  552. package/dist/translate-terms.spec.js +0 -51
  553. package/dist/translate-terms.spec.js.map +0 -1
  554. package/dist/typeOfDate-008.spec.js +0 -47
  555. package/dist/typeOfDate-008.spec.js.map +0 -1
  556. package/dist/unicode-decomposition.spec.js +0 -91
  557. package/dist/unicode-decomposition.spec.js.map +0 -1
  558. package/dist/update-field-540.spec.js +0 -51
  559. package/dist/update-field-540.spec.js.map +0 -1
  560. package/dist/urn.spec.js +0 -52
  561. package/dist/urn.spec.js.map +0 -1
  562. package/src/melindaCustomMergeFields.json +0 -5120
  563. package/src/translate-terms.spec.js +0 -52
@@ -2,7 +2,7 @@
2
2
  //import createDebugLogger from 'debug';
3
3
  //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');
4
4
 
5
- import {fieldToString} from './utils';
5
+ import {fieldToString} from './utils.js';
6
6
 
7
7
 
8
8
  export default function () {
@@ -35,7 +35,7 @@ export default function () {
35
35
  const clonedFields = JSON.parse(JSON.stringify(record.fields));
36
36
  recordNormalizeIndicators(record);
37
37
 
38
- record.fields.forEach((field, index) => compareFields(field, index)); // eslint-disable-line array-callback-return
38
+ record.fields.forEach((field, index) => compareFields(field, index));
39
39
 
40
40
  function compareFields(field, index) {
41
41
  const origFieldAsString = fieldToString(clonedFields[index]);
@@ -171,6 +171,18 @@ function normalize245Indicator1(field, record) {
171
171
  field.ind1 = field1XX.length === 0 ? '0' : '1';
172
172
  }
173
173
 
174
+ function noDisplayConstantGenerated520Indicator1(field) {
175
+ if (field.tag !== '520') {
176
+ return;
177
+ }
178
+ const as = field.subfields.filter(sf => sf.code === 'a');
179
+ // Set ind1=8 "no display constant generated" fro certain values (part of MELKEHITYS-2579):
180
+ if (as.length === 1 && ['Abstract.', 'Abstrakt.', 'Abstrakti.', 'Abstract.', 'English Summary.', 'Sammandrag.', 'Tiivistelmä.'].includes(field.subfields[0].value)) {
181
+ field.ind1 = '8';
182
+ }
183
+
184
+ }
185
+
174
186
  function normalize776Indicator2(field) {
175
187
  if (field.tag !== '776') {
176
188
  return;
@@ -229,19 +241,20 @@ function getLanguages(record) {
229
241
 
230
242
  }
231
243
 
232
- export function recordNormalizeIndicators(record) {
244
+ function recordNormalizeIndicators(record) {
233
245
  recordNormalize490(record);
234
246
 
235
247
  // Language is used to handle non-filing indicators
236
248
  const languages = getLanguages(record);
237
249
 
238
- record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages)); // eslint-disable-line array-callback-return
250
+ record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));
239
251
 
240
252
  }
241
253
 
242
254
  function fieldNormalizeIndicators(field, record, languages) {
243
255
  normalize084Indicator1(field);
244
256
  normalize245Indicator1(field, record);
257
+ noDisplayConstantGenerated520Indicator1(field);
245
258
  normalizeNonFilingIndicator1(field, languages);
246
259
  normalizeNonFilingIndicator2(field, languages);
247
260
  normalize776Indicator2(field);
@@ -1,19 +1,19 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from './indicator-fixes';
3
+ import validatorFactory from './indicator-fixes.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
6
  import createDebugLogger from 'debug';
7
7
 
8
8
  generateTests({
9
9
  callback,
10
- path: [__dirname, '..', 'test-fixtures', 'indicator-fixes'],
10
+ path: [import.meta.dirname, '..', 'test-fixtures', 'indicator-fixes'],
11
11
  useMetadataFile: true,
12
12
  recurse: false,
13
13
  fixura: {
14
14
  reader: READERS.JSON
15
15
  },
16
- mocha: {
16
+ hooks: {
17
17
  before: () => testValidatorFactory()
18
18
  }
19
19
  });
@@ -22,12 +22,9 @@ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/indica
22
22
  async function testValidatorFactory() {
23
23
  const validator = await validatorFactory();
24
24
 
25
- expect(validator)
26
- .to.be.an('object')
27
- .that.has.any.keys('description', 'validate');
28
-
29
- expect(validator.description).to.be.a('string');
30
- expect(validator.validate).to.be.a('function');
25
+ assert.equal(typeof validator, 'object');
26
+ assert.equal(typeof validator.description, 'string');
27
+ assert.equal(typeof validator.validate, 'function');
31
28
  }
32
29
 
33
30
  async function callback({getFixture, enabled = true, fix = false}) {
@@ -43,10 +40,10 @@ async function callback({getFixture, enabled = true, fix = false}) {
43
40
 
44
41
  if (!fix) {
45
42
  const result = await validator.validate(record);
46
- expect(result).to.eql(expectedResult);
43
+ assert.deepEqual(result, expectedResult);
47
44
  return;
48
45
  }
49
46
 
50
47
  await validator.fix(record);
51
- expect(record).to.eql(expectedResult);
48
+ assert.deepEqual(record, expectedResult);
52
49
  }
package/src/isbn-issn.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import ISBN from 'isbn3';
2
- import validateISSN from '@natlibfi/issn-verify';
2
+ import {issn as validateISSN} from '@natlibfi/issn-verify';
3
3
 
4
4
  // handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y
5
5
  export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
@@ -29,8 +29,14 @@ export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
29
29
 
30
30
  function invalidISBN(isbn) {
31
31
  const isbnOnly = getFirstWord(isbn);
32
- const auditedIsbn = ISBN.audit(isbnOnly);
33
- return !auditedIsbn.validIsbn;
32
+ try {
33
+ const auditedIsbn = ISBN.audit(isbnOnly);
34
+ return !auditedIsbn.validIsbn;
35
+ }
36
+ catch {
37
+ return true;
38
+ }
39
+
34
40
  }
35
41
 
36
42
  function invalidSubfield(subfield) {
@@ -173,7 +179,7 @@ export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
173
179
  function fix(record) {
174
180
  getRelevantFields(record).forEach(field => {
175
181
  if (field.tag === '020') {
176
- field.subfields.forEach(subfield => fixField020Subfield(field, subfield)); // eslint-disable-line array-callback-return
182
+ field.subfields.forEach(subfield => fixField020Subfield(field, subfield));
177
183
  return;
178
184
  }
179
185
  // 022 ISSN:
@@ -238,9 +244,8 @@ export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
238
244
  function normalizeIsbnValue(value) {
239
245
  const trimmedValue = getFirstWord(value);
240
246
  //const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
241
- const auditResult = ISBN.audit(trimmedValue);
242
- if (!auditResult.validIsbn) {
243
- return undefined;
247
+ if (invalidISBN(trimmedValue)) {
248
+ return undefined; // should this return value (= nothing normalized), not undefined?
244
249
  }
245
250
  const numbersOnly = trimmedValue.replace(/[^0-9Xx]+/ug, '');
246
251
  const parsedIsbn = ISBN.parse(trimmedValue);
@@ -1,17 +1,15 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from '../src/isbn-issn';
3
+ import validatorFactory from '../src/isbn-issn.js';
4
+ import {describe, it} from 'node:test';
4
5
 
5
6
  describe('isbn-issn', () => {
6
7
  it('Creates a validator', async () => {
7
8
  const validator = await validatorFactory();
8
9
 
9
- expect(validator)
10
- .to.be.an('object')
11
- .that.has.any.keys('description', 'validate');
12
-
13
- expect(validator.description).to.be.a('string');
14
- expect(validator.validate).to.be.a('function');
10
+ assert.equal(typeof validator, 'object');
11
+ assert.equal(typeof validator.description, 'string');
12
+ assert.equal(typeof validator.validate, 'function');
15
13
  });
16
14
 
17
15
  describe('#validate', () => {
@@ -42,7 +40,7 @@ describe('isbn-issn', () => {
42
40
  });
43
41
  const result = await validator.validate(record);
44
42
 
45
- expect(result).to.eql({valid: true});
43
+ assert.deepEqual(result, {valid: true});
46
44
  });
47
45
 
48
46
  it('Finds the record invalid', async () => {
@@ -71,7 +69,7 @@ describe('isbn-issn', () => {
71
69
  });
72
70
  const result = await validator.validate(record);
73
71
 
74
- expect(result).to.eql({
72
+ assert.deepEqual(result, {
75
73
  valid: false, messages: [
76
74
  'ISBN (foo) is not valid',
77
75
  'ISSN (bar) is not valid'
@@ -93,7 +91,7 @@ describe('isbn-issn', () => {
93
91
  });
94
92
  const result = await validator.validate(record);
95
93
 
96
- expect(result).to.eql({
94
+ assert.deepEqual(result, {
97
95
  valid: true
98
96
  });
99
97
  });
@@ -112,7 +110,7 @@ describe('isbn-issn', () => {
112
110
  });
113
111
  const result = await validator.validate(record);
114
112
 
115
- expect(result).to.eql({
113
+ assert.deepEqual(result, {
116
114
  valid: false, messages: ['ISSN (undefined) is not valid']
117
115
  });
118
116
  });
@@ -131,7 +129,7 @@ describe('isbn-issn', () => {
131
129
  });
132
130
  const result = await validator.validate(record);
133
131
 
134
- expect(result).to.eql({valid: false, messages: ['ISBN (978-600-377-017-1 (nid.)) is not valid']});
132
+ assert.deepEqual(result, {valid: false, messages: ['ISBN (978-600-377-017-1 (nid.)) is not valid']});
135
133
  });
136
134
 
137
135
  it('Finds the record invalid (ISSN in \'l\'-subfield)', async () => {
@@ -154,7 +152,7 @@ describe('isbn-issn', () => {
154
152
  });
155
153
  const result = await validator.validate(record);
156
154
 
157
- expect(result).to.eql({
155
+ assert.deepEqual(result, {
158
156
  valid: false, messages: [
159
157
  'ISBN (foo) is not valid',
160
158
  'ISSN (bar) is not valid'
@@ -188,7 +186,7 @@ describe('isbn-issn', () => {
188
186
  });
189
187
  const result = await validator.validate(record);
190
188
 
191
- expect(result).to.eql({valid: false, messages: [
189
+ assert.deepEqual(result, {valid: false, messages: [
192
190
  'ISBN (9789519155470) is not valid',
193
191
  'ISBN (9068-31-372-X) is not valid',
194
192
  'ISBN (386006004X) is not valid'
@@ -220,7 +218,7 @@ describe('isbn-issn', () => {
220
218
 
221
219
  await validator.fix(record);
222
220
 
223
- expect(record.fields).to.eql([
221
+ assert.deepEqual(record.fields, [
224
222
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},
225
223
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]},
226
224
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]},
@@ -241,7 +239,7 @@ describe('isbn-issn', () => {
241
239
 
242
240
  await validator.fix(record);
243
241
 
244
- expect(record.fields).to.eql([
242
+ assert.deepEqual(record.fields, [
245
243
  {
246
244
  tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]
247
245
  }
@@ -261,7 +259,7 @@ describe('isbn-issn', () => {
261
259
 
262
260
  await validator.fix(record);
263
261
 
264
- expect(record.fields).to.eql([
262
+ assert.deepEqual(record.fields, [
265
263
  {
266
264
  tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]
267
265
  }
@@ -288,7 +286,7 @@ describe('isbn-issn', () => {
288
286
  });
289
287
  await validator.fix(record);
290
288
 
291
- expect(record.fields).to.eql([
289
+ assert.deepEqual(record.fields, [
292
290
  // NB! Initial space does not need to be removed. It's crap, but not this fixer's crap.
293
291
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]},
294
292
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}, {code: 'q', value: '(nidottu)'}]}
@@ -313,7 +311,7 @@ describe('isbn-issn', () => {
313
311
  });
314
312
  await validator.fix(record);
315
313
 
316
- expect(record.fields).to.eql([
314
+ assert.deepEqual(record.fields, [
317
315
  {
318
316
  tag: '020',
319
317
  ind1: ' ',
@@ -353,7 +351,7 @@ describe('isbn-issn', () => {
353
351
  });
354
352
  await validator.fix(record);
355
353
 
356
- expect(record.fields).to.eql([
354
+ assert.deepEqual(record.fields, [
357
355
  {tag: '005', value: 'whatever'},
358
356
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'q', value: 'sidottu'}]},
359
357
  {tag: '024', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]}
@@ -392,7 +390,7 @@ describe('isbn-issn', () => {
392
390
 
393
391
  await validator.fix(record);
394
392
 
395
- expect(record.fields).to.eql([
393
+ assert.deepEqual(record.fields, [
396
394
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},
397
395
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},
398
396
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '90-6831-372-X'}]}, // corrected hyphens
@@ -1,25 +1,24 @@
1
- import chai from 'chai';
2
- import chaiAsPromised from 'chai-as-promised';
1
+ import assert from 'node:assert';
3
2
  import {MarcRecord} from '@natlibfi/marc-record';
4
- import validatorFactory from '../src/item-language';
5
-
6
- const {expect} = chai;
7
- chai.use(chaiAsPromised);
3
+ import validatorFactory from '../src/item-language.js';
4
+ import {describe, it} from 'node:test';
8
5
 
9
6
  describe('item-language', () => {
10
7
  it('Creates a validator', async () => {
11
8
  const validator = await validatorFactory(/^520$/u);
12
9
 
13
- expect(validator)
14
- .to.be.an('object')
15
- .that.has.any.keys('description', 'validate');
16
-
17
- expect(validator.description).to.be.a('string');
18
- expect(validator.validate).to.be.a('function');
10
+ assert.equal(typeof validator, 'object');
11
+ assert.equal(typeof validator.description, 'string');
12
+ assert.equal(typeof validator.validate, 'function');
19
13
  });
20
14
 
21
15
  it('Throws an error when tagPattern is not provided', async () => {
22
- await expect(validatorFactory()).to.be.rejectedWith(Error, 'No tagPattern provided');
16
+ await assert.rejects(validatorFactory(), (err) => {
17
+ assert.equal(err instanceof Error, true);
18
+ assert.equal(err.message, 'No tagPattern provided');
19
+ return true;
20
+ });
21
+ //await assert(validatorFactory()).to.be.rejectedWith(Error, 'No tagPattern provided');
23
22
  });
24
23
 
25
24
  describe('#validate', () => {
@@ -48,7 +47,7 @@ describe('item-language', () => {
48
47
  });
49
48
  const result = await validator.validate(record);
50
49
 
51
- expect(result).to.eql({valid: true});
50
+ assert.deepEqual(result, {valid: true});
52
51
  });
53
52
 
54
53
  it('Finds the record invalid (Language code is missing and detection failed', async () => {
@@ -70,7 +69,7 @@ describe('item-language', () => {
70
69
  });
71
70
  const result = await validator.validate(record);
72
71
 
73
- expect(result).to.eql({valid: false, messages: ['Language detection failed']});
72
+ assert.deepEqual(result, {valid: false, messages: ['Language detection failed']});
74
73
  });
75
74
 
76
75
  it('Finds the record invalid (Detected language differs)', async () => {
@@ -102,7 +101,7 @@ describe('item-language', () => {
102
101
  });
103
102
  const result = await validator.validate(record);
104
103
 
105
- expect(result).to.eql({valid: false, messages: ['Item language code is invalid. Correct language code: eng']});
104
+ assert.deepEqual(result, {valid: false, messages: ['Item language code is invalid. Correct language code: eng']});
106
105
  });
107
106
 
108
107
  it('Finds the record invalid (Probability doesn\'t meet treshold)', async () => {
@@ -134,7 +133,7 @@ describe('item-language', () => {
134
133
  });
135
134
  const result = await validator.validate(record);
136
135
 
137
- expect(result).to.eql({valid: true, messages: ['Item language code is invalid. Current code: fin, suggestions: eng']});
136
+ assert.deepEqual(result, {valid: true, messages: ['Item language code is invalid. Current code: fin, suggestions: eng']});
138
137
  });
139
138
 
140
139
  it('Finds the record invalid (No detectable text)', async () => {
@@ -155,7 +154,7 @@ describe('item-language', () => {
155
154
  });
156
155
  const result = await validator.validate(record);
157
156
 
158
- expect(result).to.eql({valid: true, messages: ['Language detection failed']});
157
+ assert.deepEqual(result, {valid: true, messages: ['Language detection failed']});
159
158
  });
160
159
  });
161
160
 
@@ -189,7 +188,7 @@ describe('item-language', () => {
189
188
  });
190
189
  await validator.fix(record);
191
190
 
192
- expect(record.fields).to.eql([
191
+ assert.deepEqual(record.fields, [
193
192
  {
194
193
  tag: '008',
195
194
  value: '151118t20162016fi^a|||^^^^^^^|0|^0|eng|^'
@@ -237,7 +236,7 @@ describe('item-language', () => {
237
236
  });
238
237
  await validator.fix(record);
239
238
 
240
- expect(record.fields).to.eql([
239
+ assert.deepEqual(record.fields, [
241
240
  {
242
241
  tag: '008',
243
242
  value: '151118t20162016fi^a|||^^^^^^^|0|^0|eng|^'
@@ -291,7 +290,7 @@ describe('item-language', () => {
291
290
  });
292
291
  await validator.fix(record);
293
292
 
294
- expect(record.fields).to.eql([
293
+ assert.deepEqual(record.fields, [
295
294
  {
296
295
  tag: '008',
297
296
  value: '151118t20162016fi^a|||^^^^^^^|0|^0|eng|^'
@@ -337,7 +336,7 @@ describe('item-language', () => {
337
336
  try {
338
337
  await validator.fix(record);
339
338
  } catch (err) {
340
- expect(err.message).to.equal('Language code is missing and detection failed');
339
+ assert.equal(err.message, 'Language code is missing and detection failed');
341
340
  }
342
341
  });
343
342
  });
@@ -1,4 +1,4 @@
1
- export const melindaCustomMergeFields = {'fields':
1
+ export const melindaFieldSpecs = {'fields':
2
2
  [
3
3
  {
4
4
  'tag': 'leader',
@@ -3,7 +3,7 @@ import createDebugLogger from 'debug';
3
3
  import {fieldHasSubfield, fieldToString, nvdebug, nvdebugSubfieldArray, subfieldIsRepeatable, subfieldsAreIdentical} from '../utils.js';
4
4
 
5
5
  //import {normalizeControlSubfieldValue} from './normalizeIdentifier';
6
- import {normalizeControlSubfieldValue} from '../normalize-identifiers';
6
+ import {normalizeControlSubfieldValue} from '../normalize-identifiers.js';
7
7
 
8
8
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:controlSubfields');
9
9
  //const debugData = debug.extend('data');
@@ -1,16 +1,17 @@
1
1
  // For each incoming field that
2
2
 
3
3
  import createDebugLogger from 'debug';
4
- import {fieldHasSubfield, fieldHasNSubfields, fieldHasMultipleSubfields, fieldToString, nvdebug, removeCopyright} from '../utils';
5
- import {cloneAndNormalizeFieldForComparison, cloneAndRemovePunctuation} from '../normalizeFieldForComparison';
4
+ import {fieldHasSubfield, fieldHasNSubfields, fieldHasMultipleSubfields, fieldToString, nvdebug, removeCopyright} from '../utils.js';
5
+ import {cloneAndNormalizeFieldForComparison, cloneAndRemovePunctuation} from '../normalizeFieldForComparison.js';
6
6
  // This should be done via our own normalizer:
7
- import {normalizeControlSubfieldValue} from '../normalize-identifiers';
7
+ import {normalizeControlSubfieldValue} from '../normalize-identifiers.js';
8
8
 
9
- import {getMergeConstraintsForTag} from './mergeConstraints';
10
- import {controlSubfieldsPermitMerge} from './controlSubfields';
11
- import {mergableIndicator1, mergableIndicator2} from './mergableIndicator';
12
- import {partsAgree} from '../normalizeSubfieldValueForComparison';
13
- import {normalizeForSamenessCheck, valueCarriesMeaning} from './worldKnowledge';
9
+ import {getMergeConstraintsForTag} from './mergeConstraints.js';
10
+ import {controlSubfieldsPermitMerge} from './controlSubfields.js';
11
+ import {mergableIndicator1, mergableIndicator2} from './mergableIndicator.js';
12
+ import {partsAgree} from '../normalizeSubfieldValueForComparison.js';
13
+ import {normalizeForSamenessCheck, valueCarriesMeaning} from './worldKnowledge.js';
14
+ import { provenanceSubfieldsPermitMerge } from './dataProvenance.js';
14
15
 
15
16
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:mergeField:counterpart');
16
17
  //const debugData = debug.extend('data');
@@ -201,7 +202,6 @@ function counterpartExtraNormalize(tag, subfieldCode, value) {
201
202
  value = value.replace(/http:\/\//ug, 'https://'); // MET-501: http vs https
202
203
  value = normalizeForSamenessCheck(tag, subfieldCode, value);
203
204
 
204
- /* eslint-enable */
205
205
  return value;
206
206
  }
207
207
 
@@ -376,6 +376,11 @@ function syntacticallyMergablePair(baseField, sourceField, config) {
376
376
  return false;
377
377
  }
378
378
 
379
+ if (!provenanceSubfieldsPermitMerge(baseField, sourceField)) {
380
+ nvdebug('non-mergable (reason: data provenance subfield)', debugDev);
381
+ return false;
382
+ }
383
+
379
384
  // NB! field1.tag and field2.tag might differ (1XX vs 7XX). Therefore required subfields might theoretically differ as well.
380
385
  // Note: Theoretically 260 $efg vs 264 with IND2=3 has already been handled by the preprocessor.
381
386
  // Thus check both:
@@ -0,0 +1,41 @@
1
+ // See https://www.loc.gov/marc/bibliographic/bdapndxj.html for details
2
+
3
+ import {subfieldArraysContainSameData} from "../utils.js";
4
+
5
+ export function tagToDataProvenanceSubfieldCode(tag) {
6
+ if ( ['533', '800', '810', '811', '830'].includes(tag)) {
7
+ return 'y';
8
+ }
9
+ if ( tag === '856' || tag === '857' ) {
10
+ return 'e';
11
+ }
12
+
13
+ if ( tag.match(/^7[678]/u) ) {
14
+ return 'l'
15
+ }
16
+
17
+ if ( tag.match(/^00/u)) {
18
+ return undefined;
19
+ }
20
+ return '7';
21
+ }
22
+
23
+
24
+ export function provenanceSubfieldsPermitMerge(baseField, sourceField) {
25
+ const provinanceSubfieldCode = tagToDataProvenanceSubfieldCode(baseField.tag);
26
+ if (!baseField.subfields) {
27
+ return true;
28
+ }
29
+ if (provinanceSubfieldCode === undefined) {
30
+ return false;
31
+ }
32
+
33
+ const baseProvinanceSubfields = baseField.subfields.filter(sf => sf.code === provinanceSubfieldCode);
34
+ const sourceProvinanceSubfields = sourceField.subfields.filter(sf => sf.code === provinanceSubfieldCode);
35
+
36
+ // Currently we just compare two arrays. Later on we might do something more sophisticated with specific $7 data provenance category/relationship codes,
37
+ // or actual values.
38
+
39
+ return subfieldArraysContainSameData(baseProvinanceSubfields, sourceProvinanceSubfields);
40
+
41
+ }
@@ -8,7 +8,7 @@
8
8
  //import createDebugLogger from 'debug';
9
9
  //import fs from 'fs';
10
10
  //import path from 'path';
11
- import {mergeField} from './mergeField';
11
+ import {mergeField} from './mergeField.js';
12
12
  import {MarcRecord} from '@natlibfi/marc-record';
13
13
  import {postprocessRecords} from './mergeOrAddPostprocess.js';
14
14
 
@@ -18,16 +18,25 @@ import {mergeConfig as defaultConfig} from './mergeConfig.js';
18
18
 
19
19
  //const defaultConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'merge-fields', 'config.json'), 'utf8'));
20
20
 
21
- export default function () {
21
+ export default function (defaultTagPattern = undefined) {
22
22
 
23
23
  return {
24
24
  description, validate, fix
25
25
  };
26
26
 
27
+ function getTagPattern(config) {
28
+ if (config && config.tagPattern) {
29
+ return config.tagPattern;
30
+ }
31
+ if (defaultTagPattern) { // Used by tests
32
+ return defaultTagPattern;
33
+ }
34
+ return '^[1678](?:00|10|11|30)$';
35
+ }
27
36
 
28
37
  function mergeFieldsWithinRecord(record, config) {
29
38
  //const candFields = record.fields.toReversed(); // Node 20+ only! Filter via config?
30
- const fields = config && config.tagPattern ? record.get(config.tagPattern) : record.get(/^[1678](?:00|10|11|30)$/u);
39
+ const fields = record.get(getTagPattern(config)); // config && config.tagPattern ? record.get(config.tagPattern) : record.get(/^[1678](?:00|10|11|30)$/u);
31
40
 
32
41
  fields.reverse();
33
42
  const mergedField = fields.find(f => mergeField(record, record, f, config));
@@ -1,5 +1,5 @@
1
1
  import createDebugLogger from 'debug';
2
- import {marc21GetTagsLegalInd1Value, marc21GetTagsLegalInd2Value, nvdebug} from '../utils';
2
+ import {marc21GetTagsLegalInd1Value, marc21GetTagsLegalInd2Value, nvdebug} from '../utils.js';
3
3
 
4
4
  // Specs: https://workgroups.helsinki.fi/x/K1ohCw (though we occasionally differ from them)...
5
5
 
@@ -1,12 +1,12 @@
1
1
  //import {MarcRecord} from '@natlibfi/marc-record';
2
2
  import createDebugLogger from 'debug';
3
- import {fieldToString, fieldsToString, fieldsAreIdentical, nvdebug, hasCopyright, removeCopyright, subfieldToString} from '../utils';
3
+ import {fieldToString, fieldsToString, fieldsAreIdentical, nvdebug, hasCopyright, removeCopyright, subfieldToString} from '../utils.js';
4
4
  import {fieldGetOccurrenceNumberPairs} from '../subfield6Utils.js';
5
- import {cloneAndNormalizeFieldForComparison, cloneAndRemovePunctuation, isEnnakkotietoSubfieldG} from '../normalizeFieldForComparison';
6
- import {mergeOrAddSubfield} from './mergeOrAddSubfield';
7
- import {mergeIndicators} from './mergeIndicator';
8
- import {mergableTag} from './mergableTag';
9
- import {getCounterpart} from './counterpartField';
5
+ import {cloneAndNormalizeFieldForComparison, cloneAndRemovePunctuation, isEnnakkotietoSubfieldG} from '../normalizeFieldForComparison.js';
6
+ import {mergeOrAddSubfield} from './mergeOrAddSubfield.js';
7
+ import {mergeIndicators} from './mergeIndicator.js';
8
+ import {mergableTag} from './mergableTag.js';
9
+ import {getCounterpart} from './counterpartField.js';
10
10
  //import {default as normalizeEncoding} from '@natlibfi/marc-record-validators-melinda/dist/normalize-utf8-diacritics';
11
11
  //import {postprocessRecords} from './mergeOrAddPostprocess.js';
12
12
  //import {preprocessBeforeAdd} from './processFilter.js';
@@ -106,8 +106,8 @@ function skipMergeField(baseRecord, sourceField, config) {
106
106
  return true;
107
107
  }
108
108
 
109
- // Skip duplicate field:
110
- if (baseRecord.fields.some(baseField => !baseField.mergeCandidate && fieldsAreIdentical(sourceField, baseField))) {
109
+ // Skip duplicate field when merging two records (NB! internal merge merges/removes the duplicate field):
110
+ if (!baseRecord.internalMerge && baseRecord.fields.some(baseField => !baseField.mergeCandidate && fieldsAreIdentical(sourceField, baseField))) {
111
111
  nvdebug(`skipMergeField(): field '${fieldToString(sourceField)}' already exists! No merge required!`, debugDev);
112
112
  sourceField.deleted = 1;
113
113
  return true;
@@ -1,5 +1,5 @@
1
1
  import createDebugLogger from 'debug';
2
- import {fieldToString, marc21GetTagsLegalInd1Value, marc21GetTagsLegalInd2Value, nvdebug} from '../utils';
2
+ import {fieldToString, marc21GetTagsLegalInd1Value, marc21GetTagsLegalInd2Value, nvdebug} from '../utils.js';
3
3
 
4
4
  // Specs: https://workgroups.helsinki.fi/x/K1ohCw (though we occasionally differ from them)...
5
5
 
@@ -1,10 +1,10 @@
1
1
  // This field should be renamed, as it is called also from outside megre.
2
2
 
3
3
  //import {MarcRecord} from '@natlibfi/marc-record';
4
- import {fieldFixPunctuation} from '../punctuation2';
5
- import {fieldRemoveDuplicateSubfields} from './removeDuplicateSubfields';
6
- import {sortAdjacentSubfields} from '../sortSubfields';
7
- import {sortAdjacentRelatorTerms} from '../sortRelatorTerms';
4
+ import {fieldFixPunctuation} from '../punctuation2.js';
5
+ import {fieldRemoveDuplicateSubfields} from './removeDuplicateSubfields.js';
6
+ import {sortAdjacentSubfields} from '../sortSubfields.js';
7
+ import {sortAdjacentRelatorTerms} from '../sortRelatorTerms.js';
8
8
 
9
9
  function postprocessBaseRecord(base) {
10
10
 
@@ -1,9 +1,9 @@
1
1
  import createDebugLogger from 'debug';
2
2
  import {cloneAndNormalizeFieldForComparison, isEnnakkotietoSubfieldG} from '../normalizeFieldForComparison.js';
3
- import {normalizeAs, normalizeControlSubfieldValue} from '../normalize-identifiers';
3
+ import {normalizeAs, normalizeControlSubfieldValue} from '../normalize-identifiers.js';
4
4
  import {fieldHasSubfield, fieldToString, isControlSubfieldCode, nvdebug, subfieldIsRepeatable, subfieldToString} from '../utils.js';
5
5
  import {mergeSubfield} from './mergeSubfield.js';
6
- import {sortAdjacentSubfields} from '../sortSubfields'; //'./sortSubfields.js';
6
+ import {sortAdjacentSubfields} from '../sortSubfields.js';
7
7
 
8
8
  import {valueCarriesMeaning} from './worldKnowledge.js';
9
9
  import {resetSubfield6Tag} from '../subfield6Utils.js';
@@ -1,9 +1,9 @@
1
1
  import createDebugLogger from 'debug';
2
- import {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison';
3
- import {valueCarriesMeaning} from './worldKnowledge';
4
- import {nvdebug} from '../utils';
2
+ import {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison.js';
3
+ import {valueCarriesMeaning} from './worldKnowledge.js';
4
+ import {nvdebug} from '../utils.js';
5
5
  import {tagAndSubfieldCodeReferToIsbn} from '../normalizeFieldForComparison.js';
6
- import {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField';
6
+ import {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField.js';
7
7
 
8
8
  const debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');
9
9
  //const debugData = debug.extend('data');