@natlibfi/marc-record-validators-melinda 12.1.0-alpha.1 → 13.0.0

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 (425) hide show
  1. package/.github/workflows/melinda-node-tests-and-publish.yml +17 -17
  2. package/README.md +1 -1
  3. package/dist/addMissingField041.js +6 -3
  4. package/dist/addMissingField041.js.map +2 -2
  5. package/dist/addMissingField336.js +7 -4
  6. package/dist/addMissingField336.js.map +2 -2
  7. package/dist/addMissingField337.js +6 -3
  8. package/dist/addMissingField337.js.map +2 -2
  9. package/dist/addMissingField338.js +8 -5
  10. package/dist/addMissingField338.js.map +2 -2
  11. package/dist/cyrillux-usemarcon-replacement.js +5 -2
  12. package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
  13. package/dist/cyrillux.js +24 -18
  14. package/dist/cyrillux.js.map +2 -2
  15. package/dist/dataProvenanceUtils.js +19 -0
  16. package/dist/dataProvenanceUtils.js.map +7 -0
  17. package/dist/disambiguateSeriesStatements.js +2 -1
  18. package/dist/disambiguateSeriesStatements.js.map +2 -2
  19. package/dist/disambiguateSeriesStatements.test.js +1 -7
  20. package/dist/disambiguateSeriesStatements.test.js.map +2 -2
  21. package/dist/drop-terms.js +123 -0
  22. package/dist/drop-terms.js.map +7 -0
  23. package/dist/drop-terms.test.js +56 -0
  24. package/dist/drop-terms.test.js.map +7 -0
  25. package/dist/field-008-18-34-character-groups.test.js +1 -7
  26. package/dist/field-008-18-34-character-groups.test.js.map +2 -2
  27. package/dist/field-505-separators.test.js +1 -7
  28. package/dist/field-505-separators.test.js.map +2 -2
  29. package/dist/field-521-fix.test.js +1 -7
  30. package/dist/field-521-fix.test.js.map +2 -2
  31. package/dist/fix-33X.js +7 -4
  32. package/dist/fix-33X.js.map +2 -2
  33. package/dist/fix-33X.test.js +1 -1
  34. package/dist/fix-33X.test.js.map +1 -1
  35. package/dist/fix-country-codes.js +5 -0
  36. package/dist/fix-country-codes.js.map +2 -2
  37. package/dist/fix-country-codes.test.js +1 -7
  38. package/dist/fix-country-codes.test.js.map +2 -2
  39. package/dist/fix-language-codes.js +5 -1
  40. package/dist/fix-language-codes.js.map +2 -2
  41. package/dist/fix-sami-041.js +109 -0
  42. package/dist/fix-sami-041.js.map +7 -0
  43. package/dist/fix-sami-041.test.js +40 -0
  44. package/dist/fix-sami-041.test.js.map +7 -0
  45. package/dist/fixRelatorTerms.js +2 -0
  46. package/dist/fixRelatorTerms.js.map +2 -2
  47. package/dist/fixRelatorTerms.test.js +1 -7
  48. package/dist/fixRelatorTerms.test.js.map +2 -2
  49. package/dist/index.js +18 -4
  50. package/dist/index.js.map +2 -2
  51. package/dist/indicator-fixes.js +15 -1
  52. package/dist/indicator-fixes.js.map +2 -2
  53. package/dist/indicator-fixes.test.js +1 -7
  54. package/dist/indicator-fixes.test.js.map +2 -2
  55. package/dist/item-language.js +41 -39
  56. package/dist/item-language.js.map +2 -2
  57. package/dist/item-language.test.js +3 -3
  58. package/dist/item-language.test.js.map +2 -2
  59. package/dist/melindaCustomMergeFields.js +31 -0
  60. package/dist/melindaCustomMergeFields.js.map +2 -2
  61. package/dist/merge-fields/controlSubfields.js.map +2 -2
  62. package/dist/merge-fields/counterpartField.js +149 -152
  63. package/dist/merge-fields/counterpartField.js.map +3 -3
  64. package/dist/merge-fields/dataProvenance.js +6 -20
  65. package/dist/merge-fields/dataProvenance.js.map +2 -2
  66. package/dist/merge-fields/index.js +1 -1
  67. package/dist/merge-fields/index.js.map +2 -2
  68. package/dist/merge-fields/mergableIndicator.js +1 -5
  69. package/dist/merge-fields/mergableIndicator.js.map +2 -2
  70. package/dist/merge-fields/mergableTag.js +2 -0
  71. package/dist/merge-fields/mergableTag.js.map +2 -2
  72. package/dist/merge-fields/mergeConfig.js +2 -0
  73. package/dist/merge-fields/mergeConfig.js.map +2 -2
  74. package/dist/merge-fields/mergeConstraints.js +38 -35
  75. package/dist/merge-fields/mergeConstraints.js.map +3 -3
  76. package/dist/merge-fields/mergeField.js +4 -3
  77. package/dist/merge-fields/mergeField.js.map +2 -2
  78. package/dist/merge-fields/mergeOrAddSubfield.js +8 -7
  79. package/dist/merge-fields/mergeOrAddSubfield.js.map +2 -2
  80. package/dist/merge-fields/mergeSubfield.js +5 -1
  81. package/dist/merge-fields/mergeSubfield.js.map +2 -2
  82. package/dist/merge-fields/worldKnowledge.js +52 -0
  83. package/dist/merge-fields/worldKnowledge.js.map +2 -2
  84. package/dist/merge-fields.test.js +4 -9
  85. package/dist/merge-fields.test.js.map +2 -2
  86. package/dist/mergeField500Lisapainokset.test.js +1 -7
  87. package/dist/mergeField500Lisapainokset.test.js.map +2 -2
  88. package/dist/mergeRelatorTermFields.js +9 -6
  89. package/dist/mergeRelatorTermFields.js.map +2 -2
  90. package/dist/mergeRelatorTermFields.test.js +1 -7
  91. package/dist/mergeRelatorTermFields.test.js.map +2 -2
  92. package/dist/multiple-subfield-0.test.js +1 -7
  93. package/dist/multiple-subfield-0.test.js.map +2 -2
  94. package/dist/normalize-dashes.js +9 -6
  95. package/dist/normalize-dashes.js.map +2 -2
  96. package/dist/normalize-dashes.test.js +1 -7
  97. package/dist/normalize-dashes.test.js.map +2 -2
  98. package/dist/normalize-identifiers.js.map +2 -2
  99. package/dist/normalize-identifiers.test.js +1 -7
  100. package/dist/normalize-identifiers.test.js.map +2 -2
  101. package/dist/normalize-qualifying-information.test.js +1 -7
  102. package/dist/normalize-qualifying-information.test.js.map +2 -2
  103. package/dist/normalize-utf8-diacritics.js.map +2 -2
  104. package/dist/normalize-utf8-diacritics.test.js +1 -7
  105. package/dist/normalize-utf8-diacritics.test.js.map +2 -2
  106. package/dist/normalizeFieldForComparison.js +24 -14
  107. package/dist/normalizeFieldForComparison.js.map +2 -2
  108. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  109. package/dist/prepublicationUtils.js +1 -1
  110. package/dist/prepublicationUtils.js.map +2 -2
  111. package/dist/punctuation.test.js +1 -7
  112. package/dist/punctuation.test.js.map +2 -2
  113. package/dist/punctuation2.js +15 -12
  114. package/dist/punctuation2.js.map +2 -2
  115. package/dist/punctuation2.test.js +1 -7
  116. package/dist/punctuation2.test.js.map +2 -2
  117. package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
  118. package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
  119. package/dist/reindexSubfield6OccurenceNumbers.test.js +1 -7
  120. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +2 -2
  121. package/dist/remove-041-zxx.js +56 -0
  122. package/dist/remove-041-zxx.js.map +7 -0
  123. package/dist/remove-041-zxx.test.js +40 -0
  124. package/dist/remove-041-zxx.test.js.map +7 -0
  125. package/dist/removeDuplicateDataFields.js +4 -26
  126. package/dist/removeDuplicateDataFields.js.map +2 -2
  127. package/dist/removeDuplicateDataFields.test.js +1 -7
  128. package/dist/removeDuplicateDataFields.test.js.map +2 -2
  129. package/dist/removeInferiorDataFields.js +82 -45
  130. package/dist/removeInferiorDataFields.js.map +3 -3
  131. package/dist/removeInferiorDataFields.test.js +5 -9
  132. package/dist/removeInferiorDataFields.test.js.map +2 -2
  133. package/dist/resolveOrphanedSubfield6s.js +4 -5
  134. package/dist/resolveOrphanedSubfield6s.js.map +2 -2
  135. package/dist/resolveOrphanedSubfield6s.test.js +1 -7
  136. package/dist/resolveOrphanedSubfield6s.test.js.map +2 -2
  137. package/dist/sanitize-vocabulary-source-codes.test.js +1 -7
  138. package/dist/sanitize-vocabulary-source-codes.test.js.map +2 -2
  139. package/dist/sortFields.js +16 -1
  140. package/dist/sortFields.js.map +2 -2
  141. package/dist/sortFields.test.js +1 -7
  142. package/dist/sortFields.test.js.map +2 -2
  143. package/dist/sortRelatorTerms.test.js +1 -7
  144. package/dist/sortRelatorTerms.test.js.map +2 -2
  145. package/dist/sortSubfields.js +27 -21
  146. package/dist/sortSubfields.js.map +2 -2
  147. package/dist/sortSubfields.test.js +1 -7
  148. package/dist/sortSubfields.test.js.map +2 -2
  149. package/dist/stripPunctuation.js +7 -3
  150. package/dist/stripPunctuation.js.map +2 -2
  151. package/dist/stripPunctuation.test.js +1 -7
  152. package/dist/stripPunctuation.test.js.map +2 -2
  153. package/dist/subfield6Utils.js +2 -12
  154. package/dist/subfield6Utils.js.map +2 -2
  155. package/dist/subfield8Utils.js +0 -5
  156. package/dist/subfield8Utils.js.map +2 -2
  157. package/dist/subfieldValueNormalizations.test.js +1 -7
  158. package/dist/subfieldValueNormalizations.test.js.map +2 -2
  159. package/dist/sync-007-and-300.test.js +1 -7
  160. package/dist/sync-007-and-300.test.js.map +2 -2
  161. package/dist/sync-language.js +103 -0
  162. package/dist/sync-language.js.map +7 -0
  163. package/dist/sync-language.test.js +40 -0
  164. package/dist/sync-language.test.js.map +7 -0
  165. package/dist/translate-terms.js +124 -87
  166. package/dist/translate-terms.js.map +3 -3
  167. package/dist/translate-terms.test.js +5 -8
  168. package/dist/translate-terms.test.js.map +2 -2
  169. package/dist/typeOfDate-008.js +3 -1
  170. package/dist/typeOfDate-008.js.map +2 -2
  171. package/dist/update-field-540.js.map +2 -2
  172. package/dist/update-field-540.test.js +1 -7
  173. package/dist/update-field-540.test.js.map +2 -2
  174. package/dist/urn.js +13 -12
  175. package/dist/urn.js.map +2 -2
  176. package/dist/urn.test.js +1 -7
  177. package/dist/urn.test.js.map +2 -2
  178. package/dist/utils.js +29 -3
  179. package/dist/utils.js.map +2 -2
  180. package/package.json +20 -27
  181. package/src/addMissingField041.js +8 -4
  182. package/src/addMissingField336.js +10 -5
  183. package/src/addMissingField337.js +9 -5
  184. package/src/addMissingField338.js +11 -6
  185. package/src/cyrillux-usemarcon-replacement.js +9 -5
  186. package/src/cyrillux.js +34 -23
  187. package/src/dataProvenanceUtils.js +21 -0
  188. package/src/disambiguateSeriesStatements.js +4 -1
  189. package/src/disambiguateSeriesStatements.test.js +3 -8
  190. package/src/drop-terms.js +164 -0
  191. package/src/drop-terms.test.js +81 -0
  192. package/src/field-008-18-34-character-groups.test.js +3 -8
  193. package/src/field-505-separators.test.js +3 -8
  194. package/src/field-521-fix.test.js +3 -8
  195. package/src/fix-33X.js +10 -6
  196. package/src/fix-33X.test.js +1 -1
  197. package/src/fix-country-codes.js +7 -3
  198. package/src/fix-country-codes.test.js +3 -8
  199. package/src/fix-language-codes.js +8 -4
  200. package/src/fix-sami-041.js +147 -0
  201. package/src/fix-sami-041.test.js +52 -0
  202. package/src/fixRelatorTerms.js +5 -0
  203. package/src/fixRelatorTerms.test.js +3 -8
  204. package/src/index.js +20 -7
  205. package/src/indicator-fixes.js +22 -7
  206. package/src/indicator-fixes.test.js +3 -8
  207. package/src/item-language.js +49 -42
  208. package/src/item-language.test.js +3 -3
  209. package/src/melindaCustomMergeFields.js +31 -0
  210. package/src/merge-fields/controlSubfields.js +0 -1
  211. package/src/merge-fields/counterpartField.js +191 -290
  212. package/src/merge-fields/dataProvenance.js +8 -25
  213. package/src/merge-fields/index.js +1 -1
  214. package/src/merge-fields/mergableIndicator.js +4 -5
  215. package/src/merge-fields/mergableTag.js +2 -0
  216. package/src/merge-fields/mergeConfig.js +2 -1
  217. package/src/merge-fields/mergeConstraints.js +41 -36
  218. package/src/merge-fields/mergeField.js +4 -7
  219. package/src/merge-fields/mergeOrAddSubfield.js +8 -7
  220. package/src/merge-fields/mergeSubfield.js +11 -2
  221. package/src/merge-fields/worldKnowledge.js +77 -3
  222. package/src/merge-fields.test.js +5 -10
  223. package/src/mergeField500Lisapainokset.test.js +3 -8
  224. package/src/mergeRelatorTermFields.js +12 -11
  225. package/src/mergeRelatorTermFields.test.js +3 -8
  226. package/src/multiple-subfield-0.test.js +3 -8
  227. package/src/normalize-dashes.js +13 -7
  228. package/src/normalize-dashes.test.js +3 -8
  229. package/src/normalize-identifiers.js +12 -19
  230. package/src/normalize-identifiers.test.js +3 -8
  231. package/src/normalize-qualifying-information.test.js +3 -8
  232. package/src/normalize-utf8-diacritics.js +6 -3
  233. package/src/normalize-utf8-diacritics.test.js +3 -8
  234. package/src/normalizeFieldForComparison.js +39 -22
  235. package/src/normalizeSubfieldValueForComparison.js +2 -2
  236. package/src/prepublicationUtils.js +1 -1
  237. package/src/punctuation.test.js +3 -8
  238. package/src/punctuation2.js +44 -40
  239. package/src/punctuation2.test.js +3 -8
  240. package/src/reindexSubfield6OccurenceNumbers.js +13 -11
  241. package/src/reindexSubfield6OccurenceNumbers.test.js +3 -8
  242. package/src/remove-041-zxx.js +85 -0
  243. package/src/remove-041-zxx.test.js +52 -0
  244. package/src/removeDuplicateDataFields.js +30 -28
  245. package/src/removeDuplicateDataFields.test.js +3 -8
  246. package/src/removeInferiorDataFields.js +126 -71
  247. package/src/removeInferiorDataFields.test.js +7 -10
  248. package/src/resolveOrphanedSubfield6s.js +7 -5
  249. package/src/resolveOrphanedSubfield6s.test.js +3 -8
  250. package/src/sanitize-vocabulary-source-codes.test.js +3 -8
  251. package/src/sortFields.js +20 -1
  252. package/src/sortFields.test.js +3 -8
  253. package/src/sortRelatorTerms.test.js +3 -8
  254. package/src/sortSubfields.js +31 -25
  255. package/src/sortSubfields.test.js +3 -8
  256. package/src/stripPunctuation.js +10 -5
  257. package/src/stripPunctuation.test.js +3 -8
  258. package/src/subfield6Utils.js +31 -33
  259. package/src/subfield8Utils.js +10 -7
  260. package/src/subfieldValueNormalizations.test.js +3 -8
  261. package/src/sync-007-and-300.test.js +3 -8
  262. package/src/sync-language.js +148 -0
  263. package/src/sync-language.test.js +52 -0
  264. package/src/translate-terms.js +168 -109
  265. package/src/translate-terms.test.js +12 -16
  266. package/src/typeOfDate-008.js +4 -1
  267. package/src/update-field-540.js +7 -5
  268. package/src/update-field-540.test.js +3 -8
  269. package/src/urn.js +17 -13
  270. package/src/urn.test.js +3 -8
  271. package/src/utils.js +39 -12
  272. package/test-fixtures/cyrillux/f02b/expectedResult.json +23 -0
  273. package/test-fixtures/cyrillux/f02b/metadata.json +11 -0
  274. package/test-fixtures/cyrillux/f02b/record.json +14 -0
  275. package/test-fixtures/cyrillux/f14/expectedResult.json +32 -0
  276. package/test-fixtures/cyrillux/f14/metadata.json +10 -0
  277. package/test-fixtures/cyrillux/f14/record.json +14 -0
  278. package/test-fixtures/drop-terms/01/expectedResult.json +31 -0
  279. package/test-fixtures/drop-terms/01/metadata.json +6 -0
  280. package/test-fixtures/drop-terms/01/record.json +35 -0
  281. package/test-fixtures/drop-terms/02/expectedResult.json +7 -0
  282. package/test-fixtures/drop-terms/02/metadata.json +6 -0
  283. package/test-fixtures/drop-terms/02/record.json +40 -0
  284. package/test-fixtures/drop-terms/03/expectedResult.json +6 -0
  285. package/test-fixtures/drop-terms/03/metadata.json +18 -0
  286. package/test-fixtures/drop-terms/03/record.json +39 -0
  287. package/test-fixtures/drop-terms/04/expectedResult.json +6 -0
  288. package/test-fixtures/drop-terms/04/metadata.json +19 -0
  289. package/test-fixtures/drop-terms/04/record.json +24 -0
  290. package/test-fixtures/fix-language-codes/02/metadata.json +1 -1
  291. package/test-fixtures/fix-relator-terms/f02/metadata.json +1 -1
  292. package/test-fixtures/fix-relator-terms/f04/expectedResult.json +18 -0
  293. package/test-fixtures/fix-relator-terms/f04/metadata.json +5 -0
  294. package/test-fixtures/fix-relator-terms/f04/record.json +20 -0
  295. package/test-fixtures/fix-sami-041/01/expectedResult.json +6 -0
  296. package/test-fixtures/fix-sami-041/01/metadata.json +4 -0
  297. package/test-fixtures/fix-sami-041/01/record.json +14 -0
  298. package/test-fixtures/fix-sami-041/02/expectedResult.json +10 -0
  299. package/test-fixtures/fix-sami-041/02/metadata.json +4 -0
  300. package/test-fixtures/fix-sami-041/02/record.json +8 -0
  301. package/test-fixtures/fix-sami-041/03/expectedResult.json +5 -0
  302. package/test-fixtures/fix-sami-041/03/metadata.json +5 -0
  303. package/test-fixtures/fix-sami-041/03/record.json +8 -0
  304. package/test-fixtures/fix-sami-041/04/expectedResult.json +7 -0
  305. package/test-fixtures/fix-sami-041/04/metadata.json +4 -0
  306. package/test-fixtures/fix-sami-041/04/record.json +10 -0
  307. package/test-fixtures/fix-sami-041/05/expectedResult.json +10 -0
  308. package/test-fixtures/fix-sami-041/05/metadata.json +6 -0
  309. package/test-fixtures/fix-sami-041/05/record.json +8 -0
  310. package/test-fixtures/fix-sami-041/06/expectedResult.json +10 -0
  311. package/test-fixtures/fix-sami-041/06/metadata.json +4 -0
  312. package/test-fixtures/fix-sami-041/06/record.json +9 -0
  313. package/test-fixtures/indicator-fixes/11/expectedResult.json +10 -0
  314. package/test-fixtures/indicator-fixes/11/metadata.json +4 -0
  315. package/test-fixtures/indicator-fixes/11/record.json +10 -0
  316. package/test-fixtures/merge-fields/f042_01/expectedResult.json +12 -0
  317. package/test-fixtures/merge-fields/f042_01/metadata.json +6 -0
  318. package/test-fixtures/merge-fields/f042_01/record.json +13 -0
  319. package/test-fixtures/merge-fields/f05/metadata.json +1 -1
  320. package/test-fixtures/merge-fields/f06/expectedResult.json +42 -0
  321. package/test-fixtures/merge-fields/f06/metadata.json +6 -0
  322. package/test-fixtures/merge-fields/f06/record.json +41 -0
  323. package/test-fixtures/merge-fields/f07/expectedResult.json +18 -0
  324. package/test-fixtures/merge-fields/f07/metadata.json +6 -0
  325. package/test-fixtures/merge-fields/f07/record.json +18 -0
  326. package/test-fixtures/merge-fields/f08/expectedResult.json +12 -0
  327. package/test-fixtures/merge-fields/f08/metadata.json +7 -0
  328. package/test-fixtures/merge-fields/f08/record.json +10 -0
  329. package/test-fixtures/merge-fields/f09/expectedResult.json +14 -0
  330. package/test-fixtures/merge-fields/f09/metadata.json +6 -0
  331. package/test-fixtures/merge-fields/f09/record.json +14 -0
  332. package/test-fixtures/merge-fields/f10/expectedResult.json +25 -0
  333. package/test-fixtures/merge-fields/f10/metadata.json +6 -0
  334. package/test-fixtures/merge-fields/f10/record.json +25 -0
  335. package/test-fixtures/merge-fields/f11/expectedResult.json +40 -0
  336. package/test-fixtures/merge-fields/f11/metadata.json +7 -0
  337. package/test-fixtures/merge-fields/f11/record.json +50 -0
  338. package/test-fixtures/merge-fields/f12/expectedResult.json +17 -0
  339. package/test-fixtures/merge-fields/f12/metadata.json +6 -0
  340. package/test-fixtures/merge-fields/f12/record.json +25 -0
  341. package/test-fixtures/merge-fields/f13/expectedResult.json +18 -0
  342. package/test-fixtures/merge-fields/f13/metadata.json +6 -0
  343. package/test-fixtures/merge-fields/f13/record.json +28 -0
  344. package/test-fixtures/merge-fields/f14/expectedResult.json +25 -0
  345. package/test-fixtures/merge-fields/f14/metadata.json +6 -0
  346. package/test-fixtures/merge-fields/f14/record.json +25 -0
  347. package/test-fixtures/merge-fields/f15/expectedResult.json +8 -0
  348. package/test-fixtures/merge-fields/f15/metadata.json +6 -0
  349. package/test-fixtures/merge-fields/f15/record.json +9 -0
  350. package/test-fixtures/merge-fields/f16/expectedResult.json +12 -0
  351. package/test-fixtures/merge-fields/f16/metadata.json +7 -0
  352. package/test-fixtures/merge-fields/f16/record.json +13 -0
  353. package/test-fixtures/merge-fields/f300_01/expectedResult.json +9 -0
  354. package/test-fixtures/merge-fields/f300_01/metadata.json +6 -0
  355. package/test-fixtures/merge-fields/f300_01/record.json +8 -0
  356. package/test-fixtures/merge-fields/f300_02/expectedResult.json +13 -0
  357. package/test-fixtures/merge-fields/f300_02/metadata.json +6 -0
  358. package/test-fixtures/merge-fields/f300_02/record.json +16 -0
  359. package/test-fixtures/merge-fields/f300_03/expectedResult.json +13 -0
  360. package/test-fixtures/merge-fields/f300_03/metadata.json +6 -0
  361. package/test-fixtures/merge-fields/f300_03/record.json +16 -0
  362. package/test-fixtures/merge-fields/f490_01/expectedResult.json +13 -0
  363. package/test-fixtures/merge-fields/f490_01/metadata.json +6 -0
  364. package/test-fixtures/merge-fields/f490_01/record.json +16 -0
  365. package/test-fixtures/remove-041-zxx/01/expectedResult.json +5 -0
  366. package/test-fixtures/remove-041-zxx/01/metadata.json +5 -0
  367. package/test-fixtures/remove-041-zxx/01/record.json +10 -0
  368. package/test-fixtures/remove-041-zxx/02/expectedResult.json +7 -0
  369. package/test-fixtures/remove-041-zxx/02/metadata.json +5 -0
  370. package/test-fixtures/remove-041-zxx/02/record.json +9 -0
  371. package/test-fixtures/remove-041-zxx/11/expectedResult.json +10 -0
  372. package/test-fixtures/remove-041-zxx/11/metadata.json +5 -0
  373. package/test-fixtures/remove-041-zxx/11/record.json +9 -0
  374. package/test-fixtures/remove-041-zxx/12/expectedResult.json +10 -0
  375. package/test-fixtures/remove-041-zxx/12/metadata.json +5 -0
  376. package/test-fixtures/remove-041-zxx/12/record.json +9 -0
  377. package/test-fixtures/remove-inferior-datafields/f17/expectedResult.json +11 -0
  378. package/test-fixtures/remove-inferior-datafields/f17/metadata.json +5 -0
  379. package/test-fixtures/remove-inferior-datafields/f17/record.json +15 -0
  380. package/test-fixtures/remove-inferior-datafields/f18/expectedResult.json +13 -0
  381. package/test-fixtures/remove-inferior-datafields/f18/metadata.json +5 -0
  382. package/test-fixtures/remove-inferior-datafields/f18/record.json +18 -0
  383. package/test-fixtures/remove-inferior-datafields/f19/expectedResult.json +17 -0
  384. package/test-fixtures/remove-inferior-datafields/f19/metadata.json +5 -0
  385. package/test-fixtures/remove-inferior-datafields/f19/record.json +18 -0
  386. package/test-fixtures/remove-inferior-datafields/f20/expectedResult.json +15 -0
  387. package/test-fixtures/remove-inferior-datafields/f20/metadata.json +5 -0
  388. package/test-fixtures/remove-inferior-datafields/f20/record.json +29 -0
  389. package/test-fixtures/sort-fields/15/input.json +9 -0
  390. package/test-fixtures/sort-fields/15/metadata.json +5 -0
  391. package/test-fixtures/sort-fields/15/result.json +10 -0
  392. package/test-fixtures/sync-language/01/expectedResult.json +5 -0
  393. package/test-fixtures/sync-language/01/metadata.json +5 -0
  394. package/test-fixtures/sync-language/01/record.json +7 -0
  395. package/test-fixtures/sync-language/02/expectedResult.json +6 -0
  396. package/test-fixtures/sync-language/02/metadata.json +5 -0
  397. package/test-fixtures/sync-language/02/record.json +10 -0
  398. package/test-fixtures/sync-language/03/expectedResult.json +6 -0
  399. package/test-fixtures/sync-language/03/metadata.json +5 -0
  400. package/test-fixtures/sync-language/03/record.json +6 -0
  401. package/test-fixtures/sync-language/10/expectedResult.json +10 -0
  402. package/test-fixtures/sync-language/10/metadata.json +5 -0
  403. package/test-fixtures/sync-language/10/record.json +8 -0
  404. package/test-fixtures/sync-language/11/expectedResult.json +10 -0
  405. package/test-fixtures/sync-language/11/metadata.json +5 -0
  406. package/test-fixtures/sync-language/11/record.json +7 -0
  407. package/test-fixtures/sync-language/12/expectedResult.json +9 -0
  408. package/test-fixtures/sync-language/12/metadata.json +6 -0
  409. package/test-fixtures/sync-language/12/record.json +6 -0
  410. package/test-fixtures/sync-language/13/expectedResult.json +10 -0
  411. package/test-fixtures/sync-language/13/metadata.json +5 -0
  412. package/test-fixtures/sync-language/13/record.json +8 -0
  413. package/test-fixtures/sync-language/14/expectedResult.json +9 -0
  414. package/test-fixtures/sync-language/14/metadata.json +5 -0
  415. package/test-fixtures/sync-language/14/record.json +7 -0
  416. package/test-fixtures/sync-language/15/expectedResult.json +9 -0
  417. package/test-fixtures/sync-language/15/metadata.json +5 -0
  418. package/test-fixtures/sync-language/15/record.json +7 -0
  419. package/test-fixtures/translate-terms/05/expectedResult.json +12 -0
  420. package/test-fixtures/translate-terms/05/metadata.json +7 -0
  421. package/test-fixtures/translate-terms/05/record.json +11 -0
  422. package/test-fixtures/translate-terms/06/expectedResult.json +12 -0
  423. package/test-fixtures/translate-terms/06/metadata.json +7 -0
  424. package/test-fixtures/translate-terms/06/record.json +11 -0
  425. package/test-fixtures/translate-terms-data.js +23 -0
