@natlibfi/marc-record-validators-melinda 3.2.0 → 3.3.14-alpha.3

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 (593) hide show
  1. package/.github/CODEOWNERS +2 -0
  2. package/.github/dependabot.yml +40 -0
  3. package/.github/workflows/melinda-node-tests.yml +61 -0
  4. package/LICENSE.txt +21 -661
  5. package/README.md +4 -5
  6. package/dist/access-rights.js +94 -0
  7. package/dist/access-rights.js.map +1 -0
  8. package/dist/access-rights.spec.js +150 -0
  9. package/dist/access-rights.spec.js.map +1 -0
  10. package/dist/double-commas.js +17 -27
  11. package/dist/double-commas.js.map +1 -1
  12. package/dist/double-commas.spec.js +72 -27
  13. package/dist/double-commas.spec.js.map +1 -1
  14. package/dist/duplicates-ind1.js +47 -27
  15. package/dist/duplicates-ind1.js.map +1 -1
  16. package/dist/duplicates-ind1.spec.js +44 -27
  17. package/dist/duplicates-ind1.spec.js.map +1 -1
  18. package/dist/empty-fields.js +79 -29
  19. package/dist/empty-fields.js.map +1 -1
  20. package/dist/empty-fields.spec.js +113 -27
  21. package/dist/empty-fields.spec.js.map +1 -1
  22. package/dist/ending-punctuation-conf.js +772 -129
  23. package/dist/ending-punctuation-conf.js.map +1 -1
  24. package/dist/ending-punctuation.js +291 -72
  25. package/dist/ending-punctuation.js.map +1 -1
  26. package/dist/ending-punctuation.spec.js +2638 -118
  27. package/dist/ending-punctuation.spec.js.map +1 -1
  28. package/dist/ending-whitespace.js +58 -0
  29. package/dist/ending-whitespace.js.map +1 -0
  30. package/dist/ending-whitespace.spec.js +42 -0
  31. package/dist/ending-whitespace.spec.js.map +1 -0
  32. package/dist/field-521-fix.js +96 -0
  33. package/dist/field-521-fix.js.map +1 -0
  34. package/dist/field-521-fix.spec.js +51 -0
  35. package/dist/field-521-fix.spec.js.map +1 -0
  36. package/dist/field-exclusion.js +214 -63
  37. package/dist/field-exclusion.js.map +1 -1
  38. package/dist/field-exclusion.spec.js +1057 -31
  39. package/dist/field-exclusion.spec.js.map +1 -1
  40. package/dist/field-structure.js +249 -78
  41. package/dist/field-structure.js.map +1 -1
  42. package/dist/field-structure.spec.js +534 -31
  43. package/dist/field-structure.spec.js.map +1 -1
  44. package/dist/fields-present.js +31 -27
  45. package/dist/fields-present.js.map +1 -1
  46. package/dist/fields-present.spec.js +120 -27
  47. package/dist/fields-present.spec.js.map +1 -1
  48. package/dist/fixed-fields.js +72 -27
  49. package/dist/fixed-fields.js.map +1 -1
  50. package/dist/fixed-fields.spec.js +139 -27
  51. package/dist/fixed-fields.spec.js.map +1 -1
  52. package/dist/identical-fields.js +42 -28
  53. package/dist/identical-fields.js.map +1 -1
  54. package/dist/identical-fields.spec.js +98 -27
  55. package/dist/identical-fields.spec.js.map +1 -1
  56. package/dist/index.js +202 -27
  57. package/dist/index.js.map +1 -1
  58. package/dist/indicator-fixes.js +191 -0
  59. package/dist/indicator-fixes.js.map +1 -0
  60. package/dist/indicator-fixes.spec.js +51 -0
  61. package/dist/indicator-fixes.spec.js.map +1 -0
  62. package/dist/isbn-issn.js +266 -27
  63. package/dist/isbn-issn.js.map +1 -1
  64. package/dist/isbn-issn.spec.js +594 -27
  65. package/dist/isbn-issn.spec.js.map +1 -1
  66. package/dist/item-language.js +171 -27
  67. package/dist/item-language.js.map +1 -1
  68. package/dist/item-language.spec.js +305 -27
  69. package/dist/item-language.spec.js.map +1 -1
  70. package/dist/mergeField500Lisapainokset.js +155 -0
  71. package/dist/mergeField500Lisapainokset.js.map +1 -0
  72. package/dist/mergeField500Lisapainokset.spec.js +51 -0
  73. package/dist/mergeField500Lisapainokset.spec.js.map +1 -0
  74. package/dist/mergeRelatorTermFields.js +140 -0
  75. package/dist/mergeRelatorTermFields.js.map +1 -0
  76. package/dist/mergeRelatorTermFields.spec.js +51 -0
  77. package/dist/mergeRelatorTermFields.spec.js.map +1 -0
  78. package/dist/multiple-subfield-0.js +120 -0
  79. package/dist/multiple-subfield-0.js.map +1 -0
  80. package/dist/multiple-subfield-0.spec.js +51 -0
  81. package/dist/multiple-subfield-0.spec.js.map +1 -0
  82. package/dist/non-breaking-space.js +61 -0
  83. package/dist/non-breaking-space.js.map +1 -0
  84. package/dist/non-breaking-space.spec.js +42 -0
  85. package/dist/non-breaking-space.spec.js.map +1 -0
  86. package/dist/normalize-identifiers.js +210 -0
  87. package/dist/normalize-identifiers.js.map +1 -0
  88. package/dist/normalize-identifiers.spec.js +51 -0
  89. package/dist/normalize-identifiers.spec.js.map +1 -0
  90. package/dist/normalize-utf8-diacritics.js +140 -0
  91. package/dist/normalize-utf8-diacritics.js.map +1 -0
  92. package/dist/normalize-utf8-diacritics.spec.js +51 -0
  93. package/dist/normalize-utf8-diacritics.spec.js.map +1 -0
  94. package/dist/punctuation/index.js +281 -0
  95. package/dist/punctuation/index.js.map +1 -0
  96. package/dist/punctuation/rules/aut.js +332 -0
  97. package/dist/punctuation/rules/aut.js.map +1 -0
  98. package/dist/punctuation/rules/bib.js +374 -0
  99. package/dist/punctuation/rules/bib.js.map +1 -0
  100. package/dist/punctuation/rules/index.js +21 -0
  101. package/dist/punctuation/rules/index.js.map +1 -0
  102. package/dist/punctuation.spec.js +51 -0
  103. package/dist/punctuation.spec.js.map +1 -0
  104. package/dist/punctuation2.js +726 -0
  105. package/dist/punctuation2.js.map +1 -0
  106. package/dist/punctuation2.spec.js +51 -0
  107. package/dist/punctuation2.spec.js.map +1 -0
  108. package/dist/reindexSubfield6OccurenceNumbers.js +199 -0
  109. package/dist/reindexSubfield6OccurenceNumbers.js.map +1 -0
  110. package/dist/reindexSubfield6OccurenceNumbers.spec.js +51 -0
  111. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +1 -0
  112. package/dist/removeDuplicateDataFields.js +405 -0
  113. package/dist/removeDuplicateDataFields.js.map +1 -0
  114. package/dist/removeDuplicateDataFields.spec.js +51 -0
  115. package/dist/removeDuplicateDataFields.spec.js.map +1 -0
  116. package/dist/removeInferiorDataFields.js +245 -0
  117. package/dist/removeInferiorDataFields.js.map +1 -0
  118. package/dist/removeInferiorDataFields.spec.js +51 -0
  119. package/dist/removeInferiorDataFields.spec.js.map +1 -0
  120. package/dist/resolvable-ext-references-melinda.js +112 -31
  121. package/dist/resolvable-ext-references-melinda.js.map +1 -1
  122. package/dist/resolvable-ext-references-melinda.spec.js +166 -27
  123. package/dist/resolvable-ext-references-melinda.spec.js.map +1 -1
  124. package/dist/resolveOrphanedSubfield6s.js +116 -0
  125. package/dist/resolveOrphanedSubfield6s.js.map +1 -0
  126. package/dist/resolveOrphanedSubfield6s.spec.js +51 -0
  127. package/dist/resolveOrphanedSubfield6s.spec.js.map +1 -0
  128. package/dist/sanitize-vocabulary-source-codes.js +93 -0
  129. package/dist/sanitize-vocabulary-source-codes.js.map +1 -0
  130. package/dist/sanitize-vocabulary-source-codes.spec.js +51 -0
  131. package/dist/sanitize-vocabulary-source-codes.spec.js.map +1 -0
  132. package/dist/sort-tags.js +53 -27
  133. package/dist/sort-tags.js.map +1 -1
  134. package/dist/sort-tags.spec.js +206 -27
  135. package/dist/sort-tags.spec.js.map +1 -1
  136. package/dist/sortRelatorTerms.js +135 -0
  137. package/dist/sortRelatorTerms.js.map +1 -0
  138. package/dist/sortRelatorTerms.spec.js +51 -0
  139. package/dist/sortRelatorTerms.spec.js.map +1 -0
  140. package/dist/sortSubfields.js +279 -0
  141. package/dist/sortSubfields.js.map +1 -0
  142. package/dist/sortSubfields.spec.js +51 -0
  143. package/dist/sortSubfields.spec.js.map +1 -0
  144. package/dist/stripPunctuation.js +49 -0
  145. package/dist/stripPunctuation.js.map +1 -0
  146. package/dist/stripPunctuation.spec.js +51 -0
  147. package/dist/stripPunctuation.spec.js.map +1 -0
  148. package/dist/subfield-exclusion.js +174 -57
  149. package/dist/subfield-exclusion.js.map +1 -1
  150. package/dist/subfield-exclusion.spec.js +521 -31
  151. package/dist/subfield-exclusion.spec.js.map +1 -1
  152. package/dist/subfield6Utils.js +457 -0
  153. package/dist/subfield6Utils.js.map +1 -0
  154. package/dist/subfield8Utils.js +99 -0
  155. package/dist/subfield8Utils.js.map +1 -0
  156. package/dist/typeOfDate-008.js +48 -0
  157. package/dist/typeOfDate-008.js.map +1 -0
  158. package/dist/typeOfDate-008.spec.js +47 -0
  159. package/dist/typeOfDate-008.spec.js.map +1 -0
  160. package/dist/unicode-decomposition.js +139 -30
  161. package/dist/unicode-decomposition.js.map +1 -1
  162. package/dist/unicode-decomposition.spec.js +90 -27
  163. package/dist/unicode-decomposition.spec.js.map +1 -1
  164. package/dist/update-field-540.js +119 -0
  165. package/dist/update-field-540.js.map +1 -0
  166. package/dist/update-field-540.spec.js +51 -0
  167. package/dist/update-field-540.spec.js.map +1 -0
  168. package/dist/urn.js +185 -0
  169. package/dist/urn.js.map +1 -0
  170. package/dist/urn.spec.js +238 -0
  171. package/dist/urn.spec.js.map +1 -0
  172. package/dist/utils.js +58 -0
  173. package/dist/utils.js.map +1 -0
  174. package/package.json +114 -124
  175. package/src/access-rights.js +84 -0
  176. package/src/access-rights.spec.js +126 -0
  177. package/src/double-commas.js +12 -49
  178. package/src/double-commas.spec.js +50 -82
  179. package/src/duplicates-ind1.js +34 -74
  180. package/src/duplicates-ind1.spec.js +39 -117
  181. package/src/empty-fields.js +62 -74
  182. package/src/empty-fields.spec.js +134 -207
  183. package/src/ending-punctuation-conf.js +679 -644
  184. package/src/ending-punctuation.js +260 -250
  185. package/src/ending-punctuation.spec.js +2545 -2322
  186. package/src/ending-whitespace.js +40 -0
  187. package/src/ending-whitespace.spec.js +44 -0
  188. package/src/field-521-fix.js +92 -0
  189. package/src/field-521-fix.spec.js +52 -0
  190. package/src/field-exclusion.js +197 -215
  191. package/src/field-exclusion.spec.js +883 -481
  192. package/src/field-structure.js +213 -271
  193. package/src/field-structure.spec.js +597 -474
  194. package/src/fields-present.js +19 -49
  195. package/src/fields-present.spec.js +90 -91
  196. package/src/fixed-fields.js +61 -94
  197. package/src/fixed-fields.spec.js +81 -125
  198. package/src/identical-fields.js +29 -48
  199. package/src/identical-fields.spec.js +114 -146
  200. package/src/index.js +41 -46
  201. package/src/indicator-fixes.js +211 -0
  202. package/src/indicator-fixes.spec.js +52 -0
  203. package/src/isbn-issn.js +254 -106
  204. package/src/isbn-issn.spec.js +399 -172
  205. package/src/item-language.js +158 -195
  206. package/src/item-language.spec.js +314 -306
  207. package/src/mergeField500Lisapainokset.js +153 -0
  208. package/src/mergeField500Lisapainokset.spec.js +52 -0
  209. package/src/mergeRelatorTermFields.js +143 -0
  210. package/src/mergeRelatorTermFields.spec.js +52 -0
  211. package/src/multiple-subfield-0.js +129 -0
  212. package/src/multiple-subfield-0.spec.js +52 -0
  213. package/src/non-breaking-space.js +49 -0
  214. package/src/non-breaking-space.spec.js +44 -0
  215. package/src/normalize-identifiers.js +197 -0
  216. package/src/normalize-identifiers.spec.js +52 -0
  217. package/src/normalize-utf8-diacritics.js +141 -0
  218. package/src/normalize-utf8-diacritics.spec.js +52 -0
  219. package/src/punctuation/index.js +292 -0
  220. package/src/punctuation/rules/aut.js +372 -0
  221. package/src/punctuation/rules/bib.js +420 -0
  222. package/src/punctuation/rules/index.js +7 -0
  223. package/src/punctuation.spec.js +52 -0
  224. package/src/punctuation2.js +441 -0
  225. package/src/punctuation2.spec.js +52 -0
  226. package/src/reindexSubfield6OccurenceNumbers.js +210 -0
  227. package/src/reindexSubfield6OccurenceNumbers.spec.js +52 -0
  228. package/src/removeDuplicateDataFields.js +447 -0
  229. package/src/removeDuplicateDataFields.spec.js +52 -0
  230. package/src/removeInferiorDataFields.js +259 -0
  231. package/src/removeInferiorDataFields.spec.js +52 -0
  232. package/src/resolvable-ext-references-melinda.js +89 -122
  233. package/src/resolvable-ext-references-melinda.spec.js +168 -198
  234. package/src/resolveOrphanedSubfield6s.js +115 -0
  235. package/src/resolveOrphanedSubfield6s.spec.js +52 -0
  236. package/src/sanitize-vocabulary-source-codes.js +99 -0
  237. package/src/sanitize-vocabulary-source-codes.spec.js +52 -0
  238. package/src/sort-tags.js +34 -60
  239. package/src/sort-tags.spec.js +256 -290
  240. package/src/sortRelatorTerms.js +142 -0
  241. package/src/sortRelatorTerms.spec.js +52 -0
  242. package/src/sortSubfields.js +176 -0
  243. package/src/sortSubfields.spec.js +52 -0
  244. package/src/stripPunctuation.js +42 -0
  245. package/src/stripPunctuation.spec.js +52 -0
  246. package/src/subfield-exclusion.js +157 -180
  247. package/src/subfield-exclusion.spec.js +507 -453
  248. package/src/subfield6Utils.js +485 -0
  249. package/src/subfield8Utils.js +102 -0
  250. package/src/typeOfDate-008.js +40 -0
  251. package/src/typeOfDate-008.spec.js +47 -0
  252. package/src/unicode-decomposition.js +130 -145
  253. package/src/unicode-decomposition.spec.js +89 -115
  254. package/src/update-field-540.js +99 -0
  255. package/src/update-field-540.spec.js +52 -0
  256. package/src/urn.js +164 -0
  257. package/src/urn.spec.js +231 -0
  258. package/src/utils.js +52 -0
  259. package/test-fixtures/duplicates-ind1/01/expectedResult.json +4 -0
  260. package/test-fixtures/duplicates-ind1/01/metadata.json +4 -0
  261. package/test-fixtures/duplicates-ind1/01/record.json +16 -0
  262. package/test-fixtures/duplicates-ind1/02/expectedResult.json +6 -0
  263. package/test-fixtures/duplicates-ind1/02/metadata.json +4 -0
  264. package/test-fixtures/duplicates-ind1/02/record.json +16 -0
  265. package/test-fixtures/duplicates-ind1/03/expectedResult.json +13 -0
  266. package/test-fixtures/duplicates-ind1/03/metadata.json +6 -0
  267. package/test-fixtures/duplicates-ind1/03/record.json +16 -0
  268. package/test-fixtures/ending-whitespace/01/expectedResult.json +4 -0
  269. package/test-fixtures/ending-whitespace/01/metadata.json +6 -0
  270. package/test-fixtures/ending-whitespace/01/record.json +15 -0
  271. package/test-fixtures/ending-whitespace/02/expectedResult.json +4 -0
  272. package/test-fixtures/ending-whitespace/02/metadata.json +6 -0
  273. package/test-fixtures/ending-whitespace/02/record.json +15 -0
  274. package/test-fixtures/ending-whitespace/03/expectedResult.json +17 -0
  275. package/test-fixtures/ending-whitespace/03/metadata.json +6 -0
  276. package/test-fixtures/ending-whitespace/03/record.json +15 -0
  277. package/test-fixtures/ending-whitespace/04/expectedResult.json +10 -0
  278. package/test-fixtures/ending-whitespace/04/metadata.json +6 -0
  279. package/test-fixtures/ending-whitespace/04/record.json +8 -0
  280. package/test-fixtures/fix521/01/expectedResult.json +6 -0
  281. package/test-fixtures/fix521/01/metadata.json +5 -0
  282. package/test-fixtures/fix521/01/record.json +13 -0
  283. package/test-fixtures/fix521/02/expectedResult.json +15 -0
  284. package/test-fixtures/fix521/02/metadata.json +5 -0
  285. package/test-fixtures/fix521/02/record.json +13 -0
  286. package/test-fixtures/fix521/03/expectedResult.json +5 -0
  287. package/test-fixtures/fix521/03/metadata.json +5 -0
  288. package/test-fixtures/fix521/03/record.json +13 -0
  289. package/test-fixtures/indicator-fixes/01/expectedResult.json +9 -0
  290. package/test-fixtures/indicator-fixes/01/metadata.json +5 -0
  291. package/test-fixtures/indicator-fixes/01/record.json +64 -0
  292. package/test-fixtures/indicator-fixes/02/expectedResult.json +66 -0
  293. package/test-fixtures/indicator-fixes/02/metadata.json +5 -0
  294. package/test-fixtures/indicator-fixes/02/record.json +64 -0
  295. package/test-fixtures/indicator-fixes/03/expectedResult.json +55 -0
  296. package/test-fixtures/indicator-fixes/03/metadata.json +5 -0
  297. package/test-fixtures/indicator-fixes/03/record.json +54 -0
  298. package/test-fixtures/indicator-fixes/04/expectedResult.json +66 -0
  299. package/test-fixtures/indicator-fixes/04/metadata.json +5 -0
  300. package/test-fixtures/indicator-fixes/04/record.json +65 -0
  301. package/test-fixtures/indicator-fixes/05/expectedResult.json +66 -0
  302. package/test-fixtures/indicator-fixes/05/metadata.json +5 -0
  303. package/test-fixtures/indicator-fixes/05/record.json +65 -0
  304. package/test-fixtures/indicator-fixes/06/expectedResult.json +75 -0
  305. package/test-fixtures/indicator-fixes/06/metadata.json +5 -0
  306. package/test-fixtures/indicator-fixes/06/record.json +74 -0
  307. package/test-fixtures/lisapainokset/fixer/01/expectedResult.json +37 -0
  308. package/test-fixtures/lisapainokset/fixer/01/metadata.json +6 -0
  309. package/test-fixtures/lisapainokset/fixer/01/record.json +61 -0
  310. package/test-fixtures/lisapainokset/fixer/02/expectedResult.json +44 -0
  311. package/test-fixtures/lisapainokset/fixer/02/metadata.json +6 -0
  312. package/test-fixtures/lisapainokset/fixer/02/record.json +45 -0
  313. package/test-fixtures/lisapainokset/fixer/03/expectedResult.json +21 -0
  314. package/test-fixtures/lisapainokset/fixer/03/metadata.json +6 -0
  315. package/test-fixtures/lisapainokset/fixer/03/record.json +45 -0
  316. package/test-fixtures/lisapainokset/validator/01/expectedResult.json +7 -0
  317. package/test-fixtures/lisapainokset/validator/01/metadata.json +6 -0
  318. package/test-fixtures/lisapainokset/validator/01/record.json +45 -0
  319. package/test-fixtures/lisapainokset/validator/02/expectedResult.json +6 -0
  320. package/test-fixtures/lisapainokset/validator/02/metadata.json +6 -0
  321. package/test-fixtures/lisapainokset/validator/02/record.json +61 -0
  322. package/test-fixtures/lisapainokset/validator/03/expectedResult.json +4 -0
  323. package/test-fixtures/lisapainokset/validator/03/metadata.json +6 -0
  324. package/test-fixtures/lisapainokset/validator/03/record.json +37 -0
  325. package/test-fixtures/mergeRelatorTermFields/fixer/01/expectedResult.json +14 -0
  326. package/test-fixtures/mergeRelatorTermFields/fixer/01/metadata.json +6 -0
  327. package/test-fixtures/mergeRelatorTermFields/fixer/01/record.json +16 -0
  328. package/test-fixtures/mergeRelatorTermFields/fixer/02/expectedResult.json +17 -0
  329. package/test-fixtures/mergeRelatorTermFields/fixer/02/metadata.json +6 -0
  330. package/test-fixtures/mergeRelatorTermFields/fixer/02/record.json +23 -0
  331. package/test-fixtures/mergeRelatorTermFields/validator/01/expectedResult.json +6 -0
  332. package/test-fixtures/mergeRelatorTermFields/validator/01/metadata.json +6 -0
  333. package/test-fixtures/mergeRelatorTermFields/validator/01/record.json +16 -0
  334. package/test-fixtures/mergeRelatorTermFields/validator/02/expectedResult.json +4 -0
  335. package/test-fixtures/mergeRelatorTermFields/validator/02/metadata.json +6 -0
  336. package/test-fixtures/mergeRelatorTermFields/validator/02/record.json +16 -0
  337. package/test-fixtures/non-breaking-space/01/expectedResult.json +4 -0
  338. package/test-fixtures/non-breaking-space/01/metadata.json +6 -0
  339. package/test-fixtures/non-breaking-space/01/record.json +15 -0
  340. package/test-fixtures/non-breaking-space/02/expectedResult.json +4 -0
  341. package/test-fixtures/non-breaking-space/02/metadata.json +6 -0
  342. package/test-fixtures/non-breaking-space/02/record.json +15 -0
  343. package/test-fixtures/non-breaking-space/03/expectedResult.json +17 -0
  344. package/test-fixtures/non-breaking-space/03/metadata.json +6 -0
  345. package/test-fixtures/non-breaking-space/03/record.json +15 -0
  346. package/test-fixtures/non-breaking-space/04/expectedResult.json +21 -0
  347. package/test-fixtures/non-breaking-space/04/metadata.json +6 -0
  348. package/test-fixtures/non-breaking-space/04/record.json +19 -0
  349. package/test-fixtures/normalize-identifiers/01/expectedResult.json +8 -0
  350. package/test-fixtures/normalize-identifiers/01/metadata.json +5 -0
  351. package/test-fixtures/normalize-identifiers/01/record.json +81 -0
  352. package/test-fixtures/normalize-identifiers/02/expectedResult.json +92 -0
  353. package/test-fixtures/normalize-identifiers/02/metadata.json +5 -0
  354. package/test-fixtures/normalize-identifiers/02/record.json +92 -0
  355. package/test-fixtures/normalize-identifiers/03/expectedResult.json +63 -0
  356. package/test-fixtures/normalize-identifiers/03/metadata.json +5 -0
  357. package/test-fixtures/normalize-identifiers/03/record.json +61 -0
  358. package/test-fixtures/normalize-identifiers/04/expectedResult.json +79 -0
  359. package/test-fixtures/normalize-identifiers/04/metadata.json +5 -0
  360. package/test-fixtures/normalize-identifiers/04/record.json +77 -0
  361. package/test-fixtures/normalize-utf8-diacritics/01/expectedResult.json +7 -0
  362. package/test-fixtures/normalize-utf8-diacritics/01/metadata.json +5 -0
  363. package/test-fixtures/normalize-utf8-diacritics/01/record.json +39 -0
  364. package/test-fixtures/normalize-utf8-diacritics/02/expectedResult.json +41 -0
  365. package/test-fixtures/normalize-utf8-diacritics/02/metadata.json +5 -0
  366. package/test-fixtures/normalize-utf8-diacritics/02/record.json +39 -0
  367. package/test-fixtures/normalize-utf8-diacritics/03/expectedResult.json +5 -0
  368. package/test-fixtures/normalize-utf8-diacritics/03/metadata.json +5 -0
  369. package/test-fixtures/normalize-utf8-diacritics/03/record.json +37 -0
  370. package/test-fixtures/normalize-utf8-diacritics/04/expectedResult.json +41 -0
  371. package/test-fixtures/normalize-utf8-diacritics/04/metadata.json +5 -0
  372. package/test-fixtures/normalize-utf8-diacritics/04/record.json +39 -0
  373. package/test-fixtures/normalize-utf8-diacritics/05/expectedResult.json +41 -0
  374. package/test-fixtures/normalize-utf8-diacritics/05/metadata.json +5 -0
  375. package/test-fixtures/normalize-utf8-diacritics/05/record.json +41 -0
  376. package/test-fixtures/punctuation/01/expectedResult.json +3 -0
  377. package/test-fixtures/punctuation/01/metadata.json +4 -0
  378. package/test-fixtures/punctuation/01/record.json +18 -0
  379. package/test-fixtures/punctuation/02/expectedResult.json +3 -0
  380. package/test-fixtures/punctuation/02/metadata.json +4 -0
  381. package/test-fixtures/punctuation/02/record.json +18 -0
  382. package/test-fixtures/punctuation/03/expectedResult.json +21 -0
  383. package/test-fixtures/punctuation/03/metadata.json +5 -0
  384. package/test-fixtures/punctuation/03/record.json +19 -0
  385. package/test-fixtures/punctuation/04/expectedResult.json +21 -0
  386. package/test-fixtures/punctuation/04/metadata.json +5 -0
  387. package/test-fixtures/punctuation/04/record.json +19 -0
  388. package/test-fixtures/punctuation/05/expectedResult.json +44 -0
  389. package/test-fixtures/punctuation/05/metadata.json +5 -0
  390. package/test-fixtures/punctuation/05/record.json +42 -0
  391. package/test-fixtures/punctuation2/01/expectedResult.json +12 -0
  392. package/test-fixtures/punctuation2/01/metadata.json +6 -0
  393. package/test-fixtures/punctuation2/01/record.json +37 -0
  394. package/test-fixtures/punctuation2/02/expectedResult.json +4 -0
  395. package/test-fixtures/punctuation2/02/metadata.json +6 -0
  396. package/test-fixtures/punctuation2/02/record.json +14 -0
  397. package/test-fixtures/punctuation2/04/expectedResult.json +7 -0
  398. package/test-fixtures/punctuation2/04/metadata.json +6 -0
  399. package/test-fixtures/punctuation2/04/record.json +22 -0
  400. package/test-fixtures/punctuation2/05/expectedResult.json +6 -0
  401. package/test-fixtures/punctuation2/05/metadata.json +6 -0
  402. package/test-fixtures/punctuation2/05/record.json +12 -0
  403. package/test-fixtures/punctuation2/98/expectedResult.json +45 -0
  404. package/test-fixtures/punctuation2/98/metadata.json +6 -0
  405. package/test-fixtures/punctuation2/98/record.json +43 -0
  406. package/test-fixtures/punctuation2/99/expectedResult.json +15 -0
  407. package/test-fixtures/punctuation2/99/metadata.json +6 -0
  408. package/test-fixtures/punctuation2/99/record.json +14 -0
  409. package/test-fixtures/reindex-sf6-occurence-numbers/f01/expectedResult.json +35 -0
  410. package/test-fixtures/reindex-sf6-occurence-numbers/f01/metadata.json +6 -0
  411. package/test-fixtures/reindex-sf6-occurence-numbers/f01/record.json +34 -0
  412. package/test-fixtures/reindex-sf6-occurence-numbers/f02/expectedResult.json +53 -0
  413. package/test-fixtures/reindex-sf6-occurence-numbers/f02/metadata.json +6 -0
  414. package/test-fixtures/reindex-sf6-occurence-numbers/f02/record.json +51 -0
  415. package/test-fixtures/reindex-sf6-occurence-numbers/f03/expectedResult.json +46 -0
  416. package/test-fixtures/reindex-sf6-occurence-numbers/f03/metadata.json +7 -0
  417. package/test-fixtures/reindex-sf6-occurence-numbers/f03/record.json +44 -0
  418. package/test-fixtures/reindex-sf6-occurence-numbers/v01/expectedResult.json +6 -0
  419. package/test-fixtures/reindex-sf6-occurence-numbers/v01/metadata.json +5 -0
  420. package/test-fixtures/reindex-sf6-occurence-numbers/v01/record.json +31 -0
  421. package/test-fixtures/reindex-sf6-occurence-numbers/v02/expectedResult.json +6 -0
  422. package/test-fixtures/reindex-sf6-occurence-numbers/v02/metadata.json +6 -0
  423. package/test-fixtures/reindex-sf6-occurence-numbers/v02/record.json +38 -0
  424. package/test-fixtures/reindex-sf6-occurence-numbers/v03/expectedResult.json +6 -0
  425. package/test-fixtures/reindex-sf6-occurence-numbers/v03/metadata.json +6 -0
  426. package/test-fixtures/reindex-sf6-occurence-numbers/v03/record.json +30 -0
  427. package/test-fixtures/remove-duplicate-datafields/f01/expectedResult.json +35 -0
  428. package/test-fixtures/remove-duplicate-datafields/f01/metadata.json +6 -0
  429. package/test-fixtures/remove-duplicate-datafields/f01/record.json +34 -0
  430. package/test-fixtures/remove-duplicate-datafields/f03/expectedResult.json +20 -0
  431. package/test-fixtures/remove-duplicate-datafields/f03/metadata.json +6 -0
  432. package/test-fixtures/remove-duplicate-datafields/f03/record.json +33 -0
  433. package/test-fixtures/remove-duplicate-datafields/f03b/expectedResult.json +20 -0
  434. package/test-fixtures/remove-duplicate-datafields/f03b/metadata.json +6 -0
  435. package/test-fixtures/remove-duplicate-datafields/f03b/record.json +35 -0
  436. package/test-fixtures/remove-duplicate-datafields/f03c/expectedResult.json +25 -0
  437. package/test-fixtures/remove-duplicate-datafields/f03c/metadata.json +6 -0
  438. package/test-fixtures/remove-duplicate-datafields/f03c/record.json +43 -0
  439. package/test-fixtures/remove-duplicate-datafields/f04/expectedResult.json +31 -0
  440. package/test-fixtures/remove-duplicate-datafields/f04/metadata.json +6 -0
  441. package/test-fixtures/remove-duplicate-datafields/f04/record.json +41 -0
  442. package/test-fixtures/remove-duplicate-datafields/f05/expectedResult.json +23 -0
  443. package/test-fixtures/remove-duplicate-datafields/f05/metadata.json +6 -0
  444. package/test-fixtures/remove-duplicate-datafields/f05/record.json +29 -0
  445. package/test-fixtures/remove-duplicate-datafields/f06/expectedResult.json +24 -0
  446. package/test-fixtures/remove-duplicate-datafields/f06/metadata.json +6 -0
  447. package/test-fixtures/remove-duplicate-datafields/f06/record.json +41 -0
  448. package/test-fixtures/remove-duplicate-datafields/f07/expectedResult.json +15 -0
  449. package/test-fixtures/remove-duplicate-datafields/f07/metadata.json +6 -0
  450. package/test-fixtures/remove-duplicate-datafields/f07/record.json +21 -0
  451. package/test-fixtures/remove-duplicate-datafields/f08/expectedResult.json +21 -0
  452. package/test-fixtures/remove-duplicate-datafields/f08/metadata.json +6 -0
  453. package/test-fixtures/remove-duplicate-datafields/f08/record.json +33 -0
  454. package/test-fixtures/remove-duplicate-datafields/f09/expectedResult.json +6 -0
  455. package/test-fixtures/remove-duplicate-datafields/f09/metadata.json +6 -0
  456. package/test-fixtures/remove-duplicate-datafields/f09/record.json +9 -0
  457. package/test-fixtures/remove-duplicate-datafields/f10/expectedResult.json +15 -0
  458. package/test-fixtures/remove-duplicate-datafields/f10/metadata.json +6 -0
  459. package/test-fixtures/remove-duplicate-datafields/f10/record.json +24 -0
  460. package/test-fixtures/remove-duplicate-datafields/f11/expectedResult.json +30 -0
  461. package/test-fixtures/remove-duplicate-datafields/f11/metadata.json +6 -0
  462. package/test-fixtures/remove-duplicate-datafields/f11/record.json +53 -0
  463. package/test-fixtures/remove-duplicate-datafields/v01/expectedResult.json +6 -0
  464. package/test-fixtures/remove-duplicate-datafields/v01/metadata.json +6 -0
  465. package/test-fixtures/remove-duplicate-datafields/v01/record.json +31 -0
  466. package/test-fixtures/remove-duplicate-datafields/v02/expectedResult.json +10 -0
  467. package/test-fixtures/remove-duplicate-datafields/v02/metadata.json +6 -0
  468. package/test-fixtures/remove-duplicate-datafields/v02/record.json +45 -0
  469. package/test-fixtures/remove-duplicate-datafields/v03/expectedResult.json +6 -0
  470. package/test-fixtures/remove-duplicate-datafields/v03/metadata.json +7 -0
  471. package/test-fixtures/remove-duplicate-datafields/v03/record.json +37 -0
  472. package/test-fixtures/remove-duplicate-datafields/v04/expectedResult.json +8 -0
  473. package/test-fixtures/remove-duplicate-datafields/v04/metadata.json +6 -0
  474. package/test-fixtures/remove-duplicate-datafields/v04/record.json +41 -0
  475. package/test-fixtures/remove-inferior-datafields/f01/expectedResult.json +21 -0
  476. package/test-fixtures/remove-inferior-datafields/f01/metadata.json +6 -0
  477. package/test-fixtures/remove-inferior-datafields/f01/record.json +31 -0
  478. package/test-fixtures/remove-inferior-datafields/f03/expectedResult.json +16 -0
  479. package/test-fixtures/remove-inferior-datafields/f03/metadata.json +6 -0
  480. package/test-fixtures/remove-inferior-datafields/f03/record.json +27 -0
  481. package/test-fixtures/remove-inferior-datafields/f04/expectedResult.json +31 -0
  482. package/test-fixtures/remove-inferior-datafields/f04/metadata.json +6 -0
  483. package/test-fixtures/remove-inferior-datafields/f04/record.json +38 -0
  484. package/test-fixtures/remove-inferior-datafields/f05/expectedResult.json +34 -0
  485. package/test-fixtures/remove-inferior-datafields/f05/metadata.json +6 -0
  486. package/test-fixtures/remove-inferior-datafields/f05/record.json +41 -0
  487. package/test-fixtures/remove-inferior-datafields/f06/expectedResult.json +16 -0
  488. package/test-fixtures/remove-inferior-datafields/f06/metadata.json +6 -0
  489. package/test-fixtures/remove-inferior-datafields/f06/record.json +20 -0
  490. package/test-fixtures/remove-inferior-datafields/v01/expectedResult.json +6 -0
  491. package/test-fixtures/remove-inferior-datafields/v01/metadata.json +6 -0
  492. package/test-fixtures/remove-inferior-datafields/v01/record.json +31 -0
  493. package/test-fixtures/remove-inferior-datafields/v02/expectedResult.json +6 -0
  494. package/test-fixtures/remove-inferior-datafields/v02/metadata.json +6 -0
  495. package/test-fixtures/remove-inferior-datafields/v02/record.json +21 -0
  496. package/test-fixtures/remove-orphanded-sf6s/f01/expectedResult.json +35 -0
  497. package/test-fixtures/remove-orphanded-sf6s/f01/metadata.json +6 -0
  498. package/test-fixtures/remove-orphanded-sf6s/f01/record.json +34 -0
  499. package/test-fixtures/remove-orphanded-sf6s/f02/expectedResult.json +40 -0
  500. package/test-fixtures/remove-orphanded-sf6s/f02/metadata.json +6 -0
  501. package/test-fixtures/remove-orphanded-sf6s/f02/record.json +43 -0
  502. package/test-fixtures/remove-orphanded-sf6s/v01/expectedResult.json +6 -0
  503. package/test-fixtures/remove-orphanded-sf6s/v01/metadata.json +6 -0
  504. package/test-fixtures/remove-orphanded-sf6s/v01/record.json +31 -0
  505. package/test-fixtures/remove-orphanded-sf6s/v02/expectedResult.json +6 -0
  506. package/test-fixtures/remove-orphanded-sf6s/v02/metadata.json +6 -0
  507. package/test-fixtures/remove-orphanded-sf6s/v02/record.json +31 -0
  508. package/test-fixtures/resolvable-ext-references-melinda.js +0 -27
  509. package/test-fixtures/sanitize-vocabulary-source-codes/f01/expectedResult.json +32 -0
  510. package/test-fixtures/sanitize-vocabulary-source-codes/f01/metadata.json +6 -0
  511. package/test-fixtures/sanitize-vocabulary-source-codes/f01/record.json +32 -0
  512. package/test-fixtures/sanitize-vocabulary-source-codes/f02/expectedResult.json +24 -0
  513. package/test-fixtures/sanitize-vocabulary-source-codes/f02/metadata.json +6 -0
  514. package/test-fixtures/sanitize-vocabulary-source-codes/f02/record.json +24 -0
  515. package/test-fixtures/sanitize-vocabulary-source-codes/v01/expectedResult.json +12 -0
  516. package/test-fixtures/sanitize-vocabulary-source-codes/v01/metadata.json +6 -0
  517. package/test-fixtures/sanitize-vocabulary-source-codes/v01/record.json +24 -0
  518. package/test-fixtures/sort-relator-terms/f01/expectedResult.json +23 -0
  519. package/test-fixtures/sort-relator-terms/f01/metadata.json +6 -0
  520. package/test-fixtures/sort-relator-terms/f01/record.json +22 -0
  521. package/test-fixtures/sort-relator-terms/f02/expectedResult.json +26 -0
  522. package/test-fixtures/sort-relator-terms/f02/metadata.json +6 -0
  523. package/test-fixtures/sort-relator-terms/f02/record.json +22 -0
  524. package/test-fixtures/sort-relator-terms/v01/expectedResult.json +5 -0
  525. package/test-fixtures/sort-relator-terms/v01/metadata.json +6 -0
  526. package/test-fixtures/sort-relator-terms/v01/record.json +22 -0
  527. package/test-fixtures/sort-relator-terms/v02/expectedResult.json +6 -0
  528. package/test-fixtures/sort-relator-terms/v02/metadata.json +6 -0
  529. package/test-fixtures/sort-relator-terms/v02/record.json +14 -0
  530. package/test-fixtures/sort-subfields/f01/expectedResult.json +24 -0
  531. package/test-fixtures/sort-subfields/f01/metadata.json +6 -0
  532. package/test-fixtures/sort-subfields/f01/record.json +20 -0
  533. package/test-fixtures/sort-subfields/v01/expectedResult.json +5 -0
  534. package/test-fixtures/sort-subfields/v01/metadata.json +6 -0
  535. package/test-fixtures/sort-subfields/v01/record.json +24 -0
  536. package/test-fixtures/sort-subfields/v02/expectedResult.json +6 -0
  537. package/test-fixtures/sort-subfields/v02/metadata.json +6 -0
  538. package/test-fixtures/sort-subfields/v02/record.json +8 -0
  539. package/test-fixtures/strip-punctuation/01/expectedResult.json +12 -0
  540. package/test-fixtures/strip-punctuation/01/metadata.json +6 -0
  541. package/test-fixtures/strip-punctuation/01/record.json +37 -0
  542. package/test-fixtures/strip-punctuation/02/expectedResult.json +4 -0
  543. package/test-fixtures/strip-punctuation/02/metadata.json +6 -0
  544. package/test-fixtures/strip-punctuation/02/record.json +14 -0
  545. package/test-fixtures/strip-punctuation/04/expectedResult.json +6 -0
  546. package/test-fixtures/strip-punctuation/04/metadata.json +6 -0
  547. package/test-fixtures/strip-punctuation/04/record.json +22 -0
  548. package/test-fixtures/strip-punctuation/05/expectedResult.json +6 -0
  549. package/test-fixtures/strip-punctuation/05/metadata.json +6 -0
  550. package/test-fixtures/strip-punctuation/05/record.json +12 -0
  551. package/test-fixtures/strip-punctuation/98/expectedResult.json +44 -0
  552. package/test-fixtures/strip-punctuation/98/metadata.json +6 -0
  553. package/test-fixtures/strip-punctuation/98/record.json +45 -0
  554. package/test-fixtures/strip-punctuation/99/expectedResult.json +16 -0
  555. package/test-fixtures/strip-punctuation/99/metadata.json +6 -0
  556. package/test-fixtures/strip-punctuation/99/record.json +16 -0
  557. package/test-fixtures/subfield0/f01/expectedResult.json +25 -0
  558. package/test-fixtures/subfield0/f01/metadata.json +6 -0
  559. package/test-fixtures/subfield0/f01/record.json +23 -0
  560. package/test-fixtures/subfield0/f02/expectedResult.json +35 -0
  561. package/test-fixtures/subfield0/f02/metadata.json +6 -0
  562. package/test-fixtures/subfield0/f02/record.json +41 -0
  563. package/test-fixtures/subfield0/f03/expectedResult.json +21 -0
  564. package/test-fixtures/subfield0/f03/metadata.json +7 -0
  565. package/test-fixtures/subfield0/f03/record.json +24 -0
  566. package/test-fixtures/subfield0/v01/expectedResult.json +4 -0
  567. package/test-fixtures/subfield0/v01/metadata.json +6 -0
  568. package/test-fixtures/subfield0/v01/record.json +23 -0
  569. package/test-fixtures/subfield0/v02/expectedResult.json +9 -0
  570. package/test-fixtures/subfield0/v02/metadata.json +6 -0
  571. package/test-fixtures/subfield0/v02/record.json +38 -0
  572. package/test-fixtures/typeOfDate-008/01/expectedResult.json +3 -0
  573. package/test-fixtures/typeOfDate-008/01/metadata.json +4 -0
  574. package/test-fixtures/typeOfDate-008/01/record.json +14 -0
  575. package/test-fixtures/typeOfDate-008/02/expectedResult.json +4 -0
  576. package/test-fixtures/typeOfDate-008/02/metadata.json +4 -0
  577. package/test-fixtures/typeOfDate-008/02/record.json +14 -0
  578. package/test-fixtures/typeOfDate-008/03/expectedResult.json +14 -0
  579. package/test-fixtures/typeOfDate-008/03/metadata.json +5 -0
  580. package/test-fixtures/typeOfDate-008/03/record.json +14 -0
  581. package/test-fixtures/typeOfDate-008/04/expectedResult.json +14 -0
  582. package/test-fixtures/typeOfDate-008/04/metadata.json +5 -0
  583. package/test-fixtures/typeOfDate-008/04/record.json +14 -0
  584. package/test-fixtures/typeOfDate-008/05/expectedResult.json +14 -0
  585. package/test-fixtures/typeOfDate-008/05/metadata.json +5 -0
  586. package/test-fixtures/typeOfDate-008/05/record.json +14 -0
  587. package/test-fixtures/update-field-540/f01/expectedResult.json +23 -0
  588. package/test-fixtures/update-field-540/f01/metadata.json +6 -0
  589. package/test-fixtures/update-field-540/f01/record.json +23 -0
  590. package/test-fixtures/update-field-540/v01/expectedResult.json +7 -0
  591. package/test-fixtures/update-field-540/v01/metadata.json +6 -0
  592. package/test-fixtures/update-field-540/v01/record.json +23 -0
  593. package/.travis.yml +0 -10
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Provides interface to validate and fix record fields, which include subfields that end with whitespace character
3
+ * @returns {Object} Object containing interfaces required by marc-record-validators-melinda package
4
+ */
5
+ export default function () {
6
+ return {
7
+ description: 'Handles subfields that ends with whitespace character',
8
+ validate,
9
+ fix
10
+ };
11
+
12
+ function validate(record) {
13
+ const nonValidFields = record.fields.filter(({subfields}) => subfields !== undefined && subfields.filter(valueEndsWithWhitespace).length > 0);
14
+
15
+ const valid = nonValidFields.length === 0;
16
+ const messages = nonValidFields.flatMap(({tag, subfields}) => subfields.map(sf => `Field ${tag} subfield $${sf.code} ends with whitespace`));
17
+
18
+ return valid ? {valid, messages: []} : {valid, messages};
19
+ }
20
+
21
+ /* eslint-disable functional/immutable-data,functional/no-conditional-statements */
22
+ function fix(record) {
23
+ record.fields.forEach(({subfields}) => {
24
+ if (subfields === undefined) {
25
+ return;
26
+ }
27
+
28
+ subfields.forEach(subfield => {
29
+ if (valueEndsWithWhitespace(subfield)) {
30
+ subfield.value = subfield.value.trimEnd();
31
+ }
32
+ });
33
+ });
34
+ }
35
+ /* eslint-enable functional/immutable-data,functional/no-conditional-statements */
36
+
37
+ function valueEndsWithWhitespace({value}) {
38
+ return (/\s$/u).test(value);
39
+ }
40
+ }
@@ -0,0 +1,44 @@
1
+ import {expect} from 'chai';
2
+ import {MarcRecord} from '@natlibfi/marc-record';
3
+ import validatorFactory from './ending-whitespace';
4
+ import {READERS} from '@natlibfi/fixura';
5
+ import generateTests from '@natlibfi/fixugen';
6
+
7
+ generateTests({
8
+ callback,
9
+ path: [__dirname, '..', 'test-fixtures', 'ending-whitespace'],
10
+ useMetadataFile: true,
11
+ recurse: false,
12
+ fixura: {
13
+ reader: READERS.JSON
14
+ },
15
+ mocha: {
16
+ before: () => testValidatorFactory()
17
+ }
18
+ });
19
+
20
+ async function testValidatorFactory() {
21
+ const validator = await validatorFactory();
22
+
23
+ expect(validator)
24
+ .to.be.an('object')
25
+ .that.has.any.keys('description', 'validate');
26
+
27
+ expect(validator.description).to.be.a('string');
28
+ expect(validator.validate).to.be.a('function');
29
+ }
30
+
31
+ async function callback({getFixture, fix = false}) {
32
+ const validator = await validatorFactory();
33
+ const record = new MarcRecord(getFixture('record.json'));
34
+ const expectedResult = getFixture('expectedResult.json');
35
+
36
+ if (!fix) {
37
+ const result = await validator.validate(record);
38
+ expect(result).to.eql(expectedResult);
39
+ return;
40
+ }
41
+
42
+ await validator.fix(record);
43
+ expect(record).to.eql(expectedResult);
44
+ }
@@ -0,0 +1,92 @@
1
+ //import createDebugLogger from 'debug';
2
+ import clone from 'clone';
3
+ import {fieldToString} from './utils';
4
+
5
+ // Author(s): Nicholas Volk
6
+ export default function () {
7
+
8
+ return {
9
+ description: 'Various fixes for field 521',
10
+ validate, fix
11
+ };
12
+
13
+ function fix(record) {
14
+ record.fields.forEach(field => {
15
+ fix521(field);
16
+ });
17
+ // Fix always succeeds (even when it really does not):
18
+ const res = {message: [], fix: [], valid: true};
19
+ return res;
20
+ }
21
+
22
+ function validate(record) {
23
+ const res = {message: []};
24
+
25
+ // Actual parsing of all fields
26
+ /*
27
+ if (!record.fields) {
28
+ return false;
29
+ }
30
+ */
31
+
32
+ record.fields?.forEach(field => {
33
+ validateField(field, res);
34
+ });
35
+
36
+ res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data
37
+ return res;
38
+ }
39
+
40
+ function validateField(field, res) {
41
+ const orig = fieldToString(field);
42
+
43
+ const normalizedField = fix521(clone(field));
44
+ const mod = fieldToString(normalizedField);
45
+ if (orig !== mod) { // Fail as the input is "broken"/"crap"/sumthing
46
+ res.message.push(`'TODO: ${orig}' => '${mod}'`); // eslint-disable-line functional/immutable-data
47
+ return;
48
+ }
49
+ return;
50
+ }
51
+ }
52
+
53
+ function fixSubfieldA(a) {
54
+ a.value = a.value. // eslint-disable-line functional/immutable-data
55
+ // MET-332:
56
+ replace(/^(Ikäsuositus) ([0-9])/u, '$1: $2'); // eslint-disable-line prefer-named-capture-group, functional/immutable-data
57
+ }
58
+
59
+ function fixSubfieldAInternalPunctuation(field) {
60
+ const a = field.subfields.filter(sf => sf.code === 'a');
61
+
62
+ a.forEach(sf => fixSubfieldA(sf));
63
+ }
64
+
65
+ function getIndicator1(field) {
66
+ const [a] = field.subfields.filter(sf => sf.code === 'a');
67
+ if (a) {
68
+ if (a.value.match(/^Ikäsuositus/u)) {
69
+ return '1';
70
+ }
71
+ }
72
+ return undefined;
73
+ }
74
+
75
+ function fixIndicator1(field) {
76
+ const value = getIndicator1(field);
77
+ if (value) {
78
+ field.ind1 = value; // eslint-disable-line functional/immutable-data
79
+ return;
80
+ }
81
+
82
+ }
83
+
84
+ function fix521(field) {
85
+ if (field.tag !== '521' || !field.subfields) {
86
+ return field;
87
+ }
88
+ fixIndicator1(field);
89
+ fixSubfieldAInternalPunctuation(field);
90
+ return field;
91
+ }
92
+
@@ -0,0 +1,52 @@
1
+ import {expect} from 'chai';
2
+ import {MarcRecord} from '@natlibfi/marc-record';
3
+ import validatorFactory from './field-521-fix';
4
+ import {READERS} from '@natlibfi/fixura';
5
+ import generateTests from '@natlibfi/fixugen';
6
+ import createDebugLogger from 'debug';
7
+
8
+ generateTests({
9
+ callback,
10
+ path: [__dirname, '..', 'test-fixtures', 'fix521'],
11
+ useMetadataFile: true,
12
+ recurse: false,
13
+ fixura: {
14
+ reader: READERS.JSON
15
+ },
16
+ mocha: {
17
+ before: () => testValidatorFactory()
18
+ }
19
+ });
20
+ const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/fix521:test');
21
+
22
+ async function testValidatorFactory() {
23
+ const validator = await validatorFactory();
24
+
25
+ expect(validator)
26
+ .to.be.an('object')
27
+ .that.has.any.keys('description', 'validate');
28
+
29
+ expect(validator.description).to.be.a('string');
30
+ expect(validator.validate).to.be.a('function');
31
+ }
32
+
33
+ async function callback({getFixture, enabled = true, fix = false}) {
34
+ if (enabled === false) {
35
+ debug('TEST SKIPPED!');
36
+ return;
37
+ }
38
+
39
+ const validator = await validatorFactory();
40
+ const record = new MarcRecord(getFixture('record.json'));
41
+ const expectedResult = getFixture('expectedResult.json');
42
+ // console.log(expectedResult); // eslint-disable-line
43
+
44
+ if (!fix) {
45
+ const result = await validator.validate(record);
46
+ expect(result).to.eql(expectedResult);
47
+ return;
48
+ }
49
+
50
+ await validator.fix(record);
51
+ expect(record).to.eql(expectedResult);
52
+ }
@@ -1,220 +1,202 @@
1
- /**
2
- *
3
- * @licstart The following is the entire license notice for the JavaScript code in this file.
4
- *
5
- * MARC record validators used in Melinda
6
- *
7
- * Copyright (C) 2014-2018 University Of Helsinki (The National Library Of Finland)
8
- *
9
- * This file is part of marc-record-validators-melinda
10
- *
11
- * marc-record-validators-melinda program is free software: you can redistribute it and/or modify
12
- * it under the terms of the GNU Affero General Public License as
13
- * published by the Free Software Foundation, either version 3 of the
14
- * License, or (at your option) any later version.
15
- *
16
- * marc-record-validators-melinda is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- * GNU Affero General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU Affero General Public License
22
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
- *
24
- * @licend The above is the entire license notice
25
- * for the JavaScript code in this file.
26
- *
27
- */
28
-
29
- /* eslint-disable require-await */
30
-
31
- 'use strict';
32
-
33
- import {forEach, every, some} from 'lodash';
34
- import {isRegExp} from 'util';
35
-
36
1
  // Configuration specification
