@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,4 @@
1
+ /* eslint-disable max-lines */
1
2
  /*
2
3
  * punctuation.js -- try and fix a marc field punctuation
3
4
  *
@@ -10,13 +11,15 @@
10
11
  * (They are jumped over when looking for next (non-controlfield subfield)
11
12
  */
12
13
  import {validateSingleField} from './ending-punctuation.js';
13
- import {tagToDataProvenanceSubfieldCode} from './merge-fields/dataProvenance.js';
14
+ import {tagToDataProvenanceSubfieldCode} from './dataProvenanceUtils.js';
14
15
  import {fieldGetUnambiguousTag} from './subfield6Utils.js';
15
- //import createDebugLogger from 'debug';
16
- import {fieldToString, isControlSubfieldCode, nvdebug} from './utils.js';
16
+ import createDebugLogger from 'debug';
17
+ import {fieldToString, isContentSubfieldCode, nvdebug} from './utils.js';
17
18
  import clone from 'clone';
18
19
 
19
- //const debug = createDebugLogger('debug/punctuation2');
20
+ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:punctuation2');
21
+ //const debugData = debug.extend('data');
22
+ const debugDev = debug.extend('dev');
20
23
 
21
24
  const descriptionString = 'Remove invalid and add valid punctuation to data fields';
22
25
  export default function () {
@@ -26,14 +29,14 @@ export default function () {
26
29
  };
27
30
 
28
31
  function fix(record) {
29
- nvdebug(`${descriptionString}: fixer`);
32
+ nvdebug(`${descriptionString}: fixer`, debugDev);
30
33
  const res = {message: [], fix: [], valid: true};
31
34
  record.fields.forEach(f => fieldFixPunctuation(f));
32
35
  return res;
33
36
  }
34
37
 
35
38
  function validate(record) {
36
- nvdebug(`${descriptionString}: validate`);
39
+ nvdebug(`${descriptionString}: validate`, debugDev);
37
40
 
38
41
  const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, true));
39
42
 
@@ -57,7 +60,7 @@ function isIrrelevantSubfield(subfield, tag) {
57
60
  if (subfield.code === dataProvenanceSubfieldCode) {
58
61
  return true;
59
62
  }
60
- return isControlSubfieldCode(subfield.code); // Currently this contains other stuff as well ($3, $4, $7, $9...)
63
+ return !isContentSubfieldCode(subfield.code); // Currently this contains other stuff as well ($3, $4, $7, $9...)
61
64
  }
62
65
 
63
66
 
@@ -123,16 +126,16 @@ const X00RemoveDotAfterBracket = {'code': 'cq', 'context': /\)\.$/u, 'remove': /
123
126
  // 390, 800, 810, 830...
124
127
  const cleanPuncBeforeLanguage = {'code': 'atvxyz', 'followedBy': 'l', 'context': puncIsProbablyPunc, 'remove': / *[.,:;]$/u};
125
128
 
126
- const addX00aComma = {'add': ',', 'code': 'abcqej', 'followedBy': 'cdeg', 'context': doesNotEndInPunc, 'contextRHS': allowsPuncRHS};
129
+ const addX00aComma = {'add': ',', 'code': 'abcqejt', 'followedBy': 'cdegnr', 'context': doesNotEndInPunc, 'contextRHS': allowsPuncRHS};
127
130
  const addX00dComma = {'name': 'X00$d ending in "-" does not get comma', 'add': ',', 'code': 'd', 'followedBy': 'cdeg', 'context': /[^-,.!]$/u, 'contextRHS': allowsPuncRHS};
128
131
  const addX00aComma2 = {'add': ',', 'code': 'abcdej', 'followedBy': 'cdeg', 'context': /(?:[A-Z]|Å|Ä|Ö)\.$/u, 'contextRHS': allowsPuncRHS};
129
132
  const addX00Dot = {'add': '.', 'code': 'abcdetv', 'followedBy': 'fklptu', 'context': needsPuncAfterAlphanumeric};
130
133
  const addEntryFieldFinalDot = {'name': 'X00 final dot', 'add': '.', 'code': 'abcdefghijklmnopqrstuvwxyz', 'followedBy': '#', 'context': /[^.)!?-]$/u};