@@ -1,3 +1,5 @@
1
+ /* eslint-disable max-lines */
2
+
1
3
  /*
2
4
  * cyrillux-usemarcon-replacement.js -- implement and improve https://github.com/NatLibFi/USEMARCON-Cyrillux/tree/master
3
5
  *
@@ -6,6 +8,7 @@
6
8
  */
7
9
 
8
10
  import clone from 'clone';
11
+ import createDebugLogger from 'debug';
9
12
  import {MarcRecord} from '@natlibfi/marc-record';
10
13
  import {default as fix33X} from './fix-33X.js';
11
14
  import {default as add041} from './addMissingField041.js';
@@ -19,11 +22,11 @@ import {default as fixIndicators} from './indicator-fixes.js';
19
22
  import {default as fixPunctuation} from './punctuation2.js';
20
23
  import {default as fixQualifyingInformation} from './normalize-qualifying-information.js';
21
24
  import {sortAdjacentSubfields} from './sortSubfields.js';
22
-
23
- // import createDebugLogger from 'debug';
24
25
  import {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString, removeSubfield} from './utils.js';
25
26
 
26
- // const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');
27
+ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux-usermarcon-replacement');
28
+ //const debugData = debug.extend('data');
29
+ const debugDev = debug.extend('dev');
27
30
 
