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

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 (563) hide show
  1. package/.github/workflows/{melinda-node-tests.yml → melinda-node-tests-and-publish.yml} +37 -12
  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 +43 -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 +873 -769
  47. package/dist/ending-punctuation-conf.js.map +7 -1
  48. package/dist/ending-punctuation.js +156 -169
  49. package/dist/ending-punctuation.js.map +7 -1
  50. package/dist/ending-punctuation.test.js +2385 -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 +182 -413
  107. package/dist/index.js.map +7 -1
  108. package/dist/indicator-fixes.js +66 -94
  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 +71 -128
  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 +187 -379
  125. package/dist/merge-fields/counterpartField.js.map +7 -1
  126. package/dist/merge-fields/dataProvenance.js +29 -0
  127. package/dist/merge-fields/dataProvenance.js.map +7 -0
  128. package/dist/merge-fields/index.js +25 -50
  129. package/dist/merge-fields/index.js.map +7 -1
  130. package/dist/merge-fields/mergableIndicator.js +18 -51
  131. package/dist/merge-fields/mergableIndicator.js.map +7 -1
  132. package/dist/merge-fields/mergableTag.js +78 -30
  133. package/dist/merge-fields/mergableTag.js.map +7 -1
  134. package/dist/merge-fields/mergeConfig.js +66 -171
  135. package/dist/merge-fields/mergeConfig.js.map +7 -1
  136. package/dist/merge-fields/mergeConstraints.js +323 -1214
  137. package/dist/merge-fields/mergeConstraints.js.map +7 -1
  138. package/dist/merge-fields/mergeField.js +47 -111
  139. package/dist/merge-fields/mergeField.js.map +7 -1
  140. package/dist/merge-fields/mergeIndicator.js +64 -118
  141. package/dist/merge-fields/mergeIndicator.js.map +7 -1
  142. package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
  143. package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
  144. package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
  145. package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
  146. package/dist/merge-fields/mergeSubfield.js +47 -95
  147. package/dist/merge-fields/mergeSubfield.js.map +7 -1
  148. package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
  149. package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
  150. package/dist/merge-fields/worldKnowledge.js +15 -40
  151. package/dist/merge-fields/worldKnowledge.js.map +7 -1
  152. package/dist/merge-fields.test.js +46 -0
  153. package/dist/merge-fields.test.js.map +7 -0
  154. package/dist/mergeField500Lisapainokset.js +27 -56
  155. package/dist/mergeField500Lisapainokset.js.map +7 -1
  156. package/dist/mergeField500Lisapainokset.test.js +44 -0
  157. package/dist/mergeField500Lisapainokset.test.js.map +7 -0
  158. package/dist/mergeRelatorTermFields.js +33 -69
  159. package/dist/mergeRelatorTermFields.js.map +7 -1
  160. package/dist/mergeRelatorTermFields.test.js +44 -0
  161. package/dist/mergeRelatorTermFields.test.js.map +7 -0
  162. package/dist/modernize-502.js +23 -55
  163. package/dist/modernize-502.js.map +7 -1
  164. package/dist/modernize-502.test.js +38 -0
  165. package/dist/modernize-502.test.js.map +7 -0
  166. package/dist/multiple-subfield-0.js +23 -48
  167. package/dist/multiple-subfield-0.js.map +7 -1
  168. package/dist/multiple-subfield-0.test.js +44 -0
  169. package/dist/multiple-subfield-0.test.js.map +7 -0
  170. package/dist/non-breaking-space.js +11 -32
  171. package/dist/non-breaking-space.js.map +7 -1
  172. package/dist/non-breaking-space.test.js +38 -0
  173. package/dist/non-breaking-space.test.js.map +7 -0
  174. package/dist/normalize-dashes.js +18 -37
  175. package/dist/normalize-dashes.js.map +7 -1
  176. package/dist/normalize-dashes.test.js +44 -0
  177. package/dist/normalize-dashes.test.js.map +7 -0
  178. package/dist/normalize-identifiers.js +54 -140
  179. package/dist/normalize-identifiers.js.map +7 -1
  180. package/dist/normalize-identifiers.test.js +44 -0
  181. package/dist/normalize-identifiers.test.js.map +7 -0
  182. package/dist/normalize-qualifying-information.js +23 -48
  183. package/dist/normalize-qualifying-information.js.map +7 -1
  184. package/dist/normalize-qualifying-information.test.js +44 -0
  185. package/dist/normalize-qualifying-information.test.js.map +7 -0
  186. package/dist/normalize-utf8-diacritics.js +19 -105
  187. package/dist/normalize-utf8-diacritics.js.map +7 -1
  188. package/dist/normalize-utf8-diacritics.test.js +44 -0
  189. package/dist/normalize-utf8-diacritics.test.js.map +7 -0
  190. package/dist/normalizeFieldForComparison.js +91 -158
  191. package/dist/normalizeFieldForComparison.js.map +7 -1
  192. package/dist/normalizeSubfieldValueForComparison.js +37 -77
  193. package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
  194. package/dist/prepublicationUtils.js +58 -111
  195. package/dist/prepublicationUtils.js.map +7 -1
  196. package/dist/punctuation/index.js +56 -72
  197. package/dist/punctuation/index.js.map +7 -1
  198. package/dist/punctuation/rules/aut.js +372 -331
  199. package/dist/punctuation/rules/aut.js.map +7 -1
  200. package/dist/punctuation/rules/bib.js +420 -373
  201. package/dist/punctuation/rules/bib.js.map +7 -1
  202. package/dist/punctuation/rules/index.js +7 -21
  203. package/dist/punctuation/rules/index.js.map +7 -1
  204. package/dist/punctuation.test.js +44 -0
  205. package/dist/punctuation.test.js.map +7 -0
  206. package/dist/punctuation2.js +259 -802
  207. package/dist/punctuation2.js.map +7 -1
  208. package/dist/punctuation2.test.js +44 -0
  209. package/dist/punctuation2.test.js.map +7 -0
  210. package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
  211. package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
  212. package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
  213. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
  214. package/dist/removeDuplicateDataFields.js +102 -202
  215. package/dist/removeDuplicateDataFields.js.map +7 -1
  216. package/dist/removeDuplicateDataFields.test.js +44 -0
  217. package/dist/removeDuplicateDataFields.test.js.map +7 -0
  218. package/dist/removeInferiorDataFields.js +104 -227
  219. package/dist/removeInferiorDataFields.js.map +7 -1
  220. package/dist/removeInferiorDataFields.test.js +44 -0
  221. package/dist/removeInferiorDataFields.test.js.map +7 -0
  222. package/dist/resolvable-ext-references-melinda.js +25 -60
  223. package/dist/resolvable-ext-references-melinda.js.map +7 -1
  224. package/dist/resolvable-ext-references-melinda.test.js +160 -0
  225. package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
  226. package/dist/resolveOrphanedSubfield6s.js +32 -63
  227. package/dist/resolveOrphanedSubfield6s.js.map +7 -1
  228. package/dist/resolveOrphanedSubfield6s.test.js +44 -0
  229. package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
  230. package/dist/sanitize-vocabulary-source-codes.js +27 -55
  231. package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
  232. package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
  233. package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
  234. package/dist/sort-tags.js +13 -25
  235. package/dist/sort-tags.js.map +7 -1
  236. package/dist/sort-tags.test.js +261 -0
  237. package/dist/sort-tags.test.js.map +7 -0
  238. package/dist/sortFields.js +152 -222
  239. package/dist/sortFields.js.map +7 -1
  240. package/dist/sortFields.test.js +44 -0
  241. package/dist/sortFields.test.js.map +7 -0
  242. package/dist/sortRelatorTerms.js +30 -68
  243. package/dist/sortRelatorTerms.js.map +7 -1
  244. package/dist/sortRelatorTerms.test.js +44 -0
  245. package/dist/sortRelatorTerms.test.js.map +7 -0
  246. package/dist/sortSubfields.js +102 -255
  247. package/dist/sortSubfields.js.map +7 -1
  248. package/dist/sortSubfields.test.js +44 -0
  249. package/dist/sortSubfields.test.js.map +7 -0
  250. package/dist/stripPunctuation.js +13 -36
  251. package/dist/stripPunctuation.js.map +7 -1
  252. package/dist/stripPunctuation.test.js +44 -0
  253. package/dist/stripPunctuation.test.js.map +7 -0
  254. package/dist/subfield-exclusion.js +28 -75
  255. package/dist/subfield-exclusion.js.map +7 -1
  256. package/dist/subfield-exclusion.test.js +471 -0
  257. package/dist/subfield-exclusion.test.js.map +7 -0
  258. package/dist/subfield6Utils.js +107 -269
  259. package/dist/subfield6Utils.js.map +7 -1
  260. package/dist/subfield8Utils.js +26 -50
  261. package/dist/subfield8Utils.js.map +7 -1
  262. package/dist/subfieldValueNormalizations.js +40 -74
  263. package/dist/subfieldValueNormalizations.js.map +7 -1
  264. package/dist/subfieldValueNormalizations.test.js +45 -0
  265. package/dist/subfieldValueNormalizations.test.js.map +7 -0
  266. package/dist/sync-007-and-300.js +22 -53
  267. package/dist/sync-007-and-300.js.map +7 -1
  268. package/dist/sync-007-and-300.test.js +44 -0
  269. package/dist/sync-007-and-300.test.js.map +7 -0
  270. package/dist/translate-terms.js +67 -155
  271. package/dist/translate-terms.js.map +7 -1
  272. package/dist/translate-terms.test.js +54 -0
  273. package/dist/translate-terms.test.js.map +7 -0
  274. package/dist/typeOfDate-008.js +10 -25
  275. package/dist/typeOfDate-008.js.map +7 -1
  276. package/dist/typeOfDate-008.test.js +40 -0
  277. package/dist/typeOfDate-008.test.js.map +7 -0
  278. package/dist/unicode-decomposition.js +94 -107
  279. package/dist/unicode-decomposition.js.map +7 -1
  280. package/dist/unicode-decomposition.test.js +94 -0
  281. package/dist/unicode-decomposition.test.js.map +7 -0
  282. package/dist/update-field-540.js +30 -75
  283. package/dist/update-field-540.js.map +7 -1
  284. package/dist/update-field-540.test.js +44 -0
  285. package/dist/update-field-540.test.js.map +7 -0
  286. package/dist/urn.js +55 -128
  287. package/dist/urn.js.map +7 -1
  288. package/dist/urn.test.js +44 -0
  289. package/dist/urn.test.js.map +7 -0
  290. package/dist/utils.js +78 -126
  291. package/dist/utils.js.map +7 -1
  292. package/eslint.config.mjs +1 -2
  293. package/package.json +28 -101
  294. package/src/access-rights.js +1 -1
  295. package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
  296. package/src/addMissingField041.js +1 -1
  297. package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
  298. package/src/addMissingField336.js +3 -3
  299. package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
  300. package/src/addMissingField337.js +2 -2
  301. package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
  302. package/src/addMissingField338.js +2 -2
  303. package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
  304. package/src/cyrillux-usemarcon-replacement.js +18 -18
  305. package/src/{cyrillux-usemarcon-replacement.spec.js → cyrillux-usemarcon-replacement.test.js} +17 -14
  306. package/src/cyrillux.js +19 -12
  307. package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
  308. package/src/disambiguateSeriesStatements.js +2 -2
  309. package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
  310. package/src/double-commas.js +1 -1
  311. package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
  312. package/src/duplicates-ind1.js +1 -1
  313. package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
  314. package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
  315. package/src/ending-punctuation-conf.js +6 -5
  316. package/src/ending-punctuation.js +115 -24
  317. package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +357 -275
  318. package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
  319. package/src/field-008-18-34-character-groups.js +2 -2
  320. package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
  321. package/src/field-505-separators.js +3 -3
  322. package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
  323. package/src/field-521-fix.js +2 -2
  324. package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
  325. package/src/field-exclusion.js +1 -1
  326. package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
  327. package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
  328. package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
  329. package/src/fix-33X.js +4 -4
  330. package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
  331. package/src/fix-country-codes.js +1 -1
  332. package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
  333. package/src/fix-language-codes.js +5 -5
  334. package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
  335. package/src/fixRelatorTerms.js +5 -5
  336. package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
  337. package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
  338. package/src/identical-fields.js +1 -1
  339. package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
  340. package/src/index.js +132 -59
  341. package/src/indicator-fixes.js +17 -4
  342. package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
  343. package/src/isbn-issn.js +12 -7
  344. package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
  345. package/src/{item-language.spec.js → item-language.test.js} +21 -22
  346. package/src/melindaCustomMergeFields.js +1 -1
  347. package/src/merge-fields/controlSubfields.js +1 -1
  348. package/src/merge-fields/counterpartField.js +14 -9
  349. package/src/merge-fields/dataProvenance.js +41 -0
  350. package/src/merge-fields/index.js +12 -3
  351. package/src/merge-fields/mergableIndicator.js +1 -1
  352. package/src/merge-fields/mergeField.js +8 -8
  353. package/src/merge-fields/mergeIndicator.js +1 -1
  354. package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
  355. package/src/merge-fields/mergeOrAddSubfield.js +2 -2
  356. package/src/merge-fields/mergeSubfield.js +4 -4
  357. package/src/merge-fields/removeDuplicateSubfields.js +2 -2
  358. package/src/{merge-fields.spec.js → merge-fields.test.js} +18 -15
  359. package/src/mergeField500Lisapainokset.js +1 -1
  360. package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
  361. package/src/mergeRelatorTermFields.js +5 -7
  362. package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
  363. package/src/modernize-502.js +1 -1
  364. package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
  365. package/src/multiple-subfield-0.js +3 -3
  366. package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
  367. package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
  368. package/src/normalize-dashes.js +2 -2
  369. package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
  370. package/src/normalize-identifiers.js +1 -1
  371. package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
  372. package/src/normalize-qualifying-information.js +2 -2
  373. package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
  374. package/src/normalize-utf8-diacritics.js +2 -2
  375. package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
  376. package/src/normalizeFieldForComparison.js +32 -6
  377. package/src/normalizeSubfieldValueForComparison.js +1 -1
  378. package/src/prepublicationUtils.js +4 -4
  379. package/src/punctuation/index.js +1 -1
  380. package/src/punctuation/rules/index.js +2 -2
  381. package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
  382. package/src/punctuation2.js +17 -8
  383. package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
  384. package/src/reindexSubfield6OccurenceNumbers.js +5 -7
  385. package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
  386. package/src/removeDuplicateDataFields.js +11 -19
  387. package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
  388. package/src/removeInferiorDataFields.js +15 -12
  389. package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
  390. package/src/resolvable-ext-references-melinda.js +1 -1
  391. package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
  392. package/src/resolveOrphanedSubfield6s.js +6 -6
  393. package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
  394. package/src/sanitize-vocabulary-source-codes.js +4 -4
  395. package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
  396. package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
  397. package/src/sortFields.js +4 -4
  398. package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
  399. package/src/sortRelatorTerms.js +3 -3
  400. package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
  401. package/src/sortSubfields.js +8 -6
  402. package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
  403. package/src/stripPunctuation.js +3 -3
  404. package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
  405. package/src/subfield-exclusion.js +1 -1
  406. package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
  407. package/src/subfield6Utils.js +6 -10
  408. package/src/subfield8Utils.js +4 -4
  409. package/src/subfieldValueNormalizations.js +3 -3
  410. package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
  411. package/src/sync-007-and-300.js +2 -2
  412. package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
  413. package/src/translate-terms.js +3 -3
  414. package/src/translate-terms.test.js +75 -0
  415. package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
  416. package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
  417. package/src/update-field-540.js +2 -2
  418. package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
  419. package/src/urn.js +2 -2
  420. package/src/{urn.spec.js → urn.test.js} +12 -13
  421. package/src/utils.js +21 -5
  422. package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
  423. package/test-fixtures/field-505-separators/03/record.json +3 -0
  424. package/test-fixtures/indicator-fixes/10/expectedResult.json +11 -0
  425. package/test-fixtures/indicator-fixes/10/metadata.json +4 -0
  426. package/test-fixtures/indicator-fixes/10/record.json +11 -0
  427. package/test-fixtures/merge-fields/f05/expectedResult.json +24 -0
  428. package/test-fixtures/merge-fields/f05/metadata.json +6 -0
  429. package/test-fixtures/merge-fields/f05/record.json +30 -0
  430. package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
  431. package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
  432. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
  433. package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
  434. package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
  435. package/test-fixtures/remove-inferior-datafields/f16/expectedResult.json +12 -0
  436. package/test-fixtures/remove-inferior-datafields/f16/metadata.json +5 -0
  437. package/test-fixtures/remove-inferior-datafields/f16/record.json +14 -0
  438. package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
  439. package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
  440. package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
  441. package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
  442. package/test-fixtures/translate-terms-data.js +42 -0
  443. package/dist/access-rights.spec.js +0 -195
  444. package/dist/access-rights.spec.js.map +0 -1
  445. package/dist/addMissingField041.spec.js +0 -45
  446. package/dist/addMissingField041.spec.js.map +0 -1
  447. package/dist/addMissingField336.spec.js +0 -45
  448. package/dist/addMissingField336.spec.js.map +0 -1
  449. package/dist/addMissingField337.spec.js +0 -43
  450. package/dist/addMissingField337.spec.js.map +0 -1
  451. package/dist/addMissingField338.spec.js +0 -45
  452. package/dist/addMissingField338.spec.js.map +0 -1
  453. package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
  454. package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
  455. package/dist/cyrillux.spec.js +0 -46
  456. package/dist/cyrillux.spec.js.map +0 -1
  457. package/dist/disambiguateSeriesStatements.spec.js +0 -51
  458. package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
  459. package/dist/double-commas.spec.js +0 -73
  460. package/dist/double-commas.spec.js.map +0 -1
  461. package/dist/duplicates-ind1.spec.js +0 -45
  462. package/dist/duplicates-ind1.spec.js.map +0 -1
  463. package/dist/empty-fields.spec.js +0 -118
  464. package/dist/empty-fields.spec.js.map +0 -1
  465. package/dist/ending-punctuation.spec.js +0 -2654
  466. package/dist/ending-punctuation.spec.js.map +0 -1
  467. package/dist/ending-whitespace.spec.js +0 -42
  468. package/dist/ending-whitespace.spec.js.map +0 -1
  469. package/dist/field-008-18-34-character-groups.spec.js +0 -51
  470. package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
  471. package/dist/field-505-separators.spec.js +0 -51
  472. package/dist/field-505-separators.spec.js.map +0 -1
  473. package/dist/field-521-fix.spec.js +0 -51
  474. package/dist/field-521-fix.spec.js.map +0 -1
  475. package/dist/field-exclusion.spec.js +0 -1054
  476. package/dist/field-exclusion.spec.js.map +0 -1
  477. package/dist/field-structure.spec.js +0 -535
  478. package/dist/field-structure.spec.js.map +0 -1
  479. package/dist/fields-present.spec.js +0 -121
  480. package/dist/fields-present.spec.js.map +0 -1
  481. package/dist/fix-33X.spec.js +0 -45
  482. package/dist/fix-33X.spec.js.map +0 -1
  483. package/dist/fix-country-codes.spec.js +0 -51
  484. package/dist/fix-country-codes.spec.js.map +0 -1
  485. package/dist/fix-language-codes.spec.js +0 -44
  486. package/dist/fix-language-codes.spec.js.map +0 -1
  487. package/dist/fixRelatorTerms.spec.js +0 -51
  488. package/dist/fixRelatorTerms.spec.js.map +0 -1
  489. package/dist/fixed-fields.spec.js +0 -140
  490. package/dist/fixed-fields.spec.js.map +0 -1
  491. package/dist/identical-fields.spec.js +0 -99
  492. package/dist/identical-fields.spec.js.map +0 -1
  493. package/dist/indicator-fixes.spec.js +0 -51
  494. package/dist/indicator-fixes.spec.js.map +0 -1
  495. package/dist/isbn-issn.spec.js +0 -595
  496. package/dist/isbn-issn.spec.js.map +0 -1
  497. package/dist/item-language.spec.js +0 -306
  498. package/dist/item-language.spec.js.map +0 -1
  499. package/dist/melindaCustomMergeFields.json +0 -5120
  500. package/dist/merge-fields.spec.js +0 -51
  501. package/dist/merge-fields.spec.js.map +0 -1
  502. package/dist/mergeField500Lisapainokset.spec.js +0 -51
  503. package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
  504. package/dist/mergeRelatorTermFields.spec.js +0 -51
  505. package/dist/mergeRelatorTermFields.spec.js.map +0 -1
  506. package/dist/modernize-502.spec.js +0 -49
  507. package/dist/modernize-502.spec.js.map +0 -1
  508. package/dist/multiple-subfield-0.spec.js +0 -51
  509. package/dist/multiple-subfield-0.spec.js.map +0 -1
  510. package/dist/non-breaking-space.spec.js +0 -42
  511. package/dist/non-breaking-space.spec.js.map +0 -1
  512. package/dist/normalize-dashes.spec.js +0 -51
  513. package/dist/normalize-dashes.spec.js.map +0 -1
  514. package/dist/normalize-identifiers.spec.js +0 -51
  515. package/dist/normalize-identifiers.spec.js.map +0 -1
  516. package/dist/normalize-qualifying-information.spec.js +0 -51
  517. package/dist/normalize-qualifying-information.spec.js.map +0 -1
  518. package/dist/normalize-utf8-diacritics.spec.js +0 -51
  519. package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
  520. package/dist/punctuation.spec.js +0 -51
  521. package/dist/punctuation.spec.js.map +0 -1
  522. package/dist/punctuation2.spec.js +0 -51
  523. package/dist/punctuation2.spec.js.map +0 -1
  524. package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
  525. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
  526. package/dist/removeDuplicateDataFields.spec.js +0 -51
  527. package/dist/removeDuplicateDataFields.spec.js.map +0 -1
  528. package/dist/removeInferiorDataFields.spec.js +0 -51
  529. package/dist/removeInferiorDataFields.spec.js.map +0 -1
  530. package/dist/resolvable-ext-references-melinda.spec.js +0 -166
  531. package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
  532. package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
  533. package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
  534. package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
  535. package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
  536. package/dist/sort-tags.spec.js +0 -207
  537. package/dist/sort-tags.spec.js.map +0 -1
  538. package/dist/sortFields.spec.js +0 -51
  539. package/dist/sortFields.spec.js.map +0 -1
  540. package/dist/sortRelatorTerms.spec.js +0 -51
  541. package/dist/sortRelatorTerms.spec.js.map +0 -1
  542. package/dist/sortSubfields.spec.js +0 -52
  543. package/dist/sortSubfields.spec.js.map +0 -1
  544. package/dist/stripPunctuation.spec.js +0 -51
  545. package/dist/stripPunctuation.spec.js.map +0 -1
  546. package/dist/subfield-exclusion.spec.js +0 -523
  547. package/dist/subfield-exclusion.spec.js.map +0 -1
  548. package/dist/subfieldValueNormalizations.spec.js +0 -51
  549. package/dist/subfieldValueNormalizations.spec.js.map +0 -1
  550. package/dist/sync-007-and-300.spec.js +0 -51
  551. package/dist/sync-007-and-300.spec.js.map +0 -1
  552. package/dist/translate-terms.spec.js +0 -51
  553. package/dist/translate-terms.spec.js.map +0 -1
  554. package/dist/typeOfDate-008.spec.js +0 -47
  555. package/dist/typeOfDate-008.spec.js.map +0 -1
  556. package/dist/unicode-decomposition.spec.js +0 -91
  557. package/dist/unicode-decomposition.spec.js.map +0 -1
  558. package/dist/update-field-540.spec.js +0 -51
  559. package/dist/update-field-540.spec.js.map +0 -1
  560. package/dist/urn.spec.js +0 -52
  561. package/dist/urn.spec.js.map +0 -1
  562. package/src/melindaCustomMergeFields.json +0 -5120
  563. package/src/translate-terms.spec.js +0 -52