131
134
 
132
135
 
133
- const addX10iColon = {name: 'Punctuate relationship information', add: ':', code: 'i', context: defaultNeedsPuncAfter2};
136
+ const addXX0iColon = {name: 'Punctuate relationship information', add: ':', code: 'i', context: defaultNeedsPuncAfter2}; // Not explicitly checking it, but this should always be followed by 'a' or 't'
134
137
  const addX10bDot = {'name': 'Add X10 pre-$b dot', 'add': '.', 'code': 'ab', 'followedBy': 'b', 'context': defaultNeedsPuncAfter2};
135
- const addX10eComma = {'add': ',', 'code': 'abe', 'followedBy': 'e', 'context': defaultNeedsPuncAfter2};
138
+ const addX10Comma = {'add': ',', 'code': 'abet', 'followedBy': 'en', 'context': defaultNeedsPuncAfter2};
136
139
  const addX10Dot = {'name': 'Add X10 final dot', 'add': '.', 'code': 'abet', 'followedBy': 'tu#', 'context': needsPuncAfterAlphanumeric};
137
140
  const addColonToRelationshipInformation = {'name': 'Add \':\' to 7X0 $i relationship info', 'add': ':', 'code': 'i', 'context': defaultNeedsPuncAfter2};
138
141
 
@@ -223,11 +226,11 @@ const cleanCrappyPunctuationRules = {
223
226
  '946': crappy24X
224
227
  };
225
228
 
226
- const cleanLegalX00Comma = {'code': 'abcde', 'followedBy': 'cdegj', 'context': /.,$/u, 'remove': /,$/u};
229
+ const cleanLegalX00Comma = {'code': 'abcdetn', 'followedBy': 'cdegjnr', 'context': /.,$/u, 'remove': /,$/u};
227
230
  // Accept upper case letters in X00$b, since they are probably Roman numerals.
228
231
  const cleanLegalX00bDot = {'code': 'b', 'followedBy': 't#', context: /^[IVXLCDM]+\.$/u, 'remove': /\.$/u};
229
232
  const cleanLegalX00iColon = {'code': 'i', 'followedBy': 'a', 'remove': / *:$/u}; // NB! context is not needed