28
31
  const description = 'Replacement for Cyrillux usemarcon rules';
29
32
 
@@ -32,13 +35,14 @@ const description = 'Replacement for Cyrillux usemarcon rules';
32
35
  const dropTags = ['001', '003', '010', '012', '014', '015', '016', '017', '019', '025', '029', '032', '035', '036', '037', '038', '042', '044', '049', '051', '061', '068', '071', '074', '079', '090', '091', '092', '094', '095', '096', '097', '099', '249', '261', '262', '350', '400', '411', '541', '561', '562', '574', '575', '577', '578', '583', '584', '589', '590', '591', '592', '593', '594', '595', '596', '597', '598', '599', '653', '698', '741', '742', '744', '751', '761', '790', '841', '842', '843', '844', '845', '850', '852', '853', '854', '855', '858', '859', '863', '864', '865', '866', '867', '868', '876', '877', '878', '882', '886', '887', '888', '890', '899'];
33
36
 
34
37
 
38
+ // eslint-disable-next-line max-lines-per-function
35
39
  export default function () {
36
40
  return {
37
41
  description, fix, validate
38
42
  };
39
43
 
40
44
  function fix(record) {
41
- nvdebug(`${description}: fix`);
45
+ nvdebug(`${description}: fix`, debugDev);
42
46
  realFix(record);
43
47
  const res = {message: [], fix: [], valid: true};
44
48
  return res;
@@ -156,7 +160,7 @@ export default function () {
156
160
 
157
161
  // Validation is currently done in subparts
158
162
  function validate(record) {
159
- nvdebug(`${description}: validate`);
163
+ nvdebug(`${description}: validate`, debugDev);
160
164
  const originalString = recordToString(record);
161
165
  const clonedRecord = new MarcRecord(record, {subfieldValues: false});
162
166
  realFix(clonedRecord);
package/src/cyrillux.js CHANGED
@@ -3,17 +3,23 @@ import clone from 'clone';
3
3
  import XRegExp from 'xregexp';
4
4
  import * as iso9 from '@natlibfi/iso9-1995';
5
5
  import * as sfs4900 from '@natlibfi/sfs-4900';
6
- import {fieldHasSubfield, fieldToString, fieldsToString, isControlSubfieldCode, nvdebug} from './utils.js';
6
+ import {fieldHasSubfield, fieldToString, fieldsToString, isContentSubfieldCode, nvdebug} from './utils.js';
7
7
  import {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils.js';
8
8
  import {default as sortFields} from './sortFields.js';
9
9
  import {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers.js';
10
10
  import {fieldStripPunctuation} from './punctuation2.js';
11
11
  import {getLanguageCode} from './addMissingField041.js';
12
+ import createDebugLogger from 'debug';
13
+
14
+ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux');
15
+ //const debugData = debug.extend('data');
16
+ const debugDev = debug.extend('dev');
12
17
 
13
18
  const iso9Trans = 'ISO9 <TRANS>';
14
19
  const cyrillicTrans = 'CYRILLIC <TRANS>';
15
20
  const sfs4900Trans = 'SFS4900 <TRANS>';
16
21
 
22
+ // eslint-disable-next-line max-lines-per-function
17
23
  export default function (config = {}) {
18
24
  // console.log(`CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console
19
25
 
@@ -111,17 +117,22 @@ export default function (config = {}) {
111
117
  }
112
118
 
113
119
  function fieldContainsCyrillicCharacters(field) { // based on melinda-ui-cyrillux
114
- return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf));
120
+ return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf, field.tag));
115
121
  }
116
122
 
117
- function subfieldRequiresTransliteration(subfield) {
118
- if (isControlSubfieldCode(subfield.code)) {
123
+ function subfieldRequiresTransliteration(subfield, tag = undefined) {
124
+ if (!isContentSubfieldCode(subfield.code, tag)) {
119
125
  return false;
120
126
  }
121
127
  return containsCyrillicCharacters(subfield.value);
122
128
  }
123
129
 
124
130
  function tagCanBeTransliterated(tag) {
131
+ // Use this to filter out "(0..)" etc
132
+ if (config.tagPattern && !tag.match(config.tagPattern)) {
133
+ return false;
134
+ }
135
+ // These are hard-coded, and will fail anyway:
125
136
  return !['336', '337', '338', '880'].includes(tag);
126
137
  }
127
138
 
@@ -130,7 +141,7 @@ export default function (config = {}) {
130
141
  // Discussion: We should probably also skip others like 05X-08X, 648, 650, 651, and 655, but this needs thinking...
131
142
  // Also I'd like to convert do CYRILLIC->ISO-9 in field 300 (and others?) without 880 mappings... (<- not implemented)
132
143
 
133
- // nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in...`);
144
+ // nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in...`, debugDev);
134
145
  if (!tagCanBeTransliterated(field.tag)) {
135
146
  return false;
136
147
  }
@@ -153,8 +164,8 @@ export default function (config = {}) {
153
164
  }
154
165
 
155
166
 
156
- function mapSubfieldToIso9(subfield) {
157
- if (!subfieldRequiresTransliteration(subfield)) {
167
+ function mapSubfieldToIso9(subfield, tag) {
168
+ if (!subfieldRequiresTransliteration(subfield, tag)) {
158
169
  return {code: subfield.code, value: subfield.value}; // just clone
159
170
  }
160
171
 
@@ -163,17 +174,17 @@ export default function (config = {}) {
163
174
  return {code: subfield.code, value: conversionResult.result};
164
175
  }
165
176
 
166
- function mapSubfieldToSfs4900(subfield, lang = 'rus') {
177
+ function mapSubfieldToSfs4900(subfield, tag, lang = 'rus') {
167
178
  const inputLang = lang === 'ukr' ? 'ukr' : 'rus'; // Support 'ukr' and 'rus', default to 'rus'
168
- if (!subfieldRequiresTransliteration(subfield)) {
179
+ if (!subfieldRequiresTransliteration(subfield, tag)) {
169
180
  return {code: subfield.code, value: subfield.value};
170
181
  }
171
182
  const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);
172
183
 
173
- console.log(JSON.stringify(conversionResult));
184
+ nvdebug(`${JSON.stringify(conversionResult)}`, debugDev);
174
185
  const result = conversionResult.result;
175
- console.log(JSON.stringify(result));
176
- //console.log(`VAL: ${subfield.value} => ${value} using ${lang}`); // eslint-disable-line no-console
186
+ nvdebug(`${JSON.stringify(result)}`, debugDev);
187
+ //nvdebug(`VAL: ${subfield.value} => ${value} using ${lang}`, debugDev);
177
188
  return {code: subfield.code, value: result};
178
189
  }
179
190
 
@@ -185,7 +196,7 @@ export default function (config = {}) {
185
196
  const transliterationFunc = iso9 ? mapSubfieldToIso9 : mapSubfieldToSfs4900;
186
197
 
187
198
  // NB! iso9 won't use lang
188
- const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, lang));
199
+ const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, field.tag, lang));
189
200
 
190
201
  const newField = {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, ...subfield9]};
191
202
 
@@ -211,7 +222,7 @@ export default function (config = {}) {
211
222
  }
212
223
  // Just converts the field to ISO-9 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either
213
224
  if (!config.retainCyrillic && !config.preferSFS4900) {
214
- const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf));
225
+ const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf, field.tag));
215
226
  return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};
216
227
  }
217
228
 
@@ -225,7 +236,7 @@ export default function (config = {}) {
225
236
  }
226
237
  // Just converts the field to SFS-4900 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either
227
238
  if (!config.retainCyrillic && config.preferSFS4900) {
228
- const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, lang));
239
+ const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, field.tag, lang));
229
240
  return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};