@@ -1,50 +1,33 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- var _clone = _interopRequireDefault(require("clone"));
8
- var _utils = require("./utils");
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- //import createDebugLogger from 'debug';
11
-
12
- // Author(s): Nicholas Volk
13
- function _default() {
1
+ import clone from "clone";
2
+ import { fieldToString } from "./utils.js";
3
+ export default function() {
14
4
  return {
15
5
  // Fixes MELINDA-8740
16
- description: 'Normalize qualifying information (020$q, 015$q, 024$q, 028$q)',
6
+ description: "Normalize qualifying information (020$q, 015$q, 024$q, 028$q)",
17
7
  validate,
18
8
  fix
19
9
  };
20
10
  function fix(record) {
21
- record.fields.forEach(field => {
11
+ record.fields.forEach((field) => {
22
12
  normalizeQualifyingInformationField(field);
23
13
  });
24
- const res = {
25
- message: [],
26
- fix: [],
27
- valid: true
28
- };
14
+ const res = { message: [], fix: [], valid: true };
29
15
  return res;
30
16
  }
31
17
  function validate(record) {
32
- const res = {
33
- message: []
34
- };
35
- record.fields?.forEach(field => {
18
+ const res = { message: [] };
19
+ record.fields?.forEach((field) => {
36
20
  validateField(field, res);
37
21
  });
38
22
  res.valid = !(res.message.length >= 1);
39
23
  return res;
40
24
  }
41
25
  function validateField(field, res) {
42
- const orig = (0, _utils.fieldToString)(field);
43
- const normalizedField = (0, _clone.default)(field);
26
+ const orig = fieldToString(field);
27
+ const normalizedField = clone(field);
44
28
  normalizeQualifyingInformationField(normalizedField);
45
- const mod = (0, _utils.fieldToString)(normalizedField);
29
+ const mod = fieldToString(normalizedField);
46
30
  if (orig !== mod) {
47
- // Fail as the input is "broken"/"crap"/sumthing
48
31
  res.message.push(`'TODO: ${orig}' => '${mod}'`);
49
32
  return;
50
33
  }
@@ -52,45 +35,37 @@ function _default() {
52
35
  }
53
36
  }
54
37
  function normalizeQualifyingInformationField(field) {
55
- if (!['015', '020', '024', '028'].includes(field.tag) || !field.subfields) {
38
+ if (!["015", "020", "024", "028"].includes(field.tag) || !field.subfields) {
56
39
  return;
57
40
  }
58
- field.subfields.forEach(sf => fixSubfield(sf)); // eslint-disable-line array-callback-return
41
+ field.subfields.forEach((sf) => fixSubfield(sf));
59
42
  return;
60
43
  function fixSubfield(sf) {
61
- if (sf.code !== 'q') {
44
+ if (sf.code !== "q") {
62
45
  return;
63
46
  }
64
47
  sf.value = normalizeValue(sf.value);
65
48
  }
66
49
  function normalizeValue(val) {
67
- // Should we do English as well: "coil bound" and "comb-bound" => "spiral-bound" (as per MTS)?
68
-
69
50
  if (val.match(/^(?:hft|häftad)[.,]*$/iu)) {
70
- // MELINDA-8740
71
- return 'mjuka pärmar';
51
+ return "mjuka p\xE4rmar";
72
52
  }
73
53
  if (val.match(/^inb(?:\.|unden)[.,]*$/iu)) {
74
- // MELINDA-8740
75
- return 'hårda pärmar';
54
+ return "h\xE5rda p\xE4rmar";
76
55
  }
77
- if (val === 'rengaskirja') {
78
- // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021
79
- return 'kierreselkä';
56
+ if (val === "rengaskirja") {
57
+ return "kierreselk\xE4";
80
58
  }
81
- if (val === 'ringpärm') {
82
- // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021
83
- return 'spiralrygg';
59
+ if (val === "ringp\xE4rm") {
60
+ return "spiralrygg";
84
61
  }
85
62
  if (val.match(/^nid(?:\.|ottu)[.,]*$/iu)) {
86
- // MELINDA-8740
87
- return 'pehmeäkantinen';
63
+ return "pehme\xE4kantinen";
88
64
  }
89
65
  if (val.match(/^sid(?:\.|ottu)[.,]*$/iu)) {
90
- // MELINDA-8740
91
- return 'kovakantinen';
66
+ return "kovakantinen";
92
67
  }
93
68
  return val;
94
69
  }
95
70
  }
96
- //# sourceMappingURL=normalize-qualifying-information.js.map
71
+ //# sourceMappingURL=normalize-qualifying-information.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"normalize-qualifying-information.js","names":["_clone","_interopRequireDefault","require","_utils","e","__esModule","default","_default","description","validate","fix","record","fields","forEach","field","normalizeQualifyingInformationField","res","message","valid","validateField","length","orig","fieldToString","normalizedField","clone","mod","push","includes","tag","subfields","sf","fixSubfield","code","value","normalizeValue","val","match"],"sources":["../src/normalize-qualifying-information.js"],"sourcesContent":["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString} from './utils';\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n // Fixes MELINDA-8740\n description: 'Normalize qualifying information (020$q, 015$q, 024$q, 028$q)',\n validate, fix\n };\n\n function fix(record) {\n record.fields.forEach(field => {\n normalizeQualifyingInformationField(field);\n });\n\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n record.fields?.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res) {\n const orig = fieldToString(field);\n\n const normalizedField = clone(field);\n normalizeQualifyingInformationField(normalizedField);\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'TODO: ${orig}' => '${mod}'`);\n return;\n }\n return;\n }\n}\n\n\nfunction normalizeQualifyingInformationField(field) {\n if (!['015', '020', '024', '028'].includes(field.tag) || !field.subfields) {\n return;\n }\n\n field.subfields.forEach(sf => fixSubfield(sf)); // eslint-disable-line array-callback-return\n return;\n\n function fixSubfield(sf) {\n if (sf.code !== 'q') {\n return;\n }\n sf.value = normalizeValue(sf.value);\n }\n\n function normalizeValue(val) {\n // Should we do English as well: \"coil bound\" and \"comb-bound\" => \"spiral-bound\" (as per MTS)?\n\n if (val.match(/^(?:hft|häftad)[.,]*$/iu)) { // MELINDA-8740\n return 'mjuka pärmar';\n }\n\n if (val.match(/^inb(?:\\.|unden)[.,]*$/iu)) { // MELINDA-8740\n return 'hårda pärmar';\n }\n\n if (val === 'rengaskirja') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'kierreselkä';\n }\n\n if (val === 'ringpärm') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'spiralrygg';\n }\n\n if (val.match(/^nid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'pehmeäkantinen';\n }\n\n if (val.match(/^sid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'kovakantinen';\n }\n return val;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/normalize-qualifying-information.js"],
4
+ "sourcesContent": ["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString} from './utils.js';\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n // Fixes MELINDA-8740\n description: 'Normalize qualifying information (020$q, 015$q, 024$q, 028$q)',\n validate, fix\n };\n\n function fix(record) {\n record.fields.forEach(field => {\n normalizeQualifyingInformationField(field);\n });\n\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n record.fields?.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res) {\n const orig = fieldToString(field);\n\n const normalizedField = clone(field);\n normalizeQualifyingInformationField(normalizedField);\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'TODO: ${orig}' => '${mod}'`);\n return;\n }\n return;\n }\n}\n\n\nfunction normalizeQualifyingInformationField(field) {\n if (!['015', '020', '024', '028'].includes(field.tag) || !field.subfields) {\n return;\n }\n\n field.subfields.forEach(sf => fixSubfield(sf));\n return;\n\n function fixSubfield(sf) {\n if (sf.code !== 'q') {\n return;\n }\n sf.value = normalizeValue(sf.value);\n }\n\n function normalizeValue(val) {\n // Should we do English as well: \"coil bound\" and \"comb-bound\" => \"spiral-bound\" (as per MTS)?\n\n if (val.match(/^(?:hft|h\u00E4ftad)[.,]*$/iu)) { // MELINDA-8740\n return 'mjuka p\u00E4rmar';\n }\n\n if (val.match(/^inb(?:\\.|unden)[.,]*$/iu)) { // MELINDA-8740\n return 'h\u00E5rda p\u00E4rmar';\n }\n\n if (val === 'rengaskirja') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'kierreselk\u00E4';\n }\n\n if (val === 'ringp\u00E4rm') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'spiralrygg';\n }\n\n if (val.match(/^nid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'pehme\u00E4kantinen';\n }\n\n if (val.match(/^sid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'kovakantinen';\n }\n return val;\n }\n}\n"],
5
+ "mappings": "AACA,OAAO,WAAW;AAClB,SAAQ,qBAAoB;AAG5B,0BAA2B;AAEzB,SAAO;AAAA;AAAA,IAEL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AACnB,WAAO,OAAO,QAAQ,WAAS;AAC7B,0CAAoC,KAAK;AAAA,IAC3C,CAAC;AAED,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAC9C,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,EAAC;AAExB,WAAO,QAAQ,QAAQ,WAAS;AAC9B,oBAAc,OAAO,GAAG;AAAA,IAC1B,CAAC;AAED,QAAI,QAAQ,EAAE,IAAI,QAAQ,UAAU;AACpC,WAAO;AAAA,EACT;AAEA,WAAS,cAAc,OAAO,KAAK;AACjC,UAAM,OAAO,cAAc,KAAK;AAEhC,UAAM,kBAAkB,MAAM,KAAK;AACnC,wCAAoC,eAAe;AACnD,UAAM,MAAM,cAAc,eAAe;AACzC,QAAI,SAAS,KAAK;AAChB,UAAI,QAAQ,KAAK,UAAU,IAAI,SAAS,GAAG,GAAG;AAC9C;AAAA,IACF;AACA;AAAA,EACF;AACF;AAGA,SAAS,oCAAoC,OAAO;AAClD,MAAI,CAAC,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,MAAM,GAAG,KAAK,CAAC,MAAM,WAAW;AACzE;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,QAAM,YAAY,EAAE,CAAC;AAC7C;AAEA,WAAS,YAAY,IAAI;AACvB,QAAI,GAAG,SAAS,KAAK;AACnB;AAAA,IACF;AACA,OAAG,QAAQ,eAAe,GAAG,KAAK;AAAA,EACpC;AAEA,WAAS,eAAe,KAAK;AAG3B,QAAI,IAAI,MAAM,yBAAyB,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,MAAM,0BAA0B,GAAG;AACzC,aAAO;AAAA,IACT;AAEA,QAAI,QAAQ,eAAe;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,QAAQ,eAAY;AACtB,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,MAAM,yBAAyB,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,MAAM,yBAAyB,GAAG;AACxC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,44 @@
1
+ import assert from "node:assert";
2
+ import { MarcRecord } from "@natlibfi/marc-record";
3
+ import validatorFactory from "./normalize-qualifying-information.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", "normalize-qualifying-information"],
10
+ useMetadataFile: true,
11
+ recurse: false,
12
+ fixura: {
13
+ reader: READERS.JSON
14
+ },
15
+ hooks: {
16
+ before: async () => {
17
+ testValidatorFactory();
18
+ }
19
+ }
20
+ });
21
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/normalize-qualifying-information:test");
22
+ async function testValidatorFactory() {
23
+ const validator = await validatorFactory();
24
+ assert.equal(typeof validator, "object");
25
+ assert.equal(typeof validator.description, "string");
26
+ assert.equal(typeof validator.validate, "function");
27
+ }
28
+ async function callback({ getFixture, enabled = true, fix = false }) {
29
+ if (enabled === false) {
30
+ debug("TEST SKIPPED!");
31
+ return;
32
+ }
33
+ const validator = await validatorFactory();
34
+ const record = new MarcRecord(getFixture("record.json"));
35
+ const expectedResult = getFixture("expectedResult.json");
36
+ if (!fix) {
37
+ const result = await validator.validate(record);
38
+ assert.deepEqual(result, expectedResult);
39
+ return;
40
+ }
41
+ await validator.fix(record);
42
+ assert.deepEqual(record, expectedResult);
43
+ }
44
+ //# sourceMappingURL=normalize-qualifying-information.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/normalize-qualifying-information.test.js"],
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './normalize-qualifying-information.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', 'normalize-qualifying-information'],\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/normalize-qualifying-information: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,kCAAkC;AAAA,EACrF,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,gFAAgF;AAEhH,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
+ }
@@ -1,71 +1,22 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- exports.fieldFixComposition = fieldFixComposition;
8
- exports.fixComposition = fixComposition;
9
- exports.precomposeFinnishLetters = precomposeFinnishLetters;
10
- var _clone = _interopRequireDefault(require("clone"));
11
- var _unicodeDecomposition = require("./unicode-decomposition");
12
- var _utils = require("./utils");
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- //import createDebugLogger from 'debug';
15
-
16
- // Note that https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js contains
17
- // similar functionalities. It's less generic and lacks diacritic removal but has it advantages as well.
18
-
19
- //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-utf-diacritics');
20
-
21
- // See also https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js .
22
- // It uses a list of convertable characters whilst this uses a generic stuff as well.
23
- // It handles various '.' and '©' type normalizations as well.
24
- // NB! This version has minor bug/feature issue regarding fixComposition()
25
-
26
- // Author(s): Nicholas Volk
27
- function _default() {
1
+ import clone from "clone";
2
+ import { convert as nongenericNormalization } from "./unicode-decomposition.js";
3
+ import { fieldToString } from "./utils.js";
4
+ export default function() {
28
5
  return {
29
- description: 'Generic normalization of latin UTF-8 diacritics. Precompose Finnish å, ä and ö. Decompose others.',
6
+ description: "Generic normalization of latin UTF-8 diacritics. Precompose Finnish \xE5, \xE4 and \xF6. Decompose others.",
30
7
  validate,
31
8
  fix
32
9
  };
33
10
  function fix(record) {
34
- const res = {
35
- message: [],
36
- fix: [],
37
- valid: true
38
- };
39
- //message.fix = [];
40
-
41
- // Actual parsing of all fields
42
- /*
43
- if (!record.fields) {
44
- return false;
45
- }
46
- */
47
-
48
- record.fields.forEach(field => {
11
+ const res = { message: [], fix: [], valid: true };
12
+ record.fields.forEach((field) => {
49
13
  fieldFixComposition(field);
50
- //validateField(field, true, message);
51
14
  });
52
-
53
- // message.valid = !(message.message.length >= 1);
54
15
  return res;
55
16
  }
56
17
  function validate(record) {
57
- const res = {
58
- message: []
59
- };
60
-
61
- // Actual parsing of all fields
62
- /*
63
- if (!record.fields) {
64
- return false;
65
- }
66
- */
67
-
68
- record.fields.forEach(field => {
18
+ const res = { message: [] };
19
+ record.fields.forEach((field) => {
69
20
  validateField(field, res);
70
21
  });
71
22
  res.valid = !(res.message.length >= 1);
@@ -75,69 +26,32 @@ function _default() {
75
26
  if (!field.subfields) {
76
27
  return;
77
28
  }
78
- const orig = (0, _utils.fieldToString)(field);
79
- const normalizedField = fieldFixComposition((0, _clone.default)(field));
80
- const mod = (0, _utils.fieldToString)(normalizedField);
29
+ const orig = fieldToString(field);
30
+ const normalizedField = fieldFixComposition(clone(field));
31
+ const mod = fieldToString(normalizedField);
81
32
  if (orig !== mod) {
82
- // Fail as the input is "broken"/"crap"/sumthing
83
33
  res.message.push(`'${orig}' requires normalization`);
84
34
  return;
85
35
  }
86
36
  return;
87
37
  }
88
38
  }
89
-
90
- // Traditionally these six are precomposed and all the rest decomposed
91
- function precomposeFinnishLetters(value = '') {
92
- return value.replace(/å/gu, 'å').replace(/ä/gu, 'ä').replace(/ö/gu, 'ö').replace(/Å/gu, 'Å').replace(/Ä/gu, 'Ä').replace(/Ö/gu, 'Ö');
39
+ export function precomposeFinnishLetters(value = "") {
40
+ return value.replace(/å/gu, "\xE5").replace(/ä/gu, "\xE4").replace(/ö/gu, "\xF6").replace(/Å/gu, "\xC5").replace(/Ä/gu, "\xC4").replace(/Ö/gu, "\xD6");
93
41
  }
94
- function fixComposition(value = '') {
95
- // Target: Diacritics use Melinda internal notation.
96
- // General solution: Decompose everything and then compose 'å', 'ä', 'ö', 'Å', 'Ä' and 'Ö'.
97
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
98
- // Bug/Feature: the generic normalize() function also normalizes non-latin encodings as well, is this ok?
99
- // Exception: Input contains non-Latin script letters: don't decompose (see field 880 tests):
42
+ export function fixComposition(value = "") {
100
43
  if (value.match(/[^\p{Script=Latin}\p{Script=Common}\p{Script=Inherited}]/u)) {
101
- // Problem with this approach: mixed language content (eg. cyrillic + latin) won't get normalized.
102
- // Hack/Damage control: we might add decomposition rules for most common diacritis here (eg. ü, é...).
103
- // OR we could split input to words and handle them separately?
104
- // NB! Hack not implemented yet. The main source of problematic case would probably be greek characters
105
- // within texts, that are written with latin alphabet.
106
- //return precomposeFinnishLetters(value);
107
- return (0, _unicodeDecomposition.convert)(value);
44
+ return nongenericNormalization(value);
108
45
  }
109
- return precomposeFinnishLetters(String(value).normalize('NFD'));
46
+ return precomposeFinnishLetters(String(value).normalize("NFD"));
110
47
  }
111
- function fieldFixComposition(field) {
48
+ export function fieldFixComposition(field) {
112
49
  if (!field.subfields) {
113
50
  return field;
114
51
  }
115
- //const originalValue = fieldToString(field);
116
- //nvdebug(`fFC: '${originalValue}'`, debug);
117
52
  field.subfields.forEach((subfield, index) => {
118
53
  field.subfields[index].value = fixComposition(subfield.value);
119
54
  });
120
- //const newValue = fieldToString(field);
121
- //if (originalValue !== newValue) {
122
- // debug(`FIXCOMP: '${originalValue}' => '${newValue}'`);
123
- //}
124
55
  return field;
125
56
  }
126
-
127
- /*
128
- export function fieldRemoveDecomposedDiacritics(field) {
129
- // Raison d'être/motivation: "Sirén" and diacriticless "Siren" might refer to a same surname, so this normalization
130
- // allows us to compare authors and avoid duplicate fields.
131
- field.subfields.forEach((sf) => {
132
- sf.value = removeDecomposedDiacritics(sf.value);
133
- });
134
-
135
- function removeDecomposedDiacritics(value = '') {
136
- // NB #1: Does nothing to precomposed letters. String.normalize('NFD') can handle them.
137
- // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this.
138
- // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.
139
- return String(value).replace(/\p{Diacritic}/gu, '');
140
- }
141
- }
142
- */
143
- //# sourceMappingURL=normalize-utf8-diacritics.js.map
57
+ //# sourceMappingURL=normalize-utf8-diacritics.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"normalize-utf8-diacritics.js","names":["_clone","_interopRequireDefault","require","_unicodeDecomposition","_utils","e","__esModule","default","_default","description","validate","fix","record","res","message","valid","fields","forEach","field","fieldFixComposition","validateField","length","subfields","orig","fieldToString","normalizedField","clone","mod","push","precomposeFinnishLetters","value","replace","fixComposition","match","nongenericNormalization","String","normalize","subfield","index"],"sources":["../src/normalize-utf8-diacritics.js"],"sourcesContent":["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {convert as nongenericNormalization} from './unicode-decomposition';\nimport {fieldToString} from './utils';\n\n// Note that https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js contains\n// similar functionalities. It's less generic and lacks diacritic removal but has it advantages as well.\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-utf-diacritics');\n\n// See also https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js .\n// It uses a list of convertable characters whilst this uses a generic stuff as well.\n// It handles various '.' and '©' type normalizations as well.\n// NB! This version has minor bug/feature issue regarding fixComposition()\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n description: 'Generic normalization of latin UTF-8 diacritics. Precompose Finnish å, ä and ö. Decompose others.',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n //message.fix = [];\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n fieldFixComposition(field);\n //validateField(field, true, message);\n });\n\n // message.valid = !(message.message.length >= 1);\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res) {\n if (!field.subfields) {\n return;\n }\n const orig = fieldToString(field);\n\n const normalizedField = fieldFixComposition(clone(field));\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'${orig}' requires normalization`);\n return;\n }\n return;\n }\n}\n\n\n// Traditionally these six are precomposed and all the rest decomposed\nexport function precomposeFinnishLetters(value = '') {\n return value.\n replace(/å/gu, 'å').\n replace(/ä/gu, 'ä').\n replace(/ö/gu, 'ö').\n replace(/Å/gu, 'Å').\n replace(/Ä/gu, 'Ä').\n replace(/Ö/gu, 'Ö');\n}\n\nexport function fixComposition(value = '') {\n // Target: Diacritics use Melinda internal notation.\n // General solution: Decompose everything and then compose 'å', 'ä', 'ö', 'Å', 'Ä' and 'Ö'.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n // Bug/Feature: the generic normalize() function also normalizes non-latin encodings as well, is this ok?\n // Exception: Input contains non-Latin script letters: don't decompose (see field 880 tests):\n if (value.match(/[^\\p{Script=Latin}\\p{Script=Common}\\p{Script=Inherited}]/u)) {\n // Problem with this approach: mixed language content (eg. cyrillic + latin) won't get normalized.\n // Hack/Damage control: we might add decomposition rules for most common diacritis here (eg. ü, é...).\n // OR we could split input to words and handle them separately?\n // NB! Hack not implemented yet. The main source of problematic case would probably be greek characters\n // within texts, that are written with latin alphabet.\n //return precomposeFinnishLetters(value);\n return nongenericNormalization(value);\n }\n return precomposeFinnishLetters(String(value).normalize('NFD'));\n}\n\n\nexport function fieldFixComposition(field) {\n if (!field.subfields) {\n return field;\n }\n //const originalValue = fieldToString(field);\n //nvdebug(`fFC: '${originalValue}'`, debug);\n field.subfields.forEach((subfield, index) => {\n field.subfields[index].value = fixComposition(subfield.value);\n });\n //const newValue = fieldToString(field);\n //if (originalValue !== newValue) {\n // debug(`FIXCOMP: '${originalValue}' => '${newValue}'`);\n //}\n return field;\n}\n\n/*\nexport function fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value);\n });\n\n function removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. String.normalize('NFD') can handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this.\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n }\n}\n*/\n\n"],"mappings":"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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/normalize-utf8-diacritics.js"],
4
+ "sourcesContent": ["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {convert as nongenericNormalization} from './unicode-decomposition.js';\nimport {fieldToString} from './utils.js';\n\n// Note that https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js contains\n// similar functionalities. It's less generic and lacks diacritic removal but has it advantages as well.\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-utf-diacritics');\n\n// See also https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js .\n// It uses a list of convertable characters whilst this uses a generic stuff as well.\n// It handles various '.' and '\u00A9' type normalizations as well.\n// NB! This version has minor bug/feature issue regarding fixComposition()\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n description: 'Generic normalization of latin UTF-8 diacritics. Precompose Finnish \u00E5, \u00E4 and \u00F6. Decompose others.',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n //message.fix = [];\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n fieldFixComposition(field);\n //validateField(field, true, message);\n });\n\n // message.valid = !(message.message.length >= 1);\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res) {\n if (!field.subfields) {\n return;\n }\n const orig = fieldToString(field);\n\n const normalizedField = fieldFixComposition(clone(field));\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'${orig}' requires normalization`);\n return;\n }\n return;\n }\n}\n\n\n// Traditionally these six are precomposed and all the rest decomposed\nexport function precomposeFinnishLetters(value = '') {\n return value.\n replace(/a\u030A/gu, '\u00E5').\n replace(/a\u0308/gu, '\u00E4').\n replace(/o\u0308/gu, '\u00F6').\n replace(/A\u030A/gu, '\u00C5').\n replace(/A\u0308/gu, '\u00C4').\n replace(/O\u0308/gu, '\u00D6');\n}\n\nexport function fixComposition(value = '') {\n // Target: Diacritics use Melinda internal notation.\n // General solution: Decompose everything and then compose '\u00E5', '\u00E4', '\u00F6', '\u00C5', '\u00C4' and '\u00D6'.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n // Bug/Feature: the generic normalize() function also normalizes non-latin encodings as well, is this ok?\n // Exception: Input contains non-Latin script letters: don't decompose (see field 880 tests):\n if (value.match(/[^\\p{Script=Latin}\\p{Script=Common}\\p{Script=Inherited}]/u)) {\n // Problem with this approach: mixed language content (eg. cyrillic + latin) won't get normalized.\n // Hack/Damage control: we might add decomposition rules for most common diacritis here (eg. \u00FC, \u00E9...).\n // OR we could split input to words and handle them separately?\n // NB! Hack not implemented yet. The main source of problematic case would probably be greek characters\n // within texts, that are written with latin alphabet.\n //return precomposeFinnishLetters(value);\n return nongenericNormalization(value);\n }\n return precomposeFinnishLetters(String(value).normalize('NFD'));\n}\n\n\nexport function fieldFixComposition(field) {\n if (!field.subfields) {\n return field;\n }\n //const originalValue = fieldToString(field);\n //nvdebug(`fFC: '${originalValue}'`, debug);\n field.subfields.forEach((subfield, index) => {\n field.subfields[index].value = fixComposition(subfield.value);\n });\n //const newValue = fieldToString(field);\n //if (originalValue !== newValue) {\n // debug(`FIXCOMP: '${originalValue}' => '${newValue}'`);\n //}\n return field;\n}\n\n/*\nexport function fieldRemoveDecomposedDiacritics(field) {\n // Raison d'\u00EAtre/motivation: \"Sir\u00E9n\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value);\n });\n\n function removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. String.normalize('NFD') can handle them.\n // NB #2: Finnish letters '\u00E5', '\u00E4', '\u00F6', '\u00C5', \u00C4', and '\u00D6' should be handled (=precomposed) before calling this.\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n }\n}\n*/\n\n"],
5
+ "mappings": "AACA,OAAO,WAAW;AAClB,SAAQ,WAAW,+BAA8B;AACjD,SAAQ,qBAAoB;AAa5B,0BAA2B;AAEzB,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AACnB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAU9C,WAAO,OAAO,QAAQ,WAAS;AAC7B,0BAAoB,KAAK;AAAA,IAE3B,CAAC;AAGD,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,EAAC;AASxB,WAAO,OAAO,QAAQ,WAAS;AAC7B,oBAAc,OAAO,GAAG;AAAA,IAC1B,CAAC;AAED,QAAI,QAAQ,EAAE,IAAI,QAAQ,UAAU;AACpC,WAAO;AAAA,EACT;AAEA,WAAS,cAAc,OAAO,KAAK;AACjC,QAAI,CAAC,MAAM,WAAW;AACpB;AAAA,IACF;AACA,UAAM,OAAO,cAAc,KAAK;AAEhC,UAAM,kBAAkB,oBAAoB,MAAM,KAAK,CAAC;AACxD,UAAM,MAAM,cAAc,eAAe;AACzC,QAAI,SAAS,KAAK;AAChB,UAAI,QAAQ,KAAK,IAAI,IAAI,0BAA0B;AACnD;AAAA,IACF;AACA;AAAA,EACF;AACF;AAIO,gBAAS,yBAAyB,QAAQ,IAAI;AACnD,SAAO,MACL,QAAQ,QAAQ,MAAG,EACnB,QAAQ,QAAQ,MAAG,EACnB,QAAQ,QAAQ,MAAG,EACnB,QAAQ,QAAQ,MAAG,EACnB,QAAQ,QAAQ,MAAG,EACnB,QAAQ,QAAQ,MAAG;AACvB;AAEO,gBAAS,eAAe,QAAQ,IAAI;AAMzC,MAAI,MAAM,MAAM,2DAA2D,GAAG;AAO5E,WAAO,wBAAwB,KAAK;AAAA,EACtC;AACA,SAAO,yBAAyB,OAAO,KAAK,EAAE,UAAU,KAAK,CAAC;AAChE;AAGO,gBAAS,oBAAoB,OAAO;AACzC,MAAI,CAAC,MAAM,WAAW;AACpB,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,QAAQ,CAAC,UAAU,UAAU;AAC3C,UAAM,UAAU,KAAK,EAAE,QAAQ,eAAe,SAAS,KAAK;AAAA,EAC9D,CAAC;AAKD,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,44 @@
1
+ import assert from "node:assert";
2
+ import { MarcRecord } from "@natlibfi/marc-record";
3
+ import validatorFactory from "./normalize-utf8-diacritics.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", "normalize-utf8-diacritics"],
10
+ useMetadataFile: true,
11
+ recurse: false,
12
+ fixura: {
13
+ reader: READERS.JSON
14
+ },
15
+ hooks: {
16
+ before: async () => {
17
+ testValidatorFactory();
18
+ }
19
+ }
20
+ });
21
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/normalize-utf8-diacritics:test");
22
+ async function testValidatorFactory() {
23
+ const validator = await validatorFactory();
24
+ assert.equal(typeof validator, "object");
25
+ assert.equal(typeof validator.description, "string");
26
+ assert.equal(typeof validator.validate, "function");
27
+ }
28
+ async function callback({ getFixture, enabled = true, fix = false }) {
29
+ if (enabled === false) {
30
+ debug("TEST SKIPPED!");
31
+ return;
32
+ }
33
+ const validator = await validatorFactory();
34
+ const record = new MarcRecord(getFixture("record.json"));
35
+ const expectedResult = getFixture("expectedResult.json");
36
+ if (!fix) {
37
+ const result = await validator.validate(record);
38
+ assert.deepEqual(result, expectedResult);
39
+ return;
40
+ }
41
+ await validator.fix(record);
42
+ assert.deepEqual(record, expectedResult);
43
+ }
44
+ //# sourceMappingURL=normalize-utf8-diacritics.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/normalize-utf8-diacritics.test.js"],
4
+ "sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './normalize-utf8-diacritics.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', 'normalize-utf8-diacritics'],\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/normalize-utf8-diacritics: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,2BAA2B;AAAA,EAC9E,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,yEAAyE;AAEzG,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
+ }