@natlibfi/marc-record-validators-melinda 11.6.7-alpha.1 → 12.0.0-alpha.1

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 (545) hide show
  1. package/.github/workflows/melinda-node-tests.yml +1 -1
  2. package/dist/access-rights.js +63 -91
  3. package/dist/access-rights.js.map +7 -1
  4. package/dist/access-rights.test.js +137 -0
  5. package/dist/access-rights.test.js.map +7 -0
  6. package/dist/addMissingField041.js +21 -53
  7. package/dist/addMissingField041.js.map +7 -1
  8. package/dist/addMissingField041.test.js +39 -0
  9. package/dist/addMissingField041.test.js.map +7 -0
  10. package/dist/addMissingField336.js +99 -191
  11. package/dist/addMissingField336.js.map +7 -1
  12. package/dist/addMissingField336.test.js +39 -0
  13. package/dist/addMissingField336.test.js.map +7 -0
  14. package/dist/addMissingField337.js +63 -132
  15. package/dist/addMissingField337.js.map +7 -1
  16. package/dist/addMissingField337.test.js +39 -0
  17. package/dist/addMissingField337.test.js.map +7 -0
  18. package/dist/addMissingField338.js +147 -253
  19. package/dist/addMissingField338.js.map +7 -1
  20. package/dist/addMissingField338.test.js +39 -0
  21. package/dist/addMissingField338.test.js.map +7 -0
  22. package/dist/cyrillux-usemarcon-replacement.js +119 -272
  23. package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
  24. package/dist/cyrillux-usemarcon-replacement.test.js +46 -0
  25. package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
  26. package/dist/cyrillux.js +119 -223
  27. package/dist/cyrillux.js.map +7 -1
  28. package/dist/cyrillux.test.js +39 -0
  29. package/dist/cyrillux.test.js.map +7 -0
  30. package/dist/disambiguateSeriesStatements.js +40 -81
  31. package/dist/disambiguateSeriesStatements.js.map +7 -1
  32. package/dist/disambiguateSeriesStatements.test.js +44 -0
  33. package/dist/disambiguateSeriesStatements.test.js.map +7 -0
  34. package/dist/double-commas.js +7 -14
  35. package/dist/double-commas.js.map +7 -1
  36. package/dist/double-commas.test.js +48 -0
  37. package/dist/double-commas.test.js.map +7 -0
  38. package/dist/duplicates-ind1.js +10 -31
  39. package/dist/duplicates-ind1.js.map +7 -1
  40. package/dist/duplicates-ind1.test.js +40 -0
  41. package/dist/duplicates-ind1.test.js.map +7 -0
  42. package/dist/empty-fields.js +10 -22
  43. package/dist/empty-fields.js.map +7 -1
  44. package/dist/empty-fields.test.js +129 -0
  45. package/dist/empty-fields.test.js.map +7 -0
  46. package/dist/ending-punctuation-conf.js +871 -769
  47. package/dist/ending-punctuation-conf.js.map +7 -1
  48. package/dist/ending-punctuation.js +84 -167
  49. package/dist/ending-punctuation.js.map +7 -1
  50. package/dist/ending-punctuation.test.js +2290 -0
  51. package/dist/ending-punctuation.test.js.map +7 -0
  52. package/dist/ending-whitespace.js +10 -35
  53. package/dist/ending-whitespace.js.map +7 -1
  54. package/dist/ending-whitespace.test.js +38 -0
  55. package/dist/ending-whitespace.test.js.map +7 -0
  56. package/dist/field-008-18-34-character-groups.js +40 -125
  57. package/dist/field-008-18-34-character-groups.js.map +7 -1
  58. package/dist/field-008-18-34-character-groups.test.js +45 -0
  59. package/dist/field-008-18-34-character-groups.test.js.map +7 -0
  60. package/dist/field-505-separators.js +19 -39
  61. package/dist/field-505-separators.js.map +7 -1
  62. package/dist/field-505-separators.test.js +45 -0
  63. package/dist/field-505-separators.test.js.map +7 -0
  64. package/dist/field-521-fix.js +19 -47
  65. package/dist/field-521-fix.js.map +7 -1
  66. package/dist/field-521-fix.test.js +44 -0
  67. package/dist/field-521-fix.test.js.map +7 -0
  68. package/dist/field-exclusion.js +37 -91
  69. package/dist/field-exclusion.js.map +7 -1
  70. package/dist/field-exclusion.test.js +821 -0
  71. package/dist/field-exclusion.test.js.map +7 -0
  72. package/dist/field-structure.js +52 -104
  73. package/dist/field-structure.js.map +7 -1
  74. package/dist/field-structure.test.js +587 -0
  75. package/dist/field-structure.test.js.map +7 -0
  76. package/dist/field33XUtils.js +119 -503
  77. package/dist/field33XUtils.js.map +7 -1
  78. package/dist/fields-present.js +11 -23
  79. package/dist/fields-present.js.map +7 -1
  80. package/dist/fields-present.test.js +95 -0
  81. package/dist/fields-present.test.js.map +7 -0
  82. package/dist/fix-33X.js +393 -431
  83. package/dist/fix-33X.js.map +7 -1
  84. package/dist/fix-33X.test.js +39 -0
  85. package/dist/fix-33X.test.js.map +7 -0
  86. package/dist/fix-country-codes.js +20 -50
  87. package/dist/fix-country-codes.js.map +7 -1
  88. package/dist/fix-country-codes.test.js +44 -0
  89. package/dist/fix-country-codes.test.js.map +7 -0
  90. package/dist/fix-language-codes.js +23 -53
  91. package/dist/fix-language-codes.js.map +7 -1
  92. package/dist/fix-language-codes.test.js +38 -0
  93. package/dist/fix-language-codes.test.js.map +7 -0
  94. package/dist/fixRelatorTerms.js +82 -209
  95. package/dist/fixRelatorTerms.js.map +7 -1
  96. package/dist/fixRelatorTerms.test.js +44 -0
  97. package/dist/fixRelatorTerms.test.js.map +7 -0
  98. package/dist/fixed-fields.js +21 -30
  99. package/dist/fixed-fields.js.map +7 -1
  100. package/dist/fixed-fields.test.js +87 -0
  101. package/dist/fixed-fields.test.js.map +7 -0
  102. package/dist/identical-fields.js +8 -24
  103. package/dist/identical-fields.js.map +7 -1
  104. package/dist/identical-fields.test.js +119 -0
  105. package/dist/identical-fields.test.js.map +7 -0
  106. package/dist/index.js +119 -413
  107. package/dist/index.js.map +7 -1
  108. package/dist/indicator-fixes.js +57 -95
  109. package/dist/indicator-fixes.js.map +7 -1
  110. package/dist/indicator-fixes.test.js +42 -0
  111. package/dist/indicator-fixes.test.js.map +7 -0
  112. package/dist/isbn-issn.js +66 -126
  113. package/dist/isbn-issn.js.map +7 -1
  114. package/dist/isbn-issn.test.js +398 -0
  115. package/dist/isbn-issn.test.js.map +7 -0
  116. package/dist/item-language.js +32 -65
  117. package/dist/item-language.js.map +7 -1
  118. package/dist/item-language.test.js +322 -0
  119. package/dist/item-language.test.js.map +7 -0
  120. package/dist/melindaCustomMergeFields.js +5182 -11233
  121. package/dist/melindaCustomMergeFields.js.map +7 -1
  122. package/dist/merge-fields/controlSubfields.js +75 -142
  123. package/dist/merge-fields/controlSubfields.js.map +7 -1
  124. package/dist/merge-fields/counterpartField.js +182 -379
  125. package/dist/merge-fields/counterpartField.js.map +7 -1
  126. package/dist/merge-fields/index.js +15 -49
  127. package/dist/merge-fields/index.js.map +7 -1
  128. package/dist/merge-fields/mergableIndicator.js +18 -51
  129. package/dist/merge-fields/mergableIndicator.js.map +7 -1
  130. package/dist/merge-fields/mergableTag.js +78 -30
  131. package/dist/merge-fields/mergableTag.js.map +7 -1
  132. package/dist/merge-fields/mergeConfig.js +66 -171
  133. package/dist/merge-fields/mergeConfig.js.map +7 -1
  134. package/dist/merge-fields/mergeConstraints.js +323 -1214
  135. package/dist/merge-fields/mergeConstraints.js.map +7 -1
  136. package/dist/merge-fields/mergeField.js +47 -111
  137. package/dist/merge-fields/mergeField.js.map +7 -1
  138. package/dist/merge-fields/mergeIndicator.js +64 -118
  139. package/dist/merge-fields/mergeIndicator.js.map +7 -1
  140. package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
  141. package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
  142. package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
  143. package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
  144. package/dist/merge-fields/mergeSubfield.js +47 -95
  145. package/dist/merge-fields/mergeSubfield.js.map +7 -1
  146. package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
  147. package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
  148. package/dist/merge-fields/worldKnowledge.js +15 -40
  149. package/dist/merge-fields/worldKnowledge.js.map +7 -1
  150. package/dist/merge-fields.test.js +44 -0
  151. package/dist/merge-fields.test.js.map +7 -0
  152. package/dist/mergeField500Lisapainokset.js +28 -57
  153. package/dist/mergeField500Lisapainokset.js.map +7 -1
  154. package/dist/mergeField500Lisapainokset.test.js +44 -0
  155. package/dist/mergeField500Lisapainokset.test.js.map +7 -0
  156. package/dist/mergeRelatorTermFields.js +33 -69
  157. package/dist/mergeRelatorTermFields.js.map +7 -1
  158. package/dist/mergeRelatorTermFields.test.js +44 -0
  159. package/dist/mergeRelatorTermFields.test.js.map +7 -0
  160. package/dist/modernize-502.js +23 -55
  161. package/dist/modernize-502.js.map +7 -1
  162. package/dist/modernize-502.test.js +38 -0
  163. package/dist/modernize-502.test.js.map +7 -0
  164. package/dist/multiple-subfield-0.js +23 -48
  165. package/dist/multiple-subfield-0.js.map +7 -1
  166. package/dist/multiple-subfield-0.test.js +44 -0
  167. package/dist/multiple-subfield-0.test.js.map +7 -0
  168. package/dist/non-breaking-space.js +11 -32
  169. package/dist/non-breaking-space.js.map +7 -1
  170. package/dist/non-breaking-space.test.js +38 -0
  171. package/dist/non-breaking-space.test.js.map +7 -0
  172. package/dist/normalize-dashes.js +18 -37
  173. package/dist/normalize-dashes.js.map +7 -1
  174. package/dist/normalize-dashes.test.js +44 -0
  175. package/dist/normalize-dashes.test.js.map +7 -0
  176. package/dist/normalize-identifiers.js +54 -140
  177. package/dist/normalize-identifiers.js.map +7 -1
  178. package/dist/normalize-identifiers.test.js +44 -0
  179. package/dist/normalize-identifiers.test.js.map +7 -0
  180. package/dist/normalize-qualifying-information.js +23 -48
  181. package/dist/normalize-qualifying-information.js.map +7 -1
  182. package/dist/normalize-qualifying-information.test.js +44 -0
  183. package/dist/normalize-qualifying-information.test.js.map +7 -0
  184. package/dist/normalize-utf8-diacritics.js +19 -105
  185. package/dist/normalize-utf8-diacritics.js.map +7 -1
  186. package/dist/normalize-utf8-diacritics.test.js +44 -0
  187. package/dist/normalize-utf8-diacritics.test.js.map +7 -0
  188. package/dist/normalizeFieldForComparison.js +67 -158
  189. package/dist/normalizeFieldForComparison.js.map +7 -1
  190. package/dist/normalizeSubfieldValueForComparison.js +37 -77
  191. package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
  192. package/dist/prepublicationUtils.js +58 -111
  193. package/dist/prepublicationUtils.js.map +7 -1
  194. package/dist/punctuation/index.js +56 -72
  195. package/dist/punctuation/index.js.map +7 -1
  196. package/dist/punctuation/rules/aut.js +372 -331
  197. package/dist/punctuation/rules/aut.js.map +7 -1
  198. package/dist/punctuation/rules/bib.js +420 -373
  199. package/dist/punctuation/rules/bib.js.map +7 -1
  200. package/dist/punctuation/rules/index.js +7 -21
  201. package/dist/punctuation/rules/index.js.map +7 -1
  202. package/dist/punctuation.test.js +44 -0
  203. package/dist/punctuation.test.js.map +7 -0
  204. package/dist/punctuation2.js +251 -800
  205. package/dist/punctuation2.js.map +7 -1
  206. package/dist/punctuation2.test.js +44 -0
  207. package/dist/punctuation2.test.js.map +7 -0
  208. package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
  209. package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
  210. package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
  211. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
  212. package/dist/removeDuplicateDataFields.js +102 -202
  213. package/dist/removeDuplicateDataFields.js.map +7 -1
  214. package/dist/removeDuplicateDataFields.test.js +44 -0
  215. package/dist/removeDuplicateDataFields.test.js.map +7 -0
  216. package/dist/removeInferiorDataFields.js +103 -227
  217. package/dist/removeInferiorDataFields.js.map +7 -1
  218. package/dist/removeInferiorDataFields.test.js +44 -0
  219. package/dist/removeInferiorDataFields.test.js.map +7 -0
  220. package/dist/resolvable-ext-references-melinda.js +25 -60
  221. package/dist/resolvable-ext-references-melinda.js.map +7 -1
  222. package/dist/resolvable-ext-references-melinda.test.js +160 -0
  223. package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
  224. package/dist/resolveOrphanedSubfield6s.js +33 -64
  225. package/dist/resolveOrphanedSubfield6s.js.map +7 -1
  226. package/dist/resolveOrphanedSubfield6s.test.js +44 -0
  227. package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
  228. package/dist/sanitize-vocabulary-source-codes.js +27 -55
  229. package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
  230. package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
  231. package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
  232. package/dist/sort-tags.js +13 -25
  233. package/dist/sort-tags.js.map +7 -1
  234. package/dist/sort-tags.test.js +261 -0
  235. package/dist/sort-tags.test.js.map +7 -0
  236. package/dist/sortFields.js +152 -222
  237. package/dist/sortFields.js.map +7 -1
  238. package/dist/sortFields.test.js +44 -0
  239. package/dist/sortFields.test.js.map +7 -0
  240. package/dist/sortRelatorTerms.js +30 -68
  241. package/dist/sortRelatorTerms.js.map +7 -1
  242. package/dist/sortRelatorTerms.test.js +44 -0
  243. package/dist/sortRelatorTerms.test.js.map +7 -0
  244. package/dist/sortSubfields.js +102 -255
  245. package/dist/sortSubfields.js.map +7 -1
  246. package/dist/sortSubfields.test.js +44 -0
  247. package/dist/sortSubfields.test.js.map +7 -0
  248. package/dist/stripPunctuation.js +13 -36
  249. package/dist/stripPunctuation.js.map +7 -1
  250. package/dist/stripPunctuation.test.js +44 -0
  251. package/dist/stripPunctuation.test.js.map +7 -0
  252. package/dist/subfield-exclusion.js +28 -75
  253. package/dist/subfield-exclusion.js.map +7 -1
  254. package/dist/subfield-exclusion.test.js +471 -0
  255. package/dist/subfield-exclusion.test.js.map +7 -0
  256. package/dist/subfield6Utils.js +107 -269
  257. package/dist/subfield6Utils.js.map +7 -1
  258. package/dist/subfield8Utils.js +26 -50
  259. package/dist/subfield8Utils.js.map +7 -1
  260. package/dist/subfieldValueNormalizations.js +40 -74
  261. package/dist/subfieldValueNormalizations.js.map +7 -1
  262. package/dist/subfieldValueNormalizations.test.js +45 -0
  263. package/dist/subfieldValueNormalizations.test.js.map +7 -0
  264. package/dist/sync-007-and-300.js +22 -53
  265. package/dist/sync-007-and-300.js.map +7 -1
  266. package/dist/sync-007-and-300.test.js +44 -0
  267. package/dist/sync-007-and-300.test.js.map +7 -0
  268. package/dist/translate-terms.js +67 -155
  269. package/dist/translate-terms.js.map +7 -1
  270. package/dist/translate-terms.test.js +44 -0
  271. package/dist/translate-terms.test.js.map +7 -0
  272. package/dist/typeOfDate-008.js +10 -25
  273. package/dist/typeOfDate-008.js.map +7 -1
  274. package/dist/typeOfDate-008.test.js +40 -0
  275. package/dist/typeOfDate-008.test.js.map +7 -0
  276. package/dist/unicode-decomposition.js +94 -107
  277. package/dist/unicode-decomposition.js.map +7 -1
  278. package/dist/unicode-decomposition.test.js +94 -0
  279. package/dist/unicode-decomposition.test.js.map +7 -0
  280. package/dist/update-field-540.js +30 -75
  281. package/dist/update-field-540.js.map +7 -1
  282. package/dist/update-field-540.test.js +44 -0
  283. package/dist/update-field-540.test.js.map +7 -0
  284. package/dist/urn.js +55 -128
  285. package/dist/urn.js.map +7 -1
  286. package/dist/urn.test.js +44 -0
  287. package/dist/urn.test.js.map +7 -0
  288. package/dist/utils.js +72 -126
  289. package/dist/utils.js.map +7 -1
  290. package/eslint.config.mjs +1 -2
  291. package/package.json +21 -93
  292. package/src/access-rights.js +1 -1
  293. package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
  294. package/src/addMissingField041.js +1 -1
  295. package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
  296. package/src/addMissingField336.js +3 -3
  297. package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
  298. package/src/addMissingField337.js +2 -2
  299. package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
  300. package/src/addMissingField338.js +2 -2
  301. package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
  302. package/src/cyrillux-usemarcon-replacement.js +18 -18
  303. package/src/cyrillux-usemarcon-replacement.test.js +55 -0
  304. package/src/cyrillux.js +19 -12
  305. package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
  306. package/src/disambiguateSeriesStatements.js +2 -2
  307. package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
  308. package/src/double-commas.js +1 -1
  309. package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
  310. package/src/duplicates-ind1.js +1 -1
  311. package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
  312. package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
  313. package/src/ending-punctuation.js +1 -1
  314. package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +172 -173
  315. package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
  316. package/src/field-008-18-34-character-groups.js +2 -2
  317. package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
  318. package/src/field-505-separators.js +3 -3
  319. package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
  320. package/src/field-521-fix.js +2 -2
  321. package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
  322. package/src/field-exclusion.js +1 -1
  323. package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
  324. package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
  325. package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
  326. package/src/fix-33X.js +4 -4
  327. package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
  328. package/src/fix-country-codes.js +1 -1
  329. package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
  330. package/src/fix-language-codes.js +5 -5
  331. package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
  332. package/src/fixRelatorTerms.js +5 -5
  333. package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
  334. package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
  335. package/src/identical-fields.js +1 -1
  336. package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
  337. package/src/indicator-fixes.js +3 -3
  338. package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
  339. package/src/isbn-issn.js +1 -1
  340. package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
  341. package/src/{item-language.spec.js → item-language.test.js} +21 -22
  342. package/src/merge-fields/controlSubfields.js +1 -1
  343. package/src/merge-fields/counterpartField.js +8 -9
  344. package/src/merge-fields/index.js +1 -1
  345. package/src/merge-fields/mergableIndicator.js +1 -1
  346. package/src/merge-fields/mergeField.js +6 -6
  347. package/src/merge-fields/mergeIndicator.js +1 -1
  348. package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
  349. package/src/merge-fields/mergeOrAddSubfield.js +2 -2
  350. package/src/merge-fields/mergeSubfield.js +4 -4
  351. package/src/merge-fields/removeDuplicateSubfields.js +2 -2
  352. package/src/{merge-fields.spec.js → merge-fields.test.js} +12 -13
  353. package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
  354. package/src/mergeRelatorTermFields.js +5 -7
  355. package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
  356. package/src/modernize-502.js +1 -1
  357. package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
  358. package/src/multiple-subfield-0.js +3 -3
  359. package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
  360. package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
  361. package/src/normalize-dashes.js +2 -2
  362. package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
  363. package/src/normalize-identifiers.js +1 -1
  364. package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
  365. package/src/normalize-qualifying-information.js +2 -2
  366. package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
  367. package/src/normalize-utf8-diacritics.js +2 -2
  368. package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
  369. package/src/normalizeFieldForComparison.js +6 -6
  370. package/src/normalizeSubfieldValueForComparison.js +1 -1
  371. package/src/prepublicationUtils.js +4 -4
  372. package/src/punctuation/index.js +1 -1
  373. package/src/punctuation/rules/index.js +2 -2
  374. package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
  375. package/src/punctuation2.js +4 -4
  376. package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
  377. package/src/reindexSubfield6OccurenceNumbers.js +5 -7
  378. package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
  379. package/src/removeDuplicateDataFields.js +11 -19
  380. package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
  381. package/src/removeInferiorDataFields.js +11 -11
  382. package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
  383. package/src/resolvable-ext-references-melinda.js +1 -1
  384. package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
  385. package/src/resolveOrphanedSubfield6s.js +5 -5
  386. package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
  387. package/src/sanitize-vocabulary-source-codes.js +4 -4
  388. package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
  389. package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
  390. package/src/sortFields.js +4 -4
  391. package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
  392. package/src/sortRelatorTerms.js +3 -3
  393. package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
  394. package/src/sortSubfields.js +1 -1
  395. package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
  396. package/src/stripPunctuation.js +3 -3
  397. package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
  398. package/src/subfield-exclusion.js +1 -1
  399. package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
  400. package/src/subfield6Utils.js +6 -10
  401. package/src/subfield8Utils.js +4 -4
  402. package/src/subfieldValueNormalizations.js +3 -3
  403. package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
  404. package/src/sync-007-and-300.js +2 -2
  405. package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
  406. package/src/translate-terms.js +3 -3
  407. package/src/{translate-terms.spec.js → translate-terms.test.js} +13 -13
  408. package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
  409. package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
  410. package/src/update-field-540.js +2 -2
  411. package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
  412. package/src/urn.js +2 -2
  413. package/src/{urn.spec.js → urn.test.js} +12 -13
  414. package/src/utils.js +3 -3
  415. package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
  416. package/test-fixtures/field-505-separators/03/record.json +3 -0
  417. package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
  418. package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
  419. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
  420. package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
  421. package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
  422. package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
  423. package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
  424. package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
  425. package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
  426. package/dist/access-rights.spec.js +0 -195
  427. package/dist/access-rights.spec.js.map +0 -1
  428. package/dist/addMissingField041.spec.js +0 -45
  429. package/dist/addMissingField041.spec.js.map +0 -1
  430. package/dist/addMissingField336.spec.js +0 -45
  431. package/dist/addMissingField336.spec.js.map +0 -1
  432. package/dist/addMissingField337.spec.js +0 -43
  433. package/dist/addMissingField337.spec.js.map +0 -1
  434. package/dist/addMissingField338.spec.js +0 -45
  435. package/dist/addMissingField338.spec.js.map +0 -1
  436. package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
  437. package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
  438. package/dist/cyrillux.spec.js +0 -46
  439. package/dist/cyrillux.spec.js.map +0 -1
  440. package/dist/disambiguateSeriesStatements.spec.js +0 -51
  441. package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
  442. package/dist/double-commas.spec.js +0 -73
  443. package/dist/double-commas.spec.js.map +0 -1
  444. package/dist/duplicates-ind1.spec.js +0 -45
  445. package/dist/duplicates-ind1.spec.js.map +0 -1
  446. package/dist/empty-fields.spec.js +0 -118
  447. package/dist/empty-fields.spec.js.map +0 -1
  448. package/dist/ending-punctuation.spec.js +0 -2654
  449. package/dist/ending-punctuation.spec.js.map +0 -1
  450. package/dist/ending-whitespace.spec.js +0 -42
  451. package/dist/ending-whitespace.spec.js.map +0 -1
  452. package/dist/field-008-18-34-character-groups.spec.js +0 -51
  453. package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
  454. package/dist/field-505-separators.spec.js +0 -51
  455. package/dist/field-505-separators.spec.js.map +0 -1
  456. package/dist/field-521-fix.spec.js +0 -51
  457. package/dist/field-521-fix.spec.js.map +0 -1
  458. package/dist/field-exclusion.spec.js +0 -1054
  459. package/dist/field-exclusion.spec.js.map +0 -1
  460. package/dist/field-structure.spec.js +0 -535
  461. package/dist/field-structure.spec.js.map +0 -1
  462. package/dist/fields-present.spec.js +0 -121
  463. package/dist/fields-present.spec.js.map +0 -1
  464. package/dist/fix-33X.spec.js +0 -45
  465. package/dist/fix-33X.spec.js.map +0 -1
  466. package/dist/fix-country-codes.spec.js +0 -51
  467. package/dist/fix-country-codes.spec.js.map +0 -1
  468. package/dist/fix-language-codes.spec.js +0 -44
  469. package/dist/fix-language-codes.spec.js.map +0 -1
  470. package/dist/fixRelatorTerms.spec.js +0 -51
  471. package/dist/fixRelatorTerms.spec.js.map +0 -1
  472. package/dist/fixed-fields.spec.js +0 -140
  473. package/dist/fixed-fields.spec.js.map +0 -1
  474. package/dist/identical-fields.spec.js +0 -99
  475. package/dist/identical-fields.spec.js.map +0 -1
  476. package/dist/indicator-fixes.spec.js +0 -51
  477. package/dist/indicator-fixes.spec.js.map +0 -1
  478. package/dist/isbn-issn.spec.js +0 -595
  479. package/dist/isbn-issn.spec.js.map +0 -1
  480. package/dist/item-language.spec.js +0 -306
  481. package/dist/item-language.spec.js.map +0 -1
  482. package/dist/melindaCustomMergeFields.json +0 -5120
  483. package/dist/merge-fields.spec.js +0 -51
  484. package/dist/merge-fields.spec.js.map +0 -1
  485. package/dist/mergeField500Lisapainokset.spec.js +0 -51
  486. package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
  487. package/dist/mergeRelatorTermFields.spec.js +0 -51
  488. package/dist/mergeRelatorTermFields.spec.js.map +0 -1
  489. package/dist/modernize-502.spec.js +0 -49
  490. package/dist/modernize-502.spec.js.map +0 -1
  491. package/dist/multiple-subfield-0.spec.js +0 -51
  492. package/dist/multiple-subfield-0.spec.js.map +0 -1
  493. package/dist/non-breaking-space.spec.js +0 -42
  494. package/dist/non-breaking-space.spec.js.map +0 -1
  495. package/dist/normalize-dashes.spec.js +0 -51
  496. package/dist/normalize-dashes.spec.js.map +0 -1
  497. package/dist/normalize-identifiers.spec.js +0 -51
  498. package/dist/normalize-identifiers.spec.js.map +0 -1
  499. package/dist/normalize-qualifying-information.spec.js +0 -51
  500. package/dist/normalize-qualifying-information.spec.js.map +0 -1
  501. package/dist/normalize-utf8-diacritics.spec.js +0 -51
  502. package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
  503. package/dist/punctuation.spec.js +0 -51
  504. package/dist/punctuation.spec.js.map +0 -1
  505. package/dist/punctuation2.spec.js +0 -51
  506. package/dist/punctuation2.spec.js.map +0 -1
  507. package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
  508. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
  509. package/dist/removeDuplicateDataFields.spec.js +0 -51
  510. package/dist/removeDuplicateDataFields.spec.js.map +0 -1
  511. package/dist/removeInferiorDataFields.spec.js +0 -51
  512. package/dist/removeInferiorDataFields.spec.js.map +0 -1
  513. package/dist/resolvable-ext-references-melinda.spec.js +0 -166
  514. package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
  515. package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
  516. package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
  517. package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
  518. package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
  519. package/dist/sort-tags.spec.js +0 -207
  520. package/dist/sort-tags.spec.js.map +0 -1
  521. package/dist/sortFields.spec.js +0 -51
  522. package/dist/sortFields.spec.js.map +0 -1
  523. package/dist/sortRelatorTerms.spec.js +0 -51
  524. package/dist/sortRelatorTerms.spec.js.map +0 -1
  525. package/dist/sortSubfields.spec.js +0 -52
  526. package/dist/sortSubfields.spec.js.map +0 -1
  527. package/dist/stripPunctuation.spec.js +0 -51
  528. package/dist/stripPunctuation.spec.js.map +0 -1
  529. package/dist/subfield-exclusion.spec.js +0 -523
  530. package/dist/subfield-exclusion.spec.js.map +0 -1
  531. package/dist/subfieldValueNormalizations.spec.js +0 -51
  532. package/dist/subfieldValueNormalizations.spec.js.map +0 -1
  533. package/dist/sync-007-and-300.spec.js +0 -51
  534. package/dist/sync-007-and-300.spec.js.map +0 -1
  535. package/dist/translate-terms.spec.js +0 -51
  536. package/dist/translate-terms.spec.js.map +0 -1
  537. package/dist/typeOfDate-008.spec.js +0 -47
  538. package/dist/typeOfDate-008.spec.js.map +0 -1
  539. package/dist/unicode-decomposition.spec.js +0 -91
  540. package/dist/unicode-decomposition.spec.js.map +0 -1
  541. package/dist/update-field-540.spec.js +0 -51
  542. package/dist/update-field-540.spec.js.map +0 -1
  543. package/dist/urn.spec.js +0 -52
  544. package/dist/urn.spec.js.map +0 -1
  545. package/src/cyrillux-usemarcon-replacement.spec.js +0 -47