230
241
  }
231
242
 
@@ -251,7 +262,7 @@ export default function (config = {}) {
251
262
  if (!config.retainCyrillic) {
252
263
  return undefined;
253
264
  }
254
- nvdebug(`Derive CYR 880 from ${fieldToString(field)}`);
265
+ nvdebug(`Derive CYR 880 from ${fieldToString(field)}`, debugDev);
255
266
  const newSubfield6 = deriveSubfield6(field.tag, field.subfields, occurrenceNumber);
256
267
  const newSubfield9 = fieldHasSubfield(field, '9', cyrillicTrans) ? [] : [{code: '9', value: cyrillicTrans}];
257
268
  const subfields = [
@@ -261,7 +272,7 @@ export default function (config = {}) {
261
272
  ];
262
273
 
263
274
  const newField = {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};
264
- nvdebug(` New CYR 880 ${fieldToString(newField)}`);
275
+ nvdebug(` New CYR 880 ${fieldToString(newField)}`, debugDev);
265
276
  return newField;
266
277
  }
267
278
 
@@ -312,8 +323,8 @@ export default function (config = {}) {
312
323
 
313
324
  // Paired field: $9 CYRILLIC <TRANS> is the only legal <TRANS>
314
325
  const [pairedField] = existingPairedFields;
315
- nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`);
316
- nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`);
326
+ nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`, debugDev);
327
+ nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`, debugDev);
317
328
  if (!fieldContainsCyrillicCharacters(pairedField)) {
318
329
  return false;
319
330
  }
