@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
@@ -197,7 +197,7 @@ export function scoreRelatorTerm(value, typeOfMaterial = void 0) {
197
197
  return 0;
198
198
  }
199
199
  export function fieldOrderComparator(fieldA, fieldB) {
200
- const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortBySubfield6, preferFenniKeep, sortByFieldLinkAndSequenceNumber];
200
+ const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortBySubfield6, preferFenniKeep, sortByFieldLinkAndSequenceNumber, sortByHacks];
201
201
  return globalFieldOrderComparator(fieldA, fieldB, sorterFunctions);
202
202
  }
203
203
  function sortByIndexTerms(fieldA, fieldB) {
@@ -335,6 +335,21 @@ function sortByFieldLinkAndSequenceNumber(fieldA, fieldB) {
335
335
  }
336
336
  return -1;
337
337
  }
338
+ function sortByHacks(fieldA, fieldB) {
339
+ if (fieldA.tag === fieldB.tag) {
340
+ if (fieldA.tag === "041") {
341
+ const a2 = fieldA.subfields.some((sf) => sf.code === "2");
342
+ const b2 = fieldB.subfields.some((sf) => sf.code === "2");
343
+ if (a2 && !b2) {
344
+ return 1;
345
+ }
346
+ if (b2 && !a2) {
347
+ return -1;
348
+ }
349
+ }
350
+ }
351
+ return 0;
352
+ }
338
353
  function sortBySubfield6(fieldA, fieldB) {
339
354
  if (fieldA.tag !== "880" || fieldB.tag !== "880") {
340
355
  return 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sortFields.js"],
4
- "sourcesContent": ["// Taken from project marc-record-js, file marcSortFields.js as this contains more and more Melinda-specific rules.\n\nimport clone from 'clone';\n//import createDebugLogger from 'debug';\nimport {fieldHasSubfield, fieldToString} from './utils.js';\nimport {sortByTag, sortAlphabetically, fieldOrderComparator as globalFieldOrderComparator} from '@natlibfi/marc-record/dist/marcFieldSort.js';\nimport {isValidSubfield8} from './subfield8Utils.js';\nimport {fieldGetUnambiguousOccurrenceNumber, fieldGetUnambiguousTag} from './subfield6Utils.js';\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:sortFields');\n//const debugData = debug.extend('data');\n//const debugDev = debug.extend('dev');\n\nconst BIG_BAD_NUMBER = 999999999;\nexport default function () {\n\n return {\n description: 'Sort fields using both generic and Melinda specific rules',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n record.fields.sort(fieldOrderComparator);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n const fields = record.fields.map(f => clone(f));\n fields.sort(fieldOrderComparator);\n\n\n const relocatedFields = fields.filter((f, i) => fieldToString(f) !== fieldToString(record.fields[i]));\n\n if (relocatedFields.length > 0) {\n res.message.push(`${relocatedFields.length} field(s) in new places`);\n }\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n}\n\n\nconst relatorTermScore = { // Here bigger is better\n // NB! This is exportable as field internal $e sorting in marc-record-validators-js uses this.\n // NB! The more abstract, the earlier it appears.\n // Note that terms with same abstraction level might also have order preferences\n // We should 1) check the order of these, and 2) add translations (support Swedish at the very least)\n // work/teos > expression/ekspressio > manifestation/manifestaatin,\n // Work https://finto.fi/mts/fi/page/m1298\n 's\u00E4velt\u00E4j\u00E4': 100, 'composer': 100,\n 'kirjoittaja': 100, 'author': 100,\n 'libretisti': 100,\n 'sarjakuvantekij\u00E4': 100, 'soitonoppaan tekij\u00E4': 100,\n 'kartantekij\u00E4': 99,\n 'taiteilija': 98,\n 'designer': 90,\n 'sanoittaja': 90,\n 'k\u00E4sikirjoittaja': 90,\n\n 'kuvaaja': 89, 'valokuvaaja': 89,\n 'kokoaja': 86,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 84, 'gratulaation kohde': 84,\n 'julkaisija': 82,\n 'tuottaja': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'sovittaja': 79, 'arranger': 79,\n 'toimittaja': 78, 'editor': 78,\n 'kuvittaja': 77,\n 'esipuheen kirjoittaja': 76,\n 'alkusanojen kirjoittaja': 75, 'loppusanojen kirjoittaja': 75,\n\n 'esitt\u00E4j\u00E4': 74,\n 'johtaja': 73, // orkesterinjohtaja\n 'editointi': 71, // for music, editor/toimittaja is another thing\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n 'lukija': 61, 'kertoja': 61,\n // Manifestation level: https://finto.fi/mts/fi/page/m491\n 'graafinen suunnittelija': 50,\n 'kustantaja': 41\n // Item level: https://finto.fi/mts/fi/page/m1157\n};\n\nconst relatorTermScoreBk = {\n // https://finto.fi/mts/fi/page/m34 100-81\n 'libretisti': 100, 'sarjakuvantekij\u00E4': 100,\n 'kirjoittaja': 99, 'author': 99, 'soitonoppaan tekij\u00E4': 99,\n 'kuvaaja': 98, 'valokuvaaja': 98,\n 'kokoaja': 86, 'designer': 86,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 84, 'gratulaation kohde': 84,\n 's\u00E4velt\u00E4j\u00E4': 83, // if 300$e has CD etc\n 'sanoittaja': 82,\n 'julkaisija': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'toimittaja': 78,\n 'kuvittaja': 77,\n 'esipuheen kirjoittaja': 76,\n 'alkusanojen kirjoittaja': 75, 'loppusanojen kirjoittaja': 75,\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n 'sovittaja': 50,\n // manifestaatio\n 'graafinen suunnittelija': 40,\n // kappale/item\n 'sitoja': 25,\n 'gratulaation kirjoittaja': 24\n};\n\nconst relatorTermScoreMu = {\n 's\u00E4velt\u00E4j\u00E4': 100,\n 'sanoittaja': 99,\n 'soitonoppaan tekij\u00E4': 98,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'sovittaja': 79,\n 'johtaja': 78,\n 'esitt\u00E4j\u00E4': 77,\n 'lukija': 76,\n 'miksaaja': 75,\n // manifestaatio\n 'esitt\u00E4j\u00E4 (manifestaatio)': 69,\n\n 'graafinen suunnittelija': 50,\n 'valmistaja': 41,\n 'jakaja': 40\n // kappale/item\n\n};\n\nconst relatorTermScoreVm = { // Visual Material\n // Work\n 'ohjaaja': 100,\n 'kirjoittaja': 99, 'author': 99, // Here we assume that film/whatever is based on author's book\n 'k\u00E4sikirjoittaja': 98, 'designer': 98,\n 'kuvaaja': 89,\n 's\u00E4velt\u00E4j\u00E4': 86, // Volatile. John Williams?\n 'alkuper\u00E4isidean luoja': 85,\n 'julkaisija': 82,\n 'tuottaja': 81,\n // Expression\n 'leikkaaja': 80,\n 'sovittaja': 79,\n 'johtaja': 78,\n 'esitt\u00E4j\u00E4': 77,\n 'lukija': 76,\n 'miksaaja': 75,\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n // Manifestation\n 'kaivertaja': 60,\n 'graafinen suunnittelija': 59,\n 'kustantaja': 42,\n 'elokuvan jakelija': 41, 'jakaja': 41\n\n // Item\n};\n\nfunction normalizeValue(value) {\n // Removing last punc char is good enough for our purposes.\n // We don't handle abbreviations here etc.\n // Brackets should not happen either, should they?\n return value.replace(/[.,]$/u, '');\n}\n\nfunction scoreRelatorTermBk(normalizedValue) {\n if (normalizedValue in relatorTermScoreBk) {\n return relatorTermScoreBk[normalizedValue];\n }\n return 0;\n}\n\nfunction scoreRelatorTermMu(normalizedValue) {\n if (normalizedValue in relatorTermScoreMu) {\n return relatorTermScoreMu[normalizedValue];\n }\n return 0;\n}\n\nfunction scoreRelatorTermVm(normalizedValue) {\n if (normalizedValue in relatorTermScoreVm) {\n return relatorTermScoreVm[normalizedValue];\n }\n return 0;\n}\n\nexport function scoreRelatorTerm(value, typeOfMaterial = undefined) {\n // NB! We are currently using type of material only for sorting relator terms, not 7XX fields!!!\n const normalizedValue = normalizeValue(value);\n if (typeOfMaterial === 'BK') { // Books\n return scoreRelatorTermBk(normalizedValue);\n }\n if (typeOfMaterial === 'MU') { // Music (NB: audio books should be BK in this context!)\n return scoreRelatorTermMu(normalizedValue);\n }\n if (typeOfMaterial === 'VM') { // video material\n return scoreRelatorTermVm(normalizedValue);\n }\n if (normalizedValue in relatorTermScore) {\n return relatorTermScore[normalizedValue];\n }\n return 0;\n}\n\nexport function fieldOrderComparator(fieldA, fieldB) {\n\n //const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortByOccurrenceNumber, preferFenniKeep, sortByFieldLinkAndSequenceNumber];\n\n const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortBySubfield6, preferFenniKeep, sortByFieldLinkAndSequenceNumber];\n //const sorterFunctions = [sortByIndexTerms, sortByRelatorTerm, sortByOccurrenceNumber, preferFenniKeep, sortByFieldLinkAndSequenceNumber];\n\n return globalFieldOrderComparator(fieldA, fieldB, sorterFunctions);\n}\n\nfunction sortByIndexTerms(fieldA, fieldB) {\n\n const indexTermFields = ['600', '610', '611', '630', '648', '650', '651', '652', '653', '654', '655', '656', '657', '658', '659', '662'];\n\n function scoreInd2(val) {\n const ind2Score = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 8, '5': 5, '6': 6, '7': 7};\n\n if (val in ind2Score) {\n return ind2Score[val];\n }\n return 9;\n }\n\n // ATM this is not needed.\n // You may need this, if you change compare function order in sorterFunctions\n // istanbul ignore next\n if (fieldA.tag !== fieldB.tag) {\n return 0;\n }\n\n if (!indexTermFields.includes(fieldA.tag)) {\n return 0;\n }\n\n // Puts ind2=4 last\n if (scoreInd2(fieldA.ind2) > scoreInd2(fieldB.ind2)) {\n return 1;\n }\n if (scoreInd2(fieldA.ind2) < scoreInd2(fieldB.ind2)) {\n return -1;\n }\n\n function scoreDictionary(dictionary) {\n const dictionarySortIndex = {\n 'yso/fin': 0,\n 'yso/swe': 1,\n 'yso/eng': 2,\n 'slm/fin': 0.1,\n 'slm/swe': 1.1,\n 'kauno/fin': 2.1,\n 'kauno/swe': 2.2,\n 'kaunokki': 4,\n 'bella': 5\n };\n\n if (dictionary in dictionarySortIndex) {\n return dictionarySortIndex[dictionary];\n }\n return BIG_BAD_NUMBER;\n }\n\n const dictionaryA = selectFirstValue(fieldA, '2');\n const dictionaryB = selectFirstValue(fieldB, '2');\n\n const dictScoreA = scoreDictionary(dictionaryA);\n const dictScoreB = scoreDictionary(dictionaryB);\n // Use priority order for listed dictionaries:\n if (dictScoreA > dictScoreB) {\n return 1;\n }\n if (dictScoreA < dictScoreB) {\n return -1;\n }\n // Unlisted dictionaries: sort $2 value alphabetically:\n //if (dictScoreA === BIG_BAD_NUMBER) {\n if (dictionaryA > dictionaryB) {\n return 1;\n }\n if (dictionaryA < dictionaryB) {\n return -1;\n }\n //}\n return 0;\n}\n\n\nfunction preferKeep(fieldA, fieldB, keepOwner = 'FENNI') {\n const hasKeepA = fieldHasSubfield(fieldA, '9', `${keepOwner}<KEEP>`);\n const hasKeepB = fieldHasSubfield(fieldB, '9', `${keepOwner}<KEEP>`);\n\n if (hasKeepA && !hasKeepB) {\n return -1;\n }\n if (!hasKeepA && hasKeepB) {\n return 1;\n }\n\n return 0;\n}\n\n\nfunction preferFenniKeep(fieldA, fieldB) {\n const fenniPreference = preferKeep(fieldA, fieldB, 'FENNI');\n if (fenniPreference !== 0) {\n return fenniPreference;\n }\n const violaPreference = preferKeep(fieldA, fieldB, 'VIOLA');\n if (violaPreference !== 0) {\n return violaPreference;\n }\n return preferKeep(fieldA, fieldB, 'FIKKA');\n}\n\nfunction sortByRelatorTerm(fieldA, fieldB) {\n //if (!['600', '610', '611', '630', '700', '710', '711', '730', '800', '810', '811', '830'].includes(fieldA.tag)) {\n if (!['700', '710', '711', '730'].includes(fieldA.tag)) {\n return 0;\n }\n\n function fieldGetMaxRelatorTermScore(field) {\n if (!field.subfields) {\n return -2;\n }\n // If field has $t, it's a teos-nimeke-auktoriteetti, and thus meaningless. These should follow all $t-less fields...\n if (fieldHasSubfield(field, 't')) {\n return -2;\n }\n const relatorSubfieldCode = ['611', '711', '811'].includes(field.tag) ? 'j' : 'e';\n const e = field.subfields.filter(sf => sf.code === relatorSubfieldCode);\n if (e.length === 0) { // No $e is still better than having a $t\n return -1;\n }\n const scores = e.map(sf => scoreRelatorTerm(sf.value));\n //debugDev(`RELATOR SCORE FOR '${fieldToString(field)}': ${scores.join(', ')}`);\n return Math.max(...scores);\n }\n\n const scoreA = fieldGetMaxRelatorTermScore(fieldA);\n const scoreB = fieldGetMaxRelatorTermScore(fieldB);\n\n if (scoreA < scoreB) {\n return 1;\n }\n if (scoreA > scoreB) {\n return -1;\n }\n return 0;\n}\n\n\nfunction fieldGetMinLinkAndSequenceNumber(field) {\n if (!field.subfields) {\n return BIG_BAD_NUMBER;\n }\n const relevantSubfields = field.subfields.filter(sf => isValidSubfield8(sf));\n // If val is something like \"1.2\\x\" parseFloat() would give a syntax erro because of hex-like escape sequnce (at least on Chrome). Thus remove tail:\n const scores = relevantSubfields.map(sf => parseFloat(sf.value.replace(/\\\\.*$/u, '')));\n if (scores.length === 0) {\n return BIG_BAD_NUMBER;\n }\n return Math.min(...scores);\n}\n\nfunction sortByFieldLinkAndSequenceNumber(fieldA, fieldB) { // Sort by subfield $8 that is...\n const scoreA = fieldGetMinLinkAndSequenceNumber(fieldA);\n const scoreB = fieldGetMinLinkAndSequenceNumber(fieldB);\n //debugDev(` sf-8-A-score for '${fieldToString(fieldA)}: ${scoreA}`);\n //debugDev(` sf-8-B-score for '${fieldToString(fieldB)}: ${scoreB}`);\n if (scoreA === scoreB) {\n return 0;\n }\n if (scoreB === 0) {\n return 1;\n }\n if (scoreA === 0) {\n return -1;\n }\n if (scoreA > scoreB) { // smaller is better\n return 1;\n }\n return -1;\n}\n\n\nfunction sortBySubfield6(fieldA, fieldB) { // Sort by subfield $6, ex-sortByOccurrenceNumber...\n if (fieldA.tag !== '880' || fieldB.tag !== '880') {\n return 0;\n }\n\n function compareLinkingTags() {\n const tagStringA = fieldGetUnambiguousTag(fieldA);\n const tagStringB = fieldGetUnambiguousTag(fieldB);\n if (tagStringA === tagStringB || !tagStringA || !tagStringB) {\n return 0;\n }\n if (tagStringA > tagStringB) {\n return 1;\n }\n return -1;\n }\n\n function compareOccurrenceNumbers() {\n const stringA = fieldGetUnambiguousOccurrenceNumber(fieldA);\n const stringB = fieldGetUnambiguousOccurrenceNumber(fieldB);\n if (stringA === stringB) { // No action required here\n return 0;\n }\n\n // Handle expections: no occurrence number, occurrence number '00':\n if (!stringB || stringB === '00') {\n if (!stringA || stringA === '00') {\n return 0;\n }\n return -1;\n }\n if (!stringA || stringA === '00') {\n return 1;\n }\n\n // NB! We need compare ints as occurrence number can exceed 99 and be a three-digit value!\n const scoreA = parseInt(stringA, 10);\n const scoreB = parseInt(stringB, 10);\n\n if (scoreA > scoreB) { // smaller is better, thus '00' is the best\n return 1;\n }\n return -1;\n }\n\n const linkingTagComparisonResult = compareLinkingTags();\n if (linkingTagComparisonResult !== 0) {\n return linkingTagComparisonResult;\n }\n\n return compareOccurrenceNumbers();\n}\n\n\nfunction selectFirstValue(field, subcode) {\n return field.subfields\n .filter(subfield => subcode === subfield.code)\n .map(subfield => subfield.value)\n .slice(0, 1);\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Taken from project marc-record-js, file marcSortFields.js as this contains more and more Melinda-specific rules.\n\nimport clone from 'clone';\n//import createDebugLogger from 'debug';\nimport {fieldHasSubfield, fieldToString} from './utils.js';\nimport {sortByTag, sortAlphabetically, fieldOrderComparator as globalFieldOrderComparator} from '@natlibfi/marc-record/dist/marcFieldSort.js';\nimport {isValidSubfield8} from './subfield8Utils.js';\nimport {fieldGetUnambiguousOccurrenceNumber, fieldGetUnambiguousTag} from './subfield6Utils.js';\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:sortFields');\n//const debugData = debug.extend('data');\n//const debugDev = debug.extend('dev');\n\nconst BIG_BAD_NUMBER = 999999999;\nexport default function () {\n\n return {\n description: 'Sort fields using both generic and Melinda specific rules',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n record.fields.sort(fieldOrderComparator);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n const fields = record.fields.map(f => clone(f));\n fields.sort(fieldOrderComparator);\n\n\n const relocatedFields = fields.filter((f, i) => fieldToString(f) !== fieldToString(record.fields[i]));\n\n if (relocatedFields.length > 0) {\n res.message.push(`${relocatedFields.length} field(s) in new places`);\n }\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n}\n\n\nconst relatorTermScore = { // Here bigger is better\n // NB! This is exportable as field internal $e sorting in marc-record-validators-js uses this.\n // NB! The more abstract, the earlier it appears.\n // Note that terms with same abstraction level might also have order preferences\n // We should 1) check the order of these, and 2) add translations (support Swedish at the very least)\n // work/teos > expression/ekspressio > manifestation/manifestaatin,\n // Work https://finto.fi/mts/fi/page/m1298\n 's\u00E4velt\u00E4j\u00E4': 100, 'composer': 100,\n 'kirjoittaja': 100, 'author': 100,\n 'libretisti': 100,\n 'sarjakuvantekij\u00E4': 100, 'soitonoppaan tekij\u00E4': 100,\n 'kartantekij\u00E4': 99,\n 'taiteilija': 98,\n 'designer': 90,\n 'sanoittaja': 90,\n 'k\u00E4sikirjoittaja': 90,\n\n 'kuvaaja': 89, 'valokuvaaja': 89,\n 'kokoaja': 86,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 84, 'gratulaation kohde': 84,\n 'julkaisija': 82,\n 'tuottaja': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'sovittaja': 79, 'arranger': 79,\n 'toimittaja': 78, 'editor': 78,\n 'kuvittaja': 77,\n 'esipuheen kirjoittaja': 76,\n 'alkusanojen kirjoittaja': 75, 'loppusanojen kirjoittaja': 75,\n\n 'esitt\u00E4j\u00E4': 74,\n 'johtaja': 73, // orkesterinjohtaja\n 'editointi': 71, // for music, editor/toimittaja is another thing\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n 'lukija': 61, 'kertoja': 61,\n // Manifestation level: https://finto.fi/mts/fi/page/m491\n 'graafinen suunnittelija': 50,\n 'kustantaja': 41\n // Item level: https://finto.fi/mts/fi/page/m1157\n};\n\nconst relatorTermScoreBk = {\n // https://finto.fi/mts/fi/page/m34 100-81\n 'libretisti': 100, 'sarjakuvantekij\u00E4': 100,\n 'kirjoittaja': 99, 'author': 99, 'soitonoppaan tekij\u00E4': 99,\n 'kuvaaja': 98, 'valokuvaaja': 98,\n 'kokoaja': 86, 'designer': 86,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 84, 'gratulaation kohde': 84,\n 's\u00E4velt\u00E4j\u00E4': 83, // if 300$e has CD etc\n 'sanoittaja': 82,\n 'julkaisija': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'toimittaja': 78,\n 'kuvittaja': 77,\n 'esipuheen kirjoittaja': 76,\n 'alkusanojen kirjoittaja': 75, 'loppusanojen kirjoittaja': 75,\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n 'sovittaja': 50,\n // manifestaatio\n 'graafinen suunnittelija': 40,\n // kappale/item\n 'sitoja': 25,\n 'gratulaation kirjoittaja': 24\n};\n\nconst relatorTermScoreMu = {\n 's\u00E4velt\u00E4j\u00E4': 100,\n 'sanoittaja': 99,\n 'soitonoppaan tekij\u00E4': 98,\n 'alkuper\u00E4isidean luoja': 85,\n 'teoksella kunnioitettu': 81,\n // expression: https://finto.fi/mts/fi/page/m153\n 'sovittaja': 79,\n 'johtaja': 78,\n 'esitt\u00E4j\u00E4': 77,\n 'lukija': 76,\n 'miksaaja': 75,\n // manifestaatio\n 'esitt\u00E4j\u00E4 (manifestaatio)': 69,\n\n 'graafinen suunnittelija': 50,\n 'valmistaja': 41,\n 'jakaja': 40\n // kappale/item\n\n};\n\nconst relatorTermScoreVm = { // Visual Material\n // Work\n 'ohjaaja': 100,\n 'kirjoittaja': 99, 'author': 99, // Here we assume that film/whatever is based on author's book\n 'k\u00E4sikirjoittaja': 98, 'designer': 98,\n 'kuvaaja': 89,\n 's\u00E4velt\u00E4j\u00E4': 86, // Volatile. John Williams?\n 'alkuper\u00E4isidean luoja': 85,\n 'julkaisija': 82,\n 'tuottaja': 81,\n // Expression\n 'leikkaaja': 80,\n 'sovittaja': 79,\n 'johtaja': 78,\n 'esitt\u00E4j\u00E4': 77,\n 'lukija': 76,\n 'miksaaja': 75,\n 'k\u00E4\u00E4nt\u00E4j\u00E4': 70,\n // Manifestation\n 'kaivertaja': 60,\n 'graafinen suunnittelija': 59,\n 'kustantaja': 42,\n 'elokuvan jakelija': 41, 'jakaja': 41\n\n // Item\n};\n\nfunction normalizeValue(value) {\n // Removing last punc char is good enough for our purposes.\n // We don't handle abbreviations here etc.\n // Brackets should not happen either, should they?\n return value.replace(/[.,]$/u, '');\n}\n\nfunction scoreRelatorTermBk(normalizedValue) {\n if (normalizedValue in relatorTermScoreBk) {\n return relatorTermScoreBk[normalizedValue];\n }\n return 0;\n}\n\nfunction scoreRelatorTermMu(normalizedValue) {\n if (normalizedValue in relatorTermScoreMu) {\n return relatorTermScoreMu[normalizedValue];\n }\n return 0;\n}\n\nfunction scoreRelatorTermVm(normalizedValue) {\n if (normalizedValue in relatorTermScoreVm) {\n return relatorTermScoreVm[normalizedValue];\n }\n return 0;\n}\n\nexport function scoreRelatorTerm(value, typeOfMaterial = undefined) {\n // NB! We are currently using type of material only for sorting relator terms, not 7XX fields!!!\n const normalizedValue = normalizeValue(value);\n if (typeOfMaterial === 'BK') { // Books\n return scoreRelatorTermBk(normalizedValue);\n }\n if (typeOfMaterial === 'MU') { // Music (NB: audio books should be BK in this context!)\n return scoreRelatorTermMu(normalizedValue);\n }\n if (typeOfMaterial === 'VM') { // video material\n return scoreRelatorTermVm(normalizedValue);\n }\n if (normalizedValue in relatorTermScore) {\n return relatorTermScore[normalizedValue];\n }\n return 0;\n}\n\nexport function fieldOrderComparator(fieldA, fieldB) {\n\n //const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortByOccurrenceNumber, preferFenniKeep, sortByFieldLinkAndSequenceNumber];\n\n const sorterFunctions = [sortByTag, sortByIndexTerms, sortAlphabetically, sortByRelatorTerm, sortBySubfield6, preferFenniKeep, sortByFieldLinkAndSequenceNumber, sortByHacks];\n //const sorterFunctions = [sortByIndexTerms, sortByRelatorTerm, sortByOccurrenceNumber, preferFenniKeep, sortByFieldLinkAndSequenceNumber];\n\n return globalFieldOrderComparator(fieldA, fieldB, sorterFunctions);\n}\n\nfunction sortByIndexTerms(fieldA, fieldB) {\n\n const indexTermFields = ['600', '610', '611', '630', '648', '650', '651', '652', '653', '654', '655', '656', '657', '658', '659', '662'];\n\n function scoreInd2(val) {\n const ind2Score = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 8, '5': 5, '6': 6, '7': 7};\n\n if (val in ind2Score) {\n return ind2Score[val];\n }\n return 9;\n }\n\n // ATM this is not needed.\n // You may need this, if you change compare function order in sorterFunctions\n // istanbul ignore next\n if (fieldA.tag !== fieldB.tag) {\n return 0;\n }\n\n if (!indexTermFields.includes(fieldA.tag)) {\n return 0;\n }\n\n // Puts ind2=4 last\n if (scoreInd2(fieldA.ind2) > scoreInd2(fieldB.ind2)) {\n return 1;\n }\n if (scoreInd2(fieldA.ind2) < scoreInd2(fieldB.ind2)) {\n return -1;\n }\n\n function scoreDictionary(dictionary) {\n const dictionarySortIndex = {\n 'yso/fin': 0,\n 'yso/swe': 1,\n 'yso/eng': 2,\n 'slm/fin': 0.1,\n 'slm/swe': 1.1,\n 'kauno/fin': 2.1,\n 'kauno/swe': 2.2,\n 'kaunokki': 4,\n 'bella': 5\n };\n\n if (dictionary in dictionarySortIndex) {\n return dictionarySortIndex[dictionary];\n }\n return BIG_BAD_NUMBER;\n }\n\n const dictionaryA = selectFirstValue(fieldA, '2');\n const dictionaryB = selectFirstValue(fieldB, '2');\n\n const dictScoreA = scoreDictionary(dictionaryA);\n const dictScoreB = scoreDictionary(dictionaryB);\n // Use priority order for listed dictionaries:\n if (dictScoreA > dictScoreB) {\n return 1;\n }\n if (dictScoreA < dictScoreB) {\n return -1;\n }\n // Unlisted dictionaries: sort $2 value alphabetically:\n //if (dictScoreA === BIG_BAD_NUMBER) {\n if (dictionaryA > dictionaryB) {\n return 1;\n }\n if (dictionaryA < dictionaryB) {\n return -1;\n }\n //}\n return 0;\n}\n\n\nfunction preferKeep(fieldA, fieldB, keepOwner = 'FENNI') {\n const hasKeepA = fieldHasSubfield(fieldA, '9', `${keepOwner}<KEEP>`);\n const hasKeepB = fieldHasSubfield(fieldB, '9', `${keepOwner}<KEEP>`);\n\n if (hasKeepA && !hasKeepB) {\n return -1;\n }\n if (!hasKeepA && hasKeepB) {\n return 1;\n }\n\n return 0;\n}\n\n\nfunction preferFenniKeep(fieldA, fieldB) {\n const fenniPreference = preferKeep(fieldA, fieldB, 'FENNI');\n if (fenniPreference !== 0) {\n return fenniPreference;\n }\n const violaPreference = preferKeep(fieldA, fieldB, 'VIOLA');\n if (violaPreference !== 0) {\n return violaPreference;\n }\n return preferKeep(fieldA, fieldB, 'FIKKA');\n}\n\nfunction sortByRelatorTerm(fieldA, fieldB) {\n //if (!['600', '610', '611', '630', '700', '710', '711', '730', '800', '810', '811', '830'].includes(fieldA.tag)) {\n if (!['700', '710', '711', '730'].includes(fieldA.tag)) {\n return 0;\n }\n\n function fieldGetMaxRelatorTermScore(field) {\n if (!field.subfields) {\n return -2;\n }\n // If field has $t, it's a teos-nimeke-auktoriteetti, and thus meaningless. These should follow all $t-less fields...\n if (fieldHasSubfield(field, 't')) {\n return -2;\n }\n const relatorSubfieldCode = ['611', '711', '811'].includes(field.tag) ? 'j' : 'e';\n const e = field.subfields.filter(sf => sf.code === relatorSubfieldCode);\n if (e.length === 0) { // No $e is still better than having a $t\n return -1;\n }\n const scores = e.map(sf => scoreRelatorTerm(sf.value));\n //debugDev(`RELATOR SCORE FOR '${fieldToString(field)}': ${scores.join(', ')}`);\n return Math.max(...scores);\n }\n\n const scoreA = fieldGetMaxRelatorTermScore(fieldA);\n const scoreB = fieldGetMaxRelatorTermScore(fieldB);\n\n if (scoreA < scoreB) {\n return 1;\n }\n if (scoreA > scoreB) {\n return -1;\n }\n return 0;\n}\n\n\nfunction fieldGetMinLinkAndSequenceNumber(field) {\n if (!field.subfields) {\n return BIG_BAD_NUMBER;\n }\n const relevantSubfields = field.subfields.filter(sf => isValidSubfield8(sf));\n // If val is something like \"1.2\\x\" parseFloat() would give a syntax erro because of hex-like escape sequnce (at least on Chrome). Thus remove tail:\n const scores = relevantSubfields.map(sf => parseFloat(sf.value.replace(/\\\\.*$/u, '')));\n if (scores.length === 0) {\n return BIG_BAD_NUMBER;\n }\n return Math.min(...scores);\n}\n\nfunction sortByFieldLinkAndSequenceNumber(fieldA, fieldB) { // Sort by subfield $8 that is...\n const scoreA = fieldGetMinLinkAndSequenceNumber(fieldA);\n const scoreB = fieldGetMinLinkAndSequenceNumber(fieldB);\n //debugDev(` sf-8-A-score for '${fieldToString(fieldA)}: ${scoreA}`);\n //debugDev(` sf-8-B-score for '${fieldToString(fieldB)}: ${scoreB}`);\n if (scoreA === scoreB) {\n return 0;\n }\n if (scoreB === 0) {\n return 1;\n }\n if (scoreA === 0) {\n return -1;\n }\n if (scoreA > scoreB) { // smaller is better\n return 1;\n }\n return -1;\n}\n\nfunction sortByHacks(fieldA, fieldB) {\n // Place for various hackier rules\n\n if (fieldA.tag === fieldB.tag) {\n if (fieldA.tag === '041') {\n // If we have multiple f041, we want to put the $2-less first; Values from $2 whatever can not be copied to 008/35-37. (See sync-language.js.)\n const a2 = fieldA.subfields.some(sf => sf.code === '2');\n const b2 = fieldB.subfields.some(sf => sf.code === '2');\n if (a2 && !b2) {\n return 1;\n }\n if (b2 && !a2) {\n return -1;\n }\n }\n\n }\n return 0;\n}\n\nfunction sortBySubfield6(fieldA, fieldB) { // Sort by subfield $6, ex-sortByOccurrenceNumber...\n if (fieldA.tag !== '880' || fieldB.tag !== '880') {\n return 0;\n }\n\n function compareLinkingTags() {\n const tagStringA = fieldGetUnambiguousTag(fieldA);\n const tagStringB = fieldGetUnambiguousTag(fieldB);\n if (tagStringA === tagStringB || !tagStringA || !tagStringB) {\n return 0;\n }\n if (tagStringA > tagStringB) {\n return 1;\n }\n return -1;\n }\n\n function compareOccurrenceNumbers() {\n const stringA = fieldGetUnambiguousOccurrenceNumber(fieldA);\n const stringB = fieldGetUnambiguousOccurrenceNumber(fieldB);\n if (stringA === stringB) { // No action required here\n return 0;\n }\n\n // Handle expections: no occurrence number, occurrence number '00':\n if (!stringB || stringB === '00') {\n if (!stringA || stringA === '00') {\n return 0;\n }\n return -1;\n }\n if (!stringA || stringA === '00') {\n return 1;\n }\n\n // NB! We need compare ints as occurrence number can exceed 99 and be a three-digit value!\n const scoreA = parseInt(stringA, 10);\n const scoreB = parseInt(stringB, 10);\n\n if (scoreA > scoreB) { // smaller is better, thus '00' is the best\n return 1;\n }\n return -1;\n }\n\n const linkingTagComparisonResult = compareLinkingTags();\n if (linkingTagComparisonResult !== 0) {\n return linkingTagComparisonResult;\n }\n\n return compareOccurrenceNumbers();\n}\n\n\nfunction selectFirstValue(field, subcode) {\n return field.subfields\n .filter(subfield => subcode === subfield.code)\n .map(subfield => subfield.value)\n .slice(0, 1);\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,6 @@ import { MarcRecord } from "@natlibfi/marc-record";
3
3
  import validatorFactory from "./sortFields.js";
4
4
  import { READERS } from "@natlibfi/fixura";
5
5
  import generateTests from "@natlibfi/fixugen";
6
- import createDebugLogger from "debug";
7
6
  generateTests({
8
7
  callback,
9
8
  path: [import.meta.dirname, "..", "test-fixtures", "sort-fields"],
@@ -18,18 +17,13 @@ generateTests({
18
17
  }
19
18
  }
20
19
  });
21
- const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/sortFields:test");
22
20
  async function testValidatorFactory() {
23
21
  const validator = await validatorFactory();
24
22
  assert.equal(typeof validator, "object");
25
23
  assert.equal(typeof validator.description, "string");
26
24
  assert.equal(typeof validator.validate, "function");
27
25
  }
28
- async function callback({ getFixture, enabled = true, fix = true }) {
29
- if (enabled === false) {
30
- debug("TEST SKIPPED!");
31
- return;
32
- }
26
+ async function callback({ getFixture, fix = true }) {
33
27
  const validator = await validatorFactory();
34
28
  const record = new MarcRecord(getFixture("input.json"));
35
29
  const expectedResult = getFixture("result.json");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sortFields.test.js"],
4
- "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortFields.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-fields'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortFields:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, enabled = true, fix = true}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('input.json'));\n const expectedResult = getFixture('result.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAC1B,OAAO,uBAAuB;AAE9B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,aAAa;AAAA,EAChE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AACD,MAAM,QAAQ,kBAAkB,0DAA0D;AAE1F,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,UAAU,MAAM,MAAM,KAAI,GAAG;AAChE,MAAI,YAAY,OAAO;AACrB,UAAM,eAAe;AACrB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,YAAY,CAAC;AACtD,QAAM,iBAAiB,WAAW,aAAa;AAG/C,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortFields.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n//import createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-fields'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortFields:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, fix = true}) {\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('input.json'));\n const expectedResult = getFixture('result.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
+ "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAG1B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,aAAa;AAAA,EAChE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAGD,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,MAAM,KAAI,GAAG;AAChD,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,YAAY,CAAC;AACtD,QAAM,iBAAiB,WAAW,aAAa;AAG/C,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,6 @@ import { MarcRecord } from "@natlibfi/marc-record";
3
3
  import validatorFactory from "./sortRelatorTerms.js";
4
4
  import { READERS } from "@natlibfi/fixura";
5
5
  import generateTests from "@natlibfi/fixugen";
6
- import createDebugLogger from "debug";
7
6
  generateTests({
8
7
  callback,
9
8
  path: [import.meta.dirname, "..", "test-fixtures", "sort-relator-terms"],
@@ -18,18 +17,13 @@ generateTests({
18
17
  }
19
18
  }
20
19
  });
21
- const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/sortRelatorTerms:test");
22
20
  async function testValidatorFactory() {
23
21
  const validator = await validatorFactory();
24
22
  assert.equal(typeof validator, object);
25
23
  assert.equal(typeof validator.description, "string");
26
24
  assert.equal(typeof validator.validate, "function");
27
25
  }
28
- async function callback({ getFixture, enabled = true, fix = false }) {
29
- if (enabled === false) {
30
- debug("TEST SKIPPED!");
31
- return;
32
- }
26
+ async function callback({ getFixture, fix = false }) {
33
27
  const validator = await validatorFactory();
34
28
  const record = new MarcRecord(getFixture("record.json"));
35
29
  const expectedResult = getFixture("expectedResult.json");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sortRelatorTerms.test.js"],
4
- "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortRelatorTerms.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-relator-terms'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortRelatorTerms:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, object);\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, enabled = true, fix = false}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAC1B,OAAO,uBAAuB;AAE9B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,oBAAoB;AAAA,EACvE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAED,MAAM,QAAQ,kBAAkB,gEAAgE;AAEhG,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,MAAM;AACrC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,UAAU,MAAM,MAAM,MAAK,GAAG;AACjE,MAAI,YAAY,OAAO;AACrB,UAAM,eAAe;AACrB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortRelatorTerms.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n//import createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-relator-terms'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortRelatorTerms:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, object);\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, fix = false}) {\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
+ "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAG1B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,oBAAoB;AAAA,EACvE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAID,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,MAAM;AACrC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,MAAM,MAAK,GAAG;AACjD,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
6
6
  "names": []
7
7
  }
@@ -3,8 +3,8 @@ import createDebugLogger from "debug";
3
3
  import { fieldToString, nvdebug } from "./utils.js";
4
4
  const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:sortSubfields");
5
5
  const debugDev = debug.extend("dev");
6
- const defaultSortOrderStringFinns = "8673abcdefghijklmnopqrstuvwxyz420159";
7
- const defaultSortOrderStringOthers = "8673abcdefghijklmnopqrstuvwxyz402159";
6
+ const defaultSortOrderStringFinns = "863abcdefghijklmnopqrstuvwxyz4201759";
7
+ const defaultSortOrderStringOthers = "863abcdefghijklmnopqrstuvwxyz4021759";
8
8
  const defaultSortOrderFinns = defaultSortOrderStringFinns.split("");
9
9
  const defaultSortOrderOthers = defaultSortOrderStringOthers.split("");
10
10
  export default function(defaultTagPattern) {
@@ -48,7 +48,7 @@ export default function(defaultTagPattern) {
48
48
  const sortOrderForX00 = ["i", "a", "b", "q", "c", "d", "e", "t", "u", "l", "f", "x", "y", "z", "0", "1", "5", "9"];
49
49
  const sortOrderForX10 = ["i", "a", "b", "t", "n", "c", "e", "v", "w", "x", "y", "z", "0", "1", "5", "9"];
50
50
  const sortOrderForX11 = ["a", "n", "d", "c", "e", "g", "j", "0", "1", "5", "9"];
51
- const sortOrderFor7XX = ["8", "7", "i", "a", "s", "t", "b", "c", "d", "m", "h", "k", "o", "x", "z", "g", "q", "w"];
51
+ const sortOrderFor7XXLinkingEntries = ["8", "7", "i", "a", "s", "t", "b", "c", "d", "m", "h", "k", "o", "x", "z", "g", "q", "w", "0", "1", "l", "9", "5"];
52
52
  const sortOrderFor246 = ["i", "a", "b", "n", "p", "f", "5", "9"];
53
53
  const subfieldSortOrder = [
54
54
  { "tag": "017", "sortOrder": ["i", "a", "b", "d"] },
@@ -56,7 +56,11 @@ const subfieldSortOrder = [
56
56
  // National convention
57
57
  //{'tag': '031', 'sortOrder': ['a', 'b', 'c', 'm', 'e', 'd']}, // utter guesswork
58
58
  { "tag": "040", "sortOrder": ["8", "a", "b", "e", "c", "d", "x"] },
59
- { "tag": "041", "sortOrder": ["8", "a", "d", "j", "p", "h", "e", "g", "m"] },
59
+ // rda mus: 041: k < h < e < n < g < m < j (I think h<e is bad)
60
+ // rda: g < h, j < p < h, i < j, k < h
61
+ // loc: b < j, $m follows $b or $g
62
+ // NV: $a
63
+ { "tag": "041", "sortOrder": ["8", "a", "d", "e", "b", "f", "i", "j", "p", "k", "h", "n", "g", "m"] },
60
64
  // guesswork
61
65
  { "tag": "048", "sortOrder": ["8", "b", "a"] },
62
66
  { "tag": "100", "sortOrder": sortOrderForX00 },
@@ -81,22 +85,22 @@ const subfieldSortOrder = [
81
85
  { "tag": "700", "sortOrder": sortOrderForX00 },
82
86
  { "tag": "710", "sortOrder": sortOrderForX10 },
83
87
  { "tag": "711", "sortOrder": sortOrderForX11 },
84
- { "tag": "760", "sortOrder": sortOrderFor7XX },
85
- { "tag": "762", "sortOrder": sortOrderFor7XX },
86
- { "tag": "765", "sortOrder": sortOrderFor7XX },
87
- { "tag": "767", "sortOrder": sortOrderFor7XX },
88
- { "tag": "770", "sortOrder": sortOrderFor7XX },
89
- { "tag": "772", "sortOrder": sortOrderFor7XX },
90
- { "tag": "773", "sortOrder": sortOrderFor7XX },
91
- { "tag": "774", "sortOrder": sortOrderFor7XX },
92
- { "tag": "775", "sortOrder": sortOrderFor7XX },
93
- { "tag": "776", "sortOrder": sortOrderFor7XX },
94
- { "tag": "777", "sortOrder": sortOrderFor7XX },
95
- { "tag": "780", "sortOrder": sortOrderFor7XX },
96
- { "tag": "785", "sortOrder": sortOrderFor7XX },
97
- { "tag": "786", "sortOrder": sortOrderFor7XX },
98
- { "tag": "787", "sortOrder": sortOrderFor7XX },
99
- { "tag": "788", "sortOrder": sortOrderFor7XX },
88
+ { "tag": "760", "sortOrder": sortOrderFor7XXLinkingEntries },
89
+ { "tag": "762", "sortOrder": sortOrderFor7XXLinkingEntries },
90
+ { "tag": "765", "sortOrder": sortOrderFor7XXLinkingEntries },
91
+ { "tag": "767", "sortOrder": sortOrderFor7XXLinkingEntries },
92
+ { "tag": "770", "sortOrder": sortOrderFor7XXLinkingEntries },
93
+ { "tag": "772", "sortOrder": sortOrderFor7XXLinkingEntries },
94
+ { "tag": "773", "sortOrder": sortOrderFor7XXLinkingEntries },
95
+ { "tag": "774", "sortOrder": sortOrderFor7XXLinkingEntries },
96
+ { "tag": "775", "sortOrder": sortOrderFor7XXLinkingEntries },
97
+ { "tag": "776", "sortOrder": sortOrderFor7XXLinkingEntries },
98
+ { "tag": "777", "sortOrder": sortOrderFor7XXLinkingEntries },
99
+ { "tag": "780", "sortOrder": sortOrderFor7XXLinkingEntries },
100
+ { "tag": "785", "sortOrder": sortOrderFor7XXLinkingEntries },
101
+ { "tag": "786", "sortOrder": sortOrderFor7XXLinkingEntries },
102
+ { "tag": "787", "sortOrder": sortOrderFor7XXLinkingEntries },
103
+ { "tag": "788", "sortOrder": sortOrderFor7XXLinkingEntries },
100
104
  { "tag": "800", "sortOrder": sortOrderForX00 },
101
105
  { "tag": "810", "sortOrder": sortOrderForX10 },
102
106
  { "tag": "811", "sortOrder": sortOrderForX11 },
@@ -116,7 +120,9 @@ function getSubfieldSortOrder(field) {
116
120
  debugDev(`sort order for ${field.tag}: ${entry[0].sortOrder}`);
117
121
  return entry[0].sortOrder;
118
122
  }
119
- nvdebug(`WARNING! No subfield order found for ${field.tag}.`);
123
+ if (!["300"].includes(field.tag)) {
124
+ nvdebug(`WARNING! No subfield order found for ${field.tag}.`, debugDev);
125
+ }
120
126
  return [];
121
127
  }
122
128
  function swapSubfields(field, sortOrder) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sortSubfields.js"],
4
- "sourcesContent": ["// Author(s): Nicholas Volk\n\nimport clone from 'clone';\nimport createDebugLogger from 'debug';\nimport {fieldToString, nvdebug} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:sortSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst defaultSortOrderStringFinns = '8673abcdefghijklmnopqrstuvwxyz420159'; // NB! We Finns like $2 before $0 in 6XX...\nconst defaultSortOrderStringOthers = '8673abcdefghijklmnopqrstuvwxyz402159';\n\nconst defaultSortOrderFinns = defaultSortOrderStringFinns.split('');\nconst defaultSortOrderOthers = defaultSortOrderStringOthers.split('');\n\n\nexport default function (defaultTagPattern) {\n\n return {\n description: 'Swap adjacent subfields',\n validate, fix\n };\n\n function getRelevantFields(record, tagPattern) {\n const datafields = record.fields.filter(f => f.subfields);\n if (!tagPattern) {\n return datafields;\n }\n\n const regexp = new RegExp(tagPattern, 'u');\n return datafields.filter(f => regexp.test(f.tag));\n }\n\n function fix(record, tagPattern = defaultTagPattern) {\n const res = {message: [], fix: [], valid: true};\n\n const relevantFields = getRelevantFields(record, tagPattern);\n\n relevantFields.forEach(field => {\n sortAdjacentSubfields(field);\n });\n\n return res;\n }\n\n function validate(record, tagPattern = defaultTagPattern) {\n const res = {message: []};\n\n const relevantFields = getRelevantFields(record, tagPattern);\n\n relevantFields.forEach(field => {\n const clonedField = clone(field);\n sortAdjacentSubfields(clonedField);\n const clonedFieldAsString = fieldToString(clonedField);\n const fieldAsString = fieldToString(field);\n if (fieldAsString !== clonedFieldAsString) {\n res.message.push(clonedFieldAsString);\n }\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n}\n\n\n// X00, X10, X11 and X130 could also for their own sets...\n// (ouch! sometimes $c comes after $d...): LoC: 100 0# \u2021a Black Foot, \u2021c Chief, \u2021d d. 1877 \u2021c (Spirit)\nconst sortOrderForX00 = ['i', 'a', 'b', 'q', 'c', 'd', 'e', 't', 'u', 'l', 'f', 'x', 'y', 'z', '0', '1', '5', '9']; // skip $g. Can't remember why, though...\nconst sortOrderForX10 = ['i', 'a', 'b', 't', 'n', 'c', 'e', 'v', 'w', 'x', 'y', 'z', '0', '1', '5', '9']; // somewhat iffy\nconst sortOrderForX11 = ['a', 'n', 'd', 'c', 'e', 'g', 'j', '0', '1', '5', '9'];\nconst sortOrderFor7XX = ['8', '7', 'i', 'a', 's', 't', 'b', 'c', 'd', 'm', 'h', 'k', 'o', 'x', 'z', 'g', 'q', 'w'];\nconst sortOrderFor246 = ['i', 'a', 'b', 'n', 'p', 'f', '5', '9']; // Used by field 946 as well\n\n// List *only* exceptional order here. Otherwise default order is used.\nconst subfieldSortOrder = [\n {'tag': '017', 'sortOrder': ['i', 'a', 'b', 'd']},\n {'tag': '028', 'sortOrder': ['b', 'a', 'q']}, // National convention\n //{'tag': '031', 'sortOrder': ['a', 'b', 'c', 'm', 'e', 'd']}, // utter guesswork\n {'tag': '040', 'sortOrder': ['8', 'a', 'b', 'e', 'c', 'd', 'x']},\n {'tag': '041', 'sortOrder': ['8', 'a', 'd', 'j', 'p', 'h', 'e', 'g', 'm']}, // guesswork\n {'tag': '048', 'sortOrder': ['8', 'b', 'a']},\n {'tag': '100', 'sortOrder': sortOrderForX00},\n {'tag': '110', 'sortOrder': sortOrderForX10},\n {'tag': '111', 'sortOrder': sortOrderForX11},\n {'tag': '130', 'sortOrder': ['a', 'n', 'p', 'k', 'l']},\n {'tag': '240', 'sortOrder': ['a', 'm', 'n', 'p', 's', 'l', '2', '0', '1', '5', '9']},\n {'tag': '245', 'sortOrder': ['a', 'b', 'n', 'p', 'k', 'f', 'c']},\n {'tag': '246', 'sortOrder': sortOrderFor246},\n {'tag': '382', 'sortOrder': ['a']},\n {'tag': '385', 'sortOrder': ['8', 'm', 'n', 'a', '2', '0', '1']},\n {'tag': '386', 'sortOrder': ['8', 'm', 'n', 'a']},\n {'tag': '490', 'sortOrder': ['a', 'x', 'y', 'v', 'l']},\n {'tag': '505', 'sortOrder': ['a']},\n {'tag': '526', 'sortOrder': ['i', 'a', 'b', 'x', 'z']},\n {'tag': '534', 'sortOrder': ['3', 'p', 'a', 't', 'l', 'c', 'f', 'b', 'e', 'o', 'x', 'z']},\n {'tag': '540', 'sortOrder': ['a', 'b', 'c', 'd', 'f', '2', 'u']},\n {'tag': '600', 'sortOrder': sortOrderForX00},\n {'tag': '610', 'sortOrder': sortOrderForX10},\n {'tag': '611', 'sortOrder': sortOrderForX11},\n {'tag': '650', 'sortOrder': ['a', 'x', 'y', 'z']},\n {'tag': '700', 'sortOrder': sortOrderForX00},\n {'tag': '710', 'sortOrder': sortOrderForX10},\n {'tag': '711', 'sortOrder': sortOrderForX11},\n {'tag': '760', 'sortOrder': sortOrderFor7XX},\n {'tag': '762', 'sortOrder': sortOrderFor7XX},\n {'tag': '765', 'sortOrder': sortOrderFor7XX},\n {'tag': '767', 'sortOrder': sortOrderFor7XX},\n {'tag': '770', 'sortOrder': sortOrderFor7XX},\n {'tag': '772', 'sortOrder': sortOrderFor7XX},\n {'tag': '773', 'sortOrder': sortOrderFor7XX},\n {'tag': '774', 'sortOrder': sortOrderFor7XX},\n {'tag': '775', 'sortOrder': sortOrderFor7XX},\n {'tag': '776', 'sortOrder': sortOrderFor7XX},\n {'tag': '777', 'sortOrder': sortOrderFor7XX},\n {'tag': '780', 'sortOrder': sortOrderFor7XX},\n {'tag': '785', 'sortOrder': sortOrderFor7XX},\n {'tag': '786', 'sortOrder': sortOrderFor7XX},\n {'tag': '787', 'sortOrder': sortOrderFor7XX},\n {'tag': '788', 'sortOrder': sortOrderFor7XX},\n {'tag': '800', 'sortOrder': sortOrderForX00},\n {'tag': '810', 'sortOrder': sortOrderForX10},\n {'tag': '811', 'sortOrder': sortOrderForX11},\n {'tag': '830', 'sortOrder': ['a', 'n', 'x', 'v']}, // INCOMPLETE, SAME AS 490? APPARENTLY NOT...\n {'tag': '856', 'sortOrder': ['3', 'u', 'q', 'x', 'y', 'z', '5']}, // incomplete, LoC examples are inconclusive\n {'tag': '880', 'sortOrder': ['a']},\n {'tag': '946', 'sortOrder': sortOrderFor246},\n {'tag': 'LOW', 'sortOrder': ['a', 'b', 'c', 'l', 'h']},\n {'tag': 'SID', 'sortOrder': ['c', 'b']} // Hack, so that default order is not used\n];\n\nfunction getSubfieldSortOrder(field) {\n const entry = subfieldSortOrder.filter(currEntry => field.tag === currEntry.tag);\n if (entry.length > 0 && 'sortOrder' in entry[0]) {\n debugDev(`sort order for ${field.tag}: ${entry[0].sortOrder}`);\n return entry[0].sortOrder;\n }\n nvdebug(`WARNING!\\tNo subfield order found for ${field.tag}.`);\n return [];\n}\n\n\nfunction swapSubfields(field, sortOrder) {\n if (!field.subfields) {\n return;\n }\n\n const loopAgain = field.subfields.some((sf, index) => {\n if (index === 0) {\n return false;\n }\n const currPos = getPosition(sf, sortOrder);\n const prevPos = getPosition(field.subfields[index - 1], sortOrder);\n if (currPos === -1 || prevPos === -1 || currPos >= prevPos) {\n return false;\n }\n // Swap:\n const tmp = field.subfields[index - 1];\n field.subfields[index - 1] = sf;\n field.subfields[index] = tmp;\n return true;\n });\n\n if (loopAgain) {\n return swapSubfields(field, sortOrder);\n }\n\n return;\n\n function getPosition(subfield, sortOrder) {\n // Magic exception that *always* comes first, used by Aleph in linking overlong fields\n if (sortOrder.indexOf('9') > -1 && subfield.code === '9' && ['^', '^^'].includes(subfield.value)) {\n return -0.5; // normal \"best value\" is 0, and \"worst value\" is N\n }\n return sortOrder.indexOf(subfield.code);\n }\n}\n\n\nfunction twoBeforeZero(field) {\n const sf2 = field.subfields.filter(sf => sf.code === '2');\n if (sf2.length !== 1) {\n return true; // both true and false are ok here\n }\n // MRA-465: gcipplatform (field 753)\n // rdasco (344), creatorbio (353), gbd (668), lsch (eg. 385)\n if (['creatorbio', 'gbd', 'gcipplatform', 'lscsh', 'rdasco'].includes(sf2[0].value)) {\n return false;\n }\n return true;\n}\n\nfunction moveSubfield6ToTheFront(field) {\n // https://www.loc.gov/marc/bibliographic/ecbdcntf.html says \"Subfield $6 is always the first subfield in the field.\"\n const sf6s = field.subfields.filter(sf => sf.code === '6');\n const others = field.subfields.filter(sf => sf.code !== '6');\n field.subfields = [...sf6s, ...others];\n}\n\nexport function sortAdjacentSubfields(field, externalSortOrder = []) {\n if (!field.subfields) {\n return field;\n }\n\n moveSubfield6ToTheFront(field); // specs: \"Subfield $6 is always the first subfield in the field.\"\n\n // Features:\n // - Swap only sort adjacent pairs.\n // - No sorting over unlisted subfield codes. Thus a given subfield can not shift to wrong side of 700$t...\n\n // Implement: 880 field should use values from $6...\n\n // Should we support multiple sort orders per field?\n\n // Try to handle control subfield order. This is not 100% fool proof. Control subfields are pretty stable, though.\n // However, there are exceptions (eg. $9 ^^ comes first and $2 $0 is a Finnish convention...)\n\n\n const finnishWay = twoBeforeZero(field);\n\n // Note: 760-789: '7' comes way earlier (after '6' and '8')\n const controlSubfieldOrder = finnishWay ? ['8', '3', 'a', '4', '2', '0', '1', '7', '5', '9'] : ['8', '7', '3', 'a', '4', '0', '1', '2', '7', '5', '9'];\n swapSubfields(field, controlSubfieldOrder);\n\n const sortOrderForField = externalSortOrder.length > 0 ? externalSortOrder : getSubfieldSortOrder(field);\n //nvdebug(`INTERMEDIATE SUBFIELD ORDER FOR ${field.tag}: ${sortOrderForField.join(', ')}`);\n\n const defaultSortOrder = finnishWay ? defaultSortOrderFinns : defaultSortOrderOthers; // $2 vs $0\n const subfieldOrder = sortOrderForField.length > 0 ? sortOrderForField : defaultSortOrder;\n //nvdebug(`FINAL SUBFIELD ORDER (FINNISH=${finnishWay}) FOR ${field.tag}: ${subfieldOrder.join(', ')}`);\n //if (sortOrder === null) { return field; } //// Currently always sort..\n //nvdebug(`IN: ${fieldToString(field)}`);\n swapSubfields(field, subfieldOrder);\n //nvdebug(`OUT: ${fieldToString(field)}`);\n\n return field;\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Author(s): Nicholas Volk\n\nimport clone from 'clone';\nimport createDebugLogger from 'debug';\nimport {fieldToString, nvdebug} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:sortSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst defaultSortOrderStringFinns = '863abcdefghijklmnopqrstuvwxyz4201759'; // NB! We Finns like $2 before $0 in 6XX...\nconst defaultSortOrderStringOthers = '863abcdefghijklmnopqrstuvwxyz4021759'; // NB 760-788 have '7' in different position...\n\nconst defaultSortOrderFinns = defaultSortOrderStringFinns.split('');\nconst defaultSortOrderOthers = defaultSortOrderStringOthers.split('');\n\n\nexport default function (defaultTagPattern) {\n\n return {\n description: 'Swap adjacent subfields',\n validate, fix\n };\n\n function getRelevantFields(record, tagPattern) {\n const datafields = record.fields.filter(f => f.subfields);\n if (!tagPattern) {\n return datafields;\n }\n\n const regexp = new RegExp(tagPattern, 'u');\n return datafields.filter(f => regexp.test(f.tag));\n }\n\n function fix(record, tagPattern = defaultTagPattern) {\n const res = {message: [], fix: [], valid: true};\n\n const relevantFields = getRelevantFields(record, tagPattern);\n\n relevantFields.forEach(field => {\n sortAdjacentSubfields(field);\n });\n\n return res;\n }\n\n function validate(record, tagPattern = defaultTagPattern) {\n const res = {message: []};\n\n const relevantFields = getRelevantFields(record, tagPattern);\n\n relevantFields.forEach(field => {\n const clonedField = clone(field);\n sortAdjacentSubfields(clonedField);\n const clonedFieldAsString = fieldToString(clonedField);\n const fieldAsString = fieldToString(field);\n if (fieldAsString !== clonedFieldAsString) {\n res.message.push(clonedFieldAsString);\n }\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n}\n\n\n// X00, X10, X11 and X130 could also for their own sets...\n// (ouch! sometimes $c comes after $d...): LoC: 100 0# \u2021a Black Foot, \u2021c Chief, \u2021d d. 1877 \u2021c (Spirit)\nconst sortOrderForX00 = ['i', 'a', 'b', 'q', 'c', 'd', 'e', 't', 'u', 'l', 'f', 'x', 'y', 'z', '0', '1', '5', '9']; // skip $g. Can't remember why, though...\nconst sortOrderForX10 = ['i', 'a', 'b', 't', 'n', 'c', 'e', 'v', 'w', 'x', 'y', 'z', '0', '1', '5', '9']; // somewhat iffy\nconst sortOrderForX11 = ['a', 'n', 'd', 'c', 'e', 'g', 'j', '0', '1', '5', '9'];\nconst sortOrderFor7XXLinkingEntries = ['8', '7', 'i', 'a', 's', 't', 'b', 'c', 'd', 'm', 'h', 'k', 'o', 'x', 'z', 'g', 'q', 'w', '0', '1', 'l', '9', '5'];\nconst sortOrderFor246 = ['i', 'a', 'b', 'n', 'p', 'f', '5', '9']; // Used by field 946 as well\n\n// List *only* exceptional order here. Otherwise default order is used.\nconst subfieldSortOrder = [\n {'tag': '017', 'sortOrder': ['i', 'a', 'b', 'd']},\n {'tag': '028', 'sortOrder': ['b', 'a', 'q']}, // National convention\n //{'tag': '031', 'sortOrder': ['a', 'b', 'c', 'm', 'e', 'd']}, // utter guesswork\n {'tag': '040', 'sortOrder': ['8', 'a', 'b', 'e', 'c', 'd', 'x']},\n // rda mus: 041: k < h < e < n < g < m < j (I think h<e is bad)\n // rda: g < h, j < p < h, i < j, k < h\n // loc: b < j, $m follows $b or $g\n // NV: $a \n {'tag': '041', 'sortOrder': ['8', 'a', 'd', 'e', 'b', 'f', 'i', 'j', 'p', 'k', 'h', 'n', 'g', 'm']}, // guesswork\n {'tag': '048', 'sortOrder': ['8', 'b', 'a']},\n {'tag': '100', 'sortOrder': sortOrderForX00},\n {'tag': '110', 'sortOrder': sortOrderForX10},\n {'tag': '111', 'sortOrder': sortOrderForX11},\n {'tag': '130', 'sortOrder': ['a', 'n', 'p', 'k', 'l']},\n {'tag': '240', 'sortOrder': ['a', 'm', 'n', 'p', 's', 'l', '2', '0', '1', '5', '9']},\n {'tag': '245', 'sortOrder': ['a', 'b', 'n', 'p', 'k', 'f', 'c']},\n {'tag': '246', 'sortOrder': sortOrderFor246},\n {'tag': '382', 'sortOrder': ['a']},\n {'tag': '385', 'sortOrder': ['8', 'm', 'n', 'a', '2', '0', '1']},\n {'tag': '386', 'sortOrder': ['8', 'm', 'n', 'a']},\n {'tag': '490', 'sortOrder': ['a', 'x', 'y', 'v', 'l']},\n {'tag': '505', 'sortOrder': ['a']},\n {'tag': '526', 'sortOrder': ['i', 'a', 'b', 'x', 'z']},\n {'tag': '534', 'sortOrder': ['3', 'p', 'a', 't', 'l', 'c', 'f', 'b', 'e', 'o', 'x', 'z']},\n {'tag': '540', 'sortOrder': ['a', 'b', 'c', 'd', 'f', '2', 'u']},\n {'tag': '600', 'sortOrder': sortOrderForX00},\n {'tag': '610', 'sortOrder': sortOrderForX10},\n {'tag': '611', 'sortOrder': sortOrderForX11},\n {'tag': '650', 'sortOrder': ['a', 'x', 'y', 'z']},\n {'tag': '700', 'sortOrder': sortOrderForX00},\n {'tag': '710', 'sortOrder': sortOrderForX10},\n {'tag': '711', 'sortOrder': sortOrderForX11},\n {'tag': '760', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '762', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '765', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '767', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '770', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '772', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '773', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '774', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '775', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '776', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '777', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '780', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '785', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '786', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '787', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '788', 'sortOrder': sortOrderFor7XXLinkingEntries},\n {'tag': '800', 'sortOrder': sortOrderForX00},\n {'tag': '810', 'sortOrder': sortOrderForX10},\n {'tag': '811', 'sortOrder': sortOrderForX11},\n {'tag': '830', 'sortOrder': ['a', 'n', 'x', 'v']}, // INCOMPLETE, SAME AS 490? APPARENTLY NOT...\n {'tag': '856', 'sortOrder': ['3', 'u', 'q', 'x', 'y', 'z', '5']}, // incomplete, LoC examples are inconclusive\n {'tag': '880', 'sortOrder': ['a']},\n {'tag': '946', 'sortOrder': sortOrderFor246},\n {'tag': 'LOW', 'sortOrder': ['a', 'b', 'c', 'l', 'h']},\n {'tag': 'SID', 'sortOrder': ['c', 'b']} // Hack, so that default order is not used\n];\n\nfunction getSubfieldSortOrder(field) {\n const entry = subfieldSortOrder.filter(currEntry => field.tag === currEntry.tag);\n if (entry.length > 0 && 'sortOrder' in entry[0]) {\n debugDev(`sort order for ${field.tag}: ${entry[0].sortOrder}`);\n return entry[0].sortOrder;\n }\n if (!['300'].includes(field.tag)) { // Lis tags which use normal $a...$z order here!\n nvdebug(`WARNING!\\tNo subfield order found for ${field.tag}.`, debugDev);\n }\n return [];\n}\n\n\nfunction swapSubfields(field, sortOrder) {\n if (!field.subfields) {\n return;\n }\n\n const loopAgain = field.subfields.some((sf, index) => {\n if (index === 0) {\n return false;\n }\n const currPos = getPosition(sf, sortOrder);\n const prevPos = getPosition(field.subfields[index - 1], sortOrder);\n if (currPos === -1 || prevPos === -1 || currPos >= prevPos) {\n return false;\n }\n // Swap:\n const tmp = field.subfields[index - 1];\n field.subfields[index - 1] = sf;\n field.subfields[index] = tmp;\n return true;\n });\n\n if (loopAgain) {\n return swapSubfields(field, sortOrder);\n }\n\n return;\n\n function getPosition(subfield, sortOrder) {\n // Magic exception that *always* comes first, used by Aleph in linking overlong fields\n if (sortOrder.indexOf('9') > -1 && subfield.code === '9' && ['^', '^^'].includes(subfield.value)) {\n return -0.5; // normal \"best value\" is 0, and \"worst value\" is N\n }\n return sortOrder.indexOf(subfield.code);\n }\n}\n\n\nfunction twoBeforeZero(field) {\n const sf2 = field.subfields.filter(sf => sf.code === '2');\n if (sf2.length !== 1) {\n return true; // both true and false are ok here\n }\n // MRA-465: gcipplatform (field 753)\n // rdasco (344), creatorbio (353), gbd (668), lsch (eg. 385)\n if (['creatorbio', 'gbd', 'gcipplatform', 'lscsh', 'rdasco'].includes(sf2[0].value)) {\n return false;\n }\n return true;\n}\n\nfunction moveSubfield6ToTheFront(field) {\n // https://www.loc.gov/marc/bibliographic/ecbdcntf.html says \"Subfield $6 is always the first subfield in the field.\"\n const sf6s = field.subfields.filter(sf => sf.code === '6');\n const others = field.subfields.filter(sf => sf.code !== '6');\n field.subfields = [...sf6s, ...others];\n}\n\nexport function sortAdjacentSubfields(field, externalSortOrder = []) {\n if (!field.subfields) {\n return field;\n }\n\n moveSubfield6ToTheFront(field); // specs: \"Subfield $6 is always the first subfield in the field.\"\n\n // Features:\n // - Swap only sort adjacent pairs.\n // - No sorting over unlisted subfield codes. Thus a given subfield can not shift to wrong side of 700$t...\n\n // Implement: 880 field should use values from $6...\n\n // Should we support multiple sort orders per field?\n\n // Try to handle control subfield order. This is not 100% fool proof. Control subfields are pretty stable, though.\n // However, there are exceptions (eg. $9 ^^ comes first and $2 $0 is a Finnish convention...)\n\n\n const finnishWay = twoBeforeZero(field);\n\n // Note: 760-789: '7' comes way earlier (after '6' and '8')\n const controlSubfieldOrder = finnishWay ? ['8', '3', 'a', '4', '2', '0', '1', '7', '5', '9'] : ['8', '7', '3', 'a', '4', '0', '1', '2', '7', '5', '9'];\n swapSubfields(field, controlSubfieldOrder);\n\n const sortOrderForField = externalSortOrder.length > 0 ? externalSortOrder : getSubfieldSortOrder(field);\n //nvdebug(`INTERMEDIATE SUBFIELD ORDER FOR ${field.tag}: ${sortOrderForField.join(', ')}`, debugDev);\n\n const defaultSortOrder = finnishWay ? defaultSortOrderFinns : defaultSortOrderOthers; // $2 vs $0\n const subfieldOrder = sortOrderForField.length > 0 ? sortOrderForField : defaultSortOrder;\n //nvdebug(`FINAL SUBFIELD ORDER (FINNISH=${finnishWay}) FOR ${field.tag}: ${subfieldOrder.join(', ')}`, debugDev);\n //if (sortOrder === null) { return field; } //// Currently always sort..\n //nvdebug(`IN: ${fieldToString(field)}`, debugDev);\n swapSubfields(field, subfieldOrder);\n //nvdebug(`OUT: ${fieldToString(field)}`, debugDev);\n\n return field;\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": ["sortOrder"]
7
7
  }
@@ -3,7 +3,6 @@ import { MarcRecord } from "@natlibfi/marc-record";
3
3
  import validatorFactory from "./sortSubfields.js";
4
4
  import { READERS } from "@natlibfi/fixura";
5
5
  import generateTests from "@natlibfi/fixugen";
6
- import createDebugLogger from "debug";
7
6
  generateTests({
8
7
  callback,
9
8
  path: [import.meta.dirname, "..", "test-fixtures", "sort-subfields"],
@@ -18,18 +17,13 @@ generateTests({
18
17
  }
19
18
  }
20
19
  });
21
- const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/sortSubfields:test");
22
20
  async function testValidatorFactory() {
23
21
  const validator = await validatorFactory();
24
22
  assert.equal(typeof validator, "object");
25
23
  assert.equal(typeof validator.description, "string");
26
24
  assert.equal(typeof validator.validate, "function");
27
25
  }
28
- async function callback({ getFixture, enabled = true, fix = false, tagPattern = false }) {
29
- if (enabled === false) {
30
- debug("TEST SKIPPED!");
31
- return;
32
- }
26
+ async function callback({ getFixture, fix = false, tagPattern = false }) {
33
27
  const validator = await validatorFactory(tagPattern);
34
28
  const record = new MarcRecord(getFixture("record.json"));
35
29
  const expectedResult = getFixture("expectedResult.json");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sortSubfields.test.js"],
4
- "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortSubfields.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-subfields'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortSubfields:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, enabled = true, fix = false, tagPattern = false}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory(tagPattern);\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAC1B,OAAO,uBAAuB;AAE9B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,gBAAgB;AAAA,EACnE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAED,MAAM,QAAQ,kBAAkB,6DAA6D;AAE7F,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,UAAU,MAAM,MAAM,OAAO,aAAa,MAAK,GAAG;AACrF,MAAI,YAAY,OAAO;AACrB,UAAM,eAAe;AACrB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,iBAAiB,UAAU;AACnD,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './sortSubfields.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n//import createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'sort-subfields'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/sortSubfields:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, fix = false, tagPattern = false}) {\n const validator = await validatorFactory(tagPattern);\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
+ "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAG1B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,gBAAgB;AAAA,EACnE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAID,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,MAAM,OAAO,aAAa,MAAK,GAAG;AACrE,QAAM,YAAY,MAAM,iBAAiB,UAAU;AACnD,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
6
6
  "names": []
7
7
  }
@@ -1,19 +1,23 @@
1
1
  import { fieldGetFixedString, fieldNeedsModification, fieldStripPunctuation } from "./punctuation2.js";
2
+ import createDebugLogger from "debug";
2
3
  import { fieldToString, nvdebug } from "./utils.js";
4
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/punctuation2");
5
+ const debugDev = debug.extend("dev");
6
+ const description = "Strip punctuation in data fields";
3
7
  export default function() {
4
8
  return {
5
- description: "Strip punctuation to data fields",
9
+ description,
6
10
  validate,
7
11
  fix
8
12
  };
9
13
  function fix(record) {
10
- nvdebug("Strip punctuation to data fields: fixer");
14
+ nvdebug(`${description}: fixer`, debugDev);
11
15
  const res = { message: [], fix: [], valid: true };
12
16
  record.fields.forEach((f) => fieldStripPunctuation(f));
13
17
  return res;
14
18
  }
15
19
  function validate(record) {
16
- nvdebug("Strip punctuation to data fields: validate");
20
+ nvdebug(`${description}: validate`, debugDev);
17
21
  const fieldsNeedingModification = record.fields.filter((f) => fieldNeedsModification(f, false));
18
22
  const values = fieldsNeedingModification.map((f) => fieldToString(f));
19
23
  const newValues = fieldsNeedingModification.map((f) => fieldGetFixedString(f, false));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/stripPunctuation.js"],
4
- "sourcesContent": ["/*\n* stripPunctuation.js -- try and remove a marc field punctuation (based on and reverse of punctuation2.js)\n*\n* Author(s): Nicholas Volk <nicholas.volk@helsinki.fi>\n*\n*/\n\nimport {fieldGetFixedString, fieldNeedsModification, fieldStripPunctuation} from './punctuation2.js';\n// import createDebugLogger from 'debug';\nimport {fieldToString, nvdebug} from './utils.js';\n\n// const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');\n\nexport default function () {\n return {\n description: 'Strip punctuation to data fields',\n validate, fix\n };\n\n function fix(record) {\n nvdebug('Strip punctuation to data fields: fixer');\n const res = {message: [], fix: [], valid: true};\n record.fields.forEach(f => fieldStripPunctuation(f));\n return res;\n }\n\n function validate(record) {\n nvdebug('Strip punctuation to data fields: validate');\n\n const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, false));\n\n const values = fieldsNeedingModification.map(f => fieldToString(f));\n const newValues = fieldsNeedingModification.map(f => fieldGetFixedString(f, false));\n\n const messages = values.map((val, i) => `'${val}' => '${newValues[i]}'`);\n\n const res = {message: messages};\n\n res.valid = res.message.length < 1;\n return res;\n }\n}\n"],
5
- "mappings": "AAOA,SAAQ,qBAAqB,wBAAwB,6BAA4B;AAEjF,SAAQ,eAAe,eAAc;AAIrC,0BAA2B;AACzB,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AACnB,YAAQ,yCAAyC;AACjD,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAC9C,WAAO,OAAO,QAAQ,OAAK,sBAAsB,CAAC,CAAC;AACnD,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,YAAQ,4CAA4C;AAEpD,UAAM,4BAA4B,OAAO,OAAO,OAAO,OAAK,uBAAuB,GAAG,KAAK,CAAC;AAE5F,UAAM,SAAS,0BAA0B,IAAI,OAAK,cAAc,CAAC,CAAC;AAClE,UAAM,YAAY,0BAA0B,IAAI,OAAK,oBAAoB,GAAG,KAAK,CAAC;AAElF,UAAM,WAAW,OAAO,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,SAAS,UAAU,CAAC,CAAC,GAAG;AAEvE,UAAM,MAAM,EAAC,SAAS,SAAQ;AAE9B,QAAI,QAAQ,IAAI,QAAQ,SAAS;AACjC,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["/*\n* stripPunctuation.js -- try and remove a marc field punctuation (based on and reverse of punctuation2.js)\n*\n* Author(s): Nicholas Volk <nicholas.volk@helsinki.fi>\n*\n*/\n\nimport {fieldGetFixedString, fieldNeedsModification, fieldStripPunctuation} from './punctuation2.js';\nimport createDebugLogger from 'debug';\n\nimport {fieldToString, nvdebug} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst description = 'Strip punctuation in data fields';\n\nexport default function () {\n return {\n description: description,\n validate, fix\n };\n\n function fix(record) {\n nvdebug(`${description}: fixer`, debugDev);\n const res = {message: [], fix: [], valid: true};\n record.fields.forEach(f => fieldStripPunctuation(f));\n return res;\n }\n\n function validate(record) {\n nvdebug(`${description}: validate`, debugDev);\n\n const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, false));\n\n const values = fieldsNeedingModification.map(f => fieldToString(f));\n const newValues = fieldsNeedingModification.map(f => fieldGetFixedString(f, false));\n\n const messages = values.map((val, i) => `'${val}' => '${newValues[i]}'`);\n\n const res = {message: messages};\n\n res.valid = res.message.length < 1;\n return res;\n }\n}\n"],
5
+ "mappings": "AAOA,SAAQ,qBAAqB,wBAAwB,6BAA4B;AACjF,OAAO,uBAAuB;AAE9B,SAAQ,eAAe,eAAc;AAErC,MAAM,QAAQ,kBAAkB,uDAAuD;AAEvF,MAAM,WAAW,MAAM,OAAO,KAAK;AAEnC,MAAM,cAAe;AAErB,0BAA2B;AACzB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AACnB,YAAQ,GAAG,WAAW,WAAW,QAAQ;AACzC,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAC9C,WAAO,OAAO,QAAQ,OAAK,sBAAsB,CAAC,CAAC;AACnD,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,YAAQ,GAAG,WAAW,cAAc,QAAQ;AAE5C,UAAM,4BAA4B,OAAO,OAAO,OAAO,OAAK,uBAAuB,GAAG,KAAK,CAAC;AAE5F,UAAM,SAAS,0BAA0B,IAAI,OAAK,cAAc,CAAC,CAAC;AAClE,UAAM,YAAY,0BAA0B,IAAI,OAAK,oBAAoB,GAAG,KAAK,CAAC;AAElF,UAAM,WAAW,OAAO,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,SAAS,UAAU,CAAC,CAAC,GAAG;AAEvE,UAAM,MAAM,EAAC,SAAS,SAAQ;AAE9B,QAAI,QAAQ,IAAI,QAAQ,SAAS;AACjC,WAAO;AAAA,EACT;AACF;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,6 @@ import { MarcRecord } from "@natlibfi/marc-record";
3
3
  import validatorFactory from "./stripPunctuation.js";
4
4
  import { READERS } from "@natlibfi/fixura";
5
5
  import generateTests from "@natlibfi/fixugen";
6
- import createDebugLogger from "debug";
7
6
  generateTests({
8
7
  callback,
9
8
  path: [import.meta.dirname, "..", "test-fixtures", "strip-punctuation"],
@@ -18,18 +17,13 @@ generateTests({
18
17
  }
19
18
  }
20
19
  });
21
- const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/stripPunctuation:test");
22
20
  async function testValidatorFactory() {
23
21
  const validator = await validatorFactory();
24
22
  assert.equal(typeof validator, "object");
25
23
  assert.equal(typeof validator.description, "string");
26
24
  assert.equal(typeof validator.validate, "function");
27
25
  }
28
- async function callback({ getFixture, enabled = true, fix = false }) {
29
- if (enabled === false) {
30
- debug("TEST SKIPPED!");
31
- return;
32
- }
26
+ async function callback({ getFixture, fix = false }) {
33
27
  const validator = await validatorFactory();
34
28
  const record = new MarcRecord(getFixture("record.json"));
35
29
  const expectedResult = getFixture("expectedResult.json");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/stripPunctuation.test.js"],
4
- "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './stripPunctuation.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'strip-punctuation'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/stripPunctuation:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, enabled = true, fix = false}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAC1B,OAAO,uBAAuB;AAE9B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,mBAAmB;AAAA,EACtE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAED,MAAM,QAAQ,kBAAkB,gEAAgE;AAEhG,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,UAAU,MAAM,MAAM,MAAK,GAAG;AACjE,MAAI,YAAY,OAAO;AACrB,UAAM,eAAe;AACrB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './stripPunctuation.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n//import createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'strip-punctuation'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/stripPunctuation:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, fix = false}) {\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
5
+ "mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAG1B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,mBAAmB;AAAA,EACtE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAID,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,MAAM,MAAK,GAAG;AACjD,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
6
6
  "names": []
7
7
  }