@@ -1,121 +1,93 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- exports.recordNormalizeIndicators = recordNormalizeIndicators;
8
- var _utils = require("./utils");
9
- // Relocated from melinda-marc-record-merge-reducers (and renamed)
10
- //import createDebugLogger from 'debug';
11
- //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');
12
-
13
- function _default() {
1
+ import { fieldToString } from "./utils.js";
2
+ export default function() {
14
3
  return {
15
- description: 'Normalizes indicator values',
4
+ description: "Normalizes indicator values",
16
5
  validate,
17
6
  fix
18
7
  };
19
8
  function fix(record) {
20
- const res = {
21
- message: [],
22
- fix: [],
23
- valid: true
24
- };
9
+ const res = { message: [], fix: [], valid: true };
25
10
  recordNormalizeIndicators(record);
26
11
  return res;
27
12
  }
28
13
  function validate(record) {
29
- const res = {
30
- message: []
31
- };
14
+ const res = { message: [] };
32
15
  validateRecord(record, res);
33
16
  res.valid = res.message.length < 1;
34
17
  return res;
35
18
  }
36
19
  function validateRecord(record, res) {
37
- //nvdebug(record);
38
20
  const clonedFields = JSON.parse(JSON.stringify(record.fields));
39
21
  recordNormalizeIndicators(record);
40
- record.fields.forEach((field, index) => compareFields(field, index)); // eslint-disable-line array-callback-return
41
-
22
+ record.fields.forEach((field, index) => compareFields(field, index));
42
23
  function compareFields(field, index) {
43
- const origFieldAsString = (0, _utils.fieldToString)(clonedFields[index]);
44
- //const clonedFieldAsString = fieldToString(field);
24
+ const origFieldAsString = fieldToString(clonedFields[index]);
45
25
  if (clonedFields[index].ind1 !== field.ind1) {
46
- //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);
47
26
  res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);
48
27
  }
49
28
  if (clonedFields[index].ind2 !== field.ind2) {
50
- //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);
51
29
  res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);
52
30
  }
53
31
  }
54
- // Validator should not change the original record:
55
32
  record.fields = clonedFields;
56
33
  return;
57
34
  }