@@ -327,7 +338,7 @@ export default function (config = {}) {
327
338
  const languageCode = getLanguageCode(record);
328
339
  const field2 = fieldToString(createFieldForSfs4900Comparison(mapFieldToSfs4900(pairedField, occurrenceNumberAsString, languageCode), field.tag));
329
340
  const field1 = fieldToString(createFieldForSfs4900Comparison(field, field.tag));
330
- nvdebug(`COMPARE CONTENTS:\n '${field1}' vs\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}`);
341
+ nvdebug(`COMPARE CONTENTS:\n '${field1}' vs\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}`, debugDev);
331
342
  return field1 === field2;
332
343
  }
333
344
 
@@ -372,17 +383,17 @@ export default function (config = {}) {
372
383
  return [originalField];
373
384
  }
374
385
 
375
- // nvdebug(`PROCESSING: ${fieldToString(originalField)}`);
386
+ // nvdebug(`PROCESSING: ${fieldToString(originalField)}`, debugDev);
376
387
 
377
388
  const newOccurrenceNumberAsInt = getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber);
378
389
  const newOccurrenceNumberAsString = intToOccurrenceNumberString(newOccurrenceNumberAsInt);
379
390
  const languageCode = getLanguageCode(record);
380
391
 
381
- // nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'`);
392
+ // nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'`, debugDev);
382
393
 