37
2
  const confSpec = {
38
- tag: { // Pattern to match the field's tags
39
- type: 'RegExp',
40
- mandatory: true
41
- },
42
- value: { // Regular expression object for matching a controlfields value. Mutual exclusive with
43
- type: 'RegExp',
44
- excl: [
45
- 'subfields', 'ind1', 'ind2'
46
- ]
47
- },
48
- ind1: { // Pattern to match the field's ind1 property.
49
- type: 'RegExp', // Array<Indicator>
50
- excl: [
51
- 'value'
52
- ]
53
- },
54
- ind2: { // Pattern to match the field's ind2 property.
55
- type: 'RegExp', // Array<Indicator>
56
- excl: [
57
- 'value'
58
- ]
59
- },
60
- subfields: { // An array of objects with the following properties
61
- code: {
62
- type: 'RegExp',
63
- mandatory: true
64
- },
65
- value: {
66
- type: 'RegExp',
67
- mandatory: true
68
- }
69
- }
3
+ tag: { // Pattern to match the field's tags
4
+ type: 'RegExp',
5
+ mandatory: true
6
+ },
7
+ value: { // Regular expression object for matching a controlfields value. Mutual exclusive with
8
+ type: 'RegExp',
9
+ excl: ['subfields', 'ind1', 'ind2']
10
+ },
11
+ ind1: { // Pattern to match the field's ind1 property.
12
+ type: 'RegExp', // Array<Indicator>
13
+ excl: ['value']
14
+ },
15
+ ind2: { // Pattern to match the field's ind2 property.
16
+ type: 'RegExp', // Array<Indicator>
17
+ excl: ['value']
18
+ },
19
+ subfields: { // An array of objects with the following properties
20
+ code: {
21
+ type: 'RegExp',
22
+ mandatory: true
23
+ },
24
+ value: {
25
+ type: 'RegExp',
26
+ mandatory: true
27
+ }
28
+ },
29
+ dependencies: {
30
+ leader: {
31
+ type: 'RegExp'
32
+ }
33
+ }
70
34
  };