230
- const cleanLegalX00Dot = {'code': 'abcdetvl', 'followedBy': 'tu#', 'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u, 'remove': /\.$/u};
233
+ const cleanLegalX00Dot = {'code': 'abcdetkvl', 'followedBy': 'tklu#', 'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u, 'remove': /\.$/u};
231
234
  const cleanDotBeforeLanguageSubfieldL = {'name': 'pre-language-$l dot', 'followedBy': 'l', 'context': /.\.$/u, 'remove': /\.$/u};
232
235
 
233
236
  const legalEntryField = [cleanDotBeforeLanguageSubfieldL];
@@ -313,8 +316,8 @@ const cleanValidPunctuationRules = {
313
316
  const addToAllEntryFields = [addDotBeforeLanguageSubfieldL, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation, addEntryFieldFinalDot];
314
317
 
315
318
 
316
- const addX00 = [addX00aComma, addX00aComma2, addX00Dot, addX00dComma, ...addToAllEntryFields];
317
- const addX10 = [addX10iColon, addX10bDot, addX10eComma, addX10Dot, ...addToAllEntryFields];
319
+ const addX00 = [addXX0iColon, addX00aComma, addX00aComma2, addX00Dot, addX00dComma, ...addToAllEntryFields];
320
+ const addX10 = [addXX0iColon, addX10bDot, addX10Comma, addX10Dot, ...addToAllEntryFields];
318
321
  const addX11 = [...addToAllEntryFields, addX11Spacecolon];
319
322
  const addX30 = [...addToAllEntryFields];
320
323
 
@@ -396,19 +399,19 @@ const addPairedPunctuationRules = {
396
399
 
397
400
  /*
398
401
  function debugRule(rule) {
399
- //nvdebug('');
400
- nvdebug(`NAME ${rule.name ? rule.name : '<unnamed>'}`);
401
- nvdebug(`SUBFIELD CODE '${rule.code}' FOLLOWED BY SUBFIELD CODE '${rule.followedBy}'`);
402
+ //nvdebug('', debugDev);
403
+ nvdebug(`NAME ${rule.name ? rule.name : '<unnamed>'}`, debugDev);
404
+ nvdebug(`SUBFIELD CODE '${rule.code}' FOLLOWED BY SUBFIELD CODE '${rule.followedBy}'`, debugDev);
402
405
  if ('add' in rule) {
403
- nvdebug(`ADD '${rule.add}'`);
406
+ nvdebug(`ADD '${rule.add}'`, debugDev);
404
407
  }
405
408
  if ('remove' in rule) {
406
- nvdebug(`REMOVE '${rule.remove}'`);
409
+ nvdebug(`REMOVE '${rule.remove}'`, debugDev);
407
410
  }
408
411
  if ('context' in rule) {
409
- nvdebug(`CONTEXT '${rule.context.toString()}'`);
412
+ nvdebug(`CONTEXT '${rule.context.toString()}'`, debugDev);
410
413
  }
411
- //nvdebug('');
414
+ //nvdebug('', debugDev);
412
415
  }
413
416
  */
414
417
 
@@ -440,19 +443,19 @@ function ruleAppliesToField(rule, field) {
440
443
 
441
444
 
442
445
  function ruleAppliesToCurrentSubfield(rule, subfield) {
443
- //nvdebug(` Apply rule on LHS?`);
446
+ //nvdebug(` Apply rule on LHS?`, debugDev);
444
447
  if (!ruleAppliesToSubfieldCode(rule.code, subfield.code)) {
445
- //nvdebug(` Reject rule!`);
448
+ //nvdebug(` Reject rule!`, debugDev);
446
449
  return false;
447
450
  }
448
451
  if ('context' in rule) {
449
- //nvdebug(` Check '${subfield.value}' versus '${rule.context.toString()}'`);
452
+ //nvdebug(` Check '${subfield.value}' versus '${rule.context.toString()}'`, debugDev);
450
453
  if (!subfield.value.match(rule.context)) { // njsscan-ignore: regex_injection_dos
451
- //nvdebug(` Reject rule!`);
454
+ //nvdebug(` Reject rule!`, debugDev);
452
455
  return false;
453
456
  }
454
457
  }
455
- //nvdebug(` Apply rule!`);
458
+ //nvdebug(` Apply rule!`, debugDev);
456
459
  return true;
457
460
  }
458
461
 
@@ -480,23 +483,24 @@ function ruleAppliesToNextSubfield(rule, nextSubfield) {
480
483
 
481
484
  function checkRule(rule, field, subfield1, subfield2) {
482
485
  if (!ruleAppliesToField(rule, field)) {
483
- //nvdebug(`FAIL ON WHOLE FIELD: '${fieldToString(field)}`);
486
+ //nvdebug(`FAIL ON WHOLE FIELD: '${fieldToString(field)}`, debugDev);
484
487
  return false;
485
488
  }
486
489
  //const name = rule.name || 'UNNAMED';
487
490
  if (!ruleAppliesToCurrentSubfield(rule, subfield1)) {
488
- //nvdebug(`${name}: FAIL ON LHS SUBFIELD: '$${subfield1.code} ${subfield1.value}', SF=${rule.code}`, debug);
491
+ //nvdebug(`${name}: FAIL ON LHS SUBFIELD: '$${subfield1.code} ${subfield1.value}', SF=${rule.code}`, debugDev);
489
492
  return false;
490
493
  }
491
494
 
492
495
  // NB! This is not a perfect solution. We might have $e$0$e where $e$0 punctuation should actually be based on $e$e rules
493
496
  if (!ruleAppliesToNextSubfield(rule, subfield2)) {
494
497
  //const msg = subfield2 ? `${name}: FAIL ON RHS SUBFIELD '${subfield2.code}' not in [${rule.followedBy}]` : `${name}: FAIL ON RHS FIELD`;
495
- //nvdebug(msg, debug);
498
+ //nvdebug(msg, debugDev);
496
499
  return false;
497
500
  }
498
501
 
499
- //nvdebug(`${rule.name ? rule.name : '<unnamed>'}: ACCEPT ${rule.code} (${subfield1.code}), SF2=${rule.followedBy} (${subfield2 ? subfield2.code : '#'})`, debug);
502
+
503
+ //nvdebug(`${rule.name ? rule.name : '<unnamed>'}: ACCEPT ${rule.code} (${subfield1.code}), SF2=${rule.followedBy} (${subfield2 ? subfield2.code : '#'})`, debugDev);
500
504
  return true;
501
505
  }
502
506
 
@@ -513,9 +517,9 @@ function applyPunctuationRules(field, subfield1, subfield2, ruleArray = null, op
513
517
  return;
514
518
  }
515
519
 
516
- //nvdebug(`PUNCTUATE ${field.tag}/${tag2} '${subfieldToString(subfield1)}' XXX '${subfield2 ? subfieldToString(subfield2) : '#'} }`);
520
+ //nvdebug(`PUNCTUATE ${field.tag}/${tag2} '${subfieldToString(subfield1)}' XXX '${subfield2 ? subfieldToString(subfield2) : '#'} }`, debugDev);
517
521
 
518
- //nvdebug(`OP=${operation} ${tag2}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`);
522
+ //nvdebug(`OP=${operation} ${tag2}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`, debugDev);
519
523
  const candRules = ruleArray[tag2];
520
524
  candRules.every(rule => { // uses "every", not "forEach", so that only one rule is applies to the given subfields
521
525
  //debugRule(rule);
@@ -525,20 +529,20 @@ function applyPunctuationRules(field, subfield1, subfield2, ruleArray = null, op
525
529
 
526
530
  //const originalValue = subfield1.value;
527
531
  if (rule.remove && [REMOVE, REMOVE_AND_ADD].includes(operation) && subfield1.value.match(rule.remove)) {
528
- //nvdebug(` PUNC REMOVAL TO BE PERFORMED FOR $${subfield1.code} '${subfield1.value}'`, debug);
532
+ //nvdebug(` PUNC REMOVAL TO BE PERFORMED FOR $${subfield1.code} '${subfield1.value}'`, debugDev);
529
533
  subfield1.value = subfield1.value.replace(rule.remove, '');
530
- //nvdebug(` PUNC REMOVAL PERFORMED FOR '${subfield1.value}'`);
534
+ //nvdebug(` PUNC REMOVAL PERFORMED FOR '${subfield1.value}'`, debugDev);
531
535
  return false;
532
536
  }
533
537
  if (rule.add && [ADD, REMOVE_AND_ADD].includes(operation)) {
534
538
  subfield1.value += rule.add;
535
- //nvdebug(` ADDED '${rule.add}' TO FORM '${subfield1.value}' USING RULE ${rule.name}`);
539
+ //nvdebug(` ADDED '${rule.add}' TO FORM '${subfield1.value}' USING RULE ${rule.name}`, debugDev);
536
540
  return false;
537
541
  }
538
542
 
539
543
  /*
540
544
  if (subfield1.value !== originalValue) {
541
- nvdebug(` PROCESS PUNC: '‡${subfield1.code} ${originalValue}' => '‡${subfield1.code} ${subfield1.value}'`, debug);
545
+ nvdebug(` PROCESS PUNC: '‡${subfield1.code} ${originalValue}' => '‡${subfield1.code} ${subfield1.value}'`, debugDev);
542
546
  }
543
547
  */
544
548
 
@@ -552,11 +556,11 @@ function subfieldFixPunctuation(field, subfield1, subfield2) {
552
556
  }
553
557
 
554
558
  function subfieldStripPunctuation(field, subfield1, subfield2) {
555
- //nvdebug(`FSP1: '${subfield1.value}'`);
559
+ //nvdebug(`FSP1: '${subfield1.value}'`, debugDev);
556
560
  applyPunctuationRules(field, subfield1, subfield2, cleanValidPunctuationRules, REMOVE);
557
- //nvdebug(`FSP2: '${subfield1.value}'`);
561
+ //nvdebug(`FSP2: '${subfield1.value}'`, debugDev);
558
562
  applyPunctuationRules(field, subfield1, subfield2, cleanCrappyPunctuationRules, REMOVE);
559
- //nvdebug(`FSP3: '${subfield1.value}'`);
563
+ //nvdebug(`FSP3: '${subfield1.value}'`, debugDev);
560
564
 
561
565
  }
562
566
 
@@ -578,7 +582,7 @@ export function fieldFixPunctuation(field) {
578
582
  if (!field.subfields) {
579
583
  return field;
580
584
  }
581
- //nvdebug(`################### fieldFixPunctuation() TEST ${fieldToString(field)}`);
585
+ //nvdebug(`################### fieldFixPunctuation() TEST ${fieldToString(field)}`, debugDev);
582
586
 
583
587
  field.subfields.forEach((sf, i) => {
584
588
  // NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './punctuation2.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/punctuation2:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2: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');
@@ -7,6 +7,8 @@ import {fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, fiel
7
7
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
8
8
 
9
9
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:reindexSubfield6OccurrenceNumbers');
10
+ //const debugData = debug.extend('data');
11
+ const debugDev = debug.extend('dev');
10
12
 
11
13
 
12
14
  // NB! This validator/fixer has two functionalities:
@@ -20,7 +22,7 @@ export default function () {
20
22
  };
21
23
 
22
24
  function fix(record) {
23
- nvdebug('Fix SF6 occurrence numbers', debug);
25
+ nvdebug('Fix SF6 occurrence numbers', debugDev);
24
26
  const res = {message: [], fix: [], valid: true};
25
27
  //message.fix = [];
26
28
 
@@ -36,13 +38,13 @@ export default function () {
36
38
  function validate(record) {
37
39
  const res = {message: []};
38
40
 
39
- nvdebug('Validate SF6 occurrence number multiuses', debug);
41
+ nvdebug('Validate SF6 occurrence number multiuses', debugDev);
40
42
  if (recordGetSharedOccurrenceNumbers(record).length) {
41
43
  res.message.push(`Multi-use of occurrence number(s) detected`);
42
44
  }
43
45
 
44
46
  // Check max, and check number of different indexes
45
- nvdebug('Validate SF6 occurrence number (max vs n instances)', debug);
47
+ nvdebug('Validate SF6 occurrence number (max vs n instances)', debugDev);
46
48
  const max = recordGetMaxSubfield6OccurrenceNumberAsInteger(record);
47
49
  const size = recordGetNumberOfUniqueSubfield6OccurrenceNumbers(record);
48
50
 
@@ -90,7 +92,7 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
90
92
  if (sharedOccurrenceNumberFields.length < 2) {
91
93
  return;
92
94
  }
93
- nvdebug(`Disambiguate occurrence numbers (N=${sharedOccurrenceNumberFields.length}) in...`, debug);
95
+ nvdebug(`Disambiguate occurrence numbers (N=${sharedOccurrenceNumberFields.length}) in...`, debugDev);
94
96
  sharedOccurrenceNumberFields.forEach(field => disambiguateOccurrenceNumber(field));
95
97
 
96
98
  function disambiguateable(field) {
@@ -98,20 +100,20 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
98
100
  return false;
99
101
  }
100
102
  const occurrenceNumber = fieldGetUnambiguousOccurrenceNumber(field);
101
- nvdebug(` Trying to disambiguate ${occurrenceNumber} in '${fieldToString(field)}`);
103
+ nvdebug(` Trying to disambiguate ${occurrenceNumber} in '${fieldToString(field)}`, debugDev);
102
104
  if (occurrenceNumber === undefined) {
103
105
  return false;
104
106
  }
105
107
  const allRelevantFields = getPotentialSharedOccurrenceNumberFields(occurrenceNumber, sharedOccurrenceNumberFields);
106
108
  if (allRelevantFields.length < 2) {
107
- nvdebug(` Currently only ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. No action required.`);
109
+ nvdebug(` Currently only ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. No action required.`, debugDev);
108
110
  return false;
109
111
  }
110
- nvdebug(` Currently ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. ACTION REQUIRED!`);
112
+ nvdebug(` Currently ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. ACTION REQUIRED!`, debugDev);
111
113
  const relevantFieldsWithCurrFieldTag = allRelevantFields.filter(candField => field.tag === candField.tag);
112
114
 
113
115
  if (relevantFieldsWithCurrFieldTag.length !== 1) {
114
- nvdebug(` Number of them using tag ${field.tag} is ${relevantFieldsWithCurrFieldTag.length}. Can not disambiguate!`);
116
+ nvdebug(` Number of them using tag ${field.tag} is ${relevantFieldsWithCurrFieldTag.length}. Can not disambiguate!`, debugDev);
115
117
  return false;
116
118
  }
117
119
 
@@ -128,7 +130,7 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
128
130
  const newOccurrenceNumber = intToOccurrenceNumberString(newOccurrenceNumberAsInt);
129
131
  const pairedFields = fieldGetOccurrenceNumberPairs(field, record.fields);
130
132
 
131
- nvdebug(` Reindex '${fieldToString(field)}' occurrence number and it's ${pairedFields.length} pair(s) using '${newOccurrenceNumber}'`, debug);
133
+ nvdebug(` Reindex '${fieldToString(field)}' occurrence number and it's ${pairedFields.length} pair(s) using '${newOccurrenceNumber}'`, debugDev);
132
134
 
133
135
  fieldResetOccurrenceNumber(field, newOccurrenceNumber, occurrenceNumber);
134
136
  pairedFields.forEach(pairedField => fieldResetOccurrenceNumber(pairedField, newOccurrenceNumber, occurrenceNumber));
@@ -172,7 +174,7 @@ export function recordResetSubfield6OccurrenceNumbers(record) { // Remove gaps
172
174
  record.fields.forEach(field => fieldResetSubfield6(field));
173
175
 
174
176
  function fieldResetSubfield6(field) {
175
- nvdebug(`fieldResetSubfield6(${fieldToString(field)}), CURR:${currentInt}`, debug);
177
+ nvdebug(`fieldResetSubfield6(${fieldToString(field)}), CURR:${currentInt}`, debugDev);
176
178
  if (!field.subfields) {
177
179
  return;
178
180
  }
@@ -189,7 +191,7 @@ export function recordResetSubfield6OccurrenceNumbers(record) { // Remove gaps
189
191
  }
190
192
 
191
193
  const newIndex = mapCurrIndexToNewIndex(currIndex);
192
- //nvdebug(`subfieldReset6(${subfieldToString(subfield)}): ${newIndex}`, debug);
194
+ //nvdebug(`subfieldReset6(${subfieldToString(subfield)}): ${newIndex}`, debugDev);
193
195
  subfield6ResetOccurrenceNumber(subfield, newIndex);
194
196
  }
195
197
 
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
3
3
  import validatorFactory from './reindexSubfield6OccurenceNumbers.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/reindexSubfield6OccurrenceNumbers:test');
22
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/reindexSubfield6OccurrenceNumbers: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,85 @@
1
+ /*
2
+ // remove-041-zxx.js
3
+ //
4
+ // https://wiki.helsinki.fi/xwiki/bin/view/rdasovellusohje/RDA-kuvailu%20MARC%2021%20-formaatilla/RDA-sovellusohje/008%20Kontrollikentt%C3%A4/#Hmp.35-37Kieli
5
+ // "008-kielikoodi on sama kuin ensimmäinen 041-kentän a- (tai d-) osakenttä. Poikkeuksen muodostaa koodi zxx:
6
+ // jos tietueen 008ssa on kielikoodi zxx (ei kielellistä sisältöä, esim. soitinmusiikki), tietueessa ei voi olla 041 a- eikä d-osakenttää."
7
+ // Effectively this means, that 'zxx' does not appear in 041!
8
+ // Author(s): Nicholas Volk
9
+ */
10
+
11
+ //import createDebugLogger from 'debug';
12
+ import clone from 'clone';
13
+
14
+ import {fieldToString} from './utils.js';
15
+
16
+ // const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:remove-041-zxx');
17
+
18
+
19
+
20
+
21
+ export default function () {
22
+
23
+ return {
24
+ description: "Remove 'zxx' from f041",
25
+ validate, fix
26
+ };
27
+
28
+ function zxxRemoval041(record, validateMode) {
29
+ const fields041 = record.fields.filter(f => f.tag === '041');
30
+
31
+ return handleZxx(fields041);
32
+
33
+ function handleZxx(fields, result = []) {
34
+ const [currField, ...remainingFields] = fields;
35
+ if ( !currField) {
36
+ return result;
37
+ }
38
+ // Theoretically 'zxx' might mean something in ISO-639-3 or some other language code list:
39
+ if (!currField.subfields || currField.subfields.some(sf => sf.code === '2')) {
40
+ return handleZxx(remainingFields, result);
41
+ }
42
+ // Presumable 'zxx' is bad in any data subfield, not just 'a' and 'd':
43
+ const otherSubfields = currField.subfields.filter(sf => (!sf.code.match(/^[a-z]$/u) || sf.value !== 'zxx'));
44
+ if (otherSubfields.length === currField.subfields.length) {
45
+ return handleZxx(remainingFields, result);
46
+ }
47
+ const originalString = fieldToString(currField);
48
+ if (otherSubfields.length === 0) {
49
+ const message = `Remove '${originalString}'`;
50
+ if (!validateMode) {
51
+ record.removeField(currField);
52
+ }
53
+ return handleZxx(remainingFields, [...result, message]);
54
+ }
55
+ // Some subfields are removed:
56
+ if (validateMode) {
57
+ // NB! In validation field is not really deleted, and the non-deleted field might trigger other fixes (than won't be done to a deleted field) later on
58
+ const clonedField = clone(currField);
59
+ clonedField.subfields = otherSubfields;
60
+ const modifiedString = fieldToString(clonedField);
61
+ const message = `Modify '${originalString}' => '${modifiedString}`;
62
+ return handleZxx(remainingFields, [...result, message]);
63
+ }
64
+ currField.subfields = otherSubfields;
65
+ const modifiedString = fieldToString(currField);
66
+ const message = `Modify '${originalString}' => '${modifiedString}`;
67
+ return handleZxx(remainingFields, [...result, message]);
68
+ }
69
+ }
70
+
71
+ function fix(record, validateMode = false) {
72
+ const messages = zxxRemoval041(record, validateMode);
73
+
74
+ if (validateMode) {
75
+ return {message: messages, valid: messages.length === 0};
76
+ }
77
+ return {message: [], fix: messages, valid: true};
78
+ }
79
+
80
+
81
+ function validate(record) {
82
+ return fix(record, true);
83
+ }
84
+ }
85
+
@@ -0,0 +1,52 @@
1
+ import assert from 'node:assert/strict';
2
+ //import createDebugLogger from 'debug';
3
+
4
+ import validatorFactory from './remove-041-zxx.js';
5
+
6
+ import {MarcRecord} from '@natlibfi/marc-record';
7
+ import {READERS} from '@natlibfi/fixura';
8
+ import generateTests from '@natlibfi/fixugen';
9
+
10
+ generateTests({
11
+ callback,
12
+ path: [import.meta.dirname, '..', 'test-fixtures', 'remove-041-zxx'],
13
+ useMetadataFile: true,
14
+ recurse: false,
15
+ fixura: {
16
+ reader: READERS.JSON
17
+ },
18
+ hooks: {
19
+ before: async () => {
20
+ testValidatorFactory();
21
+ }
22
+ }
23
+ });
24
+
25
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/drop-terms:test');
26
+
27
+ async function testValidatorFactory() {
28
+ const validator = await validatorFactory();
29
+
30
+ assert.equal(typeof validator, 'object');
31
+ assert.equal(typeof validator.description, 'string');
32
+ assert.equal(typeof validator.validate, 'function');
33
+ }
34
+
35
+ async function callback({getFixture, fix = false}) {
36
+ const validator = await validatorFactory();
37
+ const record = new MarcRecord(getFixture('record.json'));
38
+ const expectedResult = getFixture('expectedResult.json');
39
+ //const expectedResult = new MarcRecord(getFixture('expectedResult.json'));
40
+ // console.log(expectedResult); // eslint-disable-line
41
+
42
+ if (!fix) {
43
+ const result = await validator.validate(record);
44
+ assert.deepEqual(result, expectedResult);
45
+ const originalRecord = new MarcRecord(getFixture('record.json'));
46
+ assert.deepEqual(record, originalRecord); // Validation should not change the record
47
+ return;
48
+ }
49
+
50
+ await validator.fix(record);
51
+ assert.deepEqual(record, new MarcRecord(expectedResult));
52
+ }