@natlibfi/marc-record-validators-melinda 12.1.0-alpha.1 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/melinda-node-tests-and-publish.yml +17 -17
- package/README.md +1 -1
- package/dist/addMissingField041.js +6 -3
- package/dist/addMissingField041.js.map +2 -2
- package/dist/addMissingField336.js +7 -4
- package/dist/addMissingField336.js.map +2 -2
- package/dist/addMissingField337.js +6 -3
- package/dist/addMissingField337.js.map +2 -2
- package/dist/addMissingField338.js +8 -5
- package/dist/addMissingField338.js.map +2 -2
- package/dist/cyrillux-usemarcon-replacement.js +5 -2
- package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
- package/dist/cyrillux.js +24 -18
- package/dist/cyrillux.js.map +2 -2
- package/dist/dataProvenanceUtils.js +19 -0
- package/dist/dataProvenanceUtils.js.map +7 -0
- package/dist/disambiguateSeriesStatements.js +2 -1
- package/dist/disambiguateSeriesStatements.js.map +2 -2
- package/dist/disambiguateSeriesStatements.test.js +1 -7
- package/dist/disambiguateSeriesStatements.test.js.map +2 -2
- package/dist/drop-terms.js +123 -0
- package/dist/drop-terms.js.map +7 -0
- package/dist/drop-terms.test.js +56 -0
- package/dist/drop-terms.test.js.map +7 -0
- package/dist/field-008-18-34-character-groups.test.js +1 -7
- package/dist/field-008-18-34-character-groups.test.js.map +2 -2
- package/dist/field-505-separators.test.js +1 -7
- package/dist/field-505-separators.test.js.map +2 -2
- package/dist/field-521-fix.test.js +1 -7
- package/dist/field-521-fix.test.js.map +2 -2
- package/dist/fix-33X.js +7 -4
- package/dist/fix-33X.js.map +2 -2
- package/dist/fix-33X.test.js +1 -1
- package/dist/fix-33X.test.js.map +1 -1
- package/dist/fix-country-codes.js +5 -0
- package/dist/fix-country-codes.js.map +2 -2
- package/dist/fix-country-codes.test.js +1 -7
- package/dist/fix-country-codes.test.js.map +2 -2
- package/dist/fix-language-codes.js +5 -1
- package/dist/fix-language-codes.js.map +2 -2
- package/dist/fix-sami-041.js +109 -0
- package/dist/fix-sami-041.js.map +7 -0
- package/dist/fix-sami-041.test.js +40 -0
- package/dist/fix-sami-041.test.js.map +7 -0
- package/dist/fixRelatorTerms.js +2 -0
- package/dist/fixRelatorTerms.js.map +2 -2
- package/dist/fixRelatorTerms.test.js +1 -7
- package/dist/fixRelatorTerms.test.js.map +2 -2
- package/dist/index.js +18 -4
- package/dist/index.js.map +2 -2
- package/dist/indicator-fixes.js +15 -1
- package/dist/indicator-fixes.js.map +2 -2
- package/dist/indicator-fixes.test.js +1 -7
- package/dist/indicator-fixes.test.js.map +2 -2
- package/dist/item-language.js +41 -39
- package/dist/item-language.js.map +2 -2
- package/dist/item-language.test.js +3 -3
- package/dist/item-language.test.js.map +2 -2
- package/dist/melindaCustomMergeFields.js +31 -0
- package/dist/melindaCustomMergeFields.js.map +2 -2
- package/dist/merge-fields/controlSubfields.js.map +2 -2
- package/dist/merge-fields/counterpartField.js +149 -152
- package/dist/merge-fields/counterpartField.js.map +3 -3
- package/dist/merge-fields/dataProvenance.js +6 -20
- package/dist/merge-fields/dataProvenance.js.map +2 -2
- package/dist/merge-fields/index.js +1 -1
- package/dist/merge-fields/index.js.map +2 -2
- package/dist/merge-fields/mergableIndicator.js +1 -5
- package/dist/merge-fields/mergableIndicator.js.map +2 -2
- package/dist/merge-fields/mergableTag.js +2 -0
- package/dist/merge-fields/mergableTag.js.map +2 -2
- package/dist/merge-fields/mergeConfig.js +2 -0
- package/dist/merge-fields/mergeConfig.js.map +2 -2
- package/dist/merge-fields/mergeConstraints.js +38 -35
- package/dist/merge-fields/mergeConstraints.js.map +3 -3
- package/dist/merge-fields/mergeField.js +4 -3
- package/dist/merge-fields/mergeField.js.map +2 -2
- package/dist/merge-fields/mergeOrAddSubfield.js +8 -7
- package/dist/merge-fields/mergeOrAddSubfield.js.map +2 -2
- package/dist/merge-fields/mergeSubfield.js +5 -1
- package/dist/merge-fields/mergeSubfield.js.map +2 -2
- package/dist/merge-fields/worldKnowledge.js +52 -0
- package/dist/merge-fields/worldKnowledge.js.map +2 -2
- package/dist/merge-fields.test.js +4 -9
- package/dist/merge-fields.test.js.map +2 -2
- package/dist/mergeField500Lisapainokset.test.js +1 -7
- package/dist/mergeField500Lisapainokset.test.js.map +2 -2
- package/dist/mergeRelatorTermFields.js +9 -6
- package/dist/mergeRelatorTermFields.js.map +2 -2
- package/dist/mergeRelatorTermFields.test.js +1 -7
- package/dist/mergeRelatorTermFields.test.js.map +2 -2
- package/dist/multiple-subfield-0.test.js +1 -7
- package/dist/multiple-subfield-0.test.js.map +2 -2
- package/dist/normalize-dashes.js +9 -6
- package/dist/normalize-dashes.js.map +2 -2
- package/dist/normalize-dashes.test.js +1 -7
- package/dist/normalize-dashes.test.js.map +2 -2
- package/dist/normalize-identifiers.js.map +2 -2
- package/dist/normalize-identifiers.test.js +1 -7
- package/dist/normalize-identifiers.test.js.map +2 -2
- package/dist/normalize-qualifying-information.test.js +1 -7
- package/dist/normalize-qualifying-information.test.js.map +2 -2
- package/dist/normalize-utf8-diacritics.js.map +2 -2
- package/dist/normalize-utf8-diacritics.test.js +1 -7
- package/dist/normalize-utf8-diacritics.test.js.map +2 -2
- package/dist/normalizeFieldForComparison.js +24 -14
- package/dist/normalizeFieldForComparison.js.map +2 -2
- package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
- package/dist/prepublicationUtils.js +1 -1
- package/dist/prepublicationUtils.js.map +2 -2
- package/dist/punctuation.test.js +1 -7
- package/dist/punctuation.test.js.map +2 -2
- package/dist/punctuation2.js +15 -12
- package/dist/punctuation2.js.map +2 -2
- package/dist/punctuation2.test.js +1 -7
- package/dist/punctuation2.test.js.map +2 -2
- package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
- package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
- package/dist/reindexSubfield6OccurenceNumbers.test.js +1 -7
- package/dist/reindexSubfield6OccurenceNumbers.test.js.map +2 -2
- package/dist/remove-041-zxx.js +56 -0
- package/dist/remove-041-zxx.js.map +7 -0
- package/dist/remove-041-zxx.test.js +40 -0
- package/dist/remove-041-zxx.test.js.map +7 -0
- package/dist/removeDuplicateDataFields.js +4 -26
- package/dist/removeDuplicateDataFields.js.map +2 -2
- package/dist/removeDuplicateDataFields.test.js +1 -7
- package/dist/removeDuplicateDataFields.test.js.map +2 -2
- package/dist/removeInferiorDataFields.js +82 -45
- package/dist/removeInferiorDataFields.js.map +3 -3
- package/dist/removeInferiorDataFields.test.js +5 -9
- package/dist/removeInferiorDataFields.test.js.map +2 -2
- package/dist/resolveOrphanedSubfield6s.js +4 -5
- package/dist/resolveOrphanedSubfield6s.js.map +2 -2
- package/dist/resolveOrphanedSubfield6s.test.js +1 -7
- package/dist/resolveOrphanedSubfield6s.test.js.map +2 -2
- package/dist/sanitize-vocabulary-source-codes.test.js +1 -7
- package/dist/sanitize-vocabulary-source-codes.test.js.map +2 -2
- package/dist/sortFields.js +16 -1
- package/dist/sortFields.js.map +2 -2
- package/dist/sortFields.test.js +1 -7
- package/dist/sortFields.test.js.map +2 -2
- package/dist/sortRelatorTerms.test.js +1 -7
- package/dist/sortRelatorTerms.test.js.map +2 -2
- package/dist/sortSubfields.js +27 -21
- package/dist/sortSubfields.js.map +2 -2
- package/dist/sortSubfields.test.js +1 -7
- package/dist/sortSubfields.test.js.map +2 -2
- package/dist/stripPunctuation.js +7 -3
- package/dist/stripPunctuation.js.map +2 -2
- package/dist/stripPunctuation.test.js +1 -7
- package/dist/stripPunctuation.test.js.map +2 -2
- package/dist/subfield6Utils.js +2 -12
- package/dist/subfield6Utils.js.map +2 -2
- package/dist/subfield8Utils.js +0 -5
- package/dist/subfield8Utils.js.map +2 -2
- package/dist/subfieldValueNormalizations.test.js +1 -7
- package/dist/subfieldValueNormalizations.test.js.map +2 -2
- package/dist/sync-007-and-300.test.js +1 -7
- package/dist/sync-007-and-300.test.js.map +2 -2
- package/dist/sync-language.js +103 -0
- package/dist/sync-language.js.map +7 -0
- package/dist/sync-language.test.js +40 -0
- package/dist/sync-language.test.js.map +7 -0
- package/dist/translate-terms.js +124 -87
- package/dist/translate-terms.js.map +3 -3
- package/dist/translate-terms.test.js +5 -8
- package/dist/translate-terms.test.js.map +2 -2
- package/dist/typeOfDate-008.js +3 -1
- package/dist/typeOfDate-008.js.map +2 -2
- package/dist/update-field-540.js.map +2 -2
- package/dist/update-field-540.test.js +1 -7
- package/dist/update-field-540.test.js.map +2 -2
- package/dist/urn.js +13 -12
- package/dist/urn.js.map +2 -2
- package/dist/urn.test.js +1 -7
- package/dist/urn.test.js.map +2 -2
- package/dist/utils.js +29 -3
- package/dist/utils.js.map +2 -2
- package/package.json +20 -27
- package/src/addMissingField041.js +8 -4
- package/src/addMissingField336.js +10 -5
- package/src/addMissingField337.js +9 -5
- package/src/addMissingField338.js +11 -6
- package/src/cyrillux-usemarcon-replacement.js +9 -5
- package/src/cyrillux.js +34 -23
- package/src/dataProvenanceUtils.js +21 -0
- package/src/disambiguateSeriesStatements.js +4 -1
- package/src/disambiguateSeriesStatements.test.js +3 -8
- package/src/drop-terms.js +164 -0
- package/src/drop-terms.test.js +81 -0
- package/src/field-008-18-34-character-groups.test.js +3 -8
- package/src/field-505-separators.test.js +3 -8
- package/src/field-521-fix.test.js +3 -8
- package/src/fix-33X.js +10 -6
- package/src/fix-33X.test.js +1 -1
- package/src/fix-country-codes.js +7 -3
- package/src/fix-country-codes.test.js +3 -8
- package/src/fix-language-codes.js +8 -4
- package/src/fix-sami-041.js +147 -0
- package/src/fix-sami-041.test.js +52 -0
- package/src/fixRelatorTerms.js +5 -0
- package/src/fixRelatorTerms.test.js +3 -8
- package/src/index.js +20 -7
- package/src/indicator-fixes.js +22 -7
- package/src/indicator-fixes.test.js +3 -8
- package/src/item-language.js +49 -42
- package/src/item-language.test.js +3 -3
- package/src/melindaCustomMergeFields.js +31 -0
- package/src/merge-fields/controlSubfields.js +0 -1
- package/src/merge-fields/counterpartField.js +191 -290
- package/src/merge-fields/dataProvenance.js +8 -25
- package/src/merge-fields/index.js +1 -1
- package/src/merge-fields/mergableIndicator.js +4 -5
- package/src/merge-fields/mergableTag.js +2 -0
- package/src/merge-fields/mergeConfig.js +2 -1
- package/src/merge-fields/mergeConstraints.js +41 -36
- package/src/merge-fields/mergeField.js +4 -7
- package/src/merge-fields/mergeOrAddSubfield.js +8 -7
- package/src/merge-fields/mergeSubfield.js +11 -2
- package/src/merge-fields/worldKnowledge.js +77 -3
- package/src/merge-fields.test.js +5 -10
- package/src/mergeField500Lisapainokset.test.js +3 -8
- package/src/mergeRelatorTermFields.js +12 -11
- package/src/mergeRelatorTermFields.test.js +3 -8
- package/src/multiple-subfield-0.test.js +3 -8
- package/src/normalize-dashes.js +13 -7
- package/src/normalize-dashes.test.js +3 -8
- package/src/normalize-identifiers.js +12 -19
- package/src/normalize-identifiers.test.js +3 -8
- package/src/normalize-qualifying-information.test.js +3 -8
- package/src/normalize-utf8-diacritics.js +6 -3
- package/src/normalize-utf8-diacritics.test.js +3 -8
- package/src/normalizeFieldForComparison.js +39 -22
- package/src/normalizeSubfieldValueForComparison.js +2 -2
- package/src/prepublicationUtils.js +1 -1
- package/src/punctuation.test.js +3 -8
- package/src/punctuation2.js +44 -40
- package/src/punctuation2.test.js +3 -8
- package/src/reindexSubfield6OccurenceNumbers.js +13 -11
- package/src/reindexSubfield6OccurenceNumbers.test.js +3 -8
- package/src/remove-041-zxx.js +85 -0
- package/src/remove-041-zxx.test.js +52 -0
- package/src/removeDuplicateDataFields.js +30 -28
- package/src/removeDuplicateDataFields.test.js +3 -8
- package/src/removeInferiorDataFields.js +126 -71
- package/src/removeInferiorDataFields.test.js +7 -10
- package/src/resolveOrphanedSubfield6s.js +7 -5
- package/src/resolveOrphanedSubfield6s.test.js +3 -8
- package/src/sanitize-vocabulary-source-codes.test.js +3 -8
- package/src/sortFields.js +20 -1
- package/src/sortFields.test.js +3 -8
- package/src/sortRelatorTerms.test.js +3 -8
- package/src/sortSubfields.js +31 -25
- package/src/sortSubfields.test.js +3 -8
- package/src/stripPunctuation.js +10 -5
- package/src/stripPunctuation.test.js +3 -8
- package/src/subfield6Utils.js +31 -33
- package/src/subfield8Utils.js +10 -7
- package/src/subfieldValueNormalizations.test.js +3 -8
- package/src/sync-007-and-300.test.js +3 -8
- package/src/sync-language.js +148 -0
- package/src/sync-language.test.js +52 -0
- package/src/translate-terms.js +168 -109
- package/src/translate-terms.test.js +12 -16
- package/src/typeOfDate-008.js +4 -1
- package/src/update-field-540.js +7 -5
- package/src/update-field-540.test.js +3 -8
- package/src/urn.js +17 -13
- package/src/urn.test.js +3 -8
- package/src/utils.js +39 -12
- package/test-fixtures/cyrillux/f02b/expectedResult.json +23 -0
- package/test-fixtures/cyrillux/f02b/metadata.json +11 -0
- package/test-fixtures/cyrillux/f02b/record.json +14 -0
- package/test-fixtures/cyrillux/f14/expectedResult.json +32 -0
- package/test-fixtures/cyrillux/f14/metadata.json +10 -0
- package/test-fixtures/cyrillux/f14/record.json +14 -0
- package/test-fixtures/drop-terms/01/expectedResult.json +31 -0
- package/test-fixtures/drop-terms/01/metadata.json +6 -0
- package/test-fixtures/drop-terms/01/record.json +35 -0
- package/test-fixtures/drop-terms/02/expectedResult.json +7 -0
- package/test-fixtures/drop-terms/02/metadata.json +6 -0
- package/test-fixtures/drop-terms/02/record.json +40 -0
- package/test-fixtures/drop-terms/03/expectedResult.json +6 -0
- package/test-fixtures/drop-terms/03/metadata.json +18 -0
- package/test-fixtures/drop-terms/03/record.json +39 -0
- package/test-fixtures/drop-terms/04/expectedResult.json +6 -0
- package/test-fixtures/drop-terms/04/metadata.json +19 -0
- package/test-fixtures/drop-terms/04/record.json +24 -0
- package/test-fixtures/fix-language-codes/02/metadata.json +1 -1
- package/test-fixtures/fix-relator-terms/f02/metadata.json +1 -1
- package/test-fixtures/fix-relator-terms/f04/expectedResult.json +18 -0
- package/test-fixtures/fix-relator-terms/f04/metadata.json +5 -0
- package/test-fixtures/fix-relator-terms/f04/record.json +20 -0
- package/test-fixtures/fix-sami-041/01/expectedResult.json +6 -0
- package/test-fixtures/fix-sami-041/01/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/01/record.json +14 -0
- package/test-fixtures/fix-sami-041/02/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/02/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/02/record.json +8 -0
- package/test-fixtures/fix-sami-041/03/expectedResult.json +5 -0
- package/test-fixtures/fix-sami-041/03/metadata.json +5 -0
- package/test-fixtures/fix-sami-041/03/record.json +8 -0
- package/test-fixtures/fix-sami-041/04/expectedResult.json +7 -0
- package/test-fixtures/fix-sami-041/04/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/04/record.json +10 -0
- package/test-fixtures/fix-sami-041/05/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/05/metadata.json +6 -0
- package/test-fixtures/fix-sami-041/05/record.json +8 -0
- package/test-fixtures/fix-sami-041/06/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/06/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/06/record.json +9 -0
- package/test-fixtures/indicator-fixes/11/expectedResult.json +10 -0
- package/test-fixtures/indicator-fixes/11/metadata.json +4 -0
- package/test-fixtures/indicator-fixes/11/record.json +10 -0
- package/test-fixtures/merge-fields/f042_01/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f042_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f042_01/record.json +13 -0
- package/test-fixtures/merge-fields/f05/metadata.json +1 -1
- package/test-fixtures/merge-fields/f06/expectedResult.json +42 -0
- package/test-fixtures/merge-fields/f06/metadata.json +6 -0
- package/test-fixtures/merge-fields/f06/record.json +41 -0
- package/test-fixtures/merge-fields/f07/expectedResult.json +18 -0
- package/test-fixtures/merge-fields/f07/metadata.json +6 -0
- package/test-fixtures/merge-fields/f07/record.json +18 -0
- package/test-fixtures/merge-fields/f08/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f08/metadata.json +7 -0
- package/test-fixtures/merge-fields/f08/record.json +10 -0
- package/test-fixtures/merge-fields/f09/expectedResult.json +14 -0
- package/test-fixtures/merge-fields/f09/metadata.json +6 -0
- package/test-fixtures/merge-fields/f09/record.json +14 -0
- package/test-fixtures/merge-fields/f10/expectedResult.json +25 -0
- package/test-fixtures/merge-fields/f10/metadata.json +6 -0
- package/test-fixtures/merge-fields/f10/record.json +25 -0
- package/test-fixtures/merge-fields/f11/expectedResult.json +40 -0
- package/test-fixtures/merge-fields/f11/metadata.json +7 -0
- package/test-fixtures/merge-fields/f11/record.json +50 -0
- package/test-fixtures/merge-fields/f12/expectedResult.json +17 -0
- package/test-fixtures/merge-fields/f12/metadata.json +6 -0
- package/test-fixtures/merge-fields/f12/record.json +25 -0
- package/test-fixtures/merge-fields/f13/expectedResult.json +18 -0
- package/test-fixtures/merge-fields/f13/metadata.json +6 -0
- package/test-fixtures/merge-fields/f13/record.json +28 -0
- package/test-fixtures/merge-fields/f14/expectedResult.json +25 -0
- package/test-fixtures/merge-fields/f14/metadata.json +6 -0
- package/test-fixtures/merge-fields/f14/record.json +25 -0
- package/test-fixtures/merge-fields/f15/expectedResult.json +8 -0
- package/test-fixtures/merge-fields/f15/metadata.json +6 -0
- package/test-fixtures/merge-fields/f15/record.json +9 -0
- package/test-fixtures/merge-fields/f16/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f16/metadata.json +7 -0
- package/test-fixtures/merge-fields/f16/record.json +13 -0
- package/test-fixtures/merge-fields/f300_01/expectedResult.json +9 -0
- package/test-fixtures/merge-fields/f300_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_01/record.json +8 -0
- package/test-fixtures/merge-fields/f300_02/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f300_02/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_02/record.json +16 -0
- package/test-fixtures/merge-fields/f300_03/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f300_03/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_03/record.json +16 -0
- package/test-fixtures/merge-fields/f490_01/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f490_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f490_01/record.json +16 -0
- package/test-fixtures/remove-041-zxx/01/expectedResult.json +5 -0
- package/test-fixtures/remove-041-zxx/01/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/01/record.json +10 -0
- package/test-fixtures/remove-041-zxx/02/expectedResult.json +7 -0
- package/test-fixtures/remove-041-zxx/02/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/02/record.json +9 -0
- package/test-fixtures/remove-041-zxx/11/expectedResult.json +10 -0
- package/test-fixtures/remove-041-zxx/11/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/11/record.json +9 -0
- package/test-fixtures/remove-041-zxx/12/expectedResult.json +10 -0
- package/test-fixtures/remove-041-zxx/12/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/12/record.json +9 -0
- package/test-fixtures/remove-inferior-datafields/f17/expectedResult.json +11 -0
- package/test-fixtures/remove-inferior-datafields/f17/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f17/record.json +15 -0
- package/test-fixtures/remove-inferior-datafields/f18/expectedResult.json +13 -0
- package/test-fixtures/remove-inferior-datafields/f18/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f18/record.json +18 -0
- package/test-fixtures/remove-inferior-datafields/f19/expectedResult.json +17 -0
- package/test-fixtures/remove-inferior-datafields/f19/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f19/record.json +18 -0
- package/test-fixtures/remove-inferior-datafields/f20/expectedResult.json +15 -0
- package/test-fixtures/remove-inferior-datafields/f20/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f20/record.json +29 -0
- package/test-fixtures/sort-fields/15/input.json +9 -0
- package/test-fixtures/sort-fields/15/metadata.json +5 -0
- package/test-fixtures/sort-fields/15/result.json +10 -0
- package/test-fixtures/sync-language/01/expectedResult.json +5 -0
- package/test-fixtures/sync-language/01/metadata.json +5 -0
- package/test-fixtures/sync-language/01/record.json +7 -0
- package/test-fixtures/sync-language/02/expectedResult.json +6 -0
- package/test-fixtures/sync-language/02/metadata.json +5 -0
- package/test-fixtures/sync-language/02/record.json +10 -0
- package/test-fixtures/sync-language/03/expectedResult.json +6 -0
- package/test-fixtures/sync-language/03/metadata.json +5 -0
- package/test-fixtures/sync-language/03/record.json +6 -0
- package/test-fixtures/sync-language/10/expectedResult.json +10 -0
- package/test-fixtures/sync-language/10/metadata.json +5 -0
- package/test-fixtures/sync-language/10/record.json +8 -0
- package/test-fixtures/sync-language/11/expectedResult.json +10 -0
- package/test-fixtures/sync-language/11/metadata.json +5 -0
- package/test-fixtures/sync-language/11/record.json +7 -0
- package/test-fixtures/sync-language/12/expectedResult.json +9 -0
- package/test-fixtures/sync-language/12/metadata.json +6 -0
- package/test-fixtures/sync-language/12/record.json +6 -0
- package/test-fixtures/sync-language/13/expectedResult.json +10 -0
- package/test-fixtures/sync-language/13/metadata.json +5 -0
- package/test-fixtures/sync-language/13/record.json +8 -0
- package/test-fixtures/sync-language/14/expectedResult.json +9 -0
- package/test-fixtures/sync-language/14/metadata.json +5 -0
- package/test-fixtures/sync-language/14/record.json +7 -0
- package/test-fixtures/sync-language/15/expectedResult.json +9 -0
- package/test-fixtures/sync-language/15/metadata.json +5 -0
- package/test-fixtures/sync-language/15/record.json +7 -0
- package/test-fixtures/translate-terms/05/expectedResult.json +12 -0
- package/test-fixtures/translate-terms/05/metadata.json +7 -0
- package/test-fixtures/translate-terms/05/record.json +11 -0
- package/test-fixtures/translate-terms/06/expectedResult.json +12 -0
- package/test-fixtures/translate-terms/06/metadata.json +7 -0
- package/test-fixtures/translate-terms/06/record.json +11 -0
- package/test-fixtures/translate-terms-data.js +23 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
|
|
1
3
|
/*
|
|
2
4
|
* cyrillux-usemarcon-replacement.js -- implement and improve https://github.com/NatLibFi/USEMARCON-Cyrillux/tree/master
|
|
3
5
|
*
|
|
@@ -6,6 +8,7 @@
|
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
10
|
import clone from 'clone';
|
|
11
|
+
import createDebugLogger from 'debug';
|
|
9
12
|
import {MarcRecord} from '@natlibfi/marc-record';
|
|
10
13
|
import {default as fix33X} from './fix-33X.js';
|
|
11
14
|
import {default as add041} from './addMissingField041.js';
|
|
@@ -19,11 +22,11 @@ import {default as fixIndicators} from './indicator-fixes.js';
|
|
|
19
22
|
import {default as fixPunctuation} from './punctuation2.js';
|
|
20
23
|
import {default as fixQualifyingInformation} from './normalize-qualifying-information.js';
|
|
21
24
|
import {sortAdjacentSubfields} from './sortSubfields.js';
|
|
22
|
-
|
|
23
|
-
// import createDebugLogger from 'debug';
|
|
24
25
|
import {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString, removeSubfield} from './utils.js';
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux-usermarcon-replacement');
|
|
28
|
+
//const debugData = debug.extend('data');
|
|
29
|
+
const debugDev = debug.extend('dev');
|
|
27
30
|
|
|
28
31
|
const description = 'Replacement for Cyrillux usemarcon rules';
|
|
29
32
|
|
|
@@ -32,13 +35,14 @@ const description = 'Replacement for Cyrillux usemarcon rules';
|
|
|
32
35
|
const dropTags = ['001', '003', '010', '012', '014', '015', '016', '017', '019', '025', '029', '032', '035', '036', '037', '038', '042', '044', '049', '051', '061', '068', '071', '074', '079', '090', '091', '092', '094', '095', '096', '097', '099', '249', '261', '262', '350', '400', '411', '541', '561', '562', '574', '575', '577', '578', '583', '584', '589', '590', '591', '592', '593', '594', '595', '596', '597', '598', '599', '653', '698', '741', '742', '744', '751', '761', '790', '841', '842', '843', '844', '845', '850', '852', '853', '854', '855', '858', '859', '863', '864', '865', '866', '867', '868', '876', '877', '878', '882', '886', '887', '888', '890', '899'];
|
|
33
36
|
|
|
34
37
|
|
|
38
|
+
// eslint-disable-next-line max-lines-per-function
|
|
35
39
|
export default function () {
|
|
36
40
|
return {
|
|
37
41
|
description, fix, validate
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
function fix(record) {
|
|
41
|
-
nvdebug(`${description}: fix
|
|
45
|
+
nvdebug(`${description}: fix`, debugDev);
|
|
42
46
|
realFix(record);
|
|
43
47
|
const res = {message: [], fix: [], valid: true};
|
|
44
48
|
return res;
|
|
@@ -156,7 +160,7 @@ export default function () {
|
|
|
156
160
|
|
|
157
161
|
// Validation is currently done in subparts
|
|
158
162
|
function validate(record) {
|
|
159
|
-
nvdebug(`${description}: validate
|
|
163
|
+
nvdebug(`${description}: validate`, debugDev);
|
|
160
164
|
const originalString = recordToString(record);
|
|
161
165
|
const clonedRecord = new MarcRecord(record, {subfieldValues: false});
|
|
162
166
|
realFix(clonedRecord);
|
package/src/cyrillux.js
CHANGED
|
@@ -3,17 +3,23 @@ import clone from 'clone';
|
|
|
3
3
|
import XRegExp from 'xregexp';
|
|
4
4
|
import * as iso9 from '@natlibfi/iso9-1995';
|
|
5
5
|
import * as sfs4900 from '@natlibfi/sfs-4900';
|
|
6
|
-
import {fieldHasSubfield, fieldToString, fieldsToString,
|
|
6
|
+
import {fieldHasSubfield, fieldToString, fieldsToString, isContentSubfieldCode, nvdebug} from './utils.js';
|
|
7
7
|
import {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils.js';
|
|
8
8
|
import {default as sortFields} from './sortFields.js';
|
|
9
9
|
import {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers.js';
|
|
10
10
|
import {fieldStripPunctuation} from './punctuation2.js';
|
|
11
11
|
import {getLanguageCode} from './addMissingField041.js';
|
|
12
|
+
import createDebugLogger from 'debug';
|
|
13
|
+
|
|
14
|
+
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux');
|
|
15
|
+
//const debugData = debug.extend('data');
|
|
16
|
+
const debugDev = debug.extend('dev');
|
|
12
17
|
|
|
13
18
|
const iso9Trans = 'ISO9 <TRANS>';
|
|
14
19
|
const cyrillicTrans = 'CYRILLIC <TRANS>';
|
|
15
20
|
const sfs4900Trans = 'SFS4900 <TRANS>';
|
|
16
21
|
|
|
22
|
+
// eslint-disable-next-line max-lines-per-function
|
|
17
23
|
export default function (config = {}) {
|
|
18
24
|
// console.log(`CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console
|
|
19
25
|
|
|
@@ -111,17 +117,22 @@ export default function (config = {}) {
|
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
function fieldContainsCyrillicCharacters(field) { // based on melinda-ui-cyrillux
|
|
114
|
-
return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf));
|
|
120
|
+
return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf, field.tag));
|
|
115
121
|
}
|
|
116
122
|
|
|
117
|
-
function subfieldRequiresTransliteration(subfield) {
|
|
118
|
-
if (
|
|
123
|
+
function subfieldRequiresTransliteration(subfield, tag = undefined) {
|
|
124
|
+
if (!isContentSubfieldCode(subfield.code, tag)) {
|
|
119
125
|
return false;
|
|
120
126
|
}
|
|
121
127
|
return containsCyrillicCharacters(subfield.value);
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
function tagCanBeTransliterated(tag) {
|
|
131
|
+
// Use this to filter out "(0..)" etc
|
|
132
|
+
if (config.tagPattern && !tag.match(config.tagPattern)) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
// These are hard-coded, and will fail anyway:
|
|
125
136
|
return !['336', '337', '338', '880'].includes(tag);
|
|
126
137
|
}
|
|
127
138
|
|
|
@@ -130,7 +141,7 @@ export default function (config = {}) {
|
|
|
130
141
|
// Discussion: We should probably also skip others like 05X-08X, 648, 650, 651, and 655, but this needs thinking...
|
|
131
142
|
// Also I'd like to convert do CYRILLIC->ISO-9 in field 300 (and others?) without 880 mappings... (<- not implemented)
|
|
132
143
|
|
|
133
|
-
// nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in
|
|
144
|
+
// nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in...`, debugDev);
|
|
134
145
|
if (!tagCanBeTransliterated(field.tag)) {
|
|
135
146
|
return false;
|
|
136
147
|
}
|
|
@@ -153,8 +164,8 @@ export default function (config = {}) {
|
|
|
153
164
|
}
|
|
154
165
|
|
|
155
166
|
|
|
156
|
-
function mapSubfieldToIso9(subfield) {
|
|
157
|
-
if (!subfieldRequiresTransliteration(subfield)) {
|
|
167
|
+
function mapSubfieldToIso9(subfield, tag) {
|
|
168
|
+
if (!subfieldRequiresTransliteration(subfield, tag)) {
|
|
158
169
|
return {code: subfield.code, value: subfield.value}; // just clone
|
|
159
170
|
}
|
|
160
171
|
|
|
@@ -163,17 +174,17 @@ export default function (config = {}) {
|
|
|
163
174
|
return {code: subfield.code, value: conversionResult.result};
|
|
164
175
|
}
|
|
165
176
|
|
|
166
|
-
function mapSubfieldToSfs4900(subfield, lang = 'rus') {
|
|
177
|
+
function mapSubfieldToSfs4900(subfield, tag, lang = 'rus') {
|
|
167
178
|
const inputLang = lang === 'ukr' ? 'ukr' : 'rus'; // Support 'ukr' and 'rus', default to 'rus'
|
|
168
|
-
if (!subfieldRequiresTransliteration(subfield)) {
|
|
179
|
+
if (!subfieldRequiresTransliteration(subfield, tag)) {
|
|
169
180
|
return {code: subfield.code, value: subfield.value};
|
|
170
181
|
}
|
|
171
182
|
const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);
|
|
172
183
|
|
|
173
|
-
|
|
184
|
+
nvdebug(`${JSON.stringify(conversionResult)}`, debugDev);
|
|
174
185
|
const result = conversionResult.result;
|
|
175
|
-
|
|
176
|
-
//
|
|
186
|
+
nvdebug(`${JSON.stringify(result)}`, debugDev);
|
|
187
|
+
//nvdebug(`VAL: ${subfield.value} => ${value} using ${lang}`, debugDev);
|
|
177
188
|
return {code: subfield.code, value: result};
|
|
178
189
|
}
|
|
179
190
|
|
|
@@ -185,7 +196,7 @@ export default function (config = {}) {
|
|
|
185
196
|
const transliterationFunc = iso9 ? mapSubfieldToIso9 : mapSubfieldToSfs4900;
|
|
186
197
|
|
|
187
198
|
// NB! iso9 won't use lang
|
|
188
|
-
const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, lang));
|
|
199
|
+
const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, field.tag, lang));
|
|
189
200
|
|
|
190
201
|
const newField = {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, ...subfield9]};
|
|
191
202
|
|
|
@@ -211,7 +222,7 @@ export default function (config = {}) {
|
|
|
211
222
|
}
|
|
212
223
|
// Just converts the field to ISO-9 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either
|
|
213
224
|
if (!config.retainCyrillic && !config.preferSFS4900) {
|
|
214
|
-
const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf));
|
|
225
|
+
const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf, field.tag));
|
|
215
226
|
return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};
|
|
216
227
|
}
|
|
217
228
|
|
|
@@ -225,7 +236,7 @@ export default function (config = {}) {
|
|
|
225
236
|
}
|
|
226
237
|
// Just converts the field to SFS-4900 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either
|
|
227
238
|
if (!config.retainCyrillic && config.preferSFS4900) {
|
|
228
|
-
const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, lang));
|
|
239
|
+
const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, field.tag, lang));
|
|
229
240
|
return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};
|
|
230
241
|
}
|
|
231
242
|
|
|
@@ -251,7 +262,7 @@ export default function (config = {}) {
|
|
|
251
262
|
if (!config.retainCyrillic) {
|
|
252
263
|
return undefined;
|
|
253
264
|
}
|
|
254
|
-
nvdebug(`Derive CYR 880 from ${fieldToString(field)}
|
|
265
|
+
nvdebug(`Derive CYR 880 from ${fieldToString(field)}`, debugDev);
|
|
255
266
|
const newSubfield6 = deriveSubfield6(field.tag, field.subfields, occurrenceNumber);
|
|
256
267
|
const newSubfield9 = fieldHasSubfield(field, '9', cyrillicTrans) ? [] : [{code: '9', value: cyrillicTrans}];
|
|
257
268
|
const subfields = [
|
|
@@ -261,7 +272,7 @@ export default function (config = {}) {
|
|
|
261
272
|
];
|
|
262
273
|
|
|
263
274
|
const newField = {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};
|
|
264
|
-
nvdebug(` New CYR 880 ${fieldToString(newField)}
|
|
275
|
+
nvdebug(` New CYR 880 ${fieldToString(newField)}`, debugDev);
|
|
265
276
|
return newField;
|
|
266
277
|
}
|
|
267
278
|
|
|
@@ -312,8 +323,8 @@ export default function (config = {}) {
|
|
|
312
323
|
|
|
313
324
|
// Paired field: $9 CYRILLIC <TRANS> is the only legal <TRANS>
|
|
314
325
|
const [pairedField] = existingPairedFields;
|
|
315
|
-
nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}
|
|
316
|
-
nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}
|
|
326
|
+
nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`, debugDev);
|
|
327
|
+
nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`, debugDev);
|
|
317
328
|
if (!fieldContainsCyrillicCharacters(pairedField)) {
|
|
318
329
|
return false;
|
|
319
330
|
}
|
|
@@ -327,7 +338,7 @@ export default function (config = {}) {
|
|
|
327
338
|
const languageCode = getLanguageCode(record);
|
|
328
339
|
const field2 = fieldToString(createFieldForSfs4900Comparison(mapFieldToSfs4900(pairedField, occurrenceNumberAsString, languageCode), field.tag));
|
|
329
340
|
const field1 = fieldToString(createFieldForSfs4900Comparison(field, field.tag));
|
|
330
|
-
nvdebug(`COMPARE CONTENTS:\n '${field1}' vs\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}
|
|
341
|
+
nvdebug(`COMPARE CONTENTS:\n '${field1}' vs\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}`, debugDev);
|
|
331
342
|
return field1 === field2;
|
|
332
343
|
}
|
|
333
344
|
|
|
@@ -372,17 +383,17 @@ export default function (config = {}) {
|
|
|
372
383
|
return [originalField];
|
|
373
384
|
}
|
|
374
385
|
|
|
375
|
-
// nvdebug(`PROCESSING: ${fieldToString(originalField)}
|
|
386
|
+
// nvdebug(`PROCESSING: ${fieldToString(originalField)}`, debugDev);
|
|
376
387
|
|
|
377
388
|
const newOccurrenceNumberAsInt = getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber);
|
|
378
389
|
const newOccurrenceNumberAsString = intToOccurrenceNumberString(newOccurrenceNumberAsInt);
|
|
379
390
|
const languageCode = getLanguageCode(record);
|
|
380
391
|
|
|
381
|
-
// nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'
|
|
392
|
+
// nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'`, debugDev);
|
|
382
393
|
|
|
383
394
|
const existingPairedFields = fieldGetOccurrenceNumberPairs(originalField, record.get('880'));
|
|
384
395
|
|
|
385
|
-
// nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}
|
|
396
|
+
// nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}`, debugDev);
|
|
386
397
|
|
|
387
398
|
const newMainField = mapFieldToIso9(originalField, newOccurrenceNumberAsString); // ISO-9
|
|
388
399
|
const newCyrillicField = retainCyrillic(existingPairedFields) ? mapFieldToCyrillicField880(originalField, newOccurrenceNumberAsString) : undefined; // CYRILLIC
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function tagToDataProvenanceSubfieldCode(tag) {
|
|
2
|
+
if ( ['533', '800', '810', '811', '830'].includes(tag)) {
|
|
3
|
+
return 'y';
|
|
4
|
+
}
|
|
5
|
+
if ( tag === '856' || tag === '857' ) {
|
|
6
|
+
return 'e';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if ( tag.match(/^7[678]/u) ) {
|
|
10
|
+
return 'l'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if ( tag.match(/^00/u)) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return '7';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function isDataProvenanceSubfieldCode(subfieldCode, tag) {
|
|
20
|
+
return subfieldCode === tagToDataProvenanceSubfieldCode(tag);
|
|
21
|
+
}
|
|
@@ -9,6 +9,8 @@ import {fieldFixPunctuation} from './punctuation2.js';
|
|
|
9
9
|
//const {default: createNatlibfiSruClient} = natlibfiSruClient;
|
|
10
10
|
|
|
11
11
|
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:disambiguateSeriesStatements');
|
|
12
|
+
//const debugData = debug.extend('data');
|
|
13
|
+
const debugDev = debug.extend('dev');
|
|
12
14
|
|
|
13
15
|
const ELECTRONIC = 1;
|
|
14
16
|
const PRINTED = 2;
|
|
@@ -16,6 +18,7 @@ const NEITHER_OR_UNKNOWN = 0;
|
|
|
16
18
|
const SRU_API_URL = 'https://sru.api.melinda.kansalliskirjasto.fi/bib';
|
|
17
19
|
|
|
18
20
|
// Author(s): Nicholas Volk
|
|
21
|
+
// eslint-disable-next-line max-lines-per-function
|
|
19
22
|
export default function () {
|
|
20
23
|
const sruClient = createSruClient(SRU_API_URL);
|
|
21
24
|
|
|
@@ -79,7 +82,7 @@ export default function () {
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
const deletableStrings = deletableXs.map(sf => subfieldToString(sf));
|
|
82
|
-
nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`,
|
|
85
|
+
nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`, debugDev);
|
|
83
86
|
|
|
84
87
|
// fixer:
|
|
85
88
|
if (reallyFix) {
|
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './disambiguateSeriesStatements.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -19,7 +19,7 @@ generateTests({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');
|
|
23
23
|
|
|
24
24
|
async function testValidatorFactory() {
|
|
25
25
|
const validator = await validatorFactory();
|
|
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
|
|
|
29
29
|
assert.equal(typeof validator.validate, 'function');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async function callback({getFixture,
|
|
33
|
-
if (enabled === false) {
|
|
34
|
-
debug('TEST SKIPPED!');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
32
|
+
async function callback({getFixture, fix = false}) {
|
|
38
33
|
const validator = await validatorFactory();
|
|
39
34
|
const record = new MarcRecord(getFixture('record.json'));
|
|
40
35
|
const expectedResult = getFixture('expectedResult.json');
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Author(s): Nicholas Volk
|
|
2
|
+
|
|
3
|
+
import clone from 'clone';
|
|
4
|
+
import createDebugLogger from 'debug';
|
|
5
|
+
import {fieldToString, nvdebug} from './utils.js';
|
|
6
|
+
import {getLexiconAndLanguage, getTermData, isLabel, isValidSubfield0} from './translate-terms.js';
|
|
7
|
+
|
|
8
|
+
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:drop-terms');
|
|
9
|
+
//const debugData = debug.extend('data');
|
|
10
|
+
const debugDev = debug.extend('dev');
|
|
11
|
+
|
|
12
|
+
const defaultConfig = {
|
|
13
|
+
'constraints': [
|
|
14
|
+
{'tag': '648', 'lex': 'yso/fin'},
|
|
15
|
+
{'tag': '648', 'lex': 'yso/swe'},
|
|
16
|
+
{'tag': '650', 'lex': 'yso/fin'},
|
|
17
|
+
{'tag': '650', 'lex': 'yso/swe'},
|
|
18
|
+
{'tag': '651', 'lex': 'yso/fin'},
|
|
19
|
+
{'tag': '651', 'lex': 'yso/swe'},
|
|
20
|
+
{'tag': '655', 'lex': 'slm/fin'},
|
|
21
|
+
{'tag': '655', 'lex': 'slm/swe'}
|
|
22
|
+
],
|
|
23
|
+
'keep invalid url': false, // If not true, removes illegal subfield $0. The whole field removal is later decided by 'keep 0-less'
|
|
24
|
+
'keep invalid label': false, // label ($a) is neither pref Label nor altLabel => remove whole field
|
|
25
|
+
'remove altLabel': false,
|
|
26
|
+
'remove 0-less': true
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// eslint-disable-next-line max-lines-per-function
|
|
30
|
+
export default function (config = defaultConfig) {
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
description: 'Drop yso and slm terms that do not match their identifiers. Use for incoming records only! Not for records already in Melinda!',
|
|
34
|
+
validate, fix
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
async function fix(record, validateMode = false) {
|
|
38
|
+
const clonedFields = record.fields.map(f => clone(f));
|
|
39
|
+
|
|
40
|
+
const results = await processFields(clonedFields);
|
|
41
|
+
|
|
42
|
+
const removables = results.map((f, i) => !f ? record.fields[i] : undefined).filter(f => f);
|
|
43
|
+
const modMessages = results.map((f, i) => getMod(f, i)).filter(f => f);
|
|
44
|
+
const removalMessages = removables.map(f => `Remove '${fieldToString(f)}'`);
|
|
45
|
+
const allMessages = [...modMessages, ...removalMessages];
|
|
46
|
+
|
|
47
|
+
if (validateMode) {
|
|
48
|
+
if (allMessages.length === 0) {
|
|
49
|
+
return {'message': [], 'valid': true};
|
|
50
|
+
}
|
|
51
|
+
return {'message': allMessages, 'valid': false};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
removables.forEach(f => record.removeField(f));
|
|
55
|
+
|
|
56
|
+
return {message: [], fix: allMessages, valid: true};
|
|
57
|
+
|
|
58
|
+
function getMod(field, index) {
|
|
59
|
+
if (!field) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const before = fieldToString(record.fields[index]);
|
|
63
|
+
const after = fieldToString(results[index]);
|
|
64
|
+
if (before !== after) {
|
|
65
|
+
if (!validateMode) {
|
|
66
|
+
record.fields[index] = field;
|
|
67
|
+
}
|
|
68
|
+
return `Modify '${before}' => '${after}'`;
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isPotentialField(f) {
|
|
75
|
+
if (!config || !config.constraints) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return config.constraints.some(c => c.tag === f.tag && f.subfields?.some(sf => sf.code === '2' && sf.value === c.lex));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function validate(record) {
|
|
82
|
+
return fix(record, true);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async function processFields(fields, results = []) {
|
|
87
|
+
const [currField, ...remainingFields] = fields;
|
|
88
|
+
if (!currField) {
|
|
89
|
+
return results;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!isPotentialField(currField)) { // Not interested in this field
|
|
93
|
+
return processFields(remainingFields, [...results, currField]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
removeSyntacticallyIllegalSubfield0s(currField); // iff config wants them to be removed...
|
|
97
|
+
|
|
98
|
+
const removable = await isRemovableField(currField);
|
|
99
|
+
|
|
100
|
+
return processFields(remainingFields, [...results, removable ? undefined : currField]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function removeSyntacticallyIllegalSubfield0s(field) {
|
|
104
|
+
if (config['keep invalid url']) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const lexData = getLexiconAndLanguage(field);
|
|
109
|
+
if (!lexData.lang) { // This is an error of sorts. Should we proceed and remove $0s?
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
field.subfields = field.subfields.filter(sf => sf.code !== '0' || isValidSubfield0(sf, lexData.lex));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function isRemovableField(field) {
|
|
117
|
+
// nvdebug(`FOO===== ${fieldToString(field)}`, debugDev);
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// $0-less field:
|
|
121
|
+
if (!field.subfields.some(sf => sf.code === '0')) {
|
|
122
|
+
return config['remove 0-less'];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const subfield0 = field.subfields.find(sf => sf.code === '0');
|
|
126
|
+
const data = await getTermData(subfield0.value);
|
|
127
|
+
// NB! No data might be a BUG! This might delete all incoming terms if Finto is down... (we should distinguish between a miss and a failure)
|
|
128
|
+
// However, if we use this validator only for incoming records, it's fine enough.
|
|
129
|
+
|
|
130
|
+
if (data) {
|
|
131
|
+
const subfieldA = field.subfields.find(sf => sf.code === 'a');
|
|
132
|
+
if (subfieldA) {
|
|
133
|
+
const lexData = getLexiconAndLanguage(field);
|
|
134
|
+
|
|
135
|
+
// $a is the pref label. All is fine!
|
|
136
|
+
if (isLabel(data.prefLabel, subfieldA.value, lexData.lang)) {
|
|
137
|
+
nvdebug(`altLabel found: ${subfieldA.value}`, debugDev);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (isLabel(data.altLabel, subfieldA.value, lexData.lang)) {
|
|
141
|
+
nvdebug(`altLabel found: ${subfieldA.value}`, debugDev);
|
|
142
|
+
// Oddly enough this could remove altLabel but keep totally invalid labels...
|
|
143
|
+
return config['remove altLabel'];
|
|
144
|
+
}
|
|
145
|
+
nvdebug(`a-2-0 mismatch: ${fieldToString(field)}`, debugDev);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if (config['keep invalid label']) {
|
|
151
|
+
// We keep the label $a. However, we can get rid of $0 if we want to (semantic reasons)
|
|
152
|
+
if (!config['keep invalid url']) {
|
|
153
|
+
nvdebug(`=============== 0-removal`, debugDev);
|
|
154
|
+
field.subfields = field.subfields.filter(sf => sf.code !== '0');
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
//import createDebugLogger from 'debug';
|
|
3
|
+
import fetchMock from 'fetch-mock';
|
|
4
|
+
|
|
5
|
+
import validatorFactory from './drop-terms.js';
|
|
6
|
+
|
|
7
|
+
import {MarcRecord} from '@natlibfi/marc-record';
|
|
8
|
+
import {READERS} from '@natlibfi/fixura';
|
|
9
|
+
import generateTests from '@natlibfi/fixugen';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
import {fakeData} from '../test-fixtures/translate-terms-data.js';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const uris = [
|
|
16
|
+
'http://www.yso.fi/onto/yso/p444',
|
|
17
|
+
'http://www.yso.fi/onto/yso/p500',
|
|
18
|
+
'http://www.yso.fi/onto/yso/p13299',
|
|
19
|
+
'http://www.yso.fi/onto/yso/p111739',
|
|
20
|
+
'http://www.yso.fi/onto/yso/p6197061979',
|
|
21
|
+
'http://www.yso.fi/onto/yso/p6196061969',
|
|
22
|
+
'http://urn.fi/URN:NBN:fi:au:slm:s161'
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const useMock = 1;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
generateTests({
|
|
29
|
+
callback,
|
|
30
|
+
path: [import.meta.dirname, '..', 'test-fixtures', 'drop-terms'],
|
|
31
|
+
useMetadataFile: true,
|
|
32
|
+
recurse: false,
|
|
33
|
+
fixura: {
|
|
34
|
+
reader: READERS.JSON
|
|
35
|
+
},
|
|
36
|
+
hooks: {
|
|
37
|
+
before: async () => {
|
|
38
|
+
|
|
39
|
+
if (useMock) {
|
|
40
|
+
fetchMock.mockGlobal()
|
|
41
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[0]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
42
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[1]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
43
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[2]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
44
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[3]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
45
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[4]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
46
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[5]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
47
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[6]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
testValidatorFactory();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/drop-terms:test');
|
|
56
|
+
|
|
57
|
+
async function testValidatorFactory() {
|
|
58
|
+
const validator = await validatorFactory();
|
|
59
|
+
|
|
60
|
+
assert.equal(typeof validator, 'object');
|
|
61
|
+
assert.equal(typeof validator.description, 'string');
|
|
62
|
+
assert.equal(typeof validator.validate, 'function');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function callback({getFixture, fix = false, config = undefined}) {
|
|
66
|
+
const validator = await validatorFactory(config);
|
|
67
|
+
const record = new MarcRecord(getFixture('record.json'));
|
|
68
|
+
const expectedResult = getFixture('expectedResult.json');
|
|
69
|
+
// console.log(expectedResult); // eslint-disable-line
|
|
70
|
+
|
|
71
|
+
if (!fix) {
|
|
72
|
+
const result = await validator.validate(record);
|
|
73
|
+
assert.deepEqual(result, expectedResult);
|
|
74
|
+
const originalRecord = new MarcRecord(getFixture('record.json'));
|
|
75
|
+
assert.deepEqual(record, originalRecord); // Validation should not change the record
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const expectedResult2 = new MarcRecord(expectedResult);
|
|
79
|
+
await validator.fix(record);
|
|
80
|
+
assert.deepEqual(record, expectedResult2);
|
|
81
|
+
}
|
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './field-008-18-34-character-groups.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -19,7 +19,7 @@ generateTests({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-008-18-34-character-groups:test');
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-008-18-34-character-groups:test');
|
|
23
23
|
|
|
24
24
|
async function testValidatorFactory() {
|
|
25
25
|
const validator = await validatorFactory();
|
|
@@ -30,12 +30,7 @@ async function testValidatorFactory() {
|
|
|
30
30
|
assert.equal(typeof validator.validate, 'function');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
async function callback({getFixture,
|
|
34
|
-
if (enabled === false) {
|
|
35
|
-
debug('TEST SKIPPED!');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
33
|
+
async function callback({getFixture, fix = false}) {
|
|
39
34
|
const validator = await validatorFactory();
|
|
40
35
|
const record = new MarcRecord(getFixture('record.json'));
|
|
41
36
|
const expectedResult = getFixture('expectedResult.json');
|
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './field-505-separators.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -19,7 +19,7 @@ generateTests({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-505-separators:test');
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/field-505-separators:test');
|
|
23
23
|
|
|
24
24
|
async function testValidatorFactory() {
|
|
25
25
|
const validator = await validatorFactory();
|
|
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
|
|
|
29
29
|
assert.equal(typeof validator.validate, 'function');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async function callback({getFixture,
|
|
33
|
-
if (enabled === false) {
|
|
34
|
-
debug('TEST SKIPPED!');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
32
|
+
async function callback({getFixture, fix = false}) {
|
|
38
33
|
const validator = await validatorFactory();
|
|
39
34
|
|
|
40
35
|
const recordFixture = getFixture('record.json');
|
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './field-521-fix.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -19,7 +19,7 @@ generateTests({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/fix521:test');
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/fix521:test');
|
|
23
23
|
|
|
24
24
|
async function testValidatorFactory() {
|
|
25
25
|
const validator = await validatorFactory();
|
|
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
|
|
|
29
29
|
assert.equal(typeof validator.validate, 'function');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async function callback({getFixture,
|
|
33
|
-
if (enabled === false) {
|
|
34
|
-
debug('TEST SKIPPED!');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
32
|
+
async function callback({getFixture, fix = false}) {
|
|
38
33
|
const validator = await validatorFactory();
|
|
39
34
|
const record = new MarcRecord(getFixture('record.json'));
|
|
40
35
|
const expectedResult = getFixture('expectedResult.json');
|