71
35
 
72
- export default async function (config) {
73
- if (!Array.isArray(config)) {
74
- throw new TypeError('Configuration array not provided');
75
- }
76
-
77
- configValid(config);
78
-
79
- return {
80
- description:
81
- 'Checks whether the configured field-specific objects are valid in the record',
82
- validate: async record => (
83
- excludeFields(record, config, false)
84
- ),
85
- fix: async record =>
86
- excludeFields(record, config, true)
87
- };
88
-
89
- /// /////////////////////////////////////////
90
- // These check that configuration is valid
91
- function configValid(config) {
92
- let excluded = [];
93
- config.forEach(obj => {
94
- excluded = []; // Validate fields: check that they are valid to confSpec (exists, correct data type), concat excluded elements
95
- checkMandatory(confSpec, obj);
96
-
97
- forEach(obj, (val, key) => {
98
- configMatchesSpec(val, key, confSpec);
99
- // Concat all excluded elements to array
100
- if (confSpec[key].excl) {
101
- excluded = excluded.concat(confSpec[key].excl);
102
- }
103
- });
104
-
105
- // Check that no excluded elements are in use
106
- forEach(obj, (val, key) => {
107
- if (excluded.includes(key)) {
108
- throw new Error('Configuration not valid - excluded element');
109
- }
110
- });
111
- });
112
- }
113
-
114
- // Recursive validator
115
- function configMatchesSpec(data, key, spec) {
116
- // Field not found in configuration spec
117
- if (!spec[key]) {
118
- throw new Error('Configuration not valid - unidentified value: ' + key);
119
- }
120
-
121
- // If configuration type does not match type in configuration spec
122
- if (typeof data !== spec[key].type &&
123
- (spec[key].type === 'RegExp' && !(isRegExp(data)))) {
124
- throw new Error('Configuration not valid - invalid data type for: ' + key);
125
- }
126
-
127
- // Check subfields recursively
128
- if (key === 'subfields') {
129
- forEach(data, subObj => {
130
- // Console.log("subObj: ", subObj, " type: ", typeof subObj, !(Array.isArray(subObj)))
131
- if (typeof subObj === 'object' && !(Array.isArray(subObj))) {
132
- checkMandatory(spec[key], subObj);
133
-
134
- forEach(subObj, (subVal, subKey) => {
135
- configMatchesSpec(subVal, subKey, spec[key]);
136
- });
137
- } else {
138
- throw new TypeError('Configuration not valid - subfield: ' + subObj + ' not object');
139
- }
140
- });
141
- }
142
- }
143
-
144
- function checkMandatory(spec, obj) {
145
- // Check if all mandatory fields are present
146
- forEach(spec, (val, key) => {
147
- if (val.mandatory && typeof (obj[key]) === 'undefined') {
148
- throw new Error('Configuration not valid - missing mandatory element: ' + key);
149
- }
150
- });
151
- }
152
- /// /////////////////////////////////////////
153
-
154
- /// /////////////////////////////////////////
155
- // These check that record is valid
156
- function subFieldCheck(confField, element) {
157
- // Parse trough every configuration subfield, check if one matches some subobjects fields
158
- return some(confField, subField => {
159
- return some(element.subfields, elemSub => {
160
- // Check if subfield matches configuration spec
161
- if (subField.code && elemSub.code && (subField.code.test(elemSub.code)) &&
162
- subField.value && elemSub.value && (subField.value.test(elemSub.value))) {
163
- return true;
164
- }
165
- });
166
- });
167
- }
168
-
169
- function excludeFields(record, conf, fix) {
170
- var res = {};
171
- res.message = [];
172
- res.valid = true;
173
-
174
- // Parse trough every element of config array
175
- forEach(conf, confObj => {
176
- var found = record.get(confObj.tag); // Find matching record fields based on mandatory tag
177
-
178
- // Check if some of found record fields matches all configuration fields
179
- forEach(found, element => {
180
- // Compare each found element against each configuration object
181
- if (every(confObj, (confField, confKey) => {
182
- // This is already checked on .get()
183
- if (confKey === 'tag') {
184
- return true;
185
- }
186
-
187
- // Check subfield configurations
188
- if (confKey === 'subfields') {
189
- return subFieldCheck(confField, element);
190
- }
191
-
192
- // Configuration object is RegExp and record value matches it
193
- if (element[confKey] && isRegExp(confField) && confField.test(element[confKey])) {
194
- return true;
195
-
196
- // Configuration object not found from found element
197
- }
198
- return false;
199
- })) {
200
- // All configuration fields match, element should be excluded.
201
- if (fix) {
202
- record.removeField(element);
203
- } else {
204
- res.message.push('Field $' + element.tag + ' should be excluded');
205
- }
206
- }
207
- });
208
- });
209
-
210
- // Fix does not send response
211
- if (!fix) {
212
- if (res.message.length > 0) {
213
- res.valid = false;
214
- }
215
- return res;
216
- }
217
- // Res.fix.push('Field $' + element.tag + ' excluded');
218
- }
219
- /// /////////////////////////////////////////
36
+ function forEach(obj, fun) {
37
+ Object.entries(obj).forEach(fun);
38
+ }
39
+
40
+ function isRegExp(re) {
41
+ const result = re instanceof RegExp;
42
+ return result;
43
+ }
44
+
45
+ export default function (config) {
46
+ if (!Array.isArray(config)) {
47
+ throw new TypeError('Configuration array not provided');
48
+ }
49
+
50
+ // Transform RegExp-only elements to objects
51
+ const objOnlyConfigs = config.map(e => isRegExp(e) ? {tag: e} : e);
52
+ configValid(objOnlyConfigs);
53
+
54
+ return {
55
+ description:
56
+ 'Checks that the record does not contain the configured fields',
57
+ validate: record => excludeFields(record, objOnlyConfigs, false),
58
+ fix: record => excludeFields(record, objOnlyConfigs, true)
59
+ };
60
+
61
+ /// /////////////////////////////////////////
62
+ // These check that configuration is valid
63
+ function configValid(config) {
64
+ config.forEach(obj => {
65
+ const excluded = []; // Validate fields: check that they are valid to confSpec (exists, correct data type), concat excluded elements
66
+
67
+ checkMandatory(confSpec, obj);
68
+
69
+ forEach(obj, ([key, val]) => {
70
+ configMatchesSpec(val, key, confSpec);
71
+ // Concat all excluded elements to array
72
+ if (confSpec[key].excl) { // eslint-disable-line functional/no-conditional-statements
73
+ excluded.push(...confSpec[key].excl); // eslint-disable-line functional/immutable-data
74
+ }
75
+ });
76
+
77
+ // Check that no excluded elements are in use
78
+ forEach(obj, ([key]) => {
79
+ if (excluded.includes(key)) {
80
+ throw new Error('Configuration not valid - excluded element');
81
+ }
82
+ });
83
+ });
84
+ }
85
+
86
+ // Recursive validator
87
+ function configMatchesSpec(data, key, spec) {
88
+ // Field not found in configuration spec
89
+ if (!spec[key]) {
90
+ throw new Error(`Configuration not valid - unidentified value: ${key}`);
91
+ }
92
+
93
+ // If configuration type does not match type in configuration spec
94
+ if (typeof data !== spec[key].type &&
95
+ (spec[key].type === 'RegExp' && !isRegExp(data))) {
96
+ throw new Error(`Configuration not valid - invalid data type for: ${key}`);
97
+ }
98
+
99
+ // Check subfields recursively
100
+ if (key === 'subfields') { // eslint-disable-line functional/no-conditional-statements
101
+ forEach(data, ([, subObj]) => {
102
+ // Console.log("subObj: ", subObj, " type: ", typeof subObj, !(Array.isArray(subObj)))
103
+ if (typeof subObj === 'object' && !Array.isArray(subObj)) { // eslint-disable-line functional/no-conditional-statements
104
+ checkMandatory(spec[key], subObj);
105
+
106
+ forEach(subObj, ([subKey, subVal]) => {
107
+ configMatchesSpec(subVal, subKey, spec[key]);
108
+ });
109
+ } else {
110
+ throw new TypeError(`Configuration not valid - subfield: ${subObj} not object`);
111
+ }
112
+ });
113
+ }
114
+
115
+ if (key === 'dependencies') { // eslint-disable-line functional/no-conditional-statements
116
+ forEach(data, ([, subObj]) => {
117
+ if (!(typeof subObj === 'object' && !Array.isArray(subObj) && Object.keys(subObj).length === 1 && isRegExp(subObj.leader))) {
118
+ throw new TypeError('Configuration not valid - Invalid dependencies config');
119
+ }
120
+ });
121
+ }
122
+ }
123
+
124
+ function checkMandatory(spec, obj) {
125
+ // Check if all mandatory fields are present
126
+ forEach(spec, ([key, val]) => {
127
+ if (val.mandatory && typeof obj[key] === 'undefined') {
128
+ throw new Error(`Configuration not valid - missing mandatory element: ${key}`);
129
+ }
130
+ });
131
+ }
132
+ /// /////////////////////////////////////////
133
+
134
+ /// /////////////////////////////////////////
135
+ // These check that record is valid
136
+ function subFieldCheck(confField, element) {
137
+ // Parse trough every configuration subfield, check if one matches some subobjects fields
138
+ return Object.values(confField).some(subField => Object.values(element.subfields)
139
+ // Check if subfield matches configuration spec
140
+ .some(elemSub => subField.code && elemSub.code && subField.code.test(elemSub.code) &&
141
+ subField.value && elemSub.value && subField.value.test(elemSub.value)));
142
+ }
143
+
144
+ function excludeFields(record, conf, fix) {
145
+ const res = {message: [], valid: true};
146
+
147
+ // Parse trough every element of config array
148
+ forEach(conf, ([, confObj]) => {
149
+ const found = record.get(confObj.tag); // Find matching record fields based on mandatory tag
150
+ const excluded = [];
151
+
152
+ // Check if some of found record fields matches all configuration fields
153
+ found.forEach(element => {
154
+ // Compare each found element against each configuration object
155
+ if (Object.entries(confObj).every(([confKey, confField]) => {
156
+ // This is already checked on .get()
157
+ if (confKey === 'tag') {
158
+ return true;
159
+ }
160
+
161
+ if (confKey === 'dependencies') {
162
+ return confObj.dependencies.every(dependency => dependency.leader.test(record.leader));
163
+ }
164
+
165
+ // Check subfield configurations
166
+ if (confKey === 'subfields') {
167
+ return subFieldCheck(confField, element);
168
+ }
169
+
170
+ // Configuration object is RegExp and record value matches it
171
+ if (element[confKey] && isRegExp(confField) && confField.test(element[confKey])) {
172
+ return true;
173
+
174
+ // Configuration object not found from found element
175
+ }
176
+
177
+ return false;
178
+ })) {
179
+ // All configuration fields match, element should be excluded.
180
+ if (fix) { // eslint-disable-line functional/no-conditional-statements
181
+ excluded.push(element); // eslint-disable-line functional/immutable-data
182
+ } else { // eslint-disable-line functional/no-conditional-statements
183
+ res.message.push(`Field $${element.tag} should be excluded`); // eslint-disable-line functional/immutable-data
184
+ }
185
+ }
186
+ });
187
+
188
+ excluded.forEach(field => record.removeField(field));
189
+ });
190
+
191
+ // Fix does not send response
192
+ if (!fix) {
193
+ if (res.message.length > 0) { // eslint-disable-line functional/no-conditional-statements
194
+ res.valid = false; // eslint-disable-line functional/immutable-data
195
+ }
196
+
197
+ return res;
198
+ }
199
+ // Res.fix.push('Field $' + element.tag + ' excluded');
200
+ }
201
+ /// /////////////////////////////////////////
220
202
  }