@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,5 +1,5 @@
1
1
  import createDebugLogger from 'debug';
2
- import {fieldsToString, fieldToString, nvdebug} from './utils.js';
2
+ import {fieldToString, nvdebug} from './utils.js';
3
3
  import {fieldHasValidSubfield6, fieldsGetOccurrenceNumbers, fieldsToNormalizedString, fieldToNormalizedString, get6s} from './subfield6Utils.js';
4
4
  import {add8s, fieldHasLinkingNumber, fieldHasValidSubfield8, fieldsGetAllSubfield8LinkingNumbers, getSubfield8LinkingNumber, recordGetAllSubfield8LinkingNumbers, recordGetFieldsWithSubfield8LinkingNumber} from './subfield8Utils.js';
5
5
 
@@ -11,6 +11,8 @@ const LINKED_NOT_PROCESSED = 1;
11
11
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
12
12
 
13
13
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:removeDuplicateDataFields');
14
+ //const debugData = debug.extend('data');
15
+ const debugDev = debug.extend('dev');
14
16
 
15
17
  export default function () {
16
18
  return {
@@ -19,7 +21,7 @@ export default function () {
19
21
  };
20
22
 
21
23
  function fix(record) {
22
- nvdebug('Remove duplicate data fields');
24
+ nvdebug('Remove duplicate data fields', debugDev);
23
25
  const res = {message: [], fix: [], valid: true};
24
26
  removeDuplicateDatafields(record, true);
25
27
  // This can not really fail...
@@ -28,7 +30,7 @@ export default function () {
28
30
 
29
31
  function validate(record) {
30
32
  // Check max, and check number of different indexes
31
- nvdebug('Validate record: duplicate data fields cause (t)error', debug);
33
+ nvdebug('Validate record: duplicate data fields cause (t)error', debugDev);
32
34
 
33
35
  const duplicates = removeDuplicateDatafields(record, false);
34
36
 
@@ -49,7 +51,7 @@ export default function () {
49
51
 
50
52
  /*
51
53
  function numberOfLinkageSubfields(field) {
52
- nvdebug(`N of Linkage Subs(${fieldToString(field)})`);
54
+ nvdebug(`N of Linkage Subs(${fieldToString(field)})`, debugDev);
53
55
  const subfields = field.subfields.filter(sf => sf.code === '6' || sf.code === '8');
54
56
  return subfields.length;
55
57
  }
@@ -139,21 +141,21 @@ export function removeDuplicateSubfield8Chains(record, fix = true) {
139
141
 
140
142
  let removables = []; // for validation
141
143
 
142
- nvdebug("CHAIN-8");
144
+ //nvdebug("CHAIN-8", debugDev);
143
145
  const seenLinkingNumbers = recordGetAllSubfield8LinkingNumbers(record);
144
146
  if (seenLinkingNumbers.length === 0) {
145
147
  return removables;
146
148
  }
147
149
 
148
- nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debug);
150
+ //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debugDev);
149
151
 
150
152
  seenLinkingNumbers.forEach(currLinkingNumber => {
151
153
  const linkedFields = recordGetFieldsWithSubfield8LinkingNumber(record, currLinkingNumber) //getFieldsWithSubfield8Index(base, baseIndex);
152
154
  // As/If there's just one occurrence number it should be fine to use normalizeOccurrenceNumber = true
153
155
  const normalizeOccurrenceNumber = true;
154
156
  const linkedFieldsAsString = fieldsToNormalizedString(linkedFields, currLinkingNumber, normalizeOccurrenceNumber, true);
155
- nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debug);
156
- nvdebug(`${linkedFieldsAsString}`, debug);
157
+ //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debugDev);
158
+ //nvdebug(`${linkedFieldsAsString}`, debugDev);
157
159
 
158
160
  if (linkedFieldsAsString in seen) {
159
161
  if (!removables.includes(linkedFieldsAsString)) {
@@ -161,15 +163,15 @@ export function removeDuplicateSubfield8Chains(record, fix = true) {
161
163
  }
162
164
 
163
165
  if (fix) {
164
- nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debug);
166
+ //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debugDev);
165
167
  linkedFields.forEach(field => recordRemoveFieldOrSubfield8(record, field, currLinkingNumber));
166
168
  return;
167
169
  }
168
170
 
169
- nvdebug(`$8 VALIDATION: DUPLICATE DETECTED ${linkedFieldsAsString}`, debug);
171
+ //nvdebug(`$8 VALIDATION: DUPLICATE DETECTED ${linkedFieldsAsString}`, debugDev);
170
172
  return;
171
173
  }
172
- nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debug);
174
+ //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debugDev);
173
175
  seen[linkedFieldsAsString] = 1;
174
176
  return;
175
177
  });
@@ -190,28 +192,28 @@ export function handleDuplicateSubfield8Chains(record, fix) {
190
192
 
191
193
  let seen = {};
192
194
 
193
- nvdebug("CHAIN-8");
195
+ //nvdebug("CHAIN-8", debugDev);
194
196
  const seenLinkingNumbers = recordGetAllSubfield8LinkingNumbers(record);
195
197
  if (seenLinkingNumbers.length === 0) {
196
198
  return;
197
199
  }
198
200
 
199
- nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debug);
201
+ //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debugDev);
200
202
 
201
203
  seenLinkingNumbers.forEach(currLinkingNumber => {
202
204
  const linkedFields = recordGetFieldsWithSubfield8LinkingNumber(record, currLinkingNumber) //getFieldsWithSubfield8Index(base, baseIndex);
203
205
  // As/If there's just one occurrence number it should be fine to use normalizeOccurrenceNumber = true
204
206
  const normalizeOccurrenceNumber = false; //true;
205
207
  const linkedFieldsAsString = fieldsToNormalizedString(linkedFields, currLinkingNumber, normalizeOccurrenceNumber, true);
206
- nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debug);
207
- nvdebug(`${linkedFieldsAsString}`, debug);
208
+ //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debugDev);
209
+ //nvdebug(`${linkedFieldsAsString}`, debugDev);
208
210
 
209
211
  if (linkedFieldsAsString in seen) {
210
- nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debug);
212
+ //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debugDev);
211
213
  linkedFields.forEach(field => newRecordRemoveFieldOrSubfield8(record, field, currLinkingNumber, fix));
212
214
  return;
213
215
  }
214
- nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debug);
216
+ //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debugDev);
215
217
  seen[linkedFieldsAsString] = 1;
216
218
  return;
217
219
  });
@@ -223,12 +225,12 @@ function markIdenticalSubfield6Chains(chain, record) {
223
225
  const normalizeTag = chain.some(field => field.tag.substring(0, 1) === '1'); // 1XX can delete 7XX as well!
224
226
  const chainAsString = fieldsToNormalizedString(chain, 0, normalizeOccurrenceNumber, normalizeTag);
225
227
 
226
- nvdebug(`markIdenticalSubfield6Chains: ${chainAsString}`);
228
+ //nvdebug(`markIdenticalSubfield6Chains: ${chainAsString}`, debugDev);
227
229
  record.fields.forEach(f => compareWithChain(f));
228
230
 
229
231
 
230
232
  function compareWithChain(f) {
231
- nvdebug(`FIELD2CHAIN ${fieldToString(f)}`);
233
+ //nvdebug(`FIELD2CHAIN ${fieldToString(f)}`, debugDev);
232
234
  const otherChain = fieldToChain(f, record);
233
235
  // Not a lone field or chain (head) or ... or is-same-chain
234
236
  if (otherChain.length === 0 || sameField(chain[0], otherChain[0])) {
@@ -239,7 +241,7 @@ function markIdenticalSubfield6Chains(chain, record) {
239
241
  // Mark other chain as deleted:
240
242
  if (chainAsString === otherChainAsString) {
241
243
  otherChain.forEach(f => {
242
- nvdebug(` mark ${fieldToString(f)} as deleted ($6-chain)...`);
244
+ //nvdebug(` mark ${fieldToString(f)} as deleted ($6-chain)...`, debugDev);
243
245
  f.deleted = 1;
244
246
  });
245
247
  return;
@@ -260,7 +262,7 @@ function markIdenticalLoneFieldsAsDeletable(field, record) {
260
262
 
261
263
  // Mark fields as deleted:
262
264
  identicalLoneFields.forEach(f => {
263
- nvdebug(` mark ${fieldToString(f)} as deleted (lone field)...`);
265
+ //nvdebug(` mark ${fieldToString(f)} as deleted (lone field)...`, debugDev);
264
266
  f.deleted = 1;
265
267
  });
266
268
 
@@ -300,7 +302,7 @@ function acceptFieldsWithSubfield8(fieldsWithSubfield8, requireSingleTag = false
300
302
 
301
303
  // If linking number
302
304
  function anomaly8(linkingNumber) {
303
- nvdebug(` Looking for anomalies in linkin number ${linkingNumber}`);
305
+ //nvdebug(` Looking for anomalies in linkin number ${linkingNumber}`, debugDev);
304
306
  const relevantFields = fieldsWithSubfield8.filter(f => fieldHasLinkingNumber(f, linkingNumber));
305
307
  if (requireSingleTag) {
306
308
  return !isSingleTagLinkingNumber(linkingNumber, relevantFields, relevantFields[0].tag);
@@ -332,7 +334,7 @@ export function fieldToChain(field, record) {
332
334
  }
333
335
  const chain = newGetAllLinkedFields(field, record, true, true);
334
336
 
335
- nvdebug(` Chain contains ${chain.length} field(s)`);
337
+ // nvdebug(` Chain contains ${chain.length} field(s)`, debugDev);
336
338
  if (!isChainHead(field, chain)) { // newGetAllLinkedFields() marks relevant record.fields!
337
339
  return [];
338
340
  }
@@ -357,7 +359,7 @@ export function fieldToChain(field, record) {
357
359
  return [];
358
360
  }
359
361
 
360
- //nvdebug(`Proceed with ${fieldsToString(chain)}`);
362
+ //nvdebug(`Proceed with ${fieldsToString(chain)}`, debugDev);
361
363
 
362
364
 
363
365
  return chain;
@@ -366,7 +368,7 @@ export function fieldToChain(field, record) {
366
368
 
367
369
  function fieldHandleDuplicateDatafields(field, record) {
368
370
  const chain = fieldToChain(field, record);
369
- nvdebug(` TRY TO HANDLE DUPLICATES OF '${fieldsToString(chain)}'`);
371
+ //nvdebug(` TRY TO HANDLE DUPLICATES OF '${fieldsToString(chain)}'`, debugDev);
370
372
 
371
373
  if (chain.length === 0) {
372
374
  return;
@@ -383,7 +385,7 @@ function fieldHandleDuplicateDatafields(field, record) {
383
385
  if (fieldsWithSubfield6.length === 0) {
384
386
 
385
387
  if (fieldsWithSubfield8.length === 0) { // chain.length === 1?
386
- nvdebug(` Trying to find duplicates of single field '${fieldToString(chain[0])}'`);
388
+ //nvdebug(` Trying to find duplicates of single field '${fieldToString(chain[0])}'`, debugDev);
387
389
  markIdenticalLoneFieldsAsDeletable(chain[0], record);
388
390
  return;
389
391
  }
@@ -401,8 +403,8 @@ function fieldHandleDuplicateDatafields(field, record) {
401
403
  }
402
404
 
403
405
 
404
- nvdebug(` NO HANDLER FOUND FOR '${fieldsToString(chain)}'`);
405
- nvdebug(` N8s: ${fieldsWithSubfield6.length}`);
406
+ //nvdebug(` NO HANDLER FOUND FOR '${fieldsToString(chain)}'`, debugDev);
407
+ //nvdebug(` N8s: ${fieldsWithSubfield6.length}`, debugDev);
406
408
 
407
409
  }
408
410
 
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './removeDuplicateDataFields.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/removeDuplicateDataFields:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/removeDuplicateDataFields: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');
@@ -1,7 +1,7 @@
1
- import createDebugLogger from 'debug';
1
+ //import createDebugLogger from 'debug';
2
2
  import {fieldToChain, sameField} from './removeDuplicateDataFields.js';
3
3
  import {fieldGetOccurrenceNumberPairs, fieldHasValidSubfield6, fieldSevenToOneOccurrenceNumber, fieldsToNormalizedString} from './subfield6Utils.js';
4
- import {fieldHasSubfield, fieldsToString, fieldToString, nvdebug, uniqArray} from './utils.js';
4
+ import {fieldHasSubfield, fieldsToString, fieldToString, /*nvdebug,*/ uniqArray} from './utils.js';
5
5
  import {fieldHasValidSubfield8} from './subfield8Utils.js';
6
6
  import {encodingLevelIsBetterThanPrepublication, fieldRefersToKoneellisestiTuotettuTietue, getEncodingLevel} from './prepublicationUtils.js';
7
7
  import {cloneAndNormalizeFieldForComparison} from './normalizeFieldForComparison.js';
@@ -12,7 +12,10 @@ import {fixComposition, precomposeFinnishLetters} from './normalize-utf8-diacrit
12
12
  // NB! This validator handles only full fields, and does not support subfield $8 removal.
13
13
  // Also, having multiple $8 subfields in same fields is not supported.
14
14
  // If this functionality is needed, see removeDuplicateDatafields.js for examples of subfield-only stuff.
15
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:removeInferiorDataFields');
15
+
16
+ // const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:removeInferiorDataFields');
17
+ //const debugData = debug.extend('data');
18
+ //const debugDev = debug.extend('dev');
16
19
 
17
20
  export default function () {
18
21
  return {
@@ -21,7 +24,7 @@ export default function () {
21
24
  };
22
25
 
23
26
  function fix(record) {
24
- nvdebug('Fix record: remove inferior (eg. subset) data fields', debug);
27
+ //nvdebug('Fix record: remove inferior (eg. subset) data fields', debugDev);
25
28
  const res = {message: [], fix: [], valid: true};
26
29
  removeInferiorDatafields(record, true);
27
30
  // This can not really fail...
@@ -30,7 +33,7 @@ export default function () {
30
33
 
31
34
  function validate(record) {
32
35
  // Check max, and check number of different indexes
33
- nvdebug('Validate record: remove inferior (eg. subset) data fields', debug);
36
+ //nvdebug('Validate record: remove inferior (eg. subset) data fields', debugDev);
34
37
 
35
38
  const duplicates = removeInferiorDatafields(record, false);
36
39
 
@@ -43,14 +46,14 @@ export default function () {
43
46
 
44
47
 
45
48
  function deriveInferiorChains(fields, record) {
46
- //nvdebug(`======= GOT ${fields.length} FIELDS TO CHAINIFY`);
49
+ //nvdebug(`======= GOT ${fields.length} FIELDS TO CHAINIFY`, debugDev);
47
50
  const hash = {};
48
51
 
49
52
  fields.forEach(f => fieldToChainToDeletables(f));
50
53
 
51
54
  return hash;
52
55
 
53
- //nvdebug(`WP1: GOT ${todoList.length} CHAINS`);
56
+ //nvdebug(`WP1: GOT ${todoList.length} CHAINS`, debugDev);
54
57
 
55
58
 
56
59
  // here we map deletableStringObject[str] => field. The idea is to help debugging. We don't actually need the field object...
@@ -63,7 +66,7 @@ function deriveInferiorChains(fields, record) {
63
66
  }
64
67
  const chainAsString = fieldsToNormalizedString(chain, 0, true, true);
65
68
  const arr = deriveChainDeletables([chainAsString]);
66
- //nvdebug(`GOT ${arr.length} DELETABLES FOR ${chainAsString}`);
69
+ //nvdebug(`GOT ${arr.length} DELETABLES FOR ${chainAsString}`, debugDev);
67
70
  arr.forEach(val => {
68
71
  if (!(val in hash)) {
69
72
  hash[val] = field;
@@ -116,16 +119,16 @@ function isRelevantChain6(field, record) {
116
119
 
117
120
  export function removeInferiorChains(record, fix = true) {
118
121
  const fields = record.fields.filter(f => isRelevantChain6(f, record));
119
- //nvdebug(`WP2.0: GOT ${fields.length} chain(s)`);
122
+ //nvdebug(`WP2.0: GOT ${fields.length} chain(s)`, debugDev);
120
123
 
121
124
  const deletableChainsAsKeys = deriveInferiorChains(fields, record);
122
125
  const nChains = Object.keys(deletableChainsAsKeys).length;
123
- //nvdebug(`WP2: GOT ${nChains} chain(s)`);
126
+ //nvdebug(`WP2: GOT ${nChains} chain(s)`, debugDev);
124
127
  if (nChains === 0) {
125
128
  return [];
126
129
  }
127
130
 
128
- //nvdebug(`removeInferiorChains() has ${fields.length} fields-in-chain(s), and a list of ${nChains} deletable(s)`);
131
+ //nvdebug(`removeInferiorChains() has ${fields.length} fields-in-chain(s), and a list of ${nChains} deletable(s)`, debugDev);
129
132
 
130
133
  return innerRemoveInferiorChains(fields);
131
134
 
@@ -153,11 +156,11 @@ export function removeInferiorChains(record, fix = true) {
153
156
  if (chainContains1XX(chain)) {
154
157
  triggeringChain.forEach(f => sevenToOne(f, triggeringChain));
155
158
  }
156
- //nvdebug(`iRIS6C: ${chainAsString}`);
159
+ //nvdebug(`iRIS6C: ${chainAsString}`, debugDev);
157
160
  const deletedString = fieldsToString(chain);
158
161
  const message = `DEL: '${deletedString}' REASON: '${fieldsToString(triggeringChain)}'`;
159
162
  if (fix) {
160
- //nvdebug(`INFERIOR $6 CHAIN REMOVAL: ${message}}`, debug);
163
+ //nvdebug(`INFERIOR $6 CHAIN REMOVAL: ${message}}`, debugDev);
161
164
  chain.forEach(field => record.removeField(field));
162
165
  }
163
166
  return innerRemoveInferiorChains(remainingFields, [...deletedStringsArray, message]);
@@ -197,7 +200,7 @@ function deriveIndividualDeletables490(todoList, deletables = []) {
197
200
  if (fieldAsString === undefined) {
198
201
  return deletables;
199
202
  }
200
- //nvdebug(`PROCESS ${fieldAsString}`);
203
+ //nvdebug(`PROCESS ${fieldAsString}`, debugDev);
201
204
  if (!fieldAsString.match(/^490/u)) {
202
205
  return deriveIndividualDeletables490(stillToDo, deletables);
203
206
  }
@@ -220,13 +223,14 @@ function deriveIndividualDeletables490(todoList, deletables = []) {
220
223
 
221
224
  /*
222
225
  if (arr.length) {
223
- nvdebug(`${arr.length} derivation(s) for ${fieldAsString}`);
224
- nvdebug(arr.join('\n'));
226
+ nvdebug(`${arr.length} derivation(s) for ${fieldAsString}`, debugDev);
227
+ nvdebug(arr.join('\n'), debugDev);
225
228
  }
226
229
  */
227
230
  return arr;
228
231
  }
229
232
 
233
+ // eslint-disable-next-line max-lines-per-function
230
234
  function deriveIndividualDeletables(record) {
231
235
  const todoList = record.fields.map(f => fieldToString(f));
232
236
  //const finishedRecord = encodingLevelIsBetterThanPrepublication(getEncodingLevel(record));
@@ -274,28 +278,6 @@ function deriveIndividualDeletables(record) {
274
278
  }
275
279
  }
276
280
 
277
- if (currString.match(/^500 ## ‡a Lisäpainokset: Lisäpainos /u)) { // MET-569
278
- const tmp1 = currString.replace(' Lisäpainos ', ' [Lisäpainos] ');
279
- const tmp2 = currString.replace(' Lisäpainos ', ' ');
280
- if (tmp1 !== currString && tmp2 !== currString) {
281
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp1, tmp2]);
282
- }
283
- }
284
-
285
- if (currString.match(/^500 ## ‡a Lisäpainokset: \[Lisäpainos\] /u)) { // MET-569
286
- const tmp = currString.replace(' [Lisäpainos] ', ' ');
287
- if (tmp !== currString) {
288
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp]);
289
- }
290
- }
291
-
292
- if (currString.match(/^500 ## ‡a Ei vastaanotettu\.$/u)) { // MELKEHITYS-3147
293
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, '500 ## ‡a EI VASTAANOTETTU.']);
294
- }
295
- if (currString.match(/^500 ## ‡a Ei ilmesty\.$/u)) { // MELKEHITYS-3147
296
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, '500 ## ‡a EI ILMESTY.']);
297
- }
298
-
299
281
  if (currString.match(/^505 .0.*-- ‡t/u)) { // MRA-413-ish
300
282
  const tmp = currString.replace(/ -- ‡t /gu, ' -- '). // remove non-initial $t subfields
301
283
  replace(/ ‡[rg] /gu, ' '). // remove $r and $g subfields
@@ -305,53 +287,115 @@ function deriveIndividualDeletables(record) {
305
287
  if (tmp !== currString) {
306
288
  return processTodoList([tmp, ...stillToDo, ...moreToDo], [...deletables, tmp]);
307
289
  }
308
- //nvdebug(`505 ORIGINAL: '${fieldAsString}'`)
309
- //nvdebug(`505 DERIVATE: '${tmp}'`)
290
+ //nvdebug(`505 ORIGINAL: '${fieldAsString}'`, debugDev)
291
+ //nvdebug(`505 DERIVATE: '${tmp}'`, debugDev)
310
292
  }
311
293
 
312
- if (currString.match(/^594 ## ‡a Ei vastaanotettu ‡5 FENNI$/u)) { // MELKEHITYS-3147
313
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, '594 ## ‡a EI VASTAANOTETTU ‡5 FENNI']);
314
- }
315
- if (currString.match(/^594 ## ‡a Ei ilmesty ‡5 FENNI$/u)) { // MELKEHITYS-3147
316
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, '594 ## ‡a EI ILMESTY ‡5 FENNI']);
294
+ const inferiorFunctions = [ getPrepublicationTerms, getInferior341, getAiBased, getMelkehitys3147, getMet831, getMet569, getCorrespondingDeprecated502s ];
295
+
296
+ const inferiorTerms = getInferiorTerms(inferiorFunctions); //getPrepublicationTerms(currString);
297
+
298
+ const newDeletables = [...deletables, ...subsets, ...accentless, ...d490, ...inferiorTerms];
299
+
300
+ return processTodoList([...stillToDo, ...moreToDo], newDeletables);
301
+
302
+ function getInferiorTerms(functions, results = []) {
303
+ const [currFunction, ...remainingFunctions] = functions;
304
+ if (!currFunction) {
305
+ return results
306
+ }
307
+ const newDeletables = currFunction(currString);
308
+ return getInferiorTerms(remainingFunctions, [...results, ...newDeletables]);
317
309
  }
318
310
 
319
- // MET-381: remove occurence number TAG-00, if TAG-NN existists
320
- if (currString.match(/^880.*6 [0-9][0-9][0-9]-(?:[1-9][0-9]|0[1-9])/u)) {
321
- const tmp = currString.replace(/( ‡6 [0-9][0-9][0-9])-[0-9]+/u, '$1-00');
322
- //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp}'`);
323
- //deletableStringsArray.push(tmp);
324
- if (tmp.match(/ ‡6 [0-9][0-9][0-9]-00\/[^ ]+ /u)) {
325
- const tmp2 = tmp.replace(/( ‡6 [0-9][0-9][0-9]-00)[^ ]+/u, '$1');
326
- //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp2}'`);
327
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp, tmp2]);
311
+ function getMet569(string) {
312
+ if (string.match(/^500 ## a Lisäpainokset: Lisäpainos /u)) { // MET-569
313
+ const tmp1 = string.replace(' Lisäpainos ', ' [Lisäpainos] ');
314
+ const tmp2 = string.replace(' Lisäpainos ', ' ');
315
+ if (tmp1 !== string && tmp2 !== string) { // Should not happen, just a sanity check
316
+ return [tmp1, tmp2];
317
+ }
318
+ }
319
+
320
+ if (string.match(/^500 ## ‡a Lisäpainokset: \[Lisäpainos\] /u)) { // MET-569
321
+ const tmp = string.replace(' [Lisäpainos] ', ' ');
322
+ if (tmp !== string) { // Should not happen, just a sanity check
323
+ return [tmp];
324
+ }
328
325
  }
329
- return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp]);
326
+ return [];
330
327
  }
331
328
 
332
- // MET-575 (merge: applies in postprocessing)
333
- const inferiorTerms = getPrepublicationTerms(currString);
329
+ function getCorrespondingDeprecated502s(string, results = []) { // MET-801-ish
330
+ if (!string.match(/^502/u)) {
331
+ return results;
332
+ }
334
333
 
335
- // MELKEHITYS-3277-ish: non-AI is better than AI (a rare case where longer version is inferior):
336
- const aiBased = `${currString}7 (dpenmw)AI`;
334
+ // 502 ## $a Väitöskirja : $c Opinahjo, $d 1234. => 502 ## $a Väitöskirja : $c Opinahjo.
335
+ let tmp = string.replace(/,d [^‡]+\.($| ‡)/u, '.$1');
336
+ if (tmp !== string) {
337
+ return getCorrespondingDeprecated502s(tmp, [...results, tmp]);
338
+ }
339
+ // 502 ## $a Väitöskirja : $c Opinahjo. => 502 ## $a Väitöskirja.
340
+ tmp = string.replace(/ : ‡c [^‡]+\.($| ‡)/u, '.');
341
+ if (tmp !== string) {
342
+ return getCorrespondingDeprecated502s(tmp, [...results, tmp]);
343
+ }
337
344
 
338
- const newDeletables = [...deletables, ...subsets, ...accentless, ...d490, ...inferiorTerms, aiBased];
345
+ // 502 ## $a Väitöskirja--Opinahjo, YYYY. => 502 ## $a Väitöskirja : $c Opinahjo, $d YYYY.
346
+ if (string.match(/^502 ## ‡a [^‡]+--[^‡]+\.$/u)) {
347
+ tmp = string
348
+ .replace(/--(.*,) ([12][0-9][0-9][0-9]\.)$/u, ' : ‡c $1 ‡d $2')
349
+ .replace(/--/u, ': ‡c ');
350
+ return getCorrespondingDeprecated502s(tmp, [...results, tmp]);
351
+ }
352
+ return results;
353
+ }
339
354
 
340
- if (subsets.length) {
341
- return processTodoList([...stillToDo, ...moreToDo], newDeletables);
355
+ function getMet831(string) { // MET-381
356
+ // MET-381: remove occurence number TAG-00, if TAG-NN existists
357
+ if (string.match(/^880.* ‡6 [0-9][0-9][0-9]-(?:[1-9][0-9]|0[1-9])/u)) {
358
+ const tmp = string.replace(/( ‡6 [0-9][0-9][0-9])-[0-9]+/u, '$1-00');
359
+ if (tmp.match(/ ‡6 [0-9][0-9][0-9]-00\/[^ ]+ /u)) {
360
+ const tmp2 = tmp.replace(/( ‡6 [0-9][0-9][0-9]-00)[^ ]+/u, '$1');
361
+ return [tmp, tmp2];
362
+ }
363
+ return [tmp];
364
+ }
365
+ return [];
366
+ }
367
+
368
+ function getMelkehitys3147(string) {
369
+ if (string.match(/^500 ## ‡a Ei vastaanotettu\.$/u)) { // MELKEHITYS-3147
370
+ return ['500 ## ‡a EI VASTAANOTETTU.'];
371
+ }
372
+ if (string.match(/^500 ## ‡a Ei ilmesty\.$/u)) { // MELKEHITYS-3147
373
+ return ['500 ## ‡a EI ILMESTY.'];
374
+ }
375
+
376
+ if (string.match(/^594 ## ‡a Ei vastaanotettu ‡5 FENNI$/u)) { // MELKEHITYS-3147
377
+ return ['594 ## ‡a EI VASTAANOTETTU ‡5 FENNI'];
378
+ }
379
+ if (string.match(/^594 ## ‡a Ei ilmesty ‡5 FENNI$/u)) { // MELKEHITYS-3147
380
+ return ['594 ## ‡a EI ILMESTY ‡5 FENNI'];
381
+ }
382
+ return [];
342
383
  }
343
384
 
344
- return processTodoList([...stillToDo, ...moreToDo], newDeletables);
345
385
  }
346
386
 
387
+ function getAiBased(string) { // MELKEHITYS-3277-ish: non-AI is better than AI (a rare case where longer version is inferior):
388
+ return [`${string} ‡7 (dpenmw)AI`];
389
+ }
390
+
347
391
  function getAccentlessVersion(string) { // MET-527
348
- //nvdebug(`START: '${string}`);
392
+ //nvdebug(`START: '${string}`, debugDev);
349
393
  // This is a sanity check: if precomposition does something, there's something wrong, and we don't want to proceed..
350
394
  if (string !== precomposeFinnishLetters(string)) {
351
395
  return [];
352
396
  }
353
397
  const accentless = String(fixComposition(string)).replace(/\p{Diacritic}/gu, '');
354
- //nvdebug(`FROM '${string}'\n TO '${accentless}'`);
398
+ //nvdebug(`FROM '${string}'\n TO '${accentless}'`, debugDev);
355
399
  if (accentless === string) { // Don't self-destruct
356
400
  return [];
357
401
  }
@@ -359,11 +403,22 @@ function deriveIndividualDeletables(record) {
359
403
  }
360
404
 
361
405
  function getPrepublicationTerms(fieldAsString) {
406
+ const subfield7Prepub = `${fieldAsString} ‡7 Ennakkotieto`
362
407
  if (fieldAsString.match(/^653./u)) {
363
408
  // MET-528 (extented by MET-575)
364
- return [`${fieldAsString} ‡g ENNAKKOTIETO`, `${fieldAsString} ‡g Ennakkotieto`, `${fieldAsString} ‡g ennakkotieto`, `${fieldAsString} ‡g ENNAKKOTIETO.`, `${fieldAsString} ‡g Ennakkotieto.`, `${fieldAsString} ‡g ennakkotieto.`];
409
+ return [subfield7Prepub, `${fieldAsString} ‡g ENNAKKOTIETO`, `${fieldAsString} ‡g Ennakkotieto`, `${fieldAsString} ‡g ennakkotieto`, `${fieldAsString} ‡g ENNAKKOTIETO.`, `${fieldAsString} ‡g Ennakkotieto.`, `${fieldAsString} ‡g ennakkotieto.`];
365
410
  }
366
411
 
412
+ return [subfield7Prepub];
413
+ }
414
+
415
+ function getInferior341(fieldAsString) { // MET-783
416
+ if (fieldAsString.match(/^341 .. ‡a textual ‡[bcdef].* ‡2 sapdv(?:$| ‡)/u)) {
417
+ return ['341 ## ‡a textual ‡2 sapdv', '341 1# ‡a textual ‡2 sapdv', '341 0# ‡a textual ‡2 sapdv'];
418
+ }
419
+ if (fieldAsString.match(/^341 .. ‡a auditory ‡[bcdef].* ‡2 sapdv(?:$| ‡)/u)) {
420
+ return ['341 ## ‡a auditory ‡2 sapdv', '341 1# ‡a auditory ‡2 sapdv', '341 0# ‡a auditory ‡2 sapdv'];
421
+ }
367
422
  return [];
368
423
  }
369
424
 
@@ -407,8 +462,8 @@ export function removeIndividualInferiorDatafields(record, fix = true) { // No $
407
462
  const deletableFieldsAsStrings = deriveIndividualDeletables(record);
408
463
  const deletableFieldsAsNormalizedStrings = deriveIndividualNormalizedDeletables(record);
409
464
 
410
- // nvdebug(`Deletables:\n ${deletableFieldsAsStrings.join('\n ')}`);
411
- // nvdebug(`Normalized deletables:\n ${deletableFieldsAsNormalizedStrings.join('\n ')}`);
465
+ // nvdebug(`Deletables:\n ${deletableFieldsAsStrings.join('\n ')}`, debugDev);
466
+ // nvdebug(`Normalized deletables:\n ${deletableFieldsAsNormalizedStrings.join('\n ')}`, debugDev);
412
467
 
413
468
  const hits = record.fields.filter(field => isDeletableField(field));
414
469
 
@@ -416,7 +471,7 @@ export function removeIndividualInferiorDatafields(record, fix = true) { // No $
416
471
 
417
472
  if (fix) {
418
473
  hits.forEach(field => {
419
- //nvdebug(`Remove inferior field: ${fieldToString(field)}`, debug);
474
+ //nvdebug(`Remove inferior field: ${fieldToString(field)}`, debugDev);
420
475
  record.removeField(field);
421
476
  });
422
477
  }
@@ -444,8 +499,8 @@ export function removeInferiorDatafields(record, fix = true) {
444
499
  const removables6 = removeInferiorChains(record, fix); // Lone subfield $6 chains
445
500
  // HOW TO HANDLE $6+$8 combos? Skipping is relatively OK.
446
501
 
447
- nvdebug(`REMOVABLES:\n ${removables.join('\n ')}`, debug);
448
- nvdebug(`REMOVABLES 6:\n ${removables6.join('\n ')}`, debug);
502
+ //nvdebug(`REMOVABLES:\n ${removables.join('\n ')}`, debugDev);
503
+ //nvdebug(`REMOVABLES 6:\n ${removables6.join('\n ')}`, debugDev);
449
504
 
450
505
  const removablesAll = removables.concat(removables6); //.concat(removables8);
451
506
 
@@ -1,9 +1,9 @@
1
- import assert from 'node:assert';
1
+ import assert from 'node:assert/strict';
2
2
  import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './removeInferiorDataFields.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,
@@ -20,7 +20,7 @@ generateTests({
20
20
  }
21
21
  });
22
22
 
23
- const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/removeInferiorDataFields:test');
23
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/removeInferiorDataFields:test');
24
24
 
25
25
  async function testValidatorFactory() {
26
26
  const validator = await validatorFactory();
@@ -30,12 +30,7 @@ async function testValidatorFactory() {
30
30
  assert.equal(typeof validator.validate).to.be.a('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');
@@ -44,9 +39,11 @@ async function callback({getFixture, enabled = true, fix = false}) {
44
39
  if (!fix) {
45
40
  const result = await validator.validate(record);
46
41
  assert.deepEqual(result, expectedResult);
42
+ const originalRecord = new MarcRecord(getFixture('record.json'));
43
+ assert.deepEqual(record, originalRecord); // The record should now change in validation-only
47
44
  return;
48
45
  }
49
46
 
50
47
  await validator.fix(record);
51
- assert.deepEqual(record, expectedResult);
48
+ assert.deepEqual(record, new MarcRecord(expectedResult));
52
49
  }