383
394
  const existingPairedFields = fieldGetOccurrenceNumberPairs(originalField, record.get('880'));
384
395
 
385
- // nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}`);
396
+ // nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}`, debugDev);
386
397
 
387
398
  const newMainField = mapFieldToIso9(originalField, newOccurrenceNumberAsString); // ISO-9
388
399
  const newCyrillicField = retainCyrillic(existingPairedFields) ? mapFieldToCyrillicField880(originalField, newOccurrenceNumberAsString) : undefined; // CYRILLIC
@@ -0,0 +1,21 @@
1
+ export function tagToDataProvenanceSubfieldCode(tag) {
2
+ if ( ['533', '800', '810', '811', '830'].includes(tag)) {
3
+ return 'y';
4
+ }
5
+ if ( tag === '856' || tag === '857' ) {
6
+ return 'e';
7
+ }
8
+
9
+ if ( tag.match(/^7[678]/u) ) {
10
+ return 'l'
11
+ }
12
+
13
+ if ( tag.match(/^00/u)) {
14
+ return undefined;
15
+ }
16
+ return '7';
17
+ }
18
+
19
+ export function isDataProvenanceSubfieldCode(subfieldCode, tag) {
20
+ return subfieldCode === tagToDataProvenanceSubfieldCode(tag);
21
+ }
@@ -9,6 +9,8 @@ import {fieldFixPunctuation} from './punctuation2.js';
9
9
  //const {default: createNatlibfiSruClient} = natlibfiSruClient;
10
10
 
11
11
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:disambiguateSeriesStatements');
12
+ //const debugData = debug.extend('data');
13
+ const debugDev = debug.extend('dev');
12
14
 
13
15
  const ELECTRONIC = 1;
14
16
  const PRINTED = 2;
@@ -16,6 +18,7 @@ const NEITHER_OR_UNKNOWN = 0;
16
18
  const SRU_API_URL = 'https://sru.api.melinda.kansalliskirjasto.fi/bib';
17
19
 
18
20
  // Author(s): Nicholas Volk
21
+ // eslint-disable-next-line max-lines-per-function
19
22
  export default function () {
20
23
  const sruClient = createSruClient(SRU_API_URL);
21
24
 
@@ -79,7 +82,7 @@ export default function () {
79
82
  }
80
83
 
81
84
  const deletableStrings = deletableXs.map(sf => subfieldToString(sf));
82
- nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`, debug);
85
+ nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`, debugDev);
83
86
 
84
87
  // fixer:
85
88
  if (reallyFix) {
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './disambiguateSeriesStatements.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
- import createDebugLogger from 'debug';
6
+ //import createDebugLogger from 'debug';
7
7
 
8
8
  generateTests({
9
9
  callback,
@@ -19,7 +19,7 @@ generateTests({
19
19
  }
20
20
  }
21
21
  });
22
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');
23
23
 
24
24
  async function testValidatorFactory() {
25
25
  const validator = await validatorFactory();
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
29
29
  assert.equal(typeof validator.validate, 'function');
30
30
  }
31
31
 
32
- async function callback({getFixture, enabled = true, fix = false}) {
33
- if (enabled === false) {
34
- debug('TEST SKIPPED!');
35
- return;
36
- }
37
-
32
+ async function callback({getFixture, fix = false}) {
38
33
  const validator = await validatorFactory();
39
34
  const record = new MarcRecord(getFixture('record.json'));
40
35
  const expectedResult = getFixture('expectedResult.json');
@@ -0,0 +1,164 @@
1
+ // Author(s): Nicholas Volk
2
+
3
+ import clone from 'clone';
4
+ import createDebugLogger from 'debug';
5
+ import {fieldToString, nvdebug} from './utils.js';
6
+ import {getLexiconAndLanguage, getTermData, isLabel, isValidSubfield0} from './translate-terms.js';
7
+
8
+ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:drop-terms');
9
+ //const debugData = debug.extend('data');
10
+ const debugDev = debug.extend('dev');
11
+
12
+ const defaultConfig = {
13
+ 'constraints': [
14
+ {'tag': '648', 'lex': 'yso/fin'},
15
+ {'tag': '648', 'lex': 'yso/swe'},
16
+ {'tag': '650', 'lex': 'yso/fin'},
17
+ {'tag': '650', 'lex': 'yso/swe'},
18
+ {'tag': '651', 'lex': 'yso/fin'},
19
+ {'tag': '651', 'lex': 'yso/swe'},
20
+ {'tag': '655', 'lex': 'slm/fin'},
21
+ {'tag': '655', 'lex': 'slm/swe'}
22
+ ],
23
+ 'keep invalid url': false, // If not true, removes illegal subfield $0. The whole field removal is later decided by 'keep 0-less'
24
+ 'keep invalid label': false, // label ($a) is neither pref Label nor altLabel => remove whole field
25
+ 'remove altLabel': false,
26
+ 'remove 0-less': true
27
+ };
28
+
29
+ // eslint-disable-next-line max-lines-per-function
30
+ export default function (config = defaultConfig) {
31
+
32
+ return {
33
+ description: 'Drop yso and slm terms that do not match their identifiers. Use for incoming records only! Not for records already in Melinda!',
34
+ validate, fix
35
+ };
36
+
37
+ async function fix(record, validateMode = false) {
38
+ const clonedFields = record.fields.map(f => clone(f));
39
+
40
+ const results = await processFields(clonedFields);
41
+
42
+ const removables = results.map((f, i) => !f ? record.fields[i] : undefined).filter(f => f);
43
+ const modMessages = results.map((f, i) => getMod(f, i)).filter(f => f);
44
+ const removalMessages = removables.map(f => `Remove '${fieldToString(f)}'`);
45
+ const allMessages = [...modMessages, ...removalMessages];
46
+
47
+ if (validateMode) {
48
+ if (allMessages.length === 0) {
49
+ return {'message': [], 'valid': true};
50
+ }
51
+ return {'message': allMessages, 'valid': false};
52
+ }
53
+
54
+ removables.forEach(f => record.removeField(f));
55
+
56
+ return {message: [], fix: allMessages, valid: true};
57
+
58
+ function getMod(field, index) {
59
+ if (!field) {
60
+ return undefined;
61
+ }
62
+ const before = fieldToString(record.fields[index]);
63
+ const after = fieldToString(results[index]);
64
+ if (before !== after) {
65
+ if (!validateMode) {
66
+ record.fields[index] = field;
67
+ }
68
+ return `Modify '${before}' => '${after}'`;
69
+ }
70
+ return undefined;
71
+ }
72
+ }
73
+
74
+ function isPotentialField(f) {
75
+ if (!config || !config.constraints) {
76
+ return false;
77
+ }
78
+ return config.constraints.some(c => c.tag === f.tag && f.subfields?.some(sf => sf.code === '2' && sf.value === c.lex));
79
+ }
80
+
81
+ async function validate(record) {
82
+ return fix(record, true);
83
+ }
84
+
85
+
86
+ async function processFields(fields, results = []) {
87
+ const [currField, ...remainingFields] = fields;
88
+ if (!currField) {
89
+ return results;
90
+ }
91
+
92
+ if (!isPotentialField(currField)) { // Not interested in this field
93
+ return processFields(remainingFields, [...results, currField]);
94
+ }
95
+
96
+ removeSyntacticallyIllegalSubfield0s(currField); // iff config wants them to be removed...
97
+
98
+ const removable = await isRemovableField(currField);
99
+
100
+ return processFields(remainingFields, [...results, removable ? undefined : currField]);
101
+ }
102
+
103
+ function removeSyntacticallyIllegalSubfield0s(field) {
104
+ if (config['keep invalid url']) {
105
+ return;
106
+ }
107
+
108
+ const lexData = getLexiconAndLanguage(field);
109
+ if (!lexData.lang) { // This is an error of sorts. Should we proceed and remove $0s?
110
+ return;
111
+ }
112
+
113
+ field.subfields = field.subfields.filter(sf => sf.code !== '0' || isValidSubfield0(sf, lexData.lex));
114
+ }
115
+
116
+ async function isRemovableField(field) {
117
+ // nvdebug(`FOO===== ${fieldToString(field)}`, debugDev);
118
+
119
+
120
+ // $0-less field:
121
+ if (!field.subfields.some(sf => sf.code === '0')) {
122
+ return config['remove 0-less'];
123
+ }
124
+
125
+ const subfield0 = field.subfields.find(sf => sf.code === '0');
126
+ const data = await getTermData(subfield0.value);
127
+ // NB! No data might be a BUG! This might delete all incoming terms if Finto is down... (we should distinguish between a miss and a failure)
128
+ // However, if we use this validator only for incoming records, it's fine enough.
129
+
130
+ if (data) {
131
+ const subfieldA = field.subfields.find(sf => sf.code === 'a');
132
+ if (subfieldA) {
133
+ const lexData = getLexiconAndLanguage(field);
134
+
135
+ // $a is the pref label. All is fine!
136
+ if (isLabel(data.prefLabel, subfieldA.value, lexData.lang)) {
137
+ nvdebug(`altLabel found: ${subfieldA.value}`, debugDev);
138
+ return false;
139
+ }
140
+ if (isLabel(data.altLabel, subfieldA.value, lexData.lang)) {
141
+ nvdebug(`altLabel found: ${subfieldA.value}`, debugDev);
142
+ // Oddly enough this could remove altLabel but keep totally invalid labels...
143
+ return config['remove altLabel'];
144
+ }
145
+ nvdebug(`a-2-0 mismatch: ${fieldToString(field)}`, debugDev);
146
+ }
147
+ }
148
+
149
+
150
+ if (config['keep invalid label']) {
151
+ // We keep the label $a. However, we can get rid of $0 if we want to (semantic reasons)
152
+ if (!config['keep invalid url']) {
153
+ nvdebug(`=============== 0-removal`, debugDev);
154
+ field.subfields = field.subfields.filter(sf => sf.code !== '0');
155
+ }
156
+ return false;
157
+ }
158
+ return true;
159
+
160
+ }
161
+
162
+
163
+ }
164
+
@@ -0,0 +1,81 @@
1
+ import assert from 'node:assert/strict';
2
+ //import createDebugLogger from 'debug';
3
+ import fetchMock from 'fetch-mock';
4
+
5
+ import validatorFactory from './drop-terms.js';
6
+
7
+ import {MarcRecord} from '@natlibfi/marc-record';
8
+ import {READERS} from '@natlibfi/fixura';
9
+ import generateTests from '@natlibfi/fixugen';
10
+
11
+
12
+ import {fakeData} from '../test-fixtures/translate-terms-data.js';
13
+
14
+
15
+ const uris = [
16
+ 'http://www.yso.fi/onto/yso/p444',
17
+ 'http://www.yso.fi/onto/yso/p500',
18
+ 'http://www.yso.fi/onto/yso/p13299',
19
+ 'http://www.yso.fi/onto/yso/p111739',
20
+ 'http://www.yso.fi/onto/yso/p6197061979',
21
+ 'http://www.yso.fi/onto/yso/p6196061969',
22
+ 'http://urn.fi/URN:NBN:fi:au:slm:s161'
23
+ ];
24
+
25
+ const useMock = 1;
26
+
27
+
28
+ generateTests({
29
+ callback,
30
+ path: [import.meta.dirname, '..', 'test-fixtures', 'drop-terms'],
31
+ useMetadataFile: true,
32
+ recurse: false,
33
+ fixura: {
34
+ reader: READERS.JSON
35
+ },
36
+ hooks: {
37
+ before: async () => {
38
+
39
+ if (useMock) {
40
+ fetchMock.mockGlobal()
41
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[0]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
42
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[1]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
43
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[2]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
44
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[3]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
45
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[4]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
46
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[5]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
47
+ .get(`https://api.finto.fi/rest/v1/data?uri=${uris[6]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData});
48
+ }
49
+
50
+ testValidatorFactory();
51
+ }
52
+ }
53
+ });
54
+
55
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/drop-terms:test');
56
+
57
+ async function testValidatorFactory() {
58
+ const validator = await validatorFactory();
59
+
60
+ assert.equal(typeof validator, 'object');
61
+ assert.equal(typeof validator.description, 'string');
62
+ assert.equal(typeof validator.validate, 'function');
63
+ }
64
+
65
+ async function callback({getFixture, fix = false, config = undefined}) {
66
+ const validator = await validatorFactory(config);
67
+ const record = new MarcRecord(getFixture('record.json'));
68
+ const expectedResult = getFixture('expectedResult.json');
69
+ // console.log(expectedResult); // eslint-disable-line
70
+
71
+ if (!fix) {
72
+ const result = await validator.validate(record);
73
+ assert.deepEqual(result, expectedResult);
74
+ const originalRecord = new MarcRecord(getFixture('record.json'));
75
+ assert.deepEqual(record, originalRecord); // Validation should not change the record
76
+ return;
77
+ }
78
+ const expectedResult2 = new MarcRecord(expectedResult);
79
+ await validator.fix(record);
80
+ assert.deepEqual(record, expectedResult2);
81
+ }
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './field-008-18-34-character-groups.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
- import createDebugLogger from 'debug';
6
+ //import createDebugLogger from 'debug';
7
7
 
8
8
  generateTests({
9
9
  callback,
@@ -19,7 +19,7 @@ generateTests({
19
19
  }
20
20
  }
21
21
  });
22
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-008-18-34-character-groups:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-008-18-34-character-groups:test');
23
23
 
24
24
  async function testValidatorFactory() {
25
25
  const validator = await validatorFactory();
@@ -30,12 +30,7 @@ async function testValidatorFactory() {
30
30
  assert.equal(typeof validator.validate, 'function');
31
31
  }
32
32
 
33
- async function callback({getFixture, enabled = true, fix = false}) {
34
- if (enabled === false) {
35
- debug('TEST SKIPPED!');
36
- return;
37
- }
38
-
33
+ async function callback({getFixture, fix = false}) {
39
34
  const validator = await validatorFactory();
40
35
  const record = new MarcRecord(getFixture('record.json'));
41
36
  const expectedResult = getFixture('expectedResult.json');
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './field-505-separators.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
- import createDebugLogger from 'debug';
6
+ //import createDebugLogger from 'debug';
7
7
 
8
8
  generateTests({
9
9
  callback,
@@ -19,7 +19,7 @@ generateTests({
19
19
  }
20
20
  }
21
21
  });
22
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-505-separators:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-505-separators:test');
23
23
 
24
24
  async function testValidatorFactory() {
25
25
  const validator = await validatorFactory();
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
29
29
  assert.equal(typeof validator.validate, 'function');
30
30
  }
31
31
 
32
- async function callback({getFixture, enabled = true, fix = false}) {
33
- if (enabled === false) {
34
- debug('TEST SKIPPED!');
35
- return;
36
- }
37
-
32
+ async function callback({getFixture, fix = false}) {
38
33
  const validator = await validatorFactory();
39
34
 
40
35
  const recordFixture = getFixture('record.json');
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './field-521-fix.js';
4
4
  import {READERS} from '@natlibfi/fixura';
5
5
  import generateTests from '@natlibfi/fixugen';
6
- import createDebugLogger from 'debug';
6
+ //import createDebugLogger from 'debug';
7
7
 
8
8
  generateTests({
9
9
  callback,
@@ -19,7 +19,7 @@ generateTests({
19
19
  }
20
20
  }
21
21
  });
22
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/fix521:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/fix521:test');
23
23
 
24
24
  async function testValidatorFactory() {
25
25
  const validator = await validatorFactory();
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
29
29
  assert.equal(typeof validator.validate, 'function');
30
30
  }
31
31
 
32
- async function callback({getFixture, enabled = true, fix = false}) {
33
- if (enabled === false) {
34
- debug('TEST SKIPPED!');
35
- return;
36
- }
37
-
32
+ async function callback({getFixture, fix = false}) {
38
33
  const validator = await validatorFactory();
39
34
  const record = new MarcRecord(getFixture('record.json'));
40
35
  const expectedResult = getFixture('expectedResult.json');