@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
package/src/cyrillux.js CHANGED
@@ -1,15 +1,14 @@
1
1
  //import createDebugLogger from 'debug';
2
2
  import clone from 'clone';
3
- import {fieldHasSubfield, fieldToString, fieldsToString, isControlSubfieldCode, nvdebug} from './utils';
4
- import * as iso9 from 'iso9_1995';
5
- import {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils';
6
-
7
3
  import XRegExp from 'xregexp';
4
+ import * as iso9 from '@natlibfi/iso9-1995';
8
5
  import * as sfs4900 from '@natlibfi/sfs-4900';
9
- import {default as sortFields} from './sortFields';
10
- import {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers';
11
- import {fieldStripPunctuation} from './punctuation2';
12
- import {getLanguageCode} from './addMissingField041';
6
+ import {fieldHasSubfield, fieldToString, fieldsToString, isControlSubfieldCode, nvdebug} from './utils.js';
7
+ import {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils.js';
8
+ import {default as sortFields} from './sortFields.js';
9
+ import {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers.js';
10
+ import {fieldStripPunctuation} from './punctuation2.js';
11
+ import {getLanguageCode} from './addMissingField041.js';
13
12
 
14
13
  const iso9Trans = 'ISO9 <TRANS>';
15
14
  const cyrillicTrans = 'CYRILLIC <TRANS>';
@@ -158,16 +157,24 @@ export default function (config = {}) {
158
157
  if (!subfieldRequiresTransliteration(subfield)) {
159
158
  return {code: subfield.code, value: subfield.value}; // just clone
160
159
  }
161
- const value = iso9.convertToLatin(subfield.value);
162
160
 
163
- return {code: subfield.code, value};
161
+ const conversionResult = iso9.convertToLatin(subfield.value);
162
+
163
+ return {code: subfield.code, value: conversionResult.result};
164
164
  }
165
165
 
166
166
  function mapSubfieldToSfs4900(subfield, lang = 'rus') {
167
167
  const inputLang = lang === 'ukr' ? 'ukr' : 'rus'; // Support 'ukr' and 'rus', default to 'rus'
168
- const value = subfieldRequiresTransliteration(subfield) ? sfs4900.convertToLatin(subfield.value, inputLang).result : subfield.value;
168
+ if (!subfieldRequiresTransliteration(subfield)) {
169
+ return {code: subfield.code, value: subfield.value};
170
+ }
171
+ const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);
172
+
173
+ console.log(JSON.stringify(conversionResult));
174
+ const result = conversionResult.result;
175
+ console.log(JSON.stringify(result));
169
176
  //console.log(`VAL: ${subfield.value} => ${value} using ${lang}`); // eslint-disable-line no-console
170
- return {code: subfield.code, value};
177
+ return {code: subfield.code, value: result};
171
178
  }
172
179
 
173
180
  function mapField(field, occurrenceNumber, iso9 = true, lang = 'rus') {
@@ -1,32 +1,31 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from './cyrillux';
3
+ import validatorFactory from './cyrillux.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
6
 
7
7
  generateTests({
8
8
  callback,
9
- path: [__dirname, '..', 'test-fixtures', 'cyrillux'],
9
+ path: [import.meta.dirname, '..', 'test-fixtures', 'cyrillux'],
10
10
  useMetadataFile: true,
11
11
  recurse: false,
12
12
  fixura: {
13
13
  reader: READERS.JSON
14
14
  },
15
- mocha: {
16
- before: () => testValidatorFactory()
15
+ hooks: {
16
+ before: async () => {
17
+ testValidatorFactory();
18
+ }
17
19
  }
18
20
  });
19
21
 
20
22
  async function testValidatorFactory() {
21
23
  const validator = await validatorFactory();
22
24
 
23
- expect(validator)
24
- .to.be.an('object')
25
- .that.has.any.keys('description', 'validate');
26
-
27
- expect(validator.description).to.be.a('string');
28
- expect(validator.validate).to.be.a('function');
29
- expect(validator.fix).to.be.a('function');
25
+ assert.equal(typeof validator, 'object');
26
+ assert.equal(typeof validator.description, 'string');
27
+ assert.equal(typeof validator.validate, 'function');
28
+ assert.equal(typeof validator.fix, 'function');
30
29
  }
31
30
 
32
31
  async function callback({getFixture, fix = false, config = {}}) {
@@ -37,10 +36,10 @@ async function callback({getFixture, fix = false, config = {}}) {
37
36
 
38
37
  if (!fix) {
39
38
  const result = await validator.validate(record);
40
- expect(result).to.eql(expectedResult);
39
+ assert.deepEqual(result, expectedResult);
41
40
  return;
42
41
  }
43
42
 
44
43
  await validator.fix(record);
45
- expect(record).to.eql(expectedResult);
44
+ assert.deepEqual(record, expectedResult);
46
45
  }
@@ -1,10 +1,10 @@
1
1
  import createDebugLogger from 'debug';
2
- import {fieldToString, nvdebug, subfieldToString} from './utils';
2
+ import {fieldToString, nvdebug, subfieldToString} from './utils.js';
3
3
  import {MARCXML} from '@natlibfi/marc-record-serializers';
4
4
  import {Error} from '@natlibfi/melinda-commons';
5
5
  import clone from 'clone';
6
6
  import {default as createNatlibfiSruClient} from '@natlibfi/sru-client';
7
- import {fieldFixPunctuation} from './punctuation2';
7
+ import {fieldFixPunctuation} from './punctuation2.js';
8
8
 
9
9
  //const {default: createNatlibfiSruClient} = natlibfiSruClient;
10
10
 
@@ -1,20 +1,22 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from './disambiguateSeriesStatements';
3
+ import validatorFactory from './disambiguateSeriesStatements.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', 'disambiguate-series-statements'],
10
+ path: [import.meta.dirname, '..', 'test-fixtures', 'disambiguate-series-statements'],
11
11
  useMetadataFile: true,
12
12
  recurse: false,
13
13
  fixura: {
14
14
  reader: READERS.JSON
15
15
  },
16
- mocha: {
17
- before: () => testValidatorFactory()
16
+ hooks: {
17
+ before: async () => {
18
+ testValidatorFactory();
19
+ }
18
20
  }
19
21
  });
20
22
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');
@@ -22,12 +24,9 @@ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disamb
22
24
  async function testValidatorFactory() {
23
25
  const validator = await validatorFactory();
24
26
 
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');
27
+ assert.equal(typeof validator, 'object');
28
+ assert.equal(typeof validator.description, 'string');
29
+ assert.equal(typeof validator.validate, 'function');
31
30
  }
32
31
 
33
32
  async function callback({getFixture, enabled = true, fix = false}) {
@@ -43,10 +42,10 @@ async function callback({getFixture, enabled = true, fix = false}) {
43
42
 
44
43
  if (!fix) {
45
44
  const result = await validator.validate(record);
46
- expect(result).to.eql(expectedResult);
45
+ assert.deepEqual(result, expectedResult);
47
46
  return;
48
47
  }
49
48
 
50
49
  await validator.fix(record);
51
- expect(record).to.eql(expectedResult);
50
+ assert.deepEqual(record, expectedResult);
52
51
  }
@@ -6,7 +6,7 @@ export default function () {
6
6
  .get(/^700$/u)
7
7
  .some(f => f.subfields.every(sf => sf.code === 'e' && (/,,/u).test(sf.value)))
8
8
  }),
9
- fix: record => record.get(/^700$/u).forEach(f => f.subfields.filter(sf => sf.code === 'e').forEach(sf => { // eslint-disable-line array-callback-return
9
+ fix: record => record.get(/^700$/u).forEach(f => f.subfields.filter(sf => sf.code === 'e').forEach(sf => {
10
10
  sf.value = sf.value.replace(/,,/u, ',');
11
11
  }))
12
12
  };
@@ -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/double-commas';
3
+ import validatorFactory from './double-commas.js';
4
+ import {describe, it} from 'node:test';
4
5
 
5
6
  describe('double-commas', () => {
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', () => {
@@ -22,7 +20,7 @@ describe('double-commas', () => {
22
20
  });
23
21
  const result = await validator.validate(record);
24
22
 
25
- expect(result).to.eql({valid: true});
23
+ assert.deepEqual(result, {valid: true});
26
24
  });
27
25
  it('Finds the record invalid', async () => {
28
26
  const validator = await validatorFactory();
@@ -31,7 +29,7 @@ describe('double-commas', () => {
31
29
  });
32
30
  const result = await validator.validate(record);
33
31
 
34
- expect(result).to.eql({valid: false});
32
+ assert.deepEqual(result, {valid: false});
35
33
  });
36
34
  });
37
35
 
@@ -43,7 +41,7 @@ describe('double-commas', () => {
43
41
  });
44
42
  await validator.fix(record);
45
43
 
46
- expect(record.fields).to.eql([
44
+ assert.deepEqual(record.fields, [
47
45
  {
48
46
  tag: '700',
49
47
  ind1: ' ',
@@ -20,7 +20,7 @@ export default function (tagPattern) {
20
20
  iterateFields(record)
21
21
  .filter(item => item.validation === false)
22
22
  .map(({validation, ...item}) => item) // eslint-disable-line no-unused-vars
23
- .forEach(({obj}) => record.removeField(obj)); // eslint-disable-line array-callback-return
23
+ .forEach(({obj}) => record.removeField(obj));
24
24
  }
25
25
 
26
26
  function iterateFields(record) {
@@ -1,6 +1,6 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from './duplicates-ind1';
3
+ import validatorFactory from './duplicates-ind1.js';
4
4
 
5
5
  import {READERS} from '@natlibfi/fixura';
6
6
  import generateTests from '@natlibfi/fixugen';
@@ -8,14 +8,16 @@ import createDebugLogger from 'debug';
8
8
 
9
9
  generateTests({
10
10
  callback,
11
- path: [__dirname, '..', 'test-fixtures', 'duplicates-ind1'],
11
+ path: [import.meta.dirname, '..', 'test-fixtures', 'duplicates-ind1'],
12
12
  useMetadataFile: true,
13
13
  recurse: false,
14
14
  fixura: {
15
15
  reader: READERS.JSON
16
16
  },
17
- mocha: {
18
- before: () => testValidatorFactory()
17
+ hooks: {
18
+ before: async () => {
19
+ testValidatorFactory();
20
+ }
19
21
  }
20
22
  });
21
23
 
@@ -24,12 +26,9 @@ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/duplic
24
26
  async function testValidatorFactory() {
25
27
  const validator = await validatorFactory(/^500$/u);
26
28
 
27
- expect(validator)
28
- .to.be.an('object')
29
- .that.has.any.keys('description', 'validate');
30
-
31
- expect(validator.description).to.be.a('string');
32
- expect(validator.validate).to.be.a('function');
29
+ assert.equal(typeof validator, 'object');
30
+ assert.equal(typeof validator.description, 'string');
31
+ assert.equal(typeof validator.validate, 'function');
33
32
  }
34
33
 
35
34
  async function callback({getFixture, tagPattern, fix = false}) {
@@ -39,10 +38,10 @@ async function callback({getFixture, tagPattern, fix = false}) {
39
38
 
40
39
  if (!fix) {
41
40
  const result = await validator.validate(record);
42
- return expect(result).to.eql(expectedResult);
41
+ return assert.deepEqual(result, expectedResult);
43
42
  }
44
43
 
45
44
  const fixedRecord = await validator.fix(record);
46
45
  debug(fixedRecord);
47
- expect(record.fields).to.eql(expectedResult);
46
+ assert.deepEqual(record.fields, expectedResult);
48
47
  }
@@ -1,6 +1,7 @@
1
- import {expect} from 'chai';
1
+ import assert from 'node:assert';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
- import validatorFactory from '../src/empty-fields';
3
+ import validatorFactory from './empty-fields.js';
4
+ import {after, before, describe, it} from 'node:test';
4
5
 
5
6
  before(() => {
6
7
  MarcRecord.setValidationOptions({subfields: false, subfieldValues: false});
@@ -14,12 +15,9 @@ describe('empty-fields', () => {
14
15
  it('Creates a validator', async () => {
15
16
  const validator = await validatorFactory();
16
17
 
17
- expect(validator)
18
- .to.be.an('object')
19
- .that.has.any.keys('description', 'validate');
20
-
21
- expect(validator.description).to.be.a('string');
22
- expect(validator.validate).to.be.a('function');
18
+ assert.equal(typeof validator, 'object');
19
+ assert.equal(typeof validator.description, 'string');
20
+ assert.equal(typeof validator.validate, 'function');
23
21
  });
24
22
 
25
23
  describe('#validate', () => {
@@ -38,7 +36,7 @@ describe('empty-fields', () => {
38
36
  ]
39
37
  });
40
38
  const result = await validator.validate(record);
41
- expect(result).to.to.have.property('valid', true);
39
+ assert.deepEqual(result.valid, true);
42
40
  });
43
41
 
44
42
  it('Finds a missing subfield value', async () => {
@@ -57,7 +55,7 @@ describe('empty-fields', () => {
57
55
  });
58
56
  const result = await validator.validate(record);
59
57
 
60
- expect(result).to.eql({valid: false, messages: ['Field 245 has missing subfield values: a']});
58
+ assert.deepEqual(result, {valid: false, messages: ['Field 245 has missing subfield values: a']});
61
59
  });
62
60
 
63
61
  it('Finds an empty subfield array', async () => {
@@ -72,7 +70,7 @@ describe('empty-fields', () => {
72
70
  });
73
71
  const result = await validator.validate(record);
74
72
 
75
- expect(result).to.eql({valid: false, messages: ['Field 500 has no subfields']});
73
+ assert.deepEqual(result, {valid: false, messages: ['Field 500 has no subfields']});
76
74
  });
77
75
  });
78
76
 
@@ -97,7 +95,7 @@ describe('empty-fields', () => {
97
95
  });
98
96
  await validator.fix(record);
99
97
 
100
- expect(record.fields).to.eql([
98
+ assert.deepEqual(record.fields, [
101
99
  {
102
100
  tag: '245',
103
101
  ind1: ' ',
@@ -128,7 +126,7 @@ describe('empty-fields', () => {
128
126
  });
129
127
  await validator.fix(record);
130
128
 
131
- expect(record.fields).to.eql([
129
+ assert.deepEqual(record.fields, [
132
130
  {
133
131
  tag: '001',
134
132
  value: '1234567'
@@ -1,10 +1,11 @@
1
1
  // Const finnishTerms = ['ysa', 'yso', 'kassu', 'seko', 'valo', 'kulo', 'puho', 'oiko', 'mero', 'liito', 'fast', 'allars', 'kaunokki'];
2
2
  const finnishTerms = [
3
3
  /^(?:allars|bella|fast|juho|jupo|kassu|kauno|kaunokki|keko|koko|kulo|liiko|liito|local|mero|mts|musa|oiko|puho|seko|woto|valo|ysa|yso)$/u,
4
- /^(?:kauno|slm|yso)\//u
4
+ /^(?:kauno|slm|yso)\//u // <= yso/* etc
5
5
  ];
6
6
 
7
- const validPuncMarks = '?"-!,)]';
7
+ const validPuncMarks = '?-!.'; // NB! ')' and ']' are only valid for some fields!
8
+ const validQuoteChars = "\"'";
8
9
  // Configuration specification
9
10
  const confSpec = [
10
11
  { // 010-035 EI
@@ -500,7 +501,7 @@ const confSpec = [
500
501
  index: null,
501
502
  punc: false,
502
503
  special: {
503
- termField: '2',
504
+ termSubfieldCode: '2',
504
505
  finnishTerms,
505
506
  else: true
506
507
  }
@@ -516,7 +517,7 @@ const confSpec = [
516
517
  index: null,
517
518
  punc: false,
518
519
  special: {
519
- termField: '2',
520
+ termSubfieldCode: '2',
520
521
  finnishTerms,
521
522
  else: true
522
523
  }
@@ -666,4 +667,4 @@ const confSpec = [
666
667
  }
667
668
  ];
668
669
 
669
- export {finnishTerms, validPuncMarks, confSpec};
670
+ export {finnishTerms, validPuncMarks, validQuoteChars, confSpec};
@@ -27,7 +27,7 @@
27
27
  */
28
28
 
29
29
  // Import {validPuncMarks, finnishTerms, confSpec} from './ending-punctuation-conf.js';
30
- import {validPuncMarks, finnishTerms, confSpec} from './ending-punctuation-conf';
30
+ import {validPuncMarks, validQuoteChars, finnishTerms, confSpec} from './ending-punctuation-conf.js';
31
31
  import createDebugLogger from 'debug';
32
32
 
33
33
  const debug = createDebugLogger('@natlibfi/marc-record-validator-melinda/ending-punctuation');
@@ -65,40 +65,65 @@ export default function () {
65
65
 
66
66
  // Field validation with punctuation rules for normal and special cases in subfunction (to reduce complexity to please travisci)
67
67
  function validateField(field, linkedTag, fix, message) {
68
- // This is used to find last subfield that should have punctuation
69
- function findLastSubfield(field) {
70
- const subfields = field.subfields.filter(sf => isNaN(sf.code) && 'value' in sf);
71
- return subfields.slice(-1).shift();
68
+ function getDefaultPuncMarks(tag) {
69
+ if (tag.match(/^[1678](?:00|10|11|30)/u) || tag === '740') { // As defined in Loppupisteohje
70
+ return `${validPuncMarks})`;
71
+ }
72
+ // We don't want ').' here either. However, Loppupisteohje is a bit iffy here.
73
+ // BUG: Note that our generic rules will remove dot from Finnish terms such as https://finto.fi/yso-aika/fi/page/p1069910600
74
+ if (['647', '648', '650', '651', '654', '655', '656', '657', '658', '662'].includes(tag)) {
75
+ return `${validPuncMarks})`;
76
+ }
77
+ if(['260'].includes(tag)) {
78
+ return `${validPuncMarks})]`;
79
+ }
80
+ return validPuncMarks;
72
81
  }
73
82
 
74
83
  // Punctuation rule (Boolean), Check no ending dot strict (Boolean)
75
84
  function normalPuncRules(subfield, punc, tag, checkEnd, overrideValidPuncMarks) {
76
- const puncMarks = overrideValidPuncMarks || validPuncMarks;
77
- const lastPuncMark = puncMarks.includes(subfield.value.slice(-1)); // If string ends to punctuation char
78
- const lastPuncDot = '.'.includes(subfield.value.slice(-1)); // If string ends to dot
85
+ const puncMarks = overrideValidPuncMarks || getDefaultPuncMarks(tag);
86
+ const lastChar = subfield.value.slice(-1);
87
+ const lastPuncMark = puncMarks.includes(lastChar); // If string ends to punctuation char
88
+ const lastPuncDot = '.'.includes(lastChar); // If string ends to dot
89
+ const penultimateCharacter = subfield.value.length >= 2 ? subfield.value.charAt(subfield.value.length - 2) : undefined;
90
+ const antePenultimateCharacter = subfield.value.length >= 3 ? subfield.value.charAt(subfield.value.length - 3) : undefined;
91
+
79
92
 
80
- // Last char should be punc, but its not one of marks nor dot
93
+ // Last char should be punc, but it's not one of listed punctuation marks nor dot
81
94
  if (punc && !(lastPuncMark || lastPuncDot)) {
82
- // Console.log("1. Invalid punctuation - missing")
83
- message.message.push(`Field ${tag} has invalid ending punctuation`);
84
- if (fix) {
85
- subfield.value = subfield.value.concat('.');
86
- message.fix.push(`Field ${tag} - Added punctuation to $${subfield.code}`);
95
+ //console.log(puncMarks)
96
+ if (penultimateCharacter && validQuoteChars.includes(lastChar) && puncMarks.includes(penultimateCharacter)) {
97
+ // Exception: do nothing! Ending in punc+quote combo is all right, and does not imply a missing punc
98
+ }
99
+ else {
100
+ // Console.log("1. Invalid punctuation - missing")
101
+ message.message.push(`Field ${tag} requires ending punctuation, ends in '${lastChar}'`);
102
+ if (fix) {
103
+ subfield.value = subfield.value.concat('.');
104
+ message.fix.push(`Field ${tag} - Added punctuation to $${subfield.code}`);
105
+ }
87
106
  }
88
107
 
89
108
  // Last char is dot, but previous char is one of punc marks, like 'Question?.'
90
- } else if (lastPuncDot && subfield.value.length > 1 && puncMarks.includes(subfield.value.charAt(subfield.value.length - 2))) {
109
+ } else if (lastPuncDot && penultimateCharacter && puncMarks.includes(penultimateCharacter)) {
91
110
  // Console.log("2. Invalid punctuation - duplicate, like '?.'")
92
- message.message.push(`Field ${tag} has invalid ending punctuation`);
111
+ message.message.push(`Field ${tag} has an extra dot after '${penultimateCharacter}'`);
93
112
  if (fix) {
94
113
  subfield.value = subfield.value.slice(0, -1);
95
- message.fix.push(`Field ${tag} - Removed double punctuation from $${subfield.code}`);
114
+ message.fix.push(`Field ${tag} - Removed dot after punctuation from $${subfield.code}`);
115
+ }
116
+ // Last char is dot, but previous two cars are punc+quote, like 'Lorum "Ipsum.".'
117
+ } else if (lastPuncDot && antePenultimateCharacter && validQuoteChars.includes(penultimateCharacter) && puncMarks.includes(antePenultimateCharacter)) {
118
+ message.message.push(`Field ${tag} has an extra dot in '${antePenultimateCharacter}${penultimateCharacter}${lastChar}'`);
119
+ if (fix) {
120
+ subfield.value = subfield.value.slice(0, -1);
121
+ message.fix.push(`Field ${tag} - Removed '${lastChar}' after '${antePenultimateCharacter}${penultimateCharacter}'`);
96
122
  }
97
-
98
123
  // Last char shouldn't be dot !! This is behind checkEnd boolean, because of dots at end of abbreviations, so this is checked only in special cases !!//
99
124
  } else if (checkEnd && (!punc && lastPuncDot)) {
100
125
  // Console.log("3. Invalid punctuation - Shouldn't be dot, is")
101
- message.message.push(`Field ${tag} has invalid ending punctuation`);
126
+ message.message.push(`Field ${tag} has unwanted ending punctuation '${lastChar}'`);
102
127
  if (fix) {
103
128
  subfield.value = subfield.value.slice(0, -1);
104
129
  message.fix.push(`Field ${tag} - Removed punctuation from $${subfield.code}`);
@@ -136,7 +161,7 @@ function validateField(field, linkedTag, fix, message) {
136
161
  if (res.special.ifInd2 && res.special.ifInd2.includes(field.ind2)) {
137
162
  normalPuncRules(lastSubField, res.special.ifBoth, tag, true, res.special.ifLastCharNot);
138
163
 
139
- // Matches execption to special rule, noPuncIfInd2 (likely with value 4, that indicates copyright mark)
164
+ // Matches exception to special rule, noPuncIfInd2 (likely with value 4, that indicates copyright mark)
140
165
  } else if (res.special.noPuncIfInd2 && field.ind2 && res.special.noPuncIfInd2.includes(field.ind2)) {
141
166
  normalPuncRules(lastSubField, !res.special.ifBoth, tag, true, res.special.ifLastCharNot);
142
167
 
@@ -158,12 +183,17 @@ function validateField(field, linkedTag, fix, message) {
158
183
  normalPuncRules(lastSubField, res.punc, tag, false, false);
159
184
 
160
185
  // Search for Finnish terms
161
- } else if (res.special.termField) {
186
+ } else if (res.special.termSubfieldCode) {
162
187
  lastSubField = findLastSubfield(field);
163
188
 
164
189
  if (lastSubField) {
165
- const languageField = field.subfields.find(({code}) => code === res.special.termField);
166
- if (languageField && languageField.value && finnishTerms.some(p => p.test(languageField.value))) {
190
+ const lexicon = getLexicon(field, res.special.termSubfieldCode);
191
+ const proceed = !finnishException(field, res.special.termSubfieldCode, false);
192
+
193
+
194
+ //const languageField = field.subfields.find(({code}) => code === res.special.termSubfieldCode);
195
+ //if (languageField && languageField.value && finnishTerms.some(p => p.test(languageField.value))) {
196
+ if (lexicon && finnishTerms.some(p => p.test(lexicon)) && proceed) {
167
197
  // If (languageField && languageField.value && finnishTerms.indexOf(languageField.value) > -1) {
168
198
  normalPuncRules(lastSubField, res.punc, tag, true, false);
169
199
  } else {
@@ -199,6 +229,15 @@ function validateField(field, linkedTag, fix, message) {
199
229
 
200
230
  validateField(field, linkedTag, fix, message);
201
231
  }
232
+ // fallback
233
+ else {
234
+ debug(`special is definedm but no rule applies`);
235
+ const lastSubField = findLastSubfield(field);
236
+
237
+ if (lastSubField) {
238
+ normalPuncRules(lastSubField, res.punc, field.tag, false, false, fix, message);
239
+ }
240
+ }
202
241
  }
203
242
 
204
243
  let res = null;
@@ -232,8 +271,12 @@ function validateField(field, linkedTag, fix, message) {
232
271
  return;
233
272
  }
234
273
 
274
+ const forceNormal = res.special ? finnishException(field, res.special.termSubfieldCode, true) : false;
235
275
  // Normal rules
236
- if (typeof res.special === 'undefined' || res.special === null) {
276
+ if (typeof res.special === 'undefined' || res.special === null || forceNormal) {
277
+ if (forceNormal) {
278
+ console.info("EXCEPTION. SKIP FINNISH RULES");
279
+ }
237
280
  lastSubField = findLastSubfield(field);
238
281
 
239
282
  if (lastSubField) {
@@ -260,3 +303,51 @@ export function validateSingleField(field, linkedTag, fix) {
260
303
  return message;
261
304
  }
262
305
 
306
+ function getLexicon(field, subfieldCode) {
307
+ const languageSubfield = field.subfields.find(({code}) => code === subfieldCode); // res.special.termSubfieldCode);
308
+ if (!languageSubfield || !languageSubfield.value) {
309
+ return undefined;
310
+ }
311
+ if (finnishTerms.find(p => p.test(languageSubfield.value))) {
312
+ return languageSubfield.value;
313
+ }
314
+ return undefined;
315
+ }
316
+
317
+ function finnishException(field, termSubfieldCode, hasDot = true) {
318
+ const lexicon = getLexicon(field, termSubfieldCode);
319
+ if (!lexicon) {
320
+ return false;
321
+ }
322
+
323
+ const lastSubfield = findLastSubfield(field);
324
+ if (!lastSubfield || !lastSubfield.value) {
325
+ return false;
326
+ }
327
+ // Some terms can end in '.' that we want to keep
328
+ if (field.tag === '648') { // Yso-aika checks
329
+ //console.log(`Finnish Exception? '${lastSubfield.value}', '${lexicon}', '${field.tag}'`);
330
+ if (lexicon === 'yso/fin') { // 'eaa.' appears in prefLAbels and 'eKr.' in altLabels
331
+ if (hasDot) {
332
+ return lastSubfield.value.match(/ (?:eaa|[ej]Kr|jaa)\.$/u); // Finnish term from which the dot is not to be removed
333
+ }
334
+ return lastSubfield.value.match(/ (?:eaa|[ej]Kr)|jaa$/u); // Finnish word that needs a dot
335
+ }
336
+
337
+ if (lexicon === 'yso/swe') {
338
+ if (hasDot) {
339
+ return lastSubfield.value.match(/ (?:[ef]\.Kr|f\.v\.t)\.$/u);
340
+ }
341
+ return lastSubfield.value.match(/ (?:[ef]\.Kr|f\.v\.t)$/u);
342
+ }
343
+ }
344
+ // yso has 'MODEL.LA.' and 'Corel R.A.V.E.' but these are so rare I'm not listing them
345
+
346
+ return false;
347
+ }
348
+
349
+ // This is used to find last subfield that should have punctuation
350
+ function findLastSubfield(field) {
351
+ const subfields = field.subfields.filter(sf => isNaN(sf.code) && 'value' in sf);
352
+ return subfields.slice(-1).shift();
353
+ }