58
35
  }
59
- const ind1NonFilingChars = ['130', '630', '730', '740'];
60
- const ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];
36
+ const ind1NonFilingChars = ["130", "630", "730", "740"];
37
+ const ind2NonFilingChars = ["222", "240", "242", "243", "245", "830"];
61
38
  function hasNonFilingIndicator1(field) {
62
39
  return ind1NonFilingChars.includes(field.tag);
63
40
  }
64
41
  function modifiableIndicatorValue(value) {
65
- // If field contains a legit-looking value, don't try to modify it here...
66
- return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);
42
+ return !["9", "8", "7", "6", "5", "4", "3", "2", "1"].includes(value);
67
43
  }
68
44
  function hasNonFilingIndicator2(field) {
69
45
  return ind2NonFilingChars.includes(field.tag);
70
46
  }
71
47
  function valueBeginsWithDeterminer(value, cands) {
72
- return cands.find(cand => value.substring(0, cand.length) === cand);
48
+ return cands.find((cand) => value.substring(0, cand.length) === cand);
73
49
  }
74
- function determineNonFilingIndicatorValue(field, languages = undefined) {
75
- const subfieldA = field.subfields.find(sf => sf.code === 'a');
50
+ function determineNonFilingIndicatorValue(field, languages = void 0) {
51
+ const subfieldA = field.subfields.find((sf) => sf.code === "a");
76
52
  if (!subfieldA) {
77
- // nvdebug(' Subfield $a miss!');
78
53
  return;
79
54
  }
80
55
  const name = subfieldA.value.toLowerCase();
81
- if (languages.includes('eng')) {
82
- const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);
83
- if (match) {
84
- return `${match.length}`;
56
+ if (languages.includes("eng")) {
57
+ const match2 = valueBeginsWithDeterminer(name, ["a ", "an ", "the "]);
58
+ if (match2) {
59
+ return `${match2.length}`;
85
60
  }
86
61
  }
87
- if (languages.includes('fre')) {
88
- const match = valueBeginsWithDeterminer(name, ['l\'', 'le ']);
89
- if (match) {
90
- return `${match.length}`;
62
+ if (languages.includes("fre")) {
63
+ const match2 = valueBeginsWithDeterminer(name, ["l'", "le "]);
64
+ if (match2) {
65
+ return `${match2.length}`;
91
66
  }
92
67
  }
93
- if (languages.includes('ger')) {
94
- const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);
95
- if (match) {
96
- return `${match.length}`;
68
+ if (languages.includes("ger")) {
69
+ const match2 = valueBeginsWithDeterminer(name, ["das ", "der ", "die "]);
70
+ if (match2) {
71
+ return `${match2.length}`;
97
72
  }
98
73
  }
99
- if (languages.includes('swe')) {
100
- const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);
101
- if (match) {
102
- return `${match.length}`;
74
+ if (languages.includes("swe")) {
75
+ const match2 = valueBeginsWithDeterminer(name, ["en ", "ett "]);
76
+ if (match2) {
77
+ return `${match2.length}`;
103
78
  }
104
79
  if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {
105
- return '4';
80
+ return "4";
106
81
  }
107
82
  }
108
-
109
- // Fallback-ish: try to guess even without languages:
110
- const match = valueBeginsWithDeterminer(name, ['the ']);
83
+ const match = valueBeginsWithDeterminer(name, ["the "]);
111
84
  if (match) {
112
85
  return `${match.length}`;
113
86
  }
114
- if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) {
115
- // Skip "a b c", "a la carte"...
116
- return '2';
87
+ if (name.match(/^a /u) && !languages.includes("hun") && !name.match(/^a (?:b |la )/u)) {
88
+ return "2";
117
89
  }
118
- return '0';
90
+ return "0";
119
91
  }
120
92
  function normalizeNonFilingIndicator1(field, languages = []) {
121
93
  if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {
@@ -129,84 +101,74 @@ function normalizeNonFilingIndicator2(field, languages = []) {
129
101
  }
130
102
  field.ind2 = determineNonFilingIndicatorValue(field, languages);
131
103
  }
132
- const fiktiivisenAineistonLisaluokatFI = ['Eläimet', 'Erotiikka', 'Erä', 'Fantasia', 'Historia', 'Huumori', 'Jännitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];
104
+ const fiktiivisenAineistonLisaluokatFI = ["El\xE4imet", "Erotiikka", "Er\xE4", "Fantasia", "Historia", "Huumori", "J\xE4nnitys", "Kauhu", "Novellit", "Romantiikka", "Scifi", "Sota", "Urheilu", "Uskonto"];
133
105
  function containsFiktiivisenAineistonLisaluokka(field) {
134
- // Should we check Swedish versions as well?
135
- return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));
106
+ return field.subfields.some((sf) => sf.code === "a" && fiktiivisenAineistonLisaluokatFI.includes(sf.value));
136
107
  }
137
108
  function normalize084Indicator1(field) {
138
- if (field.tag !== '084') {
109
+ if (field.tag !== "084") {
139
110
  return;
140
111
  }
141
-
142
- // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka
143
- if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {
144
- field.ind1 = '9';
112
+ if (field.ind1 !== "9" && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some((sf) => sf.code === "2" && sf.value === "ykl")) {
113
+ field.ind1 = "9";
145
114
  return;
146
115
  }
147
116
  }
148
117
  function normalize245Indicator1(field, record) {
149
- if (field.tag !== '245') {
118
+ if (field.tag !== "245") {
150
119
  return;
151
120
  }
152
- const field1XX = record.get('^1..$');
153
- field.ind1 = field1XX.length === 0 ? '0' : '1';
121
+ const field1XX = record.get("^1..$");
122
+ field.ind1 = field1XX.length === 0 ? "0" : "1";
154
123
  }
155
124
  function normalize776Indicator2(field) {
156
- if (field.tag !== '776') {
125
+ if (field.tag !== "776") {
157
126
  return;
158
127
  }
159
- // If subfield $i exists, ind2 must me '8'
160
- if (field.subfields.some(sf => sf.code === 'i')) {
161
- field.ind2 = '8';
128
+ if (field.subfields.some((sf) => sf.code === "i")) {
129
+ field.ind2 = "8";
162
130
  return;
163
131
  }
164
132
  }
165
133
  function recordNormalize490(record) {
166
- const fields490 = record.get('^490$');
167
- const fields8XX = record.get('^(?:800|810|811|830)$');
134
+ const fields490 = record.get("^490$");
135
+ const fields8XX = record.get("^(?:800|810|811|830)$");
168
136
  if (fields490.length === 0) {
169
137
  return;
170
138
  }
171
139
  if (fields490.length <= fields8XX.length) {
172
- // Trace found for each field 490:
173
- fields490.forEach(f => {
174
- f.ind1 = '1';
140
+ fields490.forEach((f) => {
141
+ f.ind1 = "1";
175
142
  });
176
143
  return;
177
144
  }
178
145
  if (fields8XX.length === 0) {
179
- // Fields 490 are always untraced (no traces found)
180
- fields490.forEach(f => {
181
- f.ind1 = '0';
146
+ fields490.forEach((f) => {
147
+ f.ind1 = "0";
182
148
  });
183
149
  return;
184
150
  }
185
- // For other combinations we just can't be sure, so leave them as they are.
186
151
  }
187
152
  function getLanguages(record) {
188
- const langFields = record.get('^041$');
153
+ const langFields = record.get("^041$");
189
154
  if (langFields.length === 0) {
190
155
  return [];
191
156
  }
192
- return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);
157
+ return langFields[0].subfields.filter((sf) => isRelevantSubfield(sf)).map((subfield) => subfield.value);
193
158
  function isRelevantSubfield(subfield) {
194
- if (!['a', 'd', 'h'].includes(subfield.code)) {
159
+ if (!["a", "d", "h"].includes(subfield.code)) {
195
160
  return false;
196
161
  }
197
162
  if (subfield.value.length !== 3) {
198
163
  return false;
199
164
  }
200
- // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.
201
165
  return true;
202
166
  }
203
167
  }
204
- function recordNormalizeIndicators(record) {
168
+ export function recordNormalizeIndicators(record) {
205
169
  recordNormalize490(record);
206
-
207
- // Language is used to handle non-filing indicators
208
170
  const languages = getLanguages(record);
209
- record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages)); // eslint-disable-line array-callback-return
171
+ record.fields.forEach((field) => fieldNormalizeIndicators(field, record, languages));
210
172
  }
211
173
  function fieldNormalizeIndicators(field, record, languages) {
212
174
  normalize084Indicator1(field);
@@ -215,4 +177,4 @@ function fieldNormalizeIndicators(field, record, languages) {
215
177
  normalizeNonFilingIndicator2(field, languages);
216
178
  normalize776Indicator2(field);
217
179
  }
218
- //# sourceMappingURL=indicator-fixes.js.map
180
+ //# sourceMappingURL=indicator-fixes.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"indicator-fixes.js","names":["_utils","require","_default","description","validate","fix","record","res","message","valid","recordNormalizeIndicators","validateRecord","length","clonedFields","JSON","parse","stringify","fields","forEach","field","index","compareFields","origFieldAsString","fieldToString","ind1","push","ind2","ind1NonFilingChars","ind2NonFilingChars","hasNonFilingIndicator1","includes","tag","modifiableIndicatorValue","value","hasNonFilingIndicator2","valueBeginsWithDeterminer","cands","find","cand","substring","determineNonFilingIndicatorValue","languages","undefined","subfieldA","subfields","sf","code","name","toLowerCase","match","normalizeNonFilingIndicator1","normalizeNonFilingIndicator2","fiktiivisenAineistonLisaluokatFI","containsFiktiivisenAineistonLisaluokka","some","normalize084Indicator1","normalize245Indicator1","field1XX","get","normalize776Indicator2","recordNormalize490","fields490","fields8XX","f","getLanguages","langFields","filter","isRelevantSubfield","map","subfield","fieldNormalizeIndicators"],"sources":["../src/indicator-fixes.js"],"sourcesContent":["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\nimport {fieldToString} from './utils';\n\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n //nvdebug(record);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index)); // eslint-disable-line array-callback-return\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!');\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['Eläimet', 'Erotiikka', 'Erä', 'Fantasia', 'Historia', 'Huumori', 'Jännitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nexport function recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages)); // eslint-disable-line array-callback-return\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/indicator-fixes.js"],
4
+ "sourcesContent": ["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\nimport {fieldToString} from './utils.js';\n\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n //nvdebug(record);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index));\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!');\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['El\u00E4imet', 'Erotiikka', 'Er\u00E4', 'Fantasia', 'Historia', 'Huumori', 'J\u00E4nnitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nexport function recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["match"]
7
+ }
@@ -0,0 +1,42 @@
1
+ import assert from "node:assert";
2
+ import { MarcRecord } from "@natlibfi/marc-record";
3
+ import validatorFactory from "./indicator-fixes.js";
4
+ import { READERS } from "@natlibfi/fixura";
5
+ import generateTests from "@natlibfi/fixugen";
6
+ import createDebugLogger from "debug";
7
+ generateTests({
8
+ callback,
9
+ path: [import.meta.dirname, "..", "test-fixtures", "indicator-fixes"],
10
+ useMetadataFile: true,
11
+ recurse: false,
12
+ fixura: {
13
+ reader: READERS.JSON
14
+ },
15
+ hooks: {
16
+ before: () => testValidatorFactory()
17
+ }
18
+ });
19
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/indicator-fixes:test");
20
+ async function testValidatorFactory() {
21
+ const validator = await validatorFactory();
22
+ assert.equal(typeof validator, "object");
23
+ assert.equal(typeof validator.description, "string");
24
+ assert.equal(typeof validator.validate, "function");
25
+ }
26
+ async function callback({ getFixture, enabled = true, fix = false }) {
27
+ if (enabled === false) {
28
+ debug("TEST SKIPPED!");
29
+ return;
30
+ }
31
+ const validator = await validatorFactory();
32
+ const record = new MarcRecord(getFixture("record.json"));
33
+ const expectedResult = getFixture("expectedResult.json");
34
+ if (!fix) {
35
+ const result = await validator.validate(record);
36
+ assert.deepEqual(result, expectedResult);
37
+ return;
38
+ }
39
+ await validator.fix(record);
40
+ assert.deepEqual(record, expectedResult);
41
+ }
42
+ //# sourceMappingURL=indicator-fixes.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/indicator-fixes.test.js"],
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './indicator-fixes.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', 'indicator-fixes'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/indicator-fixes: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,iBAAiB;AAAA,EACpE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,MAAM,qBAAqB;AAAA,EACrC;AACF,CAAC;AACD,MAAM,QAAQ,kBAAkB,+DAA+D;AAE/F,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;",
6
+ "names": []
7
+ }