@natlibfi/marc-record-validators-melinda 12.1.0-alpha.1 → 13.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cyrillux-usemarcon-replacement.js"],
|
|
4
|
-
"sourcesContent": ["/*\n* cyrillux-usemarcon-replacement.js -- implement and improve https://github.com/NatLibFi/USEMARCON-Cyrillux/tree/master\n*\n* Author(s): Nicholas Volk <nicholas.volk@helsinki.fi>\n*\n*/\n\nimport clone from 'clone';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {default as fix33X} from './fix-33X.js';\nimport {default as add041} from './addMissingField041.js';\nimport {default as add336} from './addMissingField336.js';\nimport {default as add337} from './addMissingField337.js';\nimport {default as add338} from './addMissingField338.js';\nimport {default as fixCountryCodes} from './fix-country-codes.js';\nimport {default as fixLanguageCodes} from './fix-language-codes.js';\nimport {default as fixRelatorTerms} from './fixRelatorTerms.js';\nimport {default as fixIndicators} from './indicator-fixes.js';\nimport {default as fixPunctuation} from './punctuation2.js';\nimport {default as fixQualifyingInformation} from './normalize-qualifying-information.js';\nimport {sortAdjacentSubfields} from './sortSubfields.js';\n\n// import createDebugLogger from 'debug';\nimport {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString, removeSubfield} from './utils.js';\n\n// const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');\n\nconst description = 'Replacement for Cyrillux usemarcon rules';\n\n// Extended original list with 541, 561, 562, 583, 584\n// 017, 044... et al are LL additions from 2019 (via USEMARCON-RDA)\nconst 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'];\n\n\nexport default function () {\n return {\n description, fix, validate\n };\n\n function fix(record) {\n nvdebug(`${description}: fix`);\n realFix(record);\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n function realFixNonAleph(record) {\n if (isAlephRecord(record)) {\n return;\n }\n\n // Update LDR/17 to '4'\n record.leader = `${record.leader.substring(0, 17)}4${record.leader.substring(18, 24)}`;\n\n // Remove unwanted fields:\n record.fields = record.fields.filter(f => !dropTags.includes(f.tag));\n\n removeSubfield(record, '020', 'c');\n\n // Remove 084 fields that don't have $2 ykl (based on USEMARCON-RDA/bw_rda_kyril.rul code by LL 2019)\n record.fields = record.fields.filter(f => f.tag !== '084' || f.subfields.some(sf => sf.code === '2' && sf.value === 'ykl'));\n\n fieldSpecificStuff(record.fields);\n\n function fieldSpecificStuff(fields) {\n const [field, ...rest] = fields;\n\n if (field === undefined) {\n return;\n }\n\n removeOwnershipSubfield5(field);\n removeFromOldCatalog(field); // Remove LoC phrase \"[from old catalog]\" from srings\n translateFieldToFinnish(field);\n\n return fieldSpecificStuff(rest);\n }\n\n fixField040(record); // All $b values are changed to 'mul'. As a side effect 33X$b=>$a mappings are in Finnish! Ok in this domain!\n\n fieldSpecificStuff2(record.fields);\n\n function fieldSpecificStuff2(fields) {\n const [field, ...rest] = fields;\n\n if (field === undefined) {\n return;\n }\n\n removeSubfieldH(field); // NB! Do this only after 33X creation, as 245$h might be useful there!\n\n field100eKirjoittaja(field);\n\n function field100eKirjoittaja(f) { // LL 2019 USEMARCON-RDA rule\n if (f.tag === '100' && !fieldHasSubfield(f, 'e') && record.isBK()) {\n f.subfields = [{code: 'e', value: 'kirjoittaja.'}, ...f.subfields];\n sortAdjacentSubfields(f);\n // Punctuation will be done later on...\n return;\n }\n }\n\n field260To264s(field, record);\n\n // NB! 300 (before or after 33X creation?)\n field410To490And810(field, record);\n field440To490And830(field, record);\n // handle505(field); // not applying them usemarcon-cyrillux rules for field 505 as I can't understand their motivation.\n return fieldSpecificStuff2(rest);\n }\n\n }\n\n function realFixAll1(record) {\n fixLeader(record); // Fix defaults, esp. LDR/18=i\n\n fixCountryCodes().fix(record); // 008/15-17\n fixLanguageCodes().fix(record); // 008/35-37 AND 041 (note that all relevant subfield codes are fixed, not just $a)\n\n recordRemoveValuelessSubfields(record);\n\n // Field 028: use $b$a, not $a$b:\n const f028 = record.fields.filter(f => f.tag === '028');\n f028.forEach(f => sortAdjacentSubfields(f));\n\n add041().fix(record);\n\n }\n\n function realFixAll2(record) {\n fixQualifyingInformation().fix(record); // 015, 020, 024 and 028\n\n // Cyrillux specific code might change 040$b and thus affect these rules:\n fixRelatorTerms().fix(record);\n fix33X().fix(record); // 33X$a => 33X$a$b$2\n add336().fix(record);\n add337().fix(record);\n add338().fix(record);\n\n // The fixer below implements Cyrillux rules such as 245I1 | 245I1 | If (Exists(@100) Or Exists(@110) Or Exists(@111) Or Exists(@130)) Then '1' Else '0' and plenty of other good stuff:\n fixIndicators().fix(record);\n\n fixPunctuation().fix(record);\n }\n\n function realFix(record) {\n realFixAll1(record);\n\n realFixNonAleph(record);\n\n realFixAll2(record);\n\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n // Validation is currently done in subparts\n function validate(record) {\n nvdebug(`${description}: validate`);\n const originalString = recordToString(record);\n const clonedRecord = new MarcRecord(record, {subfieldValues: false});\n realFix(clonedRecord);\n const modifiedString = recordToString(clonedRecord);\n\n if (originalString === modifiedString) {\n return {message: [], valid: true};\n }\n\n return {message: ['Record changed'], valid: false}; // Less than descriptive but will do...\n\n }\n}\n\nfunction fixField040(record) {\n const f040 = record.get('040');\n\n const subfieldsBE = [\n {code: 'b', value: 'mul'},\n {code: 'e', value: 'rda'}\n ];\n\n // Add 040 if there isn't one:\n if (f040.length === 0) {\n const data = {tag: '040', ind1: ' ', ind2: ' ', subfields: subfieldsBE};\n\n record.insertField(data);\n return;\n }\n\n f040.forEach(f => fixField040Subfields(f));\n\n function fixField040Subfields(field) {\n field.subfields = field.subfields.filter(sf => !['b', 'e'].includes(sf.code));\n field.subfields.push(subfieldsBE[0]);\n field.subfields.push(subfieldsBE[1]);\n sortAdjacentSubfields(field); // put $b and $e to their proper places\n }\n\n}\n\nexport function removeFromOldCatalog(field) {\n if (!field.tag.match(/^(?:240|65[0135]|[1678](?:00|10|11|30))$/u)) {\n return;\n }\n // See https://catalog.loc.gov/vwebv/ui/en_US/htdocs/help/faqs.html for motivation\n field.subfields?.forEach(sf => removeFromOldCatalogFromSubfield(sf));\n\n function removeFromOldCatalogFromSubfield(subfield) {\n if (!subfield.value.includes('[from old catalog]')) {\n return;\n }\n subfield.value = subfield.value.replace(/ *\\[from old catalog\\]/gui, '');\n }\n}\n\nfunction removeSubfieldH(field) {\n if (!field.subfields || !['245', '246', '247', '740', '760', '762', '765', '767', '770', '772', '773', '774', '775', '776', '777', '780', '785', '786', '787', '788'].includes(field.tag)) {\n return;\n }\n\n const filteredFields = field.subfields.filter(sf => sf.code !== 'h');\n if (filteredFields.length > 0) {\n field.subfields = filteredFields;\n return;\n }\n\n}\n\nexport function removeOwnershipSubfield5(field) {\n if (!field.subfields || field.subfields.length === 0) {\n return;\n }\n const remainingSubfields = field.subfields.filter(sf => sf.code !== '5');\n if (remainingSubfields.length === 0) { // sanity check/robustness\n return;\n }\n field.subfields = remainingSubfields;\n}\n\nexport function fixLeader(record) {\n record.leader = `${record.leader.substring(0, 9)}a22${record.leader.substring(12, 18)}i${record.leader.substring(19, 20)}4500`;\n}\n\nfunction field410To490And810(field, record) { // might be generic... if so, move to utils...\n if (field.tag !== '410') {\n return;\n }\n\n const field810 = clone(field);\n\n field.tag = '490';\n field.ind1 = '1';\n field.ind2 = ' ';\n sortAdjacentSubfields(field);\n // 490: Fix punctuation elsewhere. (Note that the current support is lagging...)\n\n\n field810.tag = '810';\n field810.ind2 = ' ';\n // 810: Fix punctuation elsewhere. (Note that the current support is lagging...)\n record.insertField(field810);\n}\n\nfunction field440To490And830(field, record) { // might be generic... if so, move to utils...\n if (field.tag !== '440') {\n return;\n }\n\n const field830 = clone(field);\n\n field.tag = '490';\n field.ind1 = '1';\n field.ind2 = ' ';\n // 490: Fix punctuation elsewhere. (Note that the current support is lagging...)\n field830.tag = '830';\n // 830: Fix punctuation elsewhere. (Note that the current support is lagging...)\n record.insertField(field830);\n}\n\nfunction isAlephRecord(record) {\n // Records that are already in Aleph are not processed as aggressively as genuinely new ones:\n return record.fields.some(field => ['CAT', 'LKR', 'LOW', 'SID'].includes(field.tag));\n}\n\nfunction field260To264s(field, record) { // might be generic... if so, move to utils...\n // As per my quick reading of usemarcon-cyrillux\n if (field.tag !== '260') {\n return;\n }\n\n createCopyright264Field(field);\n\n field.tag = '264';\n field.ind1 = ' ';\n field.ind2 = '1';\n\n // NB! Usemarcon does not handle 260$e$f$g => 264$a$b$c, so I'm not botherin with it either... (However, we could check our merge reducer code...)\n\n function getCopyrightYear(string) {\n if (string.match(/^(?:\\[?[Ccp]|[^0-9]*(?:cop|\u00A9|\u2117))[^0-9]*(?:1[789][0-9][0-9]|20[0-2][0-9])[^0-9]*$/u)) {\n return string.replace(/[^0-9]/ug, '');\n }\n return false;\n }\n\n field.subfields?.forEach(sf => field260To264Normalization(sf));\n\n function field260To264Normalization(subfield) {\n subfield.value = field260To264Normalization2(subfield);\n }\n\n function createCopyright264Value(field) {\n // Extract/split copyright year to a separate field:\n const [c] = field.subfields.filter(sf => sf.code === 'c');\n if (!c) {\n return undefined;\n }\n const copyrightYear = getCopyrightYear(c.value);\n if (!copyrightYear) {\n return undefined;\n }\n const copType = c.value.match(/(?:^\\[?p|\u2117)/u) ? '\u2117' : '\u00A9';\n const returnValue = c.value.includes('[') ? `[${copType}${copyrightYear}]` : `${copType}${copyrightYear}`;\n // Moidy the original value:\n c.value = `[${copyrightYear}]`;\n return returnValue;\n }\n\n function createCopyright264Field(field) {\n const c = createCopyright264Value(field);\n if (!c) {\n return undefined;\n }\n const data = {'tag': '264', 'ind1': ' ', 'ind2': '4', 'subfields': [{'code': 'c', 'value': c}]};\n record.insertField(data);\n }\n\n function field260To264Normalization2(subfield) {\n if (subfield.code === 'a') {\n return subfield.value.replace(/\\b[Ss]\\. ?l\\./u, 'Kustannuspaikka tuntematon');\n }\n if (subfield.code === 'b') {\n return subfield.value.replace(/\\b[Ss]\\. ?n\\./u, 'kustantaja tuntematon');\n }\n if (subfield.code === 'c') {\n const year = getCopyrightYear(subfield.value);\n if (year) {\n const c = subfield.value.match(/(?:^p|\u2117)/u) ? 'p' : 'c';\n if (subfield.value.includes('[')) {\n return `${c}[${year}]`;\n }\n return `${c}${year}`;\n }\n return subfield.value.replace(/\\b[Ss]\\. ?a\\./u, 'julkaisuaika tuntematon');\n }\n return subfield.value;\n }\n\n\n}\n\n/*\nfunction handle505(field) {\n if (field.tag !== '505') {\n return;\n }\n // Don't know how/why usemarcon-cyrillux is so sure about ind1...\n field.ind1 = '0';\n // usemarcon-cyrillux drops irrelevant subfields, so we do the same. However, we have included some control subfields in the kept side:\n const keptSubfields = field.subfields.filter(sf => ['a', 'g', 'r', 't', 'u', '6', '8', '9'].includes(sf.code));\n\n if (keptSubfields.some(sf => ['a', 'g', 'r', 't', 'u'].includes(sf.code))) {\n field.subfields = keptSubfields;\n return;\n }\n}\n*/\n\nfunction translateFieldToFinnish(field) {\n if (!['020', '300'].includes(field.tag)) {\n return;\n }\n field.subfields?.forEach(sf => translateSubfieldToFinnish(sf));\n\n function translateSubfieldToFinnish(subfield) {\n if (field.tag === '020' && ['a', 'q', 'z'].includes(subfield.code)) {\n subfield.value = finnishTranslationsAndMappings(expandFinnishAbbreviations(expandSwedishAbbreviations(expandEnglishAbbreviations(subfield.value))));\n return;\n }\n if (field.tag === '300') {\n subfield.value = finnishTranslationsAndMappings(expandFinnishAbbreviations(expandSwedishAbbreviations(expandEnglishAbbreviations(subfield.value))));\n return;\n }\n }\n}\n\nfunction expandEnglishAbbreviations(value) {\n return value.replace(/\\bbk\\.\\b/gui, 'book').\n replace(/chiefly col\\./ui, 'chiefly color').\n replace(/col\\. ill\\./ui, 'color illustrations').\n replace(/diagrs\\./ui, 'diagrams').\n replace(/\\bhbk\\.\\b/gui, 'hardcover').replace(/\\bhbk\\b/gui, 'hardcover'). // expand to MTS-compliant form\n replace(/\\b1 hr\\./gui, '1 hour').\n replace(/\\bhr\\./gui, 'hours').\n replace(/\\bill\\./gui, 'illustrated'). // or illustrations (or Swedish \"illustrerad\" or...)\n replace(/\\billus\\./gui, 'illustrated'). // or illustrations\n replace(/incl\\./gui, 'includes').\n replace(/fold\\.? maps/gui, 'folded maps').\n // replace(/\\bmin\\./gu, 'minutes').\n // replace(/\\bmin\\b/gu, 'minutes').\n replace(/\\bp\\.\\b/gui, 'pages').replace(/\\bp\\b/gu, 'pages').\n replace(/\\bpbk\\.\\b/gui, 'paperback').replace(/\\bpbk\\b/gui, 'paperback'). // expand to MTS-compliant form\n replace(/\\bpdf\\b/gui, 'PDF').\n replace(/\\bports\\./gui, 'portraits').\n replace('sd., col.', 'sound, color').\n replace(/ *\\((?:chiefly col\\.|chiefly color|some col[s.])\\)/gui, '').\n replace(/\\b1 hr\\./gui, '1 hour');\n}\n\nfunction expandFinnishAbbreviations(value) {\n return value.replace(/\\bcn\\. /gu, 'noin ').\n // replace(/\\bmin\\./gu, 'minuuttia').\n // replace(/\\bmin\\b/gu, 'minuuttia').\n replace(/\\bnid\\./gu, 'nidottu').replace(/\\bnid\\b/gui, 'nidottu').\n replace(/\\bsid\\./gu, 'sidottu').replace(/\\bsid\\b/gui, 'sidottu').\n replace(/\\bverkkojulk\\.\\b/gu, 'verkkojulkaisu').replace(/\\bverkkojulk\\b/gu, 'verkkojulkaisu').\n replace(/^\\(([^)]+)\\)$/u, '$1');\n // <- removal of brackets above could use a better location\n}\n\nfunction expandSwedishAbbreviations(value) {\n return value.replace(/\\bca\\. /gu, 'circa ').\n replace(/\\bhft\\./gui, 'h\u00E4ftad').replace(/\\bhft\\b/gui, 'h\u00E4ftad');\n // replace(/\\bmin\\./gu, 'minuter').\n // replace(/\\bmin\\b/gu, 'minuter');\n}\n\nfunction finnishTranslationsAndMappings(value) {\n return value.replace('analog', 'analoginen').\n replace('approximately', 'noin').\n replace('audio discs', '\u00E4\u00E4nilevy\u00E4').\n replace('black and white', 'mustavalkoinen').\n replace(/\\bbilaga\\b/gui, 'liite').\n replace(/\\bbilagor\\b/gui, 'liitett\u00E4').\n // https://github.com/NatLibFi/USEMARCON-BOOKWHERE-RDA/blob/master/bw_rda_kyril.rul#L365\n replace(/(\\b1\\]?) \u0441\\./gui, '$1 sivu').\n replace(/(\\d\\]?) \u0441\\./gui, '$1 sivua').\n replace(/(\\d) \u0441\u043C/gui, '$1 cm').\n\n replace(/\\bcharts\\b/gui, 'kaavioita').\n replace('chiefly color illustrations', 'p\u00E4\u00E4osin v\u00E4rikuvitettu').\n replace('chiefly', 'p\u00E4\u00E4osin').\n replace(/\\bcirca\\b/gui, 'noin').\n replace(/coil[- ]?bound/gui, 'kierreselk\u00E4').\n replace('color illustrations', 'v\u00E4rikuvitus').\n replace(/comb[- ]?bound/gui, 'kierreselk\u00E4').\n replace(/\\bdigital\\b/gui, 'digitaalinen').\n replace(/\\belectronic book\\b/gui, 'verkkoaineisto').\n replace('(flera nummersviter)', '(useita numerointijaksoja)').\n replace(/\\bfolded sheet\\b/gui, 'taitelehti').\n replace(/\\bf\u00E4rgillustratione[nr]\\b/gui, 'v\u00E4rikuvitus').\n replace(/\\bhard(?:back|cover)\\b/gui, 'kovakantinen').\n replace(/\\bhours\\b/gui, 'tuntia').\n replace(/\\bi flera nummersviter/gui, 'useina numerointijaksoina').\n replace('illustrated', 'kuvitettu').\n replace(/illustrations?\\b/gui, 'kuvitettu'). // Based on usemacron-bookwhere (NB! usemarcon-cyrillux had kuvitus/kuvitettu)\n replace(/\\binbunden\\b/gui, 'kovakantinen'). // swe\n replace(/\\binsert\\b/gui, 'liite').\n replace(/\\binserts\\b/gui, 'liitteit\u00E4').\n replace(/\\bin various pagings/gui, 'useina numerointijaksoina').\n replace('leaves of plates', 'kuvalehte\u00E4').\n replace(/\\bljudskiva\\b/gui, '\u00E4\u00E4nilevy').\n replace(/\\bljudskivor\\b/gui, '\u00E4\u00E4nilevy\u00E4').\n replace(/\\bmap\\b/gui, 'kartta').\n replace(/\\bmaps\\b/gui, 'karttoja'). // or karttaa?\n replace('minutes', 'minuuttia').\n replace('mjuka p\u00E4rmar', 'pehme\u00E4kantinen').\n replace('online resource', 'verkkoaineisto').\n replace('onlineresurs', 'verkkoaineisto').\n replace('onumrerade', 'numeroimatonta').\n replace('pages of plates', 'kuvalehte\u00E4').\n replace(/\\bpages\\b/gui, 'sivua').\n replace(/\\bpaperback\\b/gui, 'pehme\u00E4kantinen'). // MTS alt\n replace(/\\bSeiten\\b/gu, 'sivua').\n replace(/\\bsoftcover\\b/gui, 'pehme\u00E4kantinen'). // MTS pref\n replace('sound, color', '\u00E4\u00E4nellinen, v\u00E4rillinen').\n replace('sound cassettes', '\u00E4\u00E4nikasettia').replace('sound cassette', '\u00E4\u00E4nikasetti').\n replace('sound discs', '\u00E4\u00E4nilevy\u00E4').replace(/sound disc\\b/gui, '\u00E4\u00E4nilevy').\n replace(/(?:spiral[- ]?bound|spiralrygg)/gui, 'kierreselk\u00E4').\n replace('svartvit', 'mustavalkoinen').\n replace('unnumbered', 'numeroimatonta').\n replace('(various pagings)', '(useita numerointijaksoja)').\n replace(/\\bverkkojulkaisu\\b/gui, 'verkkoaineisto').\n replace('videodiscs', 'videolevy\u00E4').\n replace('videodisc', 'videolevy').\n replace(/\\b1 hour\\b/gui, '1 tunti');\n\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\n\n/*\n* cyrillux-usemarcon-replacement.js -- implement and improve https://github.com/NatLibFi/USEMARCON-Cyrillux/tree/master\n*\n* Author(s): Nicholas Volk <nicholas.volk@helsinki.fi>\n*\n*/\n\nimport clone from 'clone';\nimport createDebugLogger from 'debug';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {default as fix33X} from './fix-33X.js';\nimport {default as add041} from './addMissingField041.js';\nimport {default as add336} from './addMissingField336.js';\nimport {default as add337} from './addMissingField337.js';\nimport {default as add338} from './addMissingField338.js';\nimport {default as fixCountryCodes} from './fix-country-codes.js';\nimport {default as fixLanguageCodes} from './fix-language-codes.js';\nimport {default as fixRelatorTerms} from './fixRelatorTerms.js';\nimport {default as fixIndicators} from './indicator-fixes.js';\nimport {default as fixPunctuation} from './punctuation2.js';\nimport {default as fixQualifyingInformation} from './normalize-qualifying-information.js';\nimport {sortAdjacentSubfields} from './sortSubfields.js';\nimport {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString, removeSubfield} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux-usermarcon-replacement');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst description = 'Replacement for Cyrillux usemarcon rules';\n\n// Extended original list with 541, 561, 562, 583, 584\n// 017, 044... et al are LL additions from 2019 (via USEMARCON-RDA)\nconst 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'];\n\n\n// eslint-disable-next-line max-lines-per-function\nexport default function () {\n return {\n description, fix, validate\n };\n\n function fix(record) {\n nvdebug(`${description}: fix`, debugDev);\n realFix(record);\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n function realFixNonAleph(record) {\n if (isAlephRecord(record)) {\n return;\n }\n\n // Update LDR/17 to '4'\n record.leader = `${record.leader.substring(0, 17)}4${record.leader.substring(18, 24)}`;\n\n // Remove unwanted fields:\n record.fields = record.fields.filter(f => !dropTags.includes(f.tag));\n\n removeSubfield(record, '020', 'c');\n\n // Remove 084 fields that don't have $2 ykl (based on USEMARCON-RDA/bw_rda_kyril.rul code by LL 2019)\n record.fields = record.fields.filter(f => f.tag !== '084' || f.subfields.some(sf => sf.code === '2' && sf.value === 'ykl'));\n\n fieldSpecificStuff(record.fields);\n\n function fieldSpecificStuff(fields) {\n const [field, ...rest] = fields;\n\n if (field === undefined) {\n return;\n }\n\n removeOwnershipSubfield5(field);\n removeFromOldCatalog(field); // Remove LoC phrase \"[from old catalog]\" from srings\n translateFieldToFinnish(field);\n\n return fieldSpecificStuff(rest);\n }\n\n fixField040(record); // All $b values are changed to 'mul'. As a side effect 33X$b=>$a mappings are in Finnish! Ok in this domain!\n\n fieldSpecificStuff2(record.fields);\n\n function fieldSpecificStuff2(fields) {\n const [field, ...rest] = fields;\n\n if (field === undefined) {\n return;\n }\n\n removeSubfieldH(field); // NB! Do this only after 33X creation, as 245$h might be useful there!\n\n field100eKirjoittaja(field);\n\n function field100eKirjoittaja(f) { // LL 2019 USEMARCON-RDA rule\n if (f.tag === '100' && !fieldHasSubfield(f, 'e') && record.isBK()) {\n f.subfields = [{code: 'e', value: 'kirjoittaja.'}, ...f.subfields];\n sortAdjacentSubfields(f);\n // Punctuation will be done later on...\n return;\n }\n }\n\n field260To264s(field, record);\n\n // NB! 300 (before or after 33X creation?)\n field410To490And810(field, record);\n field440To490And830(field, record);\n // handle505(field); // not applying them usemarcon-cyrillux rules for field 505 as I can't understand their motivation.\n return fieldSpecificStuff2(rest);\n }\n\n }\n\n function realFixAll1(record) {\n fixLeader(record); // Fix defaults, esp. LDR/18=i\n\n fixCountryCodes().fix(record); // 008/15-17\n fixLanguageCodes().fix(record); // 008/35-37 AND 041 (note that all relevant subfield codes are fixed, not just $a)\n\n recordRemoveValuelessSubfields(record);\n\n // Field 028: use $b$a, not $a$b:\n const f028 = record.fields.filter(f => f.tag === '028');\n f028.forEach(f => sortAdjacentSubfields(f));\n\n add041().fix(record);\n\n }\n\n function realFixAll2(record) {\n fixQualifyingInformation().fix(record); // 015, 020, 024 and 028\n\n // Cyrillux specific code might change 040$b and thus affect these rules:\n fixRelatorTerms().fix(record);\n fix33X().fix(record); // 33X$a => 33X$a$b$2\n add336().fix(record);\n add337().fix(record);\n add338().fix(record);\n\n // The fixer below implements Cyrillux rules such as 245I1 | 245I1 | If (Exists(@100) Or Exists(@110) Or Exists(@111) Or Exists(@130)) Then '1' Else '0' and plenty of other good stuff:\n fixIndicators().fix(record);\n\n fixPunctuation().fix(record);\n }\n\n function realFix(record) {\n realFixAll1(record);\n\n realFixNonAleph(record);\n\n realFixAll2(record);\n\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n // Validation is currently done in subparts\n function validate(record) {\n nvdebug(`${description}: validate`, debugDev);\n const originalString = recordToString(record);\n const clonedRecord = new MarcRecord(record, {subfieldValues: false});\n realFix(clonedRecord);\n const modifiedString = recordToString(clonedRecord);\n\n if (originalString === modifiedString) {\n return {message: [], valid: true};\n }\n\n return {message: ['Record changed'], valid: false}; // Less than descriptive but will do...\n\n }\n}\n\nfunction fixField040(record) {\n const f040 = record.get('040');\n\n const subfieldsBE = [\n {code: 'b', value: 'mul'},\n {code: 'e', value: 'rda'}\n ];\n\n // Add 040 if there isn't one:\n if (f040.length === 0) {\n const data = {tag: '040', ind1: ' ', ind2: ' ', subfields: subfieldsBE};\n\n record.insertField(data);\n return;\n }\n\n f040.forEach(f => fixField040Subfields(f));\n\n function fixField040Subfields(field) {\n field.subfields = field.subfields.filter(sf => !['b', 'e'].includes(sf.code));\n field.subfields.push(subfieldsBE[0]);\n field.subfields.push(subfieldsBE[1]);\n sortAdjacentSubfields(field); // put $b and $e to their proper places\n }\n\n}\n\nexport function removeFromOldCatalog(field) {\n if (!field.tag.match(/^(?:240|65[0135]|[1678](?:00|10|11|30))$/u)) {\n return;\n }\n // See https://catalog.loc.gov/vwebv/ui/en_US/htdocs/help/faqs.html for motivation\n field.subfields?.forEach(sf => removeFromOldCatalogFromSubfield(sf));\n\n function removeFromOldCatalogFromSubfield(subfield) {\n if (!subfield.value.includes('[from old catalog]')) {\n return;\n }\n subfield.value = subfield.value.replace(/ *\\[from old catalog\\]/gui, '');\n }\n}\n\nfunction removeSubfieldH(field) {\n if (!field.subfields || !['245', '246', '247', '740', '760', '762', '765', '767', '770', '772', '773', '774', '775', '776', '777', '780', '785', '786', '787', '788'].includes(field.tag)) {\n return;\n }\n\n const filteredFields = field.subfields.filter(sf => sf.code !== 'h');\n if (filteredFields.length > 0) {\n field.subfields = filteredFields;\n return;\n }\n\n}\n\nexport function removeOwnershipSubfield5(field) {\n if (!field.subfields || field.subfields.length === 0) {\n return;\n }\n const remainingSubfields = field.subfields.filter(sf => sf.code !== '5');\n if (remainingSubfields.length === 0) { // sanity check/robustness\n return;\n }\n field.subfields = remainingSubfields;\n}\n\nexport function fixLeader(record) {\n record.leader = `${record.leader.substring(0, 9)}a22${record.leader.substring(12, 18)}i${record.leader.substring(19, 20)}4500`;\n}\n\nfunction field410To490And810(field, record) { // might be generic... if so, move to utils...\n if (field.tag !== '410') {\n return;\n }\n\n const field810 = clone(field);\n\n field.tag = '490';\n field.ind1 = '1';\n field.ind2 = ' ';\n sortAdjacentSubfields(field);\n // 490: Fix punctuation elsewhere. (Note that the current support is lagging...)\n\n\n field810.tag = '810';\n field810.ind2 = ' ';\n // 810: Fix punctuation elsewhere. (Note that the current support is lagging...)\n record.insertField(field810);\n}\n\nfunction field440To490And830(field, record) { // might be generic... if so, move to utils...\n if (field.tag !== '440') {\n return;\n }\n\n const field830 = clone(field);\n\n field.tag = '490';\n field.ind1 = '1';\n field.ind2 = ' ';\n // 490: Fix punctuation elsewhere. (Note that the current support is lagging...)\n field830.tag = '830';\n // 830: Fix punctuation elsewhere. (Note that the current support is lagging...)\n record.insertField(field830);\n}\n\nfunction isAlephRecord(record) {\n // Records that are already in Aleph are not processed as aggressively as genuinely new ones:\n return record.fields.some(field => ['CAT', 'LKR', 'LOW', 'SID'].includes(field.tag));\n}\n\nfunction field260To264s(field, record) { // might be generic... if so, move to utils...\n // As per my quick reading of usemarcon-cyrillux\n if (field.tag !== '260') {\n return;\n }\n\n createCopyright264Field(field);\n\n field.tag = '264';\n field.ind1 = ' ';\n field.ind2 = '1';\n\n // NB! Usemarcon does not handle 260$e$f$g => 264$a$b$c, so I'm not botherin with it either... (However, we could check our merge reducer code...)\n\n function getCopyrightYear(string) {\n if (string.match(/^(?:\\[?[Ccp]|[^0-9]*(?:cop|\u00A9|\u2117))[^0-9]*(?:1[789][0-9][0-9]|20[0-2][0-9])[^0-9]*$/u)) {\n return string.replace(/[^0-9]/ug, '');\n }\n return false;\n }\n\n field.subfields?.forEach(sf => field260To264Normalization(sf));\n\n function field260To264Normalization(subfield) {\n subfield.value = field260To264Normalization2(subfield);\n }\n\n function createCopyright264Value(field) {\n // Extract/split copyright year to a separate field:\n const [c] = field.subfields.filter(sf => sf.code === 'c');\n if (!c) {\n return undefined;\n }\n const copyrightYear = getCopyrightYear(c.value);\n if (!copyrightYear) {\n return undefined;\n }\n const copType = c.value.match(/(?:^\\[?p|\u2117)/u) ? '\u2117' : '\u00A9';\n const returnValue = c.value.includes('[') ? `[${copType}${copyrightYear}]` : `${copType}${copyrightYear}`;\n // Moidy the original value:\n c.value = `[${copyrightYear}]`;\n return returnValue;\n }\n\n function createCopyright264Field(field) {\n const c = createCopyright264Value(field);\n if (!c) {\n return undefined;\n }\n const data = {'tag': '264', 'ind1': ' ', 'ind2': '4', 'subfields': [{'code': 'c', 'value': c}]};\n record.insertField(data);\n }\n\n function field260To264Normalization2(subfield) {\n if (subfield.code === 'a') {\n return subfield.value.replace(/\\b[Ss]\\. ?l\\./u, 'Kustannuspaikka tuntematon');\n }\n if (subfield.code === 'b') {\n return subfield.value.replace(/\\b[Ss]\\. ?n\\./u, 'kustantaja tuntematon');\n }\n if (subfield.code === 'c') {\n const year = getCopyrightYear(subfield.value);\n if (year) {\n const c = subfield.value.match(/(?:^p|\u2117)/u) ? 'p' : 'c';\n if (subfield.value.includes('[')) {\n return `${c}[${year}]`;\n }\n return `${c}${year}`;\n }\n return subfield.value.replace(/\\b[Ss]\\. ?a\\./u, 'julkaisuaika tuntematon');\n }\n return subfield.value;\n }\n\n\n}\n\n/*\nfunction handle505(field) {\n if (field.tag !== '505') {\n return;\n }\n // Don't know how/why usemarcon-cyrillux is so sure about ind1...\n field.ind1 = '0';\n // usemarcon-cyrillux drops irrelevant subfields, so we do the same. However, we have included some control subfields in the kept side:\n const keptSubfields = field.subfields.filter(sf => ['a', 'g', 'r', 't', 'u', '6', '8', '9'].includes(sf.code));\n\n if (keptSubfields.some(sf => ['a', 'g', 'r', 't', 'u'].includes(sf.code))) {\n field.subfields = keptSubfields;\n return;\n }\n}\n*/\n\nfunction translateFieldToFinnish(field) {\n if (!['020', '300'].includes(field.tag)) {\n return;\n }\n field.subfields?.forEach(sf => translateSubfieldToFinnish(sf));\n\n function translateSubfieldToFinnish(subfield) {\n if (field.tag === '020' && ['a', 'q', 'z'].includes(subfield.code)) {\n subfield.value = finnishTranslationsAndMappings(expandFinnishAbbreviations(expandSwedishAbbreviations(expandEnglishAbbreviations(subfield.value))));\n return;\n }\n if (field.tag === '300') {\n subfield.value = finnishTranslationsAndMappings(expandFinnishAbbreviations(expandSwedishAbbreviations(expandEnglishAbbreviations(subfield.value))));\n return;\n }\n }\n}\n\nfunction expandEnglishAbbreviations(value) {\n return value.replace(/\\bbk\\.\\b/gui, 'book').\n replace(/chiefly col\\./ui, 'chiefly color').\n replace(/col\\. ill\\./ui, 'color illustrations').\n replace(/diagrs\\./ui, 'diagrams').\n replace(/\\bhbk\\.\\b/gui, 'hardcover').replace(/\\bhbk\\b/gui, 'hardcover'). // expand to MTS-compliant form\n replace(/\\b1 hr\\./gui, '1 hour').\n replace(/\\bhr\\./gui, 'hours').\n replace(/\\bill\\./gui, 'illustrated'). // or illustrations (or Swedish \"illustrerad\" or...)\n replace(/\\billus\\./gui, 'illustrated'). // or illustrations\n replace(/incl\\./gui, 'includes').\n replace(/fold\\.? maps/gui, 'folded maps').\n // replace(/\\bmin\\./gu, 'minutes').\n // replace(/\\bmin\\b/gu, 'minutes').\n replace(/\\bp\\.\\b/gui, 'pages').replace(/\\bp\\b/gu, 'pages').\n replace(/\\bpbk\\.\\b/gui, 'paperback').replace(/\\bpbk\\b/gui, 'paperback'). // expand to MTS-compliant form\n replace(/\\bpdf\\b/gui, 'PDF').\n replace(/\\bports\\./gui, 'portraits').\n replace('sd., col.', 'sound, color').\n replace(/ *\\((?:chiefly col\\.|chiefly color|some col[s.])\\)/gui, '').\n replace(/\\b1 hr\\./gui, '1 hour');\n}\n\nfunction expandFinnishAbbreviations(value) {\n return value.replace(/\\bcn\\. /gu, 'noin ').\n // replace(/\\bmin\\./gu, 'minuuttia').\n // replace(/\\bmin\\b/gu, 'minuuttia').\n replace(/\\bnid\\./gu, 'nidottu').replace(/\\bnid\\b/gui, 'nidottu').\n replace(/\\bsid\\./gu, 'sidottu').replace(/\\bsid\\b/gui, 'sidottu').\n replace(/\\bverkkojulk\\.\\b/gu, 'verkkojulkaisu').replace(/\\bverkkojulk\\b/gu, 'verkkojulkaisu').\n replace(/^\\(([^)]+)\\)$/u, '$1');\n // <- removal of brackets above could use a better location\n}\n\nfunction expandSwedishAbbreviations(value) {\n return value.replace(/\\bca\\. /gu, 'circa ').\n replace(/\\bhft\\./gui, 'h\u00E4ftad').replace(/\\bhft\\b/gui, 'h\u00E4ftad');\n // replace(/\\bmin\\./gu, 'minuter').\n // replace(/\\bmin\\b/gu, 'minuter');\n}\n\nfunction finnishTranslationsAndMappings(value) {\n return value.replace('analog', 'analoginen').\n replace('approximately', 'noin').\n replace('audio discs', '\u00E4\u00E4nilevy\u00E4').\n replace('black and white', 'mustavalkoinen').\n replace(/\\bbilaga\\b/gui, 'liite').\n replace(/\\bbilagor\\b/gui, 'liitett\u00E4').\n // https://github.com/NatLibFi/USEMARCON-BOOKWHERE-RDA/blob/master/bw_rda_kyril.rul#L365\n replace(/(\\b1\\]?) \u0441\\./gui, '$1 sivu').\n replace(/(\\d\\]?) \u0441\\./gui, '$1 sivua').\n replace(/(\\d) \u0441\u043C/gui, '$1 cm').\n\n replace(/\\bcharts\\b/gui, 'kaavioita').\n replace('chiefly color illustrations', 'p\u00E4\u00E4osin v\u00E4rikuvitettu').\n replace('chiefly', 'p\u00E4\u00E4osin').\n replace(/\\bcirca\\b/gui, 'noin').\n replace(/coil[- ]?bound/gui, 'kierreselk\u00E4').\n replace('color illustrations', 'v\u00E4rikuvitus').\n replace(/comb[- ]?bound/gui, 'kierreselk\u00E4').\n replace(/\\bdigital\\b/gui, 'digitaalinen').\n replace(/\\belectronic book\\b/gui, 'verkkoaineisto').\n replace('(flera nummersviter)', '(useita numerointijaksoja)').\n replace(/\\bfolded sheet\\b/gui, 'taitelehti').\n replace(/\\bf\u00E4rgillustratione[nr]\\b/gui, 'v\u00E4rikuvitus').\n replace(/\\bhard(?:back|cover)\\b/gui, 'kovakantinen').\n replace(/\\bhours\\b/gui, 'tuntia').\n replace(/\\bi flera nummersviter/gui, 'useina numerointijaksoina').\n replace('illustrated', 'kuvitettu').\n replace(/illustrations?\\b/gui, 'kuvitettu'). // Based on usemacron-bookwhere (NB! usemarcon-cyrillux had kuvitus/kuvitettu)\n replace(/\\binbunden\\b/gui, 'kovakantinen'). // swe\n replace(/\\binsert\\b/gui, 'liite').\n replace(/\\binserts\\b/gui, 'liitteit\u00E4').\n replace(/\\bin various pagings/gui, 'useina numerointijaksoina').\n replace('leaves of plates', 'kuvalehte\u00E4').\n replace(/\\bljudskiva\\b/gui, '\u00E4\u00E4nilevy').\n replace(/\\bljudskivor\\b/gui, '\u00E4\u00E4nilevy\u00E4').\n replace(/\\bmap\\b/gui, 'kartta').\n replace(/\\bmaps\\b/gui, 'karttoja'). // or karttaa?\n replace('minutes', 'minuuttia').\n replace('mjuka p\u00E4rmar', 'pehme\u00E4kantinen').\n replace('online resource', 'verkkoaineisto').\n replace('onlineresurs', 'verkkoaineisto').\n replace('onumrerade', 'numeroimatonta').\n replace('pages of plates', 'kuvalehte\u00E4').\n replace(/\\bpages\\b/gui, 'sivua').\n replace(/\\bpaperback\\b/gui, 'pehme\u00E4kantinen'). // MTS alt\n replace(/\\bSeiten\\b/gu, 'sivua').\n replace(/\\bsoftcover\\b/gui, 'pehme\u00E4kantinen'). // MTS pref\n replace('sound, color', '\u00E4\u00E4nellinen, v\u00E4rillinen').\n replace('sound cassettes', '\u00E4\u00E4nikasettia').replace('sound cassette', '\u00E4\u00E4nikasetti').\n replace('sound discs', '\u00E4\u00E4nilevy\u00E4').replace(/sound disc\\b/gui, '\u00E4\u00E4nilevy').\n replace(/(?:spiral[- ]?bound|spiralrygg)/gui, 'kierreselk\u00E4').\n replace('svartvit', 'mustavalkoinen').\n replace('unnumbered', 'numeroimatonta').\n replace('(various pagings)', '(useita numerointijaksoja)').\n replace(/\\bverkkojulkaisu\\b/gui, 'verkkoaineisto').\n replace('videodiscs', 'videolevy\u00E4').\n replace('videodisc', 'videolevy').\n replace(/\\b1 hour\\b/gui, '1 tunti');\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["field"]
|
|
7
7
|
}
|
package/dist/cyrillux.js
CHANGED
|
@@ -2,12 +2,15 @@ import clone from "clone";
|
|
|
2
2
|
import XRegExp from "xregexp";
|
|
3
3
|
import * as iso9 from "@natlibfi/iso9-1995";
|
|
4
4
|
import * as sfs4900 from "@natlibfi/sfs-4900";
|
|
5
|
-
import { fieldHasSubfield, fieldToString, fieldsToString,
|
|
5
|
+
import { fieldHasSubfield, fieldToString, fieldsToString, isContentSubfieldCode, nvdebug } from "./utils.js";
|
|
6
6
|
import { fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag } from "./subfield6Utils.js";
|
|
7
7
|
import { default as sortFields } from "./sortFields.js";
|
|
8
8
|
import { default as reindexSubfield6OccurenceNumbers } from "./reindexSubfield6OccurenceNumbers.js";
|
|
9
9
|
import { fieldStripPunctuation } from "./punctuation2.js";
|
|
10
10
|
import { getLanguageCode } from "./addMissingField041.js";
|
|
11
|
+
import createDebugLogger from "debug";
|
|
12
|
+
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/cyrillux");
|
|
13
|
+
const debugDev = debug.extend("dev");
|
|
11
14
|
const iso9Trans = "ISO9 <TRANS>";
|
|
12
15
|
const cyrillicTrans = "CYRILLIC <TRANS>";
|
|
13
16
|
const sfs4900Trans = "SFS4900 <TRANS>";
|
|
@@ -85,15 +88,18 @@ export default function(config = {}) {
|
|
|
85
88
|
return str.split("").some(isCyrillicCharacter);
|
|
86
89
|
}
|
|
87
90
|
function fieldContainsCyrillicCharacters(field) {
|
|
88
|
-
return field.subfields && field.subfields.some((sf) => subfieldRequiresTransliteration(sf));
|
|
91
|
+
return field.subfields && field.subfields.some((sf) => subfieldRequiresTransliteration(sf, field.tag));
|
|
89
92
|
}
|
|
90
|
-
function subfieldRequiresTransliteration(subfield) {
|
|
91
|
-
if (
|
|
93
|
+
function subfieldRequiresTransliteration(subfield, tag = void 0) {
|
|
94
|
+
if (!isContentSubfieldCode(subfield.code, tag)) {
|
|
92
95
|
return false;
|
|
93
96
|
}
|
|
94
97
|
return containsCyrillicCharacters(subfield.value);
|
|
95
98
|
}
|
|
96
99
|
function tagCanBeTransliterated(tag) {
|
|
100
|
+
if (config.tagPattern && !tag.match(config.tagPattern)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
97
103
|
return !["336", "337", "338", "880"].includes(tag);
|
|
98
104
|
}
|
|
99
105
|
function fieldCanBeTransliterated(field) {
|
|
@@ -111,22 +117,22 @@ export default function(config = {}) {
|
|
|
111
117
|
}
|
|
112
118
|
return fieldContainsCyrillicCharacters(field);
|
|
113
119
|
}
|
|
114
|
-
function mapSubfieldToIso9(subfield) {
|
|
115
|
-
if (!subfieldRequiresTransliteration(subfield)) {
|
|
120
|
+
function mapSubfieldToIso9(subfield, tag) {
|
|
121
|
+
if (!subfieldRequiresTransliteration(subfield, tag)) {
|
|
116
122
|
return { code: subfield.code, value: subfield.value };
|
|
117
123
|
}
|
|
118
124
|
const conversionResult = iso9.convertToLatin(subfield.value);
|
|
119
125
|
return { code: subfield.code, value: conversionResult.result };
|
|
120
126
|
}
|
|
121
|
-
function mapSubfieldToSfs4900(subfield, lang = "rus") {
|
|
127
|
+
function mapSubfieldToSfs4900(subfield, tag, lang = "rus") {
|
|
122
128
|
const inputLang = lang === "ukr" ? "ukr" : "rus";
|
|
123
|
-
if (!subfieldRequiresTransliteration(subfield)) {
|
|
129
|
+
if (!subfieldRequiresTransliteration(subfield, tag)) {
|
|
124
130
|
return { code: subfield.code, value: subfield.value };
|
|
125
131
|
}
|
|
126
132
|
const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);
|
|
127
|
-
|
|
133
|
+
nvdebug(`${JSON.stringify(conversionResult)}`, debugDev);
|
|
128
134
|
const result = conversionResult.result;
|
|
129
|
-
|
|
135
|
+
nvdebug(`${JSON.stringify(result)}`, debugDev);
|
|
130
136
|
return { code: subfield.code, value: result };
|
|
131
137
|
}
|
|
132
138
|
function mapField(field, occurrenceNumber, iso92 = true, lang = "rus") {
|
|
@@ -134,7 +140,7 @@ export default function(config = {}) {
|
|
|
134
140
|
const transliterationText = iso92 ? iso9Trans : sfs4900Trans;
|
|
135
141
|
const subfield9 = fieldHasSubfield(field, "9", transliterationText) ? [] : [{ code: "9", value: transliterationText }];
|
|
136
142
|
const transliterationFunc = iso92 ? mapSubfieldToIso9 : mapSubfieldToSfs4900;
|
|
137
|
-
const subfields = field.subfields.filter((sf) => sf.code !== "6").map((sf) => transliterationFunc(sf, lang));
|
|
143
|
+
const subfields = field.subfields.filter((sf) => sf.code !== "6").map((sf) => transliterationFunc(sf, field.tag, lang));
|
|
138
144
|
const newField = { tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, ...subfield9] };
|
|
139
145
|
if (!iso92 && config.preferSFS4900) {
|
|
140
146
|
return newField;
|
|
@@ -151,7 +157,7 @@ export default function(config = {}) {
|
|
|
151
157
|
return void 0;
|
|
152
158
|
}
|
|
153
159
|
if (!config.retainCyrillic && !config.preferSFS4900) {
|
|
154
|
-
const subfields = field.subfields.map((sf) => mapSubfieldToIso9(sf));
|
|
160
|
+
const subfields = field.subfields.map((sf) => mapSubfieldToIso9(sf, field.tag));
|
|
155
161
|
return { tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields };
|
|
156
162
|
}
|
|
157
163
|
return mapField(field, occurrenceNumber, true, "rus");
|
|
@@ -161,7 +167,7 @@ export default function(config = {}) {
|
|
|
161
167
|
return void 0;
|
|
162
168
|
}
|
|
163
169
|
if (!config.retainCyrillic && config.preferSFS4900) {
|
|
164
|
-
const subfields = field.subfields.map((sf) => mapSubfieldToSfs4900(sf, lang));
|
|
170
|
+
const subfields = field.subfields.map((sf) => mapSubfieldToSfs4900(sf, field.tag, lang));
|
|
165
171
|
return { tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields };
|
|
166
172
|
}
|
|
167
173
|
return mapField(field, occurrenceNumber, false, lang);
|
|
@@ -182,7 +188,7 @@ export default function(config = {}) {
|
|
|
182
188
|
if (!config.retainCyrillic) {
|
|
183
189
|
return void 0;
|
|
184
190
|
}
|
|
185
|
-
nvdebug(`Derive CYR 880 from ${fieldToString(field)}
|
|
191
|
+
nvdebug(`Derive CYR 880 from ${fieldToString(field)}`, debugDev);
|
|
186
192
|
const newSubfield6 = deriveSubfield6(field.tag, field.subfields, occurrenceNumber);
|
|
187
193
|
const newSubfield9 = fieldHasSubfield(field, "9", cyrillicTrans) ? [] : [{ code: "9", value: cyrillicTrans }];
|
|
188
194
|
const subfields = [
|
|
@@ -191,7 +197,7 @@ export default function(config = {}) {
|
|
|
191
197
|
...newSubfield9
|
|
192
198
|
];
|
|
193
199
|
const newField = { tag: "880", ind1: field.ind1, ind2: field.ind2, subfields };
|
|
194
|
-
nvdebug(` New CYR 880 ${fieldToString(newField)}
|
|
200
|
+
nvdebug(` New CYR 880 ${fieldToString(newField)}`, debugDev);
|
|
195
201
|
return newField;
|
|
196
202
|
}
|
|
197
203
|
function getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber = 0) {
|
|
@@ -228,8 +234,8 @@ export default function(config = {}) {
|
|
|
228
234
|
return false;
|
|
229
235
|
}
|
|
230
236
|
const [pairedField] = existingPairedFields;
|
|
231
|
-
nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}
|
|
232
|
-
nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}
|
|
237
|
+
nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`, debugDev);
|
|
238
|
+
nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`, debugDev);
|
|
233
239
|
if (!fieldContainsCyrillicCharacters(pairedField)) {
|
|
234
240
|
return false;
|
|
235
241
|
}
|
|
@@ -242,7 +248,7 @@ export default function(config = {}) {
|
|
|
242
248
|
const field1 = fieldToString(createFieldForSfs4900Comparison(field, field.tag));
|
|
243
249
|
nvdebug(`COMPARE CONTENTS:
|
|
244
250
|
'${field1}' vs
|
|
245
|
-
'${field2}': ${field1 === field2 ? "OK" : "FAIL"}
|
|
251
|
+
'${field2}': ${field1 === field2 ? "OK" : "FAIL"}`, debugDev);
|
|
246
252
|
return field1 === field2;
|
|
247
253
|
}
|
|
248
254
|
function createFieldForSfs4900Comparison(field, tag) {
|
package/dist/cyrillux.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cyrillux.js"],
|
|
4
|
-
"sourcesContent": ["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport XRegExp from 'xregexp';\nimport * as iso9 from '@natlibfi/iso9-1995';\nimport * as sfs4900 from '@natlibfi/sfs-4900';\nimport {fieldHasSubfield, fieldToString, fieldsToString, isControlSubfieldCode, nvdebug} from './utils.js';\nimport {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils.js';\nimport {default as sortFields} from './sortFields.js';\nimport {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers.js';\nimport {fieldStripPunctuation} from './punctuation2.js';\nimport {getLanguageCode} from './addMissingField041.js';\n\nconst iso9Trans = 'ISO9 <TRANS>';\nconst cyrillicTrans = 'CYRILLIC <TRANS>';\nconst sfs4900Trans = 'SFS4900 <TRANS>';\n\nexport default function (config = {}) {\n // console.log(`CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console\n\n return {\n description: 'Cyrillux functionality: convert original field to latinitsa (ISO-9) and add 880s for original cyrillic and latinitsa (SFS-4900)',\n validate, fix\n };\n\n function preprocessConfig() {\n config.retainCyrillic = typeof config.retainCyrillic === 'undefined' ? true : config.retainCyrillic;\n config.doISO9Transliteration = typeof config.doISO9Transliteration === 'undefined' ? true : config.doISO9Transliteration;\n config.doSFS4900Transliteration = typeof config.doSFS4900Transliteration === 'undefined' ? true : config.doSFS4900Transliteration;\n config.preferSFS4900 = setPreference();\n\n function setPreference() {\n if (!config.doSFS4900Transliteration) {\n return false;\n }\n if (!config.doISO9Transliteration && config.doSFS4900Transliteration) {\n return true;\n }\n if (typeof config.preferSFS4900 === 'undefined') {\n return false;\n }\n return config.preferSFS4900;\n }\n }\n\n function fix(record) {\n // console.log(`FIX has CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console\n // Fix always succeeds\n const res = {message: [], fix: [], valid: true};\n\n preprocessConfig();\n\n const nBefore = record.fields.length;\n\n record.fields = processFields(record.fields);\n\n if (nBefore < record.fields.length) {\n reindexSubfield6OccurenceNumbers().fix(record);\n sortFields().fix(record);\n }\n\n function processFields(input, output = []) {\n const [currField, ...remainingInput] = input;\n if (!currField) {\n return output;\n }\n\n const fakeRecord = {fields: output};\n const createdMax = recordGetMaxSubfield6OccurrenceNumberAsInteger(fakeRecord);\n const result = processField(currField, record, createdMax);\n\n return processFields(remainingInput, [...output, ...result]);\n }\n\n return res;\n }\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n preprocessConfig();\n\n record.fields?.forEach(field => {\n validateField(field, res, record);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res, record) {\n const orig = fieldToString(field);\n\n const normalizedFields = processField(clone(field), record);\n const mod = fieldsToString(normalizedFields).replace(/\\t__SEPARATOR__\\t/ug, ', ').replace(/ (\u20216 [0-9][0-9][0-9])-[0-9][0-9]+/gu, ' $1-NN');\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`CHANGE: ${orig} => ${mod}`);\n return;\n }\n return;\n }\n\n function isCyrillicCharacter(char) {\n return XRegExp('[\\\\p{Cyrillic}]').test(char);\n }\n\n function containsCyrillicCharacters(str) { // from melinda-ui-cyrillux\n if (!str) {\n return false;\n }\n return str.split('').some(isCyrillicCharacter);\n }\n\n function fieldContainsCyrillicCharacters(field) { // based on melinda-ui-cyrillux\n return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf));\n }\n\n function subfieldRequiresTransliteration(subfield) {\n if (isControlSubfieldCode(subfield.code)) {\n return false;\n }\n return containsCyrillicCharacters(subfield.value);\n }\n\n function tagCanBeTransliterated(tag) {\n return !['336', '337', '338', '880'].includes(tag);\n }\n\n function fieldCanBeTransliterated(field) {\n // Skip certain tags ('880' is the actual skip-me beef here, but we have seen other no-nos as well).\n // Discussion: We should probably also skip others like 05X-08X, 648, 650, 651, and 655, but this needs thinking...\n // Also I'd like to convert do CYRILLIC->ISO-9 in field 300 (and others?) without 880 mappings... (<- not implemented)\n\n // nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in...`);\n if (!tagCanBeTransliterated(field.tag)) {\n return false;\n }\n\n if (!config.doISO9Transliteration && !config.doSFS4900Transliteration) {\n return false;\n }\n\n // Skip control fields:\n if (!field.subfields) {\n return false;\n }\n // When doing MELINDA-10330-ish, we noticed that $6 should not prevent translittaration per se, so this restriction is no longer applied!\n\n if (field.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>'))) {\n return false;\n }\n\n return fieldContainsCyrillicCharacters(field); // We have something to translitterate:\n }\n\n\n function mapSubfieldToIso9(subfield) {\n if (!subfieldRequiresTransliteration(subfield)) {\n return {code: subfield.code, value: subfield.value}; // just clone\n }\n\n const conversionResult = iso9.convertToLatin(subfield.value);\n\n return {code: subfield.code, value: conversionResult.result};\n }\n\n function mapSubfieldToSfs4900(subfield, lang = 'rus') {\n const inputLang = lang === 'ukr' ? 'ukr' : 'rus'; // Support 'ukr' and 'rus', default to 'rus'\n if (!subfieldRequiresTransliteration(subfield)) {\n return {code: subfield.code, value: subfield.value};\n }\n const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);\n\n console.log(JSON.stringify(conversionResult));\n const result = conversionResult.result;\n console.log(JSON.stringify(result));\n //console.log(`VAL: ${subfield.value} => ${value} using ${lang}`); // eslint-disable-line no-console\n return {code: subfield.code, value: result};\n }\n\n function mapField(field, occurrenceNumber, iso9 = true, lang = 'rus') {\n const subfield6 = deriveSubfield6('880', field.subfields, occurrenceNumber);\n const transliterationText = iso9 ? iso9Trans : sfs4900Trans;\n\n const subfield9 = fieldHasSubfield(field, '9', transliterationText) ? [] : [{code: '9', value: transliterationText}]; // Add only if needed\n const transliterationFunc = iso9 ? mapSubfieldToIso9 : mapSubfieldToSfs4900;\n\n // NB! iso9 won't use lang\n const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, lang));\n\n const newField = {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, ...subfield9]};\n\n // Transliteration goes to the original field:\n if (!iso9 && config.preferSFS4900) {\n return newField;\n }\n if (iso9 && !config.preferSFS4900) {\n return newField;\n }\n // Translitetation goes to field 880:\n\n //const subfield6 = newField.subfields.find(sf => sf.code === '6');\n newField.tag = '880';\n resetSubfield6Tag(subfield6, field.tag);\n return newField;\n\n }\n\n function mapFieldToIso9(field, occurrenceNumber) {\n if (!config.doISO9Transliteration) {\n return undefined;\n }\n // Just converts the field to ISO-9 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either\n if (!config.retainCyrillic && !config.preferSFS4900) {\n const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf));\n return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};\n }\n\n return mapField(field, occurrenceNumber, true, 'rus');\n\n }\n\n function mapFieldToSfs4900(field, occurrenceNumber, lang = 'rus') {\n if (!config.doSFS4900Transliteration) {\n return undefined;\n }\n // Just converts the field to SFS-4900 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either\n if (!config.retainCyrillic && config.preferSFS4900) {\n const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, lang));\n return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};\n }\n\n return mapField(field, occurrenceNumber, false, lang);\n }\n\n function deriveSubfield6(tag, subfields, occurrenceNumber) {\n const initialSubfield = {code: '6', value: `${tag}-${occurrenceNumber}`};\n if (tag === '880') { // If *tag in subfield $6* is 880, field is not 880 :D\n return initialSubfield;\n }\n // Try to use existing subfield\n const [subfield6] = subfields.filter(sf => sf.code === '6').map(sf => clone(sf));\n if (subfield6) {\n resetSubfield6Tag(subfield6, tag); // Should we update occurrence number?\n return subfield6;\n }\n\n return initialSubfield;\n }\n\n function mapFieldToCyrillicField880(field, occurrenceNumber) {\n if (!config.retainCyrillic) {\n return undefined;\n }\n nvdebug(`Derive CYR 880 from ${fieldToString(field)}`);\n const newSubfield6 = deriveSubfield6(field.tag, field.subfields, occurrenceNumber);\n const newSubfield9 = fieldHasSubfield(field, '9', cyrillicTrans) ? [] : [{code: '9', value: cyrillicTrans}];\n const subfields = [\n newSubfield6,\n ...field.subfields.filter(sf => sf.code !== '6').map(sf => clone(sf)),\n ...newSubfield9\n ];\n\n const newField = {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};\n nvdebug(` New CYR 880 ${fieldToString(newField)}`);\n return newField;\n }\n\n\n function getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber = 0) {\n const occurrenceNumber = fieldGetMaxSubfield6OccurrenceNumberAsInteger(originalField);\n // Return existing occurrence number:\n if (occurrenceNumber > 0) {\n return occurrenceNumber;\n }\n if (maxCreatedOccurrenceNumber) {\n return maxCreatedOccurrenceNumber + 1;\n }\n return recordGetMaxSubfield6OccurrenceNumberAsInteger(record) + 1;\n }\n\n function retainCyrillic(existingPairedFields) {\n // Should we move cyrillic content from a normali field to a 880?\n if (!config.retainCyrillic) {\n return false;\n }\n // Fail if we already have a paired 880 $9 <CYRILLIC> TRANS\n return !existingPairedFields.some(f => fieldHasSubfield(f, '9', cyrillicTrans));\n }\n\n function needsSfs4900Transliteration(existingPairedFields) {\n if (!config.doSFS4900Transliteration) {\n return false;\n }\n return !existingPairedFields.some(f => fieldHasSubfield(f, '9', sfs4900Trans));\n }\n\n function sfs4900PairCanBeTransliterated(field, record) {\n // MELINDA-10330: we already have public library data: (unmarked) SFS-4900 in FIELD and (unmarked) Cyrillic in 880\n if (!field.subfields || !tagCanBeTransliterated(field.tag) || !config.doISO9Transliteration || !config.retainCyrillic || !config.doSFS4900Transliteration) {\n return false;\n }\n\n // Original field: $9 ISO9 <TRANS> is the only legal <TRANS>\n if (fieldContainsCyrillicCharacters(field) || field.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>') && sf.value !== iso9Trans)) {\n return false;\n }\n\n const existingPairedFields = fieldGetOccurrenceNumberPairs(field, record.get('880'));\n if (existingPairedFields.length !== 1) {\n return false;\n }\n\n // Paired field: $9 CYRILLIC <TRANS> is the only legal <TRANS>\n const [pairedField] = existingPairedFields;\n nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`);\n nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`);\n if (!fieldContainsCyrillicCharacters(pairedField)) {\n return false;\n }\n if (pairedField.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>') && sf.value !== cyrillicTrans)) {\n return false;\n }\n\n // Actually check that original field and and sfs-4900-fied cyrillic field are equal (after punctuation clean-up),\n // and thus it's a real case of MELINDA-10330 ISO9 adding:\n const occurrenceNumberAsString = fieldGetUnambiguousOccurrenceNumber(field);\n const languageCode = getLanguageCode(record);\n const field2 = fieldToString(createFieldForSfs4900Comparison(mapFieldToSfs4900(pairedField, occurrenceNumberAsString, languageCode), field.tag));\n const field1 = fieldToString(createFieldForSfs4900Comparison(field, field.tag));\n nvdebug(`COMPARE CONTENTS:\\n '${field1}' vs\\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}`);\n return field1 === field2;\n }\n\n function createFieldForSfs4900Comparison(field, tag) {\n const clonedField = clone(field);\n clonedField.tag = tag;\n clonedField.subfields = clonedField.subfields.filter(sf => sf.code !== '9' || sf.value !== sfs4900Trans);\n return fieldStripPunctuation(clonedField);\n }\n\n function transliterateSfs4900Pair(field, record) {\n // Handle MELINDA-10330: Field is already in SFS-4900 and the only paired field is in Cyrillic!\n if (!config.doISO9Transliteration) {\n return [];\n }\n const [pairedField] = fieldGetOccurrenceNumberPairs(field, record.get('880'));\n\n const occurrenceNumberAsString = fieldGetUnambiguousOccurrenceNumber(field);\n const languageCode = getLanguageCode(record);\n\n const tmpField = {'tag': field.tag, 'ind1': field.ind1, 'ind2': field.ind2, 'subfields': pairedField.subfields};\n\n const newMainField = config.doISO9Transliteration ? mapFieldToIso9(tmpField, occurrenceNumberAsString) : undefined; // Cyrillic => ISO-9\n const newCyrillicField = config.retainCyrillic ? mapFieldToCyrillicField880(tmpField, occurrenceNumberAsString) : undefined; // CYRILLIC\n const newSFS4900Field = config.doSFS4900Transliteration ? mapFieldToSfs4900(field, occurrenceNumberAsString, languageCode) : undefined; // SFS-4900\n\n // Trigger the drop of original counterpart $6 :\n pairedField.cyrilluxSkip = 1;\n\n return [newMainField, newCyrillicField, newSFS4900Field].filter(f => f);\n }\n\n\n function processField(originalField, record, maxCreatedOccurrenceNumber = 0) {\n if (!fieldCanBeTransliterated(originalField)) {\n if (sfs4900PairCanBeTransliterated(originalField, record)) { // MELINDA-10330\n return transliterateSfs4900Pair(originalField, record);\n }\n if (originalField.cyrilluxSkip) { // MELINDA-10330 hack to remove 880 fields that were replaced/sort-of processed with their counterpair.\n return [];\n }\n return [originalField];\n }\n\n // nvdebug(`PROCESSING: ${fieldToString(originalField)}`);\n\n const newOccurrenceNumberAsInt = getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber);\n const newOccurrenceNumberAsString = intToOccurrenceNumberString(newOccurrenceNumberAsInt);\n const languageCode = getLanguageCode(record);\n\n // nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'`);\n\n const existingPairedFields = fieldGetOccurrenceNumberPairs(originalField, record.get('880'));\n\n // nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}`);\n\n const newMainField = mapFieldToIso9(originalField, newOccurrenceNumberAsString); // ISO-9\n const newCyrillicField = retainCyrillic(existingPairedFields) ? mapFieldToCyrillicField880(originalField, newOccurrenceNumberAsString) : undefined; // CYRILLIC\n const newSFS4900Field = needsSfs4900Transliteration(existingPairedFields) ? mapFieldToSfs4900(originalField, newOccurrenceNumberAsString, languageCode) : undefined; /// SFS-4900\n\n return [newMainField, newCyrillicField, newSFS4900Field].filter(f => f);\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,OAAO,WAAW;AAClB,OAAO,aAAa;AACpB,YAAY,UAAU;AACtB,YAAY,aAAa;AACzB,SAAQ,kBAAkB,eAAe,gBAAgB,uBAAuB,eAAc;AAC9F,SAAQ,+CAA+C,+BAA+B,qCAAqC,6BAA6B,gDAAgD,yBAAwB;AAChO,SAAQ,WAAW,kBAAiB;AACpC,SAAQ,WAAW,wCAAuC;AAC1D,SAAQ,6BAA4B;AACpC,SAAQ,uBAAsB;AAE9B,MAAM,YAAY;AAClB,MAAM,gBAAgB;AACtB,MAAM,eAAe;
|
|
4
|
+
"sourcesContent": ["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport XRegExp from 'xregexp';\nimport * as iso9 from '@natlibfi/iso9-1995';\nimport * as sfs4900 from '@natlibfi/sfs-4900';\nimport {fieldHasSubfield, fieldToString, fieldsToString, isContentSubfieldCode, nvdebug} from './utils.js';\nimport {fieldGetMaxSubfield6OccurrenceNumberAsInteger, fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger, resetSubfield6Tag} from './subfield6Utils.js';\nimport {default as sortFields} from './sortFields.js';\nimport {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers.js';\nimport {fieldStripPunctuation} from './punctuation2.js';\nimport {getLanguageCode} from './addMissingField041.js';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/cyrillux');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst iso9Trans = 'ISO9 <TRANS>';\nconst cyrillicTrans = 'CYRILLIC <TRANS>';\nconst sfs4900Trans = 'SFS4900 <TRANS>';\n\n// eslint-disable-next-line max-lines-per-function\nexport default function (config = {}) {\n // console.log(`CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console\n\n return {\n description: 'Cyrillux functionality: convert original field to latinitsa (ISO-9) and add 880s for original cyrillic and latinitsa (SFS-4900)',\n validate, fix\n };\n\n function preprocessConfig() {\n config.retainCyrillic = typeof config.retainCyrillic === 'undefined' ? true : config.retainCyrillic;\n config.doISO9Transliteration = typeof config.doISO9Transliteration === 'undefined' ? true : config.doISO9Transliteration;\n config.doSFS4900Transliteration = typeof config.doSFS4900Transliteration === 'undefined' ? true : config.doSFS4900Transliteration;\n config.preferSFS4900 = setPreference();\n\n function setPreference() {\n if (!config.doSFS4900Transliteration) {\n return false;\n }\n if (!config.doISO9Transliteration && config.doSFS4900Transliteration) {\n return true;\n }\n if (typeof config.preferSFS4900 === 'undefined') {\n return false;\n }\n return config.preferSFS4900;\n }\n }\n\n function fix(record) {\n // console.log(`FIX has CONFIG=${JSON.stringify(config)}`); // eslint-disable-line no-console\n // Fix always succeeds\n const res = {message: [], fix: [], valid: true};\n\n preprocessConfig();\n\n const nBefore = record.fields.length;\n\n record.fields = processFields(record.fields);\n\n if (nBefore < record.fields.length) {\n reindexSubfield6OccurenceNumbers().fix(record);\n sortFields().fix(record);\n }\n\n function processFields(input, output = []) {\n const [currField, ...remainingInput] = input;\n if (!currField) {\n return output;\n }\n\n const fakeRecord = {fields: output};\n const createdMax = recordGetMaxSubfield6OccurrenceNumberAsInteger(fakeRecord);\n const result = processField(currField, record, createdMax);\n\n return processFields(remainingInput, [...output, ...result]);\n }\n\n return res;\n }\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n preprocessConfig();\n\n record.fields?.forEach(field => {\n validateField(field, res, record);\n });\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField(field, res, record) {\n const orig = fieldToString(field);\n\n const normalizedFields = processField(clone(field), record);\n const mod = fieldsToString(normalizedFields).replace(/\\t__SEPARATOR__\\t/ug, ', ').replace(/ (\u20216 [0-9][0-9][0-9])-[0-9][0-9]+/gu, ' $1-NN');\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`CHANGE: ${orig} => ${mod}`);\n return;\n }\n return;\n }\n\n function isCyrillicCharacter(char) {\n return XRegExp('[\\\\p{Cyrillic}]').test(char);\n }\n\n function containsCyrillicCharacters(str) { // from melinda-ui-cyrillux\n if (!str) {\n return false;\n }\n return str.split('').some(isCyrillicCharacter);\n }\n\n function fieldContainsCyrillicCharacters(field) { // based on melinda-ui-cyrillux\n return field.subfields && field.subfields.some(sf => subfieldRequiresTransliteration(sf, field.tag));\n }\n\n function subfieldRequiresTransliteration(subfield, tag = undefined) {\n if (!isContentSubfieldCode(subfield.code, tag)) {\n return false;\n }\n return containsCyrillicCharacters(subfield.value);\n }\n\n function tagCanBeTransliterated(tag) {\n // Use this to filter out \"(0..)\" etc\n if (config.tagPattern && !tag.match(config.tagPattern)) {\n return false;\n }\n // These are hard-coded, and will fail anyway:\n return !['336', '337', '338', '880'].includes(tag);\n }\n\n function fieldCanBeTransliterated(field) {\n // Skip certain tags ('880' is the actual skip-me beef here, but we have seen other no-nos as well).\n // Discussion: We should probably also skip others like 05X-08X, 648, 650, 651, and 655, but this needs thinking...\n // Also I'd like to convert do CYRILLIC->ISO-9 in field 300 (and others?) without 880 mappings... (<- not implemented)\n\n // nvdebug(`fieldCanBeTransliterated('${fieldToString(field)}') in...`, debugDev);\n if (!tagCanBeTransliterated(field.tag)) {\n return false;\n }\n\n if (!config.doISO9Transliteration && !config.doSFS4900Transliteration) {\n return false;\n }\n\n // Skip control fields:\n if (!field.subfields) {\n return false;\n }\n // When doing MELINDA-10330-ish, we noticed that $6 should not prevent translittaration per se, so this restriction is no longer applied!\n\n if (field.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>'))) {\n return false;\n }\n\n return fieldContainsCyrillicCharacters(field); // We have something to translitterate:\n }\n\n\n function mapSubfieldToIso9(subfield, tag) {\n if (!subfieldRequiresTransliteration(subfield, tag)) {\n return {code: subfield.code, value: subfield.value}; // just clone\n }\n\n const conversionResult = iso9.convertToLatin(subfield.value);\n\n return {code: subfield.code, value: conversionResult.result};\n }\n\n function mapSubfieldToSfs4900(subfield, tag, lang = 'rus') {\n const inputLang = lang === 'ukr' ? 'ukr' : 'rus'; // Support 'ukr' and 'rus', default to 'rus'\n if (!subfieldRequiresTransliteration(subfield, tag)) {\n return {code: subfield.code, value: subfield.value};\n }\n const conversionResult = sfs4900.convertToLatin(subfield.value, inputLang);\n\n nvdebug(`${JSON.stringify(conversionResult)}`, debugDev);\n const result = conversionResult.result;\n nvdebug(`${JSON.stringify(result)}`, debugDev);\n //nvdebug(`VAL: ${subfield.value} => ${value} using ${lang}`, debugDev);\n return {code: subfield.code, value: result};\n }\n\n function mapField(field, occurrenceNumber, iso9 = true, lang = 'rus') {\n const subfield6 = deriveSubfield6('880', field.subfields, occurrenceNumber);\n const transliterationText = iso9 ? iso9Trans : sfs4900Trans;\n\n const subfield9 = fieldHasSubfield(field, '9', transliterationText) ? [] : [{code: '9', value: transliterationText}]; // Add only if needed\n const transliterationFunc = iso9 ? mapSubfieldToIso9 : mapSubfieldToSfs4900;\n\n // NB! iso9 won't use lang\n const subfields = field.subfields.filter(sf => sf.code !== '6').map(sf => transliterationFunc(sf, field.tag, lang));\n\n const newField = {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, ...subfield9]};\n\n // Transliteration goes to the original field:\n if (!iso9 && config.preferSFS4900) {\n return newField;\n }\n if (iso9 && !config.preferSFS4900) {\n return newField;\n }\n // Translitetation goes to field 880:\n\n //const subfield6 = newField.subfields.find(sf => sf.code === '6');\n newField.tag = '880';\n resetSubfield6Tag(subfield6, field.tag);\n return newField;\n\n }\n\n function mapFieldToIso9(field, occurrenceNumber) {\n if (!config.doISO9Transliteration) {\n return undefined;\n }\n // Just converts the field to ISO-9 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either\n if (!config.retainCyrillic && !config.preferSFS4900) {\n const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf, field.tag));\n return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};\n }\n\n return mapField(field, occurrenceNumber, true, 'rus');\n\n }\n\n function mapFieldToSfs4900(field, occurrenceNumber, lang = 'rus') {\n if (!config.doSFS4900Transliteration) {\n return undefined;\n }\n // Just converts the field to SFS-4900 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either\n if (!config.retainCyrillic && config.preferSFS4900) {\n const subfields = field.subfields.map(sf => mapSubfieldToSfs4900(sf, field.tag, lang));\n return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};\n }\n\n return mapField(field, occurrenceNumber, false, lang);\n }\n\n function deriveSubfield6(tag, subfields, occurrenceNumber) {\n const initialSubfield = {code: '6', value: `${tag}-${occurrenceNumber}`};\n if (tag === '880') { // If *tag in subfield $6* is 880, field is not 880 :D\n return initialSubfield;\n }\n // Try to use existing subfield\n const [subfield6] = subfields.filter(sf => sf.code === '6').map(sf => clone(sf));\n if (subfield6) {\n resetSubfield6Tag(subfield6, tag); // Should we update occurrence number?\n return subfield6;\n }\n\n return initialSubfield;\n }\n\n function mapFieldToCyrillicField880(field, occurrenceNumber) {\n if (!config.retainCyrillic) {\n return undefined;\n }\n nvdebug(`Derive CYR 880 from ${fieldToString(field)}`, debugDev);\n const newSubfield6 = deriveSubfield6(field.tag, field.subfields, occurrenceNumber);\n const newSubfield9 = fieldHasSubfield(field, '9', cyrillicTrans) ? [] : [{code: '9', value: cyrillicTrans}];\n const subfields = [\n newSubfield6,\n ...field.subfields.filter(sf => sf.code !== '6').map(sf => clone(sf)),\n ...newSubfield9\n ];\n\n const newField = {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};\n nvdebug(` New CYR 880 ${fieldToString(newField)}`, debugDev);\n return newField;\n }\n\n\n function getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber = 0) {\n const occurrenceNumber = fieldGetMaxSubfield6OccurrenceNumberAsInteger(originalField);\n // Return existing occurrence number:\n if (occurrenceNumber > 0) {\n return occurrenceNumber;\n }\n if (maxCreatedOccurrenceNumber) {\n return maxCreatedOccurrenceNumber + 1;\n }\n return recordGetMaxSubfield6OccurrenceNumberAsInteger(record) + 1;\n }\n\n function retainCyrillic(existingPairedFields) {\n // Should we move cyrillic content from a normali field to a 880?\n if (!config.retainCyrillic) {\n return false;\n }\n // Fail if we already have a paired 880 $9 <CYRILLIC> TRANS\n return !existingPairedFields.some(f => fieldHasSubfield(f, '9', cyrillicTrans));\n }\n\n function needsSfs4900Transliteration(existingPairedFields) {\n if (!config.doSFS4900Transliteration) {\n return false;\n }\n return !existingPairedFields.some(f => fieldHasSubfield(f, '9', sfs4900Trans));\n }\n\n function sfs4900PairCanBeTransliterated(field, record) {\n // MELINDA-10330: we already have public library data: (unmarked) SFS-4900 in FIELD and (unmarked) Cyrillic in 880\n if (!field.subfields || !tagCanBeTransliterated(field.tag) || !config.doISO9Transliteration || !config.retainCyrillic || !config.doSFS4900Transliteration) {\n return false;\n }\n\n // Original field: $9 ISO9 <TRANS> is the only legal <TRANS>\n if (fieldContainsCyrillicCharacters(field) || field.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>') && sf.value !== iso9Trans)) {\n return false;\n }\n\n const existingPairedFields = fieldGetOccurrenceNumberPairs(field, record.get('880'));\n if (existingPairedFields.length !== 1) {\n return false;\n }\n\n // Paired field: $9 CYRILLIC <TRANS> is the only legal <TRANS>\n const [pairedField] = existingPairedFields;\n nvdebug(`LOOKING FOR SFS4900 PAIR: ${fieldToString(field)}`, debugDev);\n nvdebug(` HAVING PAIRED FIELD: ${fieldToString(pairedField)}`, debugDev);\n if (!fieldContainsCyrillicCharacters(pairedField)) {\n return false;\n }\n if (pairedField.subfields.some(sf => sf.code === '9' && sf.value.includes('<TRANS>') && sf.value !== cyrillicTrans)) {\n return false;\n }\n\n // Actually check that original field and and sfs-4900-fied cyrillic field are equal (after punctuation clean-up),\n // and thus it's a real case of MELINDA-10330 ISO9 adding:\n const occurrenceNumberAsString = fieldGetUnambiguousOccurrenceNumber(field);\n const languageCode = getLanguageCode(record);\n const field2 = fieldToString(createFieldForSfs4900Comparison(mapFieldToSfs4900(pairedField, occurrenceNumberAsString, languageCode), field.tag));\n const field1 = fieldToString(createFieldForSfs4900Comparison(field, field.tag));\n nvdebug(`COMPARE CONTENTS:\\n '${field1}' vs\\n '${field2}': ${field1 === field2 ? 'OK' : 'FAIL'}`, debugDev);\n return field1 === field2;\n }\n\n function createFieldForSfs4900Comparison(field, tag) {\n const clonedField = clone(field);\n clonedField.tag = tag;\n clonedField.subfields = clonedField.subfields.filter(sf => sf.code !== '9' || sf.value !== sfs4900Trans);\n return fieldStripPunctuation(clonedField);\n }\n\n function transliterateSfs4900Pair(field, record) {\n // Handle MELINDA-10330: Field is already in SFS-4900 and the only paired field is in Cyrillic!\n if (!config.doISO9Transliteration) {\n return [];\n }\n const [pairedField] = fieldGetOccurrenceNumberPairs(field, record.get('880'));\n\n const occurrenceNumberAsString = fieldGetUnambiguousOccurrenceNumber(field);\n const languageCode = getLanguageCode(record);\n\n const tmpField = {'tag': field.tag, 'ind1': field.ind1, 'ind2': field.ind2, 'subfields': pairedField.subfields};\n\n const newMainField = config.doISO9Transliteration ? mapFieldToIso9(tmpField, occurrenceNumberAsString) : undefined; // Cyrillic => ISO-9\n const newCyrillicField = config.retainCyrillic ? mapFieldToCyrillicField880(tmpField, occurrenceNumberAsString) : undefined; // CYRILLIC\n const newSFS4900Field = config.doSFS4900Transliteration ? mapFieldToSfs4900(field, occurrenceNumberAsString, languageCode) : undefined; // SFS-4900\n\n // Trigger the drop of original counterpart $6 :\n pairedField.cyrilluxSkip = 1;\n\n return [newMainField, newCyrillicField, newSFS4900Field].filter(f => f);\n }\n\n\n function processField(originalField, record, maxCreatedOccurrenceNumber = 0) {\n if (!fieldCanBeTransliterated(originalField)) {\n if (sfs4900PairCanBeTransliterated(originalField, record)) { // MELINDA-10330\n return transliterateSfs4900Pair(originalField, record);\n }\n if (originalField.cyrilluxSkip) { // MELINDA-10330 hack to remove 880 fields that were replaced/sort-of processed with their counterpair.\n return [];\n }\n return [originalField];\n }\n\n // nvdebug(`PROCESSING: ${fieldToString(originalField)}`, debugDev);\n\n const newOccurrenceNumberAsInt = getNewOccurrenceNumber(originalField, record, maxCreatedOccurrenceNumber);\n const newOccurrenceNumberAsString = intToOccurrenceNumberString(newOccurrenceNumberAsInt);\n const languageCode = getLanguageCode(record);\n\n // nvdebug(`NEW OCCURRENCE NUMBER: '${newOccurrenceNumberAsString}'`, debugDev);\n\n const existingPairedFields = fieldGetOccurrenceNumberPairs(originalField, record.get('880'));\n\n // nvdebug(`NUMBER OF PAIRED 880 FIELDS: ${existingPairedFields.length}`, debugDev);\n\n const newMainField = mapFieldToIso9(originalField, newOccurrenceNumberAsString); // ISO-9\n const newCyrillicField = retainCyrillic(existingPairedFields) ? mapFieldToCyrillicField880(originalField, newOccurrenceNumberAsString) : undefined; // CYRILLIC\n const newSFS4900Field = needsSfs4900Transliteration(existingPairedFields) ? mapFieldToSfs4900(originalField, newOccurrenceNumberAsString, languageCode) : undefined; /// SFS-4900\n\n return [newMainField, newCyrillicField, newSFS4900Field].filter(f => f);\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,OAAO,WAAW;AAClB,OAAO,aAAa;AACpB,YAAY,UAAU;AACtB,YAAY,aAAa;AACzB,SAAQ,kBAAkB,eAAe,gBAAgB,uBAAuB,eAAc;AAC9F,SAAQ,+CAA+C,+BAA+B,qCAAqC,6BAA6B,gDAAgD,yBAAwB;AAChO,SAAQ,WAAW,kBAAiB;AACpC,SAAQ,WAAW,wCAAuC;AAC1D,SAAQ,6BAA4B;AACpC,SAAQ,uBAAsB;AAC9B,OAAO,uBAAuB;AAE9B,MAAM,QAAQ,kBAAkB,mDAAmD;AAEnF,MAAM,WAAW,MAAM,OAAO,KAAK;AAEnC,MAAM,YAAY;AAClB,MAAM,gBAAgB;AACtB,MAAM,eAAe;AAGrB,wBAAyB,SAAS,CAAC,GAAG;AAGpC,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,mBAAmB;AAC1B,WAAO,iBAAiB,OAAO,OAAO,mBAAmB,cAAc,OAAO,OAAO;AACrF,WAAO,wBAAwB,OAAO,OAAO,0BAA0B,cAAc,OAAO,OAAO;AACnG,WAAO,2BAA2B,OAAO,OAAO,6BAA6B,cAAc,OAAO,OAAO;AACzG,WAAO,gBAAgB,cAAc;AAErC,aAAS,gBAAgB;AACvB,UAAI,CAAC,OAAO,0BAA0B;AACpC,eAAO;AAAA,MACT;AACA,UAAI,CAAC,OAAO,yBAAyB,OAAO,0BAA0B;AACpE,eAAO;AAAA,MACT;AACA,UAAI,OAAO,OAAO,kBAAkB,aAAa;AAC/C,eAAO;AAAA,MACT;AACA,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAEA,WAAS,IAAI,QAAQ;AAGnB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAE9C,qBAAiB;AAEjB,UAAM,UAAU,OAAO,OAAO;AAE9B,WAAO,SAAS,cAAc,OAAO,MAAM;AAE3C,QAAI,UAAU,OAAO,OAAO,QAAQ;AAClC,uCAAiC,EAAE,IAAI,MAAM;AAC7C,iBAAW,EAAE,IAAI,MAAM;AAAA,IACzB;AAEA,aAAS,cAAc,OAAO,SAAS,CAAC,GAAG;AACzC,YAAM,CAAC,WAAW,GAAG,cAAc,IAAI;AACvC,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,MACT;AAEA,YAAM,aAAa,EAAC,QAAQ,OAAM;AAClC,YAAM,aAAa,+CAA+C,UAAU;AAC5E,YAAM,SAAS,aAAa,WAAW,QAAQ,UAAU;AAEzD,aAAO,cAAc,gBAAgB,CAAC,GAAG,QAAQ,GAAG,MAAM,CAAC;AAAA,IAC7D;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,OAAO,KAAI;AAErC,qBAAiB;AAEjB,WAAO,QAAQ,QAAQ,WAAS;AAC9B,oBAAc,OAAO,KAAK,MAAM;AAAA,IAClC,CAAC;AAED,QAAI,QAAQ,EAAE,IAAI,QAAQ,UAAU;AACpC,WAAO;AAAA,EACT;AAEA,WAAS,cAAc,OAAO,KAAK,QAAQ;AACzC,UAAM,OAAO,cAAc,KAAK;AAEhC,UAAM,mBAAmB,aAAa,MAAM,KAAK,GAAG,MAAM;AAC1D,UAAM,MAAM,eAAe,gBAAgB,EAAE,QAAQ,uBAAuB,IAAI,EAAE,QAAQ,uCAAuC,QAAQ;AACzI,QAAI,SAAS,KAAK;AAChB,UAAI,QAAQ,KAAK,WAAW,IAAI,OAAO,GAAG,EAAE;AAC5C;AAAA,IACF;AACA;AAAA,EACF;AAEA,WAAS,oBAAoB,MAAM;AACjC,WAAO,QAAQ,iBAAiB,EAAE,KAAK,IAAI;AAAA,EAC7C;AAEA,WAAS,2BAA2B,KAAK;AACvC,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,IACT;AACA,WAAO,IAAI,MAAM,EAAE,EAAE,KAAK,mBAAmB;AAAA,EAC/C;AAEA,WAAS,gCAAgC,OAAO;AAC9C,WAAO,MAAM,aAAa,MAAM,UAAU,KAAK,QAAM,gCAAgC,IAAI,MAAM,GAAG,CAAC;AAAA,EACrG;AAEA,WAAS,gCAAgC,UAAU,MAAM,QAAW;AAClE,QAAI,CAAC,sBAAsB,SAAS,MAAM,GAAG,GAAG;AAC9C,aAAO;AAAA,IACT;AACA,WAAO,2BAA2B,SAAS,KAAK;AAAA,EAClD;AAEA,WAAS,uBAAuB,KAAK;AAEnC,QAAI,OAAO,cAAc,CAAC,IAAI,MAAM,OAAO,UAAU,GAAG;AACtD,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,GAAG;AAAA,EACnD;AAEA,WAAS,yBAAyB,OAAO;AAMvC,QAAI,CAAC,uBAAuB,MAAM,GAAG,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,yBAAyB,CAAC,OAAO,0BAA0B;AACrE,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,MAAM,WAAW;AACpB,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,UAAU,KAAK,QAAM,GAAG,SAAS,OAAO,GAAG,MAAM,SAAS,SAAS,CAAC,GAAG;AAC/E,aAAO;AAAA,IACT;AAEA,WAAO,gCAAgC,KAAK;AAAA,EAC9C;AAGA,WAAS,kBAAkB,UAAU,KAAK;AACxC,QAAI,CAAC,gCAAgC,UAAU,GAAG,GAAG;AACnD,aAAO,EAAC,MAAM,SAAS,MAAM,OAAO,SAAS,MAAK;AAAA,IACpD;AAEA,UAAM,mBAAmB,KAAK,eAAe,SAAS,KAAK;AAE3D,WAAO,EAAC,MAAM,SAAS,MAAM,OAAO,iBAAiB,OAAM;AAAA,EAC7D;AAEA,WAAS,qBAAqB,UAAU,KAAK,OAAO,OAAO;AACzD,UAAM,YAAY,SAAS,QAAQ,QAAQ;AAC3C,QAAI,CAAC,gCAAgC,UAAU,GAAG,GAAG;AACnD,aAAO,EAAC,MAAM,SAAS,MAAM,OAAO,SAAS,MAAK;AAAA,IACpD;AACA,UAAM,mBAAmB,QAAQ,eAAe,SAAS,OAAO,SAAS;AAEzE,YAAQ,GAAG,KAAK,UAAU,gBAAgB,CAAC,IAAI,QAAQ;AACvD,UAAM,SAAS,iBAAiB;AAChC,YAAQ,GAAG,KAAK,UAAU,MAAM,CAAC,IAAI,QAAQ;AAE7C,WAAO,EAAC,MAAM,SAAS,MAAM,OAAO,OAAM;AAAA,EAC5C;AAEA,WAAS,SAAS,OAAO,kBAAkBA,QAAO,MAAM,OAAO,OAAO;AACpE,UAAM,YAAY,gBAAgB,OAAO,MAAM,WAAW,gBAAgB;AAC1E,UAAM,sBAAsBA,QAAO,YAAY;AAE/C,UAAM,YAAY,iBAAiB,OAAO,KAAK,mBAAmB,IAAI,CAAC,IAAI,CAAC,EAAC,MAAM,KAAK,OAAO,oBAAmB,CAAC;AACnH,UAAM,sBAAsBA,QAAO,oBAAoB;AAGvD,UAAM,YAAY,MAAM,UAAU,OAAO,QAAM,GAAG,SAAS,GAAG,EAAE,IAAI,QAAM,oBAAoB,IAAI,MAAM,KAAK,IAAI,CAAC;AAElH,UAAM,WAAW,EAAC,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WAAW,CAAC,WAAW,GAAG,WAAW,GAAG,SAAS,EAAC;AAGxH,QAAI,CAACA,SAAQ,OAAO,eAAe;AACjC,aAAO;AAAA,IACT;AACA,QAAIA,SAAQ,CAAC,OAAO,eAAe;AACjC,aAAO;AAAA,IACT;AAIA,aAAS,MAAM;AACf,sBAAkB,WAAW,MAAM,GAAG;AACtC,WAAO;AAAA,EAET;AAEA,WAAS,eAAe,OAAO,kBAAkB;AAC/C,QAAI,CAAC,OAAO,uBAAuB;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,kBAAkB,CAAC,OAAO,eAAe;AACnD,YAAM,YAAY,MAAM,UAAU,IAAI,QAAM,kBAAkB,IAAI,MAAM,GAAG,CAAC;AAC5E,aAAO,EAAC,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,UAAS;AAAA,IACvE;AAEA,WAAO,SAAS,OAAO,kBAAkB,MAAM,KAAK;AAAA,EAEtD;AAEA,WAAS,kBAAkB,OAAO,kBAAkB,OAAO,OAAO;AAChE,QAAI,CAAC,OAAO,0BAA0B;AACpC,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,kBAAkB,OAAO,eAAe;AAClD,YAAM,YAAY,MAAM,UAAU,IAAI,QAAM,qBAAqB,IAAI,MAAM,KAAK,IAAI,CAAC;AACrF,aAAO,EAAC,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,UAAS;AAAA,IACvE;AAEA,WAAO,SAAS,OAAO,kBAAkB,OAAO,IAAI;AAAA,EACtD;AAEA,WAAS,gBAAgB,KAAK,WAAW,kBAAkB;AACzD,UAAM,kBAAkB,EAAC,MAAM,KAAK,OAAO,GAAG,GAAG,IAAI,gBAAgB,GAAE;AACvE,QAAI,QAAQ,OAAO;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,CAAC,SAAS,IAAI,UAAU,OAAO,QAAM,GAAG,SAAS,GAAG,EAAE,IAAI,QAAM,MAAM,EAAE,CAAC;AAC/E,QAAI,WAAW;AACb,wBAAkB,WAAW,GAAG;AAChC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,2BAA2B,OAAO,kBAAkB;AAC3D,QAAI,CAAC,OAAO,gBAAgB;AAC1B,aAAO;AAAA,IACT;AACA,YAAQ,uBAAuB,cAAc,KAAK,CAAC,IAAI,QAAQ;AAC/D,UAAM,eAAe,gBAAgB,MAAM,KAAK,MAAM,WAAW,gBAAgB;AACjF,UAAM,eAAe,iBAAiB,OAAO,KAAK,aAAa,IAAI,CAAC,IAAI,CAAC,EAAC,MAAM,KAAK,OAAO,cAAa,CAAC;AAC1G,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,GAAG,MAAM,UAAU,OAAO,QAAM,GAAG,SAAS,GAAG,EAAE,IAAI,QAAM,MAAM,EAAE,CAAC;AAAA,MACpE,GAAG;AAAA,IACL;AAEA,UAAM,WAAW,EAAC,KAAK,OAAO,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,UAAS;AAC3E,YAAQ,uBAAuB,cAAc,QAAQ,CAAC,IAAI,QAAQ;AAClE,WAAO;AAAA,EACT;AAGA,WAAS,uBAAuB,eAAe,QAAQ,6BAA6B,GAAG;AACrF,UAAM,mBAAmB,8CAA8C,aAAa;AAEpF,QAAI,mBAAmB,GAAG;AACxB,aAAO;AAAA,IACT;AACA,QAAI,4BAA4B;AAC9B,aAAO,6BAA6B;AAAA,IACtC;AACA,WAAO,+CAA+C,MAAM,IAAI;AAAA,EAClE;AAEA,WAAS,eAAe,sBAAsB;AAE5C,QAAI,CAAC,OAAO,gBAAgB;AAC1B,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,qBAAqB,KAAK,OAAK,iBAAiB,GAAG,KAAK,aAAa,CAAC;AAAA,EAChF;AAEA,WAAS,4BAA4B,sBAAsB;AACzD,QAAI,CAAC,OAAO,0BAA0B;AACpC,aAAO;AAAA,IACT;AACA,WAAO,CAAC,qBAAqB,KAAK,OAAK,iBAAiB,GAAG,KAAK,YAAY,CAAC;AAAA,EAC/E;AAEA,WAAS,+BAA+B,OAAO,QAAQ;AAErD,QAAI,CAAC,MAAM,aAAa,CAAC,uBAAuB,MAAM,GAAG,KAAK,CAAC,OAAO,yBAAyB,CAAC,OAAO,kBAAkB,CAAC,OAAO,0BAA0B;AACzJ,aAAO;AAAA,IACT;AAGA,QAAI,gCAAgC,KAAK,KAAK,MAAM,UAAU,KAAK,QAAM,GAAG,SAAS,OAAO,GAAG,MAAM,SAAS,SAAS,KAAK,GAAG,UAAU,SAAS,GAAG;AACnJ,aAAO;AAAA,IACT;AAEA,UAAM,uBAAuB,8BAA8B,OAAO,OAAO,IAAI,KAAK,CAAC;AACnF,QAAI,qBAAqB,WAAW,GAAG;AACrC,aAAO;AAAA,IACT;AAGA,UAAM,CAAC,WAAW,IAAI;AACtB,YAAQ,6BAA6B,cAAc,KAAK,CAAC,IAAI,QAAQ;AACrE,YAAQ,6BAA6B,cAAc,WAAW,CAAC,IAAI,QAAQ;AAC3E,QAAI,CAAC,gCAAgC,WAAW,GAAG;AACjD,aAAO;AAAA,IACT;AACA,QAAI,YAAY,UAAU,KAAK,QAAM,GAAG,SAAS,OAAO,GAAG,MAAM,SAAS,SAAS,KAAK,GAAG,UAAU,aAAa,GAAG;AACnH,aAAO;AAAA,IACT;AAIA,UAAM,2BAA2B,oCAAoC,KAAK;AAC1E,UAAM,eAAe,gBAAgB,MAAM;AAC3C,UAAM,SAAS,cAAc,gCAAgC,kBAAkB,aAAa,0BAA0B,YAAY,GAAG,MAAM,GAAG,CAAC;AAC/I,UAAM,SAAS,cAAc,gCAAgC,OAAO,MAAM,GAAG,CAAC;AAC9E,YAAQ;AAAA,KAAyB,MAAM;AAAA,KAAY,MAAM,MAAM,WAAW,SAAS,OAAO,MAAM,IAAI,QAAQ;AAC5G,WAAO,WAAW;AAAA,EACpB;AAEA,WAAS,gCAAgC,OAAO,KAAK;AACnD,UAAM,cAAc,MAAM,KAAK;AAC/B,gBAAY,MAAM;AAClB,gBAAY,YAAY,YAAY,UAAU,OAAO,QAAM,GAAG,SAAS,OAAO,GAAG,UAAU,YAAY;AACvG,WAAO,sBAAsB,WAAW;AAAA,EAC1C;AAEA,WAAS,yBAAyB,OAAO,QAAQ;AAE/C,QAAI,CAAC,OAAO,uBAAuB;AACjC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,CAAC,WAAW,IAAI,8BAA8B,OAAO,OAAO,IAAI,KAAK,CAAC;AAE5E,UAAM,2BAA2B,oCAAoC,KAAK;AAC1E,UAAM,eAAe,gBAAgB,MAAM;AAE3C,UAAM,WAAW,EAAC,OAAO,MAAM,KAAK,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,aAAa,YAAY,UAAS;AAE9G,UAAM,eAAe,OAAO,wBAAwB,eAAe,UAAU,wBAAwB,IAAI;AACzG,UAAM,mBAAmB,OAAO,iBAAiB,2BAA2B,UAAU,wBAAwB,IAAI;AAClH,UAAM,kBAAkB,OAAO,2BAA2B,kBAAkB,OAAO,0BAA0B,YAAY,IAAI;AAG7H,gBAAY,eAAe;AAE3B,WAAO,CAAC,cAAc,kBAAkB,eAAe,EAAE,OAAO,OAAK,CAAC;AAAA,EACxE;AAGA,WAAS,aAAa,eAAe,QAAQ,6BAA6B,GAAG;AAC3E,QAAI,CAAC,yBAAyB,aAAa,GAAG;AAC5C,UAAI,+BAA+B,eAAe,MAAM,GAAG;AACzD,eAAO,yBAAyB,eAAe,MAAM;AAAA,MACvD;AACA,UAAI,cAAc,cAAc;AAC9B,eAAO,CAAC;AAAA,MACV;AACA,aAAO,CAAC,aAAa;AAAA,IACvB;AAIA,UAAM,2BAA2B,uBAAuB,eAAe,QAAQ,0BAA0B;AACzG,UAAM,8BAA8B,4BAA4B,wBAAwB;AACxF,UAAM,eAAe,gBAAgB,MAAM;AAI3C,UAAM,uBAAuB,8BAA8B,eAAe,OAAO,IAAI,KAAK,CAAC;AAI3F,UAAM,eAAe,eAAe,eAAe,2BAA2B;AAC9E,UAAM,mBAAmB,eAAe,oBAAoB,IAAI,2BAA2B,eAAe,2BAA2B,IAAI;AACzI,UAAM,kBAAkB,4BAA4B,oBAAoB,IAAI,kBAAkB,eAAe,6BAA6B,YAAY,IAAI;AAE1J,WAAO,CAAC,cAAc,kBAAkB,eAAe,EAAE,OAAO,OAAK,CAAC;AAAA,EACxE;AACF;",
|
|
6
6
|
"names": ["iso9"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
if (tag.match(/^7[678]/u)) {
|
|
9
|
+
return "l";
|
|
10
|
+
}
|
|
11
|
+
if (tag.match(/^00/u)) {
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
return "7";
|
|
15
|
+
}
|
|
16
|
+
export function isDataProvenanceSubfieldCode(subfieldCode, tag) {
|
|
17
|
+
return subfieldCode === tagToDataProvenanceSubfieldCode(tag);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=dataProvenanceUtils.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/dataProvenanceUtils.js"],
|
|
4
|
+
"sourcesContent": ["export function tagToDataProvenanceSubfieldCode(tag) {\n if ( ['533', '800', '810', '811', '830'].includes(tag)) {\n return 'y';\n }\n if ( tag === '856' || tag === '857' ) {\n return 'e';\n }\n\n if ( tag.match(/^7[678]/u) ) {\n return 'l'\n }\n\n if ( tag.match(/^00/u)) {\n return undefined;\n }\n return '7';\n}\n\nexport function isDataProvenanceSubfieldCode(subfieldCode, tag) {\n return subfieldCode === tagToDataProvenanceSubfieldCode(tag);\n}"],
|
|
5
|
+
"mappings": "AAAO,gBAAS,gCAAgC,KAAK;AACjD,MAAK,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACpD,WAAO;AAAA,EACX;AACA,MAAK,QAAQ,SAAS,QAAQ,OAAQ;AAClC,WAAO;AAAA,EACX;AAEA,MAAK,IAAI,MAAM,UAAU,GAAI;AACzB,WAAO;AAAA,EACX;AAEA,MAAK,IAAI,MAAM,MAAM,GAAG;AACpB,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAEO,gBAAS,6BAA6B,cAAc,KAAK;AAC5D,SAAO,iBAAiB,gCAAgC,GAAG;AAC/D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,6 +6,7 @@ import clone from "clone";
|
|
|
6
6
|
import { default as createNatlibfiSruClient } from "@natlibfi/sru-client";
|
|
7
7
|
import { fieldFixPunctuation } from "./punctuation2.js";
|
|
8
8
|
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:disambiguateSeriesStatements");
|
|
9
|
+
const debugDev = debug.extend("dev");
|
|
9
10
|
const ELECTRONIC = 1;
|
|
10
11
|
const PRINTED = 2;
|
|
11
12
|
const NEITHER_OR_UNKNOWN = 0;
|
|
@@ -56,7 +57,7 @@ export default function() {
|
|
|
56
57
|
return fix490x(recordType, remainingFields, reallyFix, message);
|
|
57
58
|
}
|
|
58
59
|
const deletableStrings = deletableXs.map((sf) => subfieldToString(sf));
|
|
59
|
-
nvdebug(`Field has removable ISSNS: '${deletableStrings.join(", ")}`,
|
|
60
|
+
nvdebug(`Field has removable ISSNS: '${deletableStrings.join(", ")}`, debugDev);
|
|
60
61
|
if (reallyFix) {
|
|
61
62
|
currField.subfields = currField.subfields.filter((sf) => !deletableStrings.includes(subfieldToString(sf)));
|
|
62
63
|
fieldFixPunctuation(currField);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/disambiguateSeriesStatements.js"],
|
|
4
|
-
"sourcesContent": ["import createDebugLogger from 'debug';\nimport {fieldToString, nvdebug, subfieldToString} from './utils.js';\nimport {MARCXML} from '@natlibfi/marc-record-serializers';\nimport {Error} from '@natlibfi/melinda-commons';\nimport clone from 'clone';\nimport {default as createNatlibfiSruClient} from '@natlibfi/sru-client';\nimport {fieldFixPunctuation} from './punctuation2.js';\n\n//const {default: createNatlibfiSruClient} = natlibfiSruClient;\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:disambiguateSeriesStatements');\n\nconst ELECTRONIC = 1;\nconst PRINTED = 2;\nconst NEITHER_OR_UNKNOWN = 0;\nconst SRU_API_URL = 'https://sru.api.melinda.kansalliskirjasto.fi/bib';\n\n// Author(s): Nicholas Volk\nexport default function () {\n const sruClient = createSruClient(SRU_API_URL);\n\n return {\n description: 'Disambiguate between printed and electonic series statements (490 with multiple $xs)',\n validate, fix\n };\n\n async function fix(record) {\n const recordType = getRecordType(record);\n\n const relevantFields = getRelevantFields(record.fields);\n const message = await fix490x(recordType, relevantFields, true);\n\n return {message, fix: [], valid: true};\n }\n\n async function validate(record) {\n const recordType = getRecordType(record);\n\n const relevantFields = getRelevantFields(record.fields);\n const message = await fix490x(recordType, relevantFields, false);\n\n return {message, valid: message.length === 0};\n }\n\n\n function getValidIssnSubfields(field) {\n const subfields = field.subfields?.filter(sf => sf.code === 'x' && sf.value.match(/^[0-9]{4}-[0-9][0-9][0-9][0-9Xx][^0-9Xx]*$/u));\n return subfields;\n }\n\n function isRelevantField(field) {\n if (field.tag !== '490') {\n return false;\n }\n return getValidIssnSubfields(field).length > 1;\n }\n\n function getRelevantFields(fields) {\n return fields.filter(f => isRelevantField(f));\n }\n\n async function fix490x(recordType, fields, reallyFix, message = []) {\n\n if (recordType === NEITHER_OR_UNKNOWN) {\n return message;\n }\n const [currField, ...remainingFields] = fields;\n\n if (!currField) {\n return message;\n }\n\n const validXs = getValidIssnSubfields(currField);\n\n const deletableXs = await getRemovableSubfields(validXs, recordType);\n\n if (deletableXs.length === 0 || deletableXs.length === validXs.length) {\n return fix490x(recordType, remainingFields, reallyFix, message);\n }\n\n const deletableStrings = deletableXs.map(sf => subfieldToString(sf));\n nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`,
|
|
5
|
-
"mappings": "AAAA,OAAO,uBAAuB;AAC9B,SAAQ,eAAe,SAAS,wBAAuB;AACvD,SAAQ,eAAc;AACtB,SAAQ,aAAY;AACpB,OAAO,WAAW;AAClB,SAAQ,WAAW,+BAA8B;AACjD,SAAQ,2BAA0B;AAIlC,MAAM,QAAQ,kBAAkB,uEAAuE;AAEvG,MAAM,aAAa;AACnB,MAAM,UAAU;AAChB,MAAM,qBAAqB;AAC3B,MAAM,cAAc;
|
|
4
|
+
"sourcesContent": ["import createDebugLogger from 'debug';\nimport {fieldToString, nvdebug, subfieldToString} from './utils.js';\nimport {MARCXML} from '@natlibfi/marc-record-serializers';\nimport {Error} from '@natlibfi/melinda-commons';\nimport clone from 'clone';\nimport {default as createNatlibfiSruClient} from '@natlibfi/sru-client';\nimport {fieldFixPunctuation} from './punctuation2.js';\n\n//const {default: createNatlibfiSruClient} = natlibfiSruClient;\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:disambiguateSeriesStatements');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst ELECTRONIC = 1;\nconst PRINTED = 2;\nconst NEITHER_OR_UNKNOWN = 0;\nconst SRU_API_URL = 'https://sru.api.melinda.kansalliskirjasto.fi/bib';\n\n// Author(s): Nicholas Volk\n// eslint-disable-next-line max-lines-per-function\nexport default function () {\n const sruClient = createSruClient(SRU_API_URL);\n\n return {\n description: 'Disambiguate between printed and electonic series statements (490 with multiple $xs)',\n validate, fix\n };\n\n async function fix(record) {\n const recordType = getRecordType(record);\n\n const relevantFields = getRelevantFields(record.fields);\n const message = await fix490x(recordType, relevantFields, true);\n\n return {message, fix: [], valid: true};\n }\n\n async function validate(record) {\n const recordType = getRecordType(record);\n\n const relevantFields = getRelevantFields(record.fields);\n const message = await fix490x(recordType, relevantFields, false);\n\n return {message, valid: message.length === 0};\n }\n\n\n function getValidIssnSubfields(field) {\n const subfields = field.subfields?.filter(sf => sf.code === 'x' && sf.value.match(/^[0-9]{4}-[0-9][0-9][0-9][0-9Xx][^0-9Xx]*$/u));\n return subfields;\n }\n\n function isRelevantField(field) {\n if (field.tag !== '490') {\n return false;\n }\n return getValidIssnSubfields(field).length > 1;\n }\n\n function getRelevantFields(fields) {\n return fields.filter(f => isRelevantField(f));\n }\n\n async function fix490x(recordType, fields, reallyFix, message = []) {\n\n if (recordType === NEITHER_OR_UNKNOWN) {\n return message;\n }\n const [currField, ...remainingFields] = fields;\n\n if (!currField) {\n return message;\n }\n\n const validXs = getValidIssnSubfields(currField);\n\n const deletableXs = await getRemovableSubfields(validXs, recordType);\n\n if (deletableXs.length === 0 || deletableXs.length === validXs.length) {\n return fix490x(recordType, remainingFields, reallyFix, message);\n }\n\n const deletableStrings = deletableXs.map(sf => subfieldToString(sf));\n nvdebug(`Field has removable ISSNS: '${deletableStrings.join(', ')}`, debugDev);\n\n // fixer:\n if (reallyFix) {\n currField.subfields = currField.subfields.filter(sf => !deletableStrings.includes(subfieldToString(sf)));\n fieldFixPunctuation(currField);\n return fix490x(recordType, remainingFields, reallyFix, message);\n }\n // validators:\n const clonedField = clone(currField);\n const originalString = fieldToString(clonedField);\n clonedField.subfields = clonedField.subfields.filter(sf => !deletableStrings.includes(subfieldToString(sf)));\n\n const newMessage = `Replace '${originalString}' with '${fieldToString(clonedField)}'`;\n\n return fix490x(recordType, remainingFields, reallyFix, [...message, newMessage]);\n }\n\n async function getRemovableSubfields(validXs, recordType, removables = []) {\n const [currSubfield, ...remainingXs] = validXs;\n\n if (!currSubfield) {\n return removables;\n }\n\n const isRemoveable = await isRemovableSubfield(currSubfield, recordType);\n if (isRemoveable) {\n return getRemovableSubfields(remainingXs, recordType, [...removables, currSubfield]);\n }\n return getRemovableSubfields(remainingXs, recordType, removables);\n }\n\n async function isRemovableSubfield(subfield, recordType) {\n //console.info(` isRemovableField() in...`); // eslint-disable-line no-console\n const issn = subfield.value.substring(0, 9); // Strip punctuation (ISSN consists of nine letter, eg. \"1234-5678\")\n\n //console.info(` got ISSN ${issn}`); // eslint-disable-line no-console\n const issnRecords = await issnToRecords(issn);\n //console.info(` ISSN returned ${issnRecords.length} record(s)`); // eslint-disable-line no-console\n\n // !isMismatchingRecord !== isMatchingRecord as NEITHER_OR_UNKNOWN record type is neutral. Thus double negative \"not mismatch\". Sorry about that.\n if (issnRecords.some(r => !isMismatchingRecord(r))) {\n return false;\n }\n return true;\n\n function isMismatchingRecord(r) {\n const issnRecordType = getRecordType(r);\n if (issnRecordType === NEITHER_OR_UNKNOWN) {\n return false;\n }\n return issnRecordType !== recordType;\n }\n }\n\n async function issnToRecords(issn) {\n //console.log('issnToRecords() in...'); // eslint-disable-line no-console\n const records = await search(sruClient, `bath.issn=${issn}`);\n //console.log(`ISSN2RECORDS got ${records.length} record(s)!`); // eslint-disable-line no-console\n return records;\n }\n\n function getRecordType(record) {\n const f337 = record.get('337');\n if (f337.length !== 1) {\n return NEITHER_OR_UNKNOWN;\n }\n\n const b = f337[0].subfields.filter(sf => sf.code === 'b');\n if (b.length !== 1) {\n return NEITHER_OR_UNKNOWN;\n }\n\n if (b[0].value === 'c') {\n return ELECTRONIC;\n }\n\n if (b[0].value === 'n') {\n return PRINTED;\n }\n\n return NEITHER_OR_UNKNOWN;\n }\n\n}\n\n// All the code below is copypasted from melinda-ui-artikkelit project file src/services/sruServices/sruClient.js\n\nexport function createSruClient(sruApiUrl) {\n\n const sruClientOptions = {\n url: sruApiUrl,\n recordSchema: 'marcxml',\n retrieveAll: false,\n maxRecordsPerRequest: 100\n };\n\n return createNatlibfiSruClient(sruClientOptions);\n}\n\n\n/*******************************************************************************/\n/* Search and retrieve (copypaste from melinda-ui-artikkelit) */\n\nexport function search(sruClient, query, one = false) {\n\n return new Promise((resolve, reject) => {\n const promises = [];\n\n const noValidation = {\n fields: false,\n subfields: false,\n subfieldValues: false\n };\n\n // console.info(`SRU query: $${searchUrl}`);\n\n sruClient.searchRetrieve(query)\n .on('record', xmlString => {\n promises.push(MARCXML.from(xmlString, noValidation));\n })\n .on('end', async () => {\n try {\n\n if (promises.length > 0) {\n\n if (one) {\n const [firstPromise] = promises;\n const firstRecord = await firstPromise;\n return resolve(firstRecord);\n }\n\n const records = await Promise.all(promises);\n return resolve(records);\n }\n reject(new Error(404, 'No records found with search and retrieve'));\n\n } catch (error) {\n reject(error);\n }\n })\n .on('error', error => {\n reject(error);\n });\n });\n}\n\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,uBAAuB;AAC9B,SAAQ,eAAe,SAAS,wBAAuB;AACvD,SAAQ,eAAc;AACtB,SAAQ,aAAY;AACpB,OAAO,WAAW;AAClB,SAAQ,WAAW,+BAA8B;AACjD,SAAQ,2BAA0B;AAIlC,MAAM,QAAQ,kBAAkB,uEAAuE;AAEvG,MAAM,WAAW,MAAM,OAAO,KAAK;AAEnC,MAAM,aAAa;AACnB,MAAM,UAAU;AAChB,MAAM,qBAAqB;AAC3B,MAAM,cAAc;AAIpB,0BAA2B;AACzB,QAAM,YAAY,gBAAgB,WAAW;AAE7C,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,iBAAe,IAAI,QAAQ;AACzB,UAAM,aAAa,cAAc,MAAM;AAEvC,UAAM,iBAAiB,kBAAkB,OAAO,MAAM;AACtD,UAAM,UAAU,MAAM,QAAQ,YAAY,gBAAgB,IAAI;AAE9D,WAAO,EAAC,SAAS,KAAK,CAAC,GAAG,OAAO,KAAI;AAAA,EACvC;AAEA,iBAAe,SAAS,QAAQ;AAC9B,UAAM,aAAa,cAAc,MAAM;AAEvC,UAAM,iBAAiB,kBAAkB,OAAO,MAAM;AACtD,UAAM,UAAU,MAAM,QAAQ,YAAY,gBAAgB,KAAK;AAE/D,WAAO,EAAC,SAAS,OAAO,QAAQ,WAAW,EAAC;AAAA,EAC9C;AAGA,WAAS,sBAAsB,OAAO;AACpC,UAAM,YAAY,MAAM,WAAW,OAAO,QAAM,GAAG,SAAS,OAAO,GAAG,MAAM,MAAM,6CAA6C,CAAC;AAChI,WAAO;AAAA,EACT;AAEA,WAAS,gBAAgB,OAAO;AAC9B,QAAI,MAAM,QAAQ,OAAO;AACvB,aAAO;AAAA,IACT;AACA,WAAO,sBAAsB,KAAK,EAAE,SAAS;AAAA,EAC/C;AAEA,WAAS,kBAAkB,QAAQ;AACjC,WAAO,OAAO,OAAO,OAAK,gBAAgB,CAAC,CAAC;AAAA,EAC9C;AAEA,iBAAe,QAAQ,YAAY,QAAQ,WAAW,UAAU,CAAC,GAAG;AAElE,QAAI,eAAe,oBAAoB;AACrC,aAAO;AAAA,IACT;AACA,UAAM,CAAC,WAAW,GAAG,eAAe,IAAI;AAExC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,sBAAsB,SAAS;AAE/C,UAAM,cAAc,MAAM,sBAAsB,SAAS,UAAU;AAEnE,QAAI,YAAY,WAAW,KAAK,YAAY,WAAW,QAAQ,QAAQ;AACrE,aAAO,QAAQ,YAAY,iBAAiB,WAAW,OAAO;AAAA,IAChE;AAEA,UAAM,mBAAmB,YAAY,IAAI,QAAM,iBAAiB,EAAE,CAAC;AACnE,YAAQ,+BAA+B,iBAAiB,KAAK,IAAI,CAAC,IAAI,QAAQ;AAG9E,QAAI,WAAW;AACb,gBAAU,YAAY,UAAU,UAAU,OAAO,QAAM,CAAC,iBAAiB,SAAS,iBAAiB,EAAE,CAAC,CAAC;AACvG,0BAAoB,SAAS;AAC7B,aAAO,QAAQ,YAAY,iBAAiB,WAAW,OAAO;AAAA,IAChE;AAEA,UAAM,cAAc,MAAM,SAAS;AACnC,UAAM,iBAAiB,cAAc,WAAW;AAChD,gBAAY,YAAY,YAAY,UAAU,OAAO,QAAM,CAAC,iBAAiB,SAAS,iBAAiB,EAAE,CAAC,CAAC;AAE3G,UAAM,aAAa,YAAY,cAAc,WAAW,cAAc,WAAW,CAAC;AAElF,WAAO,QAAQ,YAAY,iBAAiB,WAAW,CAAC,GAAG,SAAS,UAAU,CAAC;AAAA,EACjF;AAEA,iBAAe,sBAAsB,SAAS,YAAY,aAAa,CAAC,GAAG;AACzE,UAAM,CAAC,cAAc,GAAG,WAAW,IAAI;AAEvC,QAAI,CAAC,cAAc;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,MAAM,oBAAoB,cAAc,UAAU;AACvE,QAAI,cAAc;AAChB,aAAO,sBAAsB,aAAa,YAAY,CAAC,GAAG,YAAY,YAAY,CAAC;AAAA,IACrF;AACA,WAAO,sBAAsB,aAAa,YAAY,UAAU;AAAA,EAClE;AAEA,iBAAe,oBAAoB,UAAU,YAAY;AAEvD,UAAM,OAAO,SAAS,MAAM,UAAU,GAAG,CAAC;AAG1C,UAAM,cAAc,MAAM,cAAc,IAAI;AAI5C,QAAI,YAAY,KAAK,OAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG;AAClD,aAAO;AAAA,IACT;AACA,WAAO;AAEP,aAAS,oBAAoB,GAAG;AAC9B,YAAM,iBAAiB,cAAc,CAAC;AACtC,UAAI,mBAAmB,oBAAoB;AACzC,eAAO;AAAA,MACT;AACA,aAAO,mBAAmB;AAAA,IAC5B;AAAA,EACF;AAEA,iBAAe,cAAc,MAAM;AAEjC,UAAM,UAAU,MAAM,OAAO,WAAW,aAAa,IAAI,EAAE;AAE3D,WAAO;AAAA,EACT;AAEA,WAAS,cAAc,QAAQ;AAC7B,UAAM,OAAO,OAAO,IAAI,KAAK;AAC7B,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,KAAK,CAAC,EAAE,UAAU,OAAO,QAAM,GAAG,SAAS,GAAG;AACxD,QAAI,EAAE,WAAW,GAAG;AAClB,aAAO;AAAA,IACT;AAEA,QAAI,EAAE,CAAC,EAAE,UAAU,KAAK;AACtB,aAAO;AAAA,IACT;AAEA,QAAI,EAAE,CAAC,EAAE,UAAU,KAAK;AACtB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEF;AAIO,gBAAS,gBAAgB,WAAW;AAEzC,QAAM,mBAAmB;AAAA,IACvB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,aAAa;AAAA,IACb,sBAAsB;AAAA,EACxB;AAEA,SAAO,wBAAwB,gBAAgB;AACjD;AAMO,gBAAS,OAAO,WAAW,OAAO,MAAM,OAAO;AAEpD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,WAAW,CAAC;AAElB,UAAM,eAAe;AAAA,MACnB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,gBAAgB;AAAA,IAClB;AAIA,cAAU,eAAe,KAAK,EAC3B,GAAG,UAAU,eAAa;AACzB,eAAS,KAAK,QAAQ,KAAK,WAAW,YAAY,CAAC;AAAA,IACrD,CAAC,EACA,GAAG,OAAO,YAAY;AACrB,UAAI;AAEF,YAAI,SAAS,SAAS,GAAG;AAEvB,cAAI,KAAK;AACP,kBAAM,CAAC,YAAY,IAAI;AACvB,kBAAM,cAAc,MAAM;AAC1B,mBAAO,QAAQ,WAAW;AAAA,UAC5B;AAEA,gBAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ;AAC1C,iBAAO,QAAQ,OAAO;AAAA,QACxB;AACA,eAAO,IAAI,MAAM,KAAK,2CAA2C,CAAC;AAAA,MAEpE,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC,EACA,GAAG,SAAS,WAAS;AACpB,aAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACL,CAAC;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,7 +3,6 @@ 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";
|
|
7
6
|
generateTests({
|
|
8
7
|
callback,
|
|
9
8
|
path: [import.meta.dirname, "..", "test-fixtures", "disambiguate-series-statements"],
|
|
@@ -18,18 +17,13 @@ generateTests({
|
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
19
|
});
|
|
21
|
-
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test");
|
|
22
20
|
async function testValidatorFactory() {
|
|
23
21
|
const validator = await validatorFactory();
|
|
24
22
|
assert.equal(typeof validator, "object");
|
|
25
23
|
assert.equal(typeof validator.description, "string");
|
|
26
24
|
assert.equal(typeof validator.validate, "function");
|
|
27
25
|
}
|
|
28
|
-
async function callback({ getFixture,
|
|
29
|
-
if (enabled === false) {
|
|
30
|
-
debug("TEST SKIPPED!");
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
26
|
+
async function callback({ getFixture, fix = false }) {
|
|
33
27
|
const validator = await validatorFactory();
|
|
34
28
|
const record = new MarcRecord(getFixture("record.json"));
|
|
35
29
|
const expectedResult = getFixture("expectedResult.json");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/disambiguateSeriesStatements.test.js"],
|
|
4
|
-
"sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './disambiguateSeriesStatements.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\
|
|
5
|
-
"mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;
|
|
4
|
+
"sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './disambiguateSeriesStatements.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n//import createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'disambiguate-series-statements'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: async () => {\n testValidatorFactory();\n }\n }\n});\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/disambiguateSeriesStatements:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, fix = false}) {\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAG1B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,gCAAgC;AAAA,EACnF,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,YAAY;AAClB,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF,CAAC;AAGD,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,MAAM,MAAK,GAAG;AACjD,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|