@natlibfi/marc-record-validators-melinda 12.1.0-alpha.1 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/melinda-node-tests-and-publish.yml +17 -17
- package/README.md +1 -1
- package/dist/addMissingField041.js +6 -3
- package/dist/addMissingField041.js.map +2 -2
- package/dist/addMissingField336.js +7 -4
- package/dist/addMissingField336.js.map +2 -2
- package/dist/addMissingField337.js +6 -3
- package/dist/addMissingField337.js.map +2 -2
- package/dist/addMissingField338.js +8 -5
- package/dist/addMissingField338.js.map +2 -2
- package/dist/cyrillux-usemarcon-replacement.js +5 -2
- package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
- package/dist/cyrillux.js +24 -18
- package/dist/cyrillux.js.map +2 -2
- package/dist/dataProvenanceUtils.js +19 -0
- package/dist/dataProvenanceUtils.js.map +7 -0
- package/dist/disambiguateSeriesStatements.js +2 -1
- package/dist/disambiguateSeriesStatements.js.map +2 -2
- package/dist/disambiguateSeriesStatements.test.js +1 -7
- package/dist/disambiguateSeriesStatements.test.js.map +2 -2
- package/dist/drop-terms.js +123 -0
- package/dist/drop-terms.js.map +7 -0
- package/dist/drop-terms.test.js +56 -0
- package/dist/drop-terms.test.js.map +7 -0
- package/dist/field-008-18-34-character-groups.test.js +1 -7
- package/dist/field-008-18-34-character-groups.test.js.map +2 -2
- package/dist/field-505-separators.test.js +1 -7
- package/dist/field-505-separators.test.js.map +2 -2
- package/dist/field-521-fix.test.js +1 -7
- package/dist/field-521-fix.test.js.map +2 -2
- package/dist/fix-33X.js +7 -4
- package/dist/fix-33X.js.map +2 -2
- package/dist/fix-33X.test.js +1 -1
- package/dist/fix-33X.test.js.map +1 -1
- package/dist/fix-country-codes.js +5 -0
- package/dist/fix-country-codes.js.map +2 -2
- package/dist/fix-country-codes.test.js +1 -7
- package/dist/fix-country-codes.test.js.map +2 -2
- package/dist/fix-language-codes.js +5 -1
- package/dist/fix-language-codes.js.map +2 -2
- package/dist/fix-sami-041.js +109 -0
- package/dist/fix-sami-041.js.map +7 -0
- package/dist/fix-sami-041.test.js +40 -0
- package/dist/fix-sami-041.test.js.map +7 -0
- package/dist/fixRelatorTerms.js +2 -0
- package/dist/fixRelatorTerms.js.map +2 -2
- package/dist/fixRelatorTerms.test.js +1 -7
- package/dist/fixRelatorTerms.test.js.map +2 -2
- package/dist/index.js +18 -4
- package/dist/index.js.map +2 -2
- package/dist/indicator-fixes.js +15 -1
- package/dist/indicator-fixes.js.map +2 -2
- package/dist/indicator-fixes.test.js +1 -7
- package/dist/indicator-fixes.test.js.map +2 -2
- package/dist/item-language.js +41 -39
- package/dist/item-language.js.map +2 -2
- package/dist/item-language.test.js +3 -3
- package/dist/item-language.test.js.map +2 -2
- package/dist/melindaCustomMergeFields.js +31 -0
- package/dist/melindaCustomMergeFields.js.map +2 -2
- package/dist/merge-fields/controlSubfields.js.map +2 -2
- package/dist/merge-fields/counterpartField.js +149 -152
- package/dist/merge-fields/counterpartField.js.map +3 -3
- package/dist/merge-fields/dataProvenance.js +6 -20
- package/dist/merge-fields/dataProvenance.js.map +2 -2
- package/dist/merge-fields/index.js +1 -1
- package/dist/merge-fields/index.js.map +2 -2
- package/dist/merge-fields/mergableIndicator.js +1 -5
- package/dist/merge-fields/mergableIndicator.js.map +2 -2
- package/dist/merge-fields/mergableTag.js +2 -0
- package/dist/merge-fields/mergableTag.js.map +2 -2
- package/dist/merge-fields/mergeConfig.js +2 -0
- package/dist/merge-fields/mergeConfig.js.map +2 -2
- package/dist/merge-fields/mergeConstraints.js +38 -35
- package/dist/merge-fields/mergeConstraints.js.map +3 -3
- package/dist/merge-fields/mergeField.js +4 -3
- package/dist/merge-fields/mergeField.js.map +2 -2
- package/dist/merge-fields/mergeOrAddSubfield.js +8 -7
- package/dist/merge-fields/mergeOrAddSubfield.js.map +2 -2
- package/dist/merge-fields/mergeSubfield.js +5 -1
- package/dist/merge-fields/mergeSubfield.js.map +2 -2
- package/dist/merge-fields/worldKnowledge.js +52 -0
- package/dist/merge-fields/worldKnowledge.js.map +2 -2
- package/dist/merge-fields.test.js +4 -9
- package/dist/merge-fields.test.js.map +2 -2
- package/dist/mergeField500Lisapainokset.test.js +1 -7
- package/dist/mergeField500Lisapainokset.test.js.map +2 -2
- package/dist/mergeRelatorTermFields.js +9 -6
- package/dist/mergeRelatorTermFields.js.map +2 -2
- package/dist/mergeRelatorTermFields.test.js +1 -7
- package/dist/mergeRelatorTermFields.test.js.map +2 -2
- package/dist/multiple-subfield-0.test.js +1 -7
- package/dist/multiple-subfield-0.test.js.map +2 -2
- package/dist/normalize-dashes.js +9 -6
- package/dist/normalize-dashes.js.map +2 -2
- package/dist/normalize-dashes.test.js +1 -7
- package/dist/normalize-dashes.test.js.map +2 -2
- package/dist/normalize-identifiers.js.map +2 -2
- package/dist/normalize-identifiers.test.js +1 -7
- package/dist/normalize-identifiers.test.js.map +2 -2
- package/dist/normalize-qualifying-information.test.js +1 -7
- package/dist/normalize-qualifying-information.test.js.map +2 -2
- package/dist/normalize-utf8-diacritics.js.map +2 -2
- package/dist/normalize-utf8-diacritics.test.js +1 -7
- package/dist/normalize-utf8-diacritics.test.js.map +2 -2
- package/dist/normalizeFieldForComparison.js +24 -14
- package/dist/normalizeFieldForComparison.js.map +2 -2
- package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
- package/dist/prepublicationUtils.js +1 -1
- package/dist/prepublicationUtils.js.map +2 -2
- package/dist/punctuation.test.js +1 -7
- package/dist/punctuation.test.js.map +2 -2
- package/dist/punctuation2.js +15 -12
- package/dist/punctuation2.js.map +2 -2
- package/dist/punctuation2.test.js +1 -7
- package/dist/punctuation2.test.js.map +2 -2
- package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
- package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
- package/dist/reindexSubfield6OccurenceNumbers.test.js +1 -7
- package/dist/reindexSubfield6OccurenceNumbers.test.js.map +2 -2
- package/dist/remove-041-zxx.js +56 -0
- package/dist/remove-041-zxx.js.map +7 -0
- package/dist/remove-041-zxx.test.js +40 -0
- package/dist/remove-041-zxx.test.js.map +7 -0
- package/dist/removeDuplicateDataFields.js +4 -26
- package/dist/removeDuplicateDataFields.js.map +2 -2
- package/dist/removeDuplicateDataFields.test.js +1 -7
- package/dist/removeDuplicateDataFields.test.js.map +2 -2
- package/dist/removeInferiorDataFields.js +82 -45
- package/dist/removeInferiorDataFields.js.map +3 -3
- package/dist/removeInferiorDataFields.test.js +5 -9
- package/dist/removeInferiorDataFields.test.js.map +2 -2
- package/dist/resolveOrphanedSubfield6s.js +4 -5
- package/dist/resolveOrphanedSubfield6s.js.map +2 -2
- package/dist/resolveOrphanedSubfield6s.test.js +1 -7
- package/dist/resolveOrphanedSubfield6s.test.js.map +2 -2
- package/dist/sanitize-vocabulary-source-codes.test.js +1 -7
- package/dist/sanitize-vocabulary-source-codes.test.js.map +2 -2
- package/dist/sortFields.js +16 -1
- package/dist/sortFields.js.map +2 -2
- package/dist/sortFields.test.js +1 -7
- package/dist/sortFields.test.js.map +2 -2
- package/dist/sortRelatorTerms.test.js +1 -7
- package/dist/sortRelatorTerms.test.js.map +2 -2
- package/dist/sortSubfields.js +27 -21
- package/dist/sortSubfields.js.map +2 -2
- package/dist/sortSubfields.test.js +1 -7
- package/dist/sortSubfields.test.js.map +2 -2
- package/dist/stripPunctuation.js +7 -3
- package/dist/stripPunctuation.js.map +2 -2
- package/dist/stripPunctuation.test.js +1 -7
- package/dist/stripPunctuation.test.js.map +2 -2
- package/dist/subfield6Utils.js +2 -12
- package/dist/subfield6Utils.js.map +2 -2
- package/dist/subfield8Utils.js +0 -5
- package/dist/subfield8Utils.js.map +2 -2
- package/dist/subfieldValueNormalizations.test.js +1 -7
- package/dist/subfieldValueNormalizations.test.js.map +2 -2
- package/dist/sync-007-and-300.test.js +1 -7
- package/dist/sync-007-and-300.test.js.map +2 -2
- package/dist/sync-language.js +103 -0
- package/dist/sync-language.js.map +7 -0
- package/dist/sync-language.test.js +40 -0
- package/dist/sync-language.test.js.map +7 -0
- package/dist/translate-terms.js +124 -87
- package/dist/translate-terms.js.map +3 -3
- package/dist/translate-terms.test.js +5 -8
- package/dist/translate-terms.test.js.map +2 -2
- package/dist/typeOfDate-008.js +3 -1
- package/dist/typeOfDate-008.js.map +2 -2
- package/dist/update-field-540.js.map +2 -2
- package/dist/update-field-540.test.js +1 -7
- package/dist/update-field-540.test.js.map +2 -2
- package/dist/urn.js +13 -12
- package/dist/urn.js.map +2 -2
- package/dist/urn.test.js +1 -7
- package/dist/urn.test.js.map +2 -2
- package/dist/utils.js +29 -3
- package/dist/utils.js.map +2 -2
- package/package.json +20 -27
- package/src/addMissingField041.js +8 -4
- package/src/addMissingField336.js +10 -5
- package/src/addMissingField337.js +9 -5
- package/src/addMissingField338.js +11 -6
- package/src/cyrillux-usemarcon-replacement.js +9 -5
- package/src/cyrillux.js +34 -23
- package/src/dataProvenanceUtils.js +21 -0
- package/src/disambiguateSeriesStatements.js +4 -1
- package/src/disambiguateSeriesStatements.test.js +3 -8
- package/src/drop-terms.js +164 -0
- package/src/drop-terms.test.js +81 -0
- package/src/field-008-18-34-character-groups.test.js +3 -8
- package/src/field-505-separators.test.js +3 -8
- package/src/field-521-fix.test.js +3 -8
- package/src/fix-33X.js +10 -6
- package/src/fix-33X.test.js +1 -1
- package/src/fix-country-codes.js +7 -3
- package/src/fix-country-codes.test.js +3 -8
- package/src/fix-language-codes.js +8 -4
- package/src/fix-sami-041.js +147 -0
- package/src/fix-sami-041.test.js +52 -0
- package/src/fixRelatorTerms.js +5 -0
- package/src/fixRelatorTerms.test.js +3 -8
- package/src/index.js +20 -7
- package/src/indicator-fixes.js +22 -7
- package/src/indicator-fixes.test.js +3 -8
- package/src/item-language.js +49 -42
- package/src/item-language.test.js +3 -3
- package/src/melindaCustomMergeFields.js +31 -0
- package/src/merge-fields/controlSubfields.js +0 -1
- package/src/merge-fields/counterpartField.js +191 -290
- package/src/merge-fields/dataProvenance.js +8 -25
- package/src/merge-fields/index.js +1 -1
- package/src/merge-fields/mergableIndicator.js +4 -5
- package/src/merge-fields/mergableTag.js +2 -0
- package/src/merge-fields/mergeConfig.js +2 -1
- package/src/merge-fields/mergeConstraints.js +41 -36
- package/src/merge-fields/mergeField.js +4 -7
- package/src/merge-fields/mergeOrAddSubfield.js +8 -7
- package/src/merge-fields/mergeSubfield.js +11 -2
- package/src/merge-fields/worldKnowledge.js +77 -3
- package/src/merge-fields.test.js +5 -10
- package/src/mergeField500Lisapainokset.test.js +3 -8
- package/src/mergeRelatorTermFields.js +12 -11
- package/src/mergeRelatorTermFields.test.js +3 -8
- package/src/multiple-subfield-0.test.js +3 -8
- package/src/normalize-dashes.js +13 -7
- package/src/normalize-dashes.test.js +3 -8
- package/src/normalize-identifiers.js +12 -19
- package/src/normalize-identifiers.test.js +3 -8
- package/src/normalize-qualifying-information.test.js +3 -8
- package/src/normalize-utf8-diacritics.js +6 -3
- package/src/normalize-utf8-diacritics.test.js +3 -8
- package/src/normalizeFieldForComparison.js +39 -22
- package/src/normalizeSubfieldValueForComparison.js +2 -2
- package/src/prepublicationUtils.js +1 -1
- package/src/punctuation.test.js +3 -8
- package/src/punctuation2.js +44 -40
- package/src/punctuation2.test.js +3 -8
- package/src/reindexSubfield6OccurenceNumbers.js +13 -11
- package/src/reindexSubfield6OccurenceNumbers.test.js +3 -8
- package/src/remove-041-zxx.js +85 -0
- package/src/remove-041-zxx.test.js +52 -0
- package/src/removeDuplicateDataFields.js +30 -28
- package/src/removeDuplicateDataFields.test.js +3 -8
- package/src/removeInferiorDataFields.js +126 -71
- package/src/removeInferiorDataFields.test.js +7 -10
- package/src/resolveOrphanedSubfield6s.js +7 -5
- package/src/resolveOrphanedSubfield6s.test.js +3 -8
- package/src/sanitize-vocabulary-source-codes.test.js +3 -8
- package/src/sortFields.js +20 -1
- package/src/sortFields.test.js +3 -8
- package/src/sortRelatorTerms.test.js +3 -8
- package/src/sortSubfields.js +31 -25
- package/src/sortSubfields.test.js +3 -8
- package/src/stripPunctuation.js +10 -5
- package/src/stripPunctuation.test.js +3 -8
- package/src/subfield6Utils.js +31 -33
- package/src/subfield8Utils.js +10 -7
- package/src/subfieldValueNormalizations.test.js +3 -8
- package/src/sync-007-and-300.test.js +3 -8
- package/src/sync-language.js +148 -0
- package/src/sync-language.test.js +52 -0
- package/src/translate-terms.js +168 -109
- package/src/translate-terms.test.js +12 -16
- package/src/typeOfDate-008.js +4 -1
- package/src/update-field-540.js +7 -5
- package/src/update-field-540.test.js +3 -8
- package/src/urn.js +17 -13
- package/src/urn.test.js +3 -8
- package/src/utils.js +39 -12
- package/test-fixtures/cyrillux/f02b/expectedResult.json +23 -0
- package/test-fixtures/cyrillux/f02b/metadata.json +11 -0
- package/test-fixtures/cyrillux/f02b/record.json +14 -0
- package/test-fixtures/cyrillux/f14/expectedResult.json +32 -0
- package/test-fixtures/cyrillux/f14/metadata.json +10 -0
- package/test-fixtures/cyrillux/f14/record.json +14 -0
- package/test-fixtures/drop-terms/01/expectedResult.json +31 -0
- package/test-fixtures/drop-terms/01/metadata.json +6 -0
- package/test-fixtures/drop-terms/01/record.json +35 -0
- package/test-fixtures/drop-terms/02/expectedResult.json +7 -0
- package/test-fixtures/drop-terms/02/metadata.json +6 -0
- package/test-fixtures/drop-terms/02/record.json +40 -0
- package/test-fixtures/drop-terms/03/expectedResult.json +6 -0
- package/test-fixtures/drop-terms/03/metadata.json +18 -0
- package/test-fixtures/drop-terms/03/record.json +39 -0
- package/test-fixtures/drop-terms/04/expectedResult.json +6 -0
- package/test-fixtures/drop-terms/04/metadata.json +19 -0
- package/test-fixtures/drop-terms/04/record.json +24 -0
- package/test-fixtures/fix-language-codes/02/metadata.json +1 -1
- package/test-fixtures/fix-relator-terms/f02/metadata.json +1 -1
- package/test-fixtures/fix-relator-terms/f04/expectedResult.json +18 -0
- package/test-fixtures/fix-relator-terms/f04/metadata.json +5 -0
- package/test-fixtures/fix-relator-terms/f04/record.json +20 -0
- package/test-fixtures/fix-sami-041/01/expectedResult.json +6 -0
- package/test-fixtures/fix-sami-041/01/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/01/record.json +14 -0
- package/test-fixtures/fix-sami-041/02/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/02/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/02/record.json +8 -0
- package/test-fixtures/fix-sami-041/03/expectedResult.json +5 -0
- package/test-fixtures/fix-sami-041/03/metadata.json +5 -0
- package/test-fixtures/fix-sami-041/03/record.json +8 -0
- package/test-fixtures/fix-sami-041/04/expectedResult.json +7 -0
- package/test-fixtures/fix-sami-041/04/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/04/record.json +10 -0
- package/test-fixtures/fix-sami-041/05/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/05/metadata.json +6 -0
- package/test-fixtures/fix-sami-041/05/record.json +8 -0
- package/test-fixtures/fix-sami-041/06/expectedResult.json +10 -0
- package/test-fixtures/fix-sami-041/06/metadata.json +4 -0
- package/test-fixtures/fix-sami-041/06/record.json +9 -0
- package/test-fixtures/indicator-fixes/11/expectedResult.json +10 -0
- package/test-fixtures/indicator-fixes/11/metadata.json +4 -0
- package/test-fixtures/indicator-fixes/11/record.json +10 -0
- package/test-fixtures/merge-fields/f042_01/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f042_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f042_01/record.json +13 -0
- package/test-fixtures/merge-fields/f05/metadata.json +1 -1
- package/test-fixtures/merge-fields/f06/expectedResult.json +42 -0
- package/test-fixtures/merge-fields/f06/metadata.json +6 -0
- package/test-fixtures/merge-fields/f06/record.json +41 -0
- package/test-fixtures/merge-fields/f07/expectedResult.json +18 -0
- package/test-fixtures/merge-fields/f07/metadata.json +6 -0
- package/test-fixtures/merge-fields/f07/record.json +18 -0
- package/test-fixtures/merge-fields/f08/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f08/metadata.json +7 -0
- package/test-fixtures/merge-fields/f08/record.json +10 -0
- package/test-fixtures/merge-fields/f09/expectedResult.json +14 -0
- package/test-fixtures/merge-fields/f09/metadata.json +6 -0
- package/test-fixtures/merge-fields/f09/record.json +14 -0
- package/test-fixtures/merge-fields/f10/expectedResult.json +25 -0
- package/test-fixtures/merge-fields/f10/metadata.json +6 -0
- package/test-fixtures/merge-fields/f10/record.json +25 -0
- package/test-fixtures/merge-fields/f11/expectedResult.json +40 -0
- package/test-fixtures/merge-fields/f11/metadata.json +7 -0
- package/test-fixtures/merge-fields/f11/record.json +50 -0
- package/test-fixtures/merge-fields/f12/expectedResult.json +17 -0
- package/test-fixtures/merge-fields/f12/metadata.json +6 -0
- package/test-fixtures/merge-fields/f12/record.json +25 -0
- package/test-fixtures/merge-fields/f13/expectedResult.json +18 -0
- package/test-fixtures/merge-fields/f13/metadata.json +6 -0
- package/test-fixtures/merge-fields/f13/record.json +28 -0
- package/test-fixtures/merge-fields/f14/expectedResult.json +25 -0
- package/test-fixtures/merge-fields/f14/metadata.json +6 -0
- package/test-fixtures/merge-fields/f14/record.json +25 -0
- package/test-fixtures/merge-fields/f15/expectedResult.json +8 -0
- package/test-fixtures/merge-fields/f15/metadata.json +6 -0
- package/test-fixtures/merge-fields/f15/record.json +9 -0
- package/test-fixtures/merge-fields/f16/expectedResult.json +12 -0
- package/test-fixtures/merge-fields/f16/metadata.json +7 -0
- package/test-fixtures/merge-fields/f16/record.json +13 -0
- package/test-fixtures/merge-fields/f300_01/expectedResult.json +9 -0
- package/test-fixtures/merge-fields/f300_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_01/record.json +8 -0
- package/test-fixtures/merge-fields/f300_02/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f300_02/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_02/record.json +16 -0
- package/test-fixtures/merge-fields/f300_03/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f300_03/metadata.json +6 -0
- package/test-fixtures/merge-fields/f300_03/record.json +16 -0
- package/test-fixtures/merge-fields/f490_01/expectedResult.json +13 -0
- package/test-fixtures/merge-fields/f490_01/metadata.json +6 -0
- package/test-fixtures/merge-fields/f490_01/record.json +16 -0
- package/test-fixtures/remove-041-zxx/01/expectedResult.json +5 -0
- package/test-fixtures/remove-041-zxx/01/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/01/record.json +10 -0
- package/test-fixtures/remove-041-zxx/02/expectedResult.json +7 -0
- package/test-fixtures/remove-041-zxx/02/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/02/record.json +9 -0
- package/test-fixtures/remove-041-zxx/11/expectedResult.json +10 -0
- package/test-fixtures/remove-041-zxx/11/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/11/record.json +9 -0
- package/test-fixtures/remove-041-zxx/12/expectedResult.json +10 -0
- package/test-fixtures/remove-041-zxx/12/metadata.json +5 -0
- package/test-fixtures/remove-041-zxx/12/record.json +9 -0
- package/test-fixtures/remove-inferior-datafields/f17/expectedResult.json +11 -0
- package/test-fixtures/remove-inferior-datafields/f17/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f17/record.json +15 -0
- package/test-fixtures/remove-inferior-datafields/f18/expectedResult.json +13 -0
- package/test-fixtures/remove-inferior-datafields/f18/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f18/record.json +18 -0
- package/test-fixtures/remove-inferior-datafields/f19/expectedResult.json +17 -0
- package/test-fixtures/remove-inferior-datafields/f19/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f19/record.json +18 -0
- package/test-fixtures/remove-inferior-datafields/f20/expectedResult.json +15 -0
- package/test-fixtures/remove-inferior-datafields/f20/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f20/record.json +29 -0
- package/test-fixtures/sort-fields/15/input.json +9 -0
- package/test-fixtures/sort-fields/15/metadata.json +5 -0
- package/test-fixtures/sort-fields/15/result.json +10 -0
- package/test-fixtures/sync-language/01/expectedResult.json +5 -0
- package/test-fixtures/sync-language/01/metadata.json +5 -0
- package/test-fixtures/sync-language/01/record.json +7 -0
- package/test-fixtures/sync-language/02/expectedResult.json +6 -0
- package/test-fixtures/sync-language/02/metadata.json +5 -0
- package/test-fixtures/sync-language/02/record.json +10 -0
- package/test-fixtures/sync-language/03/expectedResult.json +6 -0
- package/test-fixtures/sync-language/03/metadata.json +5 -0
- package/test-fixtures/sync-language/03/record.json +6 -0
- package/test-fixtures/sync-language/10/expectedResult.json +10 -0
- package/test-fixtures/sync-language/10/metadata.json +5 -0
- package/test-fixtures/sync-language/10/record.json +8 -0
- package/test-fixtures/sync-language/11/expectedResult.json +10 -0
- package/test-fixtures/sync-language/11/metadata.json +5 -0
- package/test-fixtures/sync-language/11/record.json +7 -0
- package/test-fixtures/sync-language/12/expectedResult.json +9 -0
- package/test-fixtures/sync-language/12/metadata.json +6 -0
- package/test-fixtures/sync-language/12/record.json +6 -0
- package/test-fixtures/sync-language/13/expectedResult.json +10 -0
- package/test-fixtures/sync-language/13/metadata.json +5 -0
- package/test-fixtures/sync-language/13/record.json +8 -0
- package/test-fixtures/sync-language/14/expectedResult.json +9 -0
- package/test-fixtures/sync-language/14/metadata.json +5 -0
- package/test-fixtures/sync-language/14/record.json +7 -0
- package/test-fixtures/sync-language/15/expectedResult.json +9 -0
- package/test-fixtures/sync-language/15/metadata.json +5 -0
- package/test-fixtures/sync-language/15/record.json +7 -0
- package/test-fixtures/translate-terms/05/expectedResult.json +12 -0
- package/test-fixtures/translate-terms/05/metadata.json +7 -0
- package/test-fixtures/translate-terms/05/record.json +11 -0
- package/test-fixtures/translate-terms/06/expectedResult.json +12 -0
- package/test-fixtures/translate-terms/06/metadata.json +7 -0
- package/test-fixtures/translate-terms/06/record.json +11 -0
- package/test-fixtures/translate-terms-data.js +23 -0
package/src/translate-terms.js
CHANGED
|
@@ -4,6 +4,9 @@ import {fieldHasSubfield, fieldToString, nvdebug} from './utils.js';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:translate-terms');
|
|
7
|
+
//const debugData = debug.extend('data');
|
|
8
|
+
const debugDev = debug.extend('dev');
|
|
9
|
+
|
|
7
10
|
const defaultTags = ['648', '650', '651', '655'];
|
|
8
11
|
|
|
9
12
|
const swapLanguageCode = {'fin': 'swe', 'fi': 'sv', 'sv': 'fi', 'swe': 'fin'};
|
|
@@ -12,6 +15,7 @@ const changeAbbrHash = {'fi': 'fin', 'fin': 'fi', 'sv': 'swe', 'swe': 'sv'};
|
|
|
12
15
|
const termCache = {};
|
|
13
16
|
|
|
14
17
|
// Author(s): Nicholas Volk
|
|
18
|
+
// eslint-disable-next-line max-lines-per-function
|
|
15
19
|
export default function () {
|
|
16
20
|
|
|
17
21
|
|
|
@@ -23,7 +27,7 @@ export default function () {
|
|
|
23
27
|
async function fix(record) {
|
|
24
28
|
const newFields = await getFields(record, defaultTags, []);
|
|
25
29
|
|
|
26
|
-
newFields.forEach(nf => nvdebug(`Add new field '${fieldToString(nf)}'`,
|
|
30
|
+
newFields.forEach(nf => nvdebug(`Add new field '${fieldToString(nf)}'`, debugDev));
|
|
27
31
|
|
|
28
32
|
newFields.forEach(nf => record.insertField(nf));
|
|
29
33
|
|
|
@@ -60,12 +64,12 @@ export default function () {
|
|
|
60
64
|
return [];
|
|
61
65
|
}
|
|
62
66
|
const fields = record.get(tag);
|
|
63
|
-
const finnishFields = fields.filter(f =>
|
|
64
|
-
const swedishFields = fields.filter(f =>
|
|
67
|
+
const finnishFields = fields.filter(f => isTranslatable(f, 'fin'));
|
|
68
|
+
const swedishFields = fields.filter(f => isTranslatable(f, 'swe'));
|
|
65
69
|
const finnishOnly = getMisses(finnishFields, swedishFields);
|
|
66
70
|
const swedishOnly = getMisses(swedishFields, finnishFields);
|
|
67
71
|
|
|
68
|
-
//
|
|
72
|
+
//nvdebug(` Looking at ${finnishOnly.length} + ${swedishOnly.length} fields`, debugDev);
|
|
69
73
|
return [...finnishOnly, ...swedishOnly].filter(f => tagAndFieldAgree(f));
|
|
70
74
|
|
|
71
75
|
function tagAndFieldAgree(field) {
|
|
@@ -79,6 +83,7 @@ export default function () {
|
|
|
79
83
|
const pairlessFields = getPairlessFinnishAndSwedishFields(record, tag);
|
|
80
84
|
|
|
81
85
|
// Dunno how to handle loop+promise combo in our normal coding style. Spent half a day trying... (I reckon it takes like 2 minuts to do this properly...)
|
|
86
|
+
// Did a proper implementation in drop-terms.js...
|
|
82
87
|
let prefLabels = [];
|
|
83
88
|
for (let i=0; i < pairlessFields.length; i += 1) {
|
|
84
89
|
prefLabels[i] = await getPrefLabel(pairlessFields[i]);
|
|
@@ -92,12 +97,12 @@ export default function () {
|
|
|
92
97
|
if (!prefLabels) {
|
|
93
98
|
return undefined;
|
|
94
99
|
}
|
|
95
|
-
//
|
|
100
|
+
//nvdebug(`pairField() WP 1: ${fieldToString(field)}`, debugDev);
|
|
96
101
|
const lexAndLang = getLexiconAndLanguage(field);
|
|
97
|
-
//
|
|
102
|
+
//nvdebug(`pairField() WP 2: ${JSON.stringify(lexAndLang)}`, debugDev);
|
|
98
103
|
const twoLetterOtherLang = swapLanguageCodeBetweenLanguages(changeAbbr(lexAndLang.lang));
|
|
99
104
|
const prefLabel = prefLabels.find(l => l.lang === twoLetterOtherLang);
|
|
100
|
-
//
|
|
105
|
+
//nvdebug(`pairField() WP 4: ${JSON.stringify(prefLabel)}`, debugDev);
|
|
101
106
|
const sfA = {'code': 'a', 'value': prefLabel.value}; // field.subfields.field(sf => sf.code === 'a');
|
|
102
107
|
const sf0 = clone(field.subfields.find(sf => sf.code === '0'));
|
|
103
108
|
const sf2 = {'code': '2', 'value': `${lexAndLang.lex}/${lexAndLang.lang === 'fin' ? 'swe' : 'fin'}`}; // swap fin <=> swe
|
|
@@ -105,119 +110,48 @@ export default function () {
|
|
|
105
110
|
return newField;
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
const subfield2 = field.subfields.find(sf => sf.code === '2');
|
|
110
|
-
if (subfield2.value === 'slm/fin') {
|
|
111
|
-
return {'lex': 'slm', 'lang': 'fin'};
|
|
112
|
-
}
|
|
113
|
-
if (subfield2.value === 'slm/swe') {
|
|
114
|
-
return {'lex': 'slm', 'lang': 'swe'};
|
|
115
|
-
}
|
|
116
|
-
if (subfield2.value === 'yso/fin') {
|
|
117
|
-
return {'lex': 'yso', 'lang': 'fin'};
|
|
118
|
-
}
|
|
119
|
-
if (subfield2.value === 'yso/swe') {
|
|
120
|
-
return {'lex': 'yso', 'lang': 'swe'};
|
|
121
|
-
}
|
|
122
|
-
return {};
|
|
123
|
-
}
|
|
113
|
+
|
|
124
114
|
|
|
125
115
|
async function getPrefLabel(field) {
|
|
126
|
-
//
|
|
116
|
+
// Pre-requisite: tag vs $2 correlation has already been checked!
|
|
127
117
|
const uri = fieldToUri(field);
|
|
128
118
|
if (!uri) { // $0 is invalid or sumthing
|
|
129
119
|
return undefined;
|
|
130
120
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
121
|
+
|
|
122
|
+
const data = await getTermData(uri);
|
|
123
|
+
|
|
124
|
+
if (!data) { // Sanity check. Miss caused by illegal id etc.
|
|
125
|
+
nvdebug(`No labels found for ${uri}`, debugDev);
|
|
134
126
|
return undefined;
|
|
135
127
|
}
|
|
136
|
-
const lexData = getLexiconAndLanguage(field); // $2 data
|
|
137
|
-
const lang = changeAbbr(lexData.lang);
|
|
138
128
|
|
|
129
|
+
const prefLabels = data.prefLabel;
|
|
139
130
|
|
|
131
|
+
const lexData = getLexiconAndLanguage(field); // $2 data
|
|
132
|
+
const lang = changeAbbr(lexData.lang); // fi <=> fin (finto use 2 chars, we use 3-letters)
|
|
140
133
|
const subfieldA = field.subfields.find(sf => sf.code === 'a');
|
|
141
134
|
|
|
142
|
-
|
|
143
|
-
//console.info(`Compare prefLabel '${prefLabel.value}' AND $a '${subfieldA.value}'`); // eslint-disable-line no-console
|
|
144
|
-
if (prefLabel.value === subfieldA.value) {
|
|
145
|
-
nvdebug(`'${fieldToString(field)}' requires translating`, debug);
|
|
135
|
+
if (isLabel(prefLabels, subfieldA.value, lang)) {
|
|
146
136
|
return prefLabels;
|
|
147
137
|
}
|
|
148
138
|
return undefined;
|
|
149
139
|
}
|
|
150
140
|
|
|
151
|
-
function swapLanguageCodeBetweenLanguages(code) {
|
|
152
|
-
if (swapLanguageCode[code]) {
|
|
153
|
-
return swapLanguageCode[code];
|
|
154
|
-
}
|
|
155
|
-
return code;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function changeAbbr(abbr) {
|
|
159
|
-
if (changeAbbrHash[abbr]) {
|
|
160
|
-
return changeAbbrHash[abbr];
|
|
161
|
-
}
|
|
162
|
-
return abbr;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function swaggerQuery(uri) {
|
|
166
|
-
// This would work for only yso, not yso-paikat etc `https://api.finto.fi/rest/v1/yso/data?format=application%2Fjson&uri=${uri}`;
|
|
167
|
-
return `https://api.finto.fi/rest/v1/data?uri=${uri}&format=application%2Fjson`; // This is simpler, but contains more irrelevant data
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async function getTermData(uri) {
|
|
171
|
-
//console.log(`getTermData(${uri})`); // eslint-disable-line no-console
|
|
172
|
-
if (termCache[uri]) { // Don't think current implementation uses the cache any more.
|
|
173
|
-
//console.log(`CACHED ${uri}`); // eslint-disable-line no-console
|
|
174
|
-
return termCache[uri];
|
|
175
|
-
}
|
|
176
|
-
const tmp = await getTermDataFromFinto(uri);
|
|
177
|
-
termCache[uri] = tmp;
|
|
178
|
-
return tmp;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function getTermDataFromFinto(uri) {
|
|
182
|
-
const headers = {'Accept': 'application/json'};
|
|
183
|
-
const uri2 = swaggerQuery(uri);
|
|
184
|
-
|
|
185
|
-
const response = await fetch(uri2, {method: 'GET', headers});
|
|
186
|
-
if (!response.ok) {
|
|
187
|
-
return undefined;
|
|
188
|
-
}
|
|
189
|
-
const json = await response.json();
|
|
190
|
-
|
|
191
|
-
if (!json.graph) {
|
|
192
|
-
return undefined;
|
|
193
|
-
}
|
|
194
|
-
const arr = json.graph;
|
|
195
|
-
const [hit] = arr.filter(row => row.uri === uri);
|
|
196
|
-
//console.log(`NEW JSON: ${JSON.stringify(hit.prefLabel)}`); // eslint-disable-line no-console
|
|
197
|
-
return hit.prefLabel;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
141
|
|
|
201
142
|
function fieldToUri(field) {
|
|
202
143
|
const lex = mapTagToLex(field.tag);
|
|
203
144
|
|
|
204
145
|
const subfield0 = field.subfields.find(sf => sf.code === '0');
|
|
205
146
|
const id = subfield0.value.replace(/^[^0-9]+/u, '');
|
|
206
|
-
|
|
207
|
-
//return `http%3A%2F%2Fwww.yso.fi%2Fonto%2Fyso%2Fp${id}`;
|
|
208
|
-
return `http://www.yso.fi/onto/yso/p${id}`;
|
|
209
|
-
}
|
|
210
|
-
if (lex === 'slm') {
|
|
211
|
-
return `http://urn.fi/URN:NBN:fi:au:slm:s${id}`;
|
|
212
|
-
}
|
|
213
|
-
return undefined;
|
|
147
|
+
return buildUri(lex, id);
|
|
214
148
|
}
|
|
215
149
|
|
|
216
|
-
function
|
|
150
|
+
function isTranslatable(field, lang) {
|
|
217
151
|
const fieldAsString = fieldToString(field);
|
|
218
152
|
|
|
219
153
|
// We should probably allow an optional $8 as the first subfield.
|
|
220
|
-
if (!fieldAsString.match(/^... #7 ‡a [^‡]+ ‡2 [^‡]+ ‡0 [^‡]+(?: ‡9 [A-Z]+<(?:KEEP|DROP)>)*$/u)) {
|
|
154
|
+
if (!fieldAsString.match(/^... #7 (?: ‡8 [^‡]+ )*‡a [^‡]+ ‡2 [^‡]+ ‡0 [^‡]+(?: ‡9 [A-Z]+<(?:KEEP|DROP)>)*$/u)) {
|
|
221
155
|
return false;
|
|
222
156
|
}
|
|
223
157
|
const lex = mapTagToLex(field.tag);
|
|
@@ -228,17 +162,6 @@ export default function () {
|
|
|
228
162
|
return fieldHasValidSubfield0(field);
|
|
229
163
|
}
|
|
230
164
|
|
|
231
|
-
function fieldHasValidSubfield0(field) {
|
|
232
|
-
const lex = mapTagToLex(field.tag);
|
|
233
|
-
const subfield0 = field.subfields.find(sf => sf.code === '0');
|
|
234
|
-
if (lex === 'yso' && subfield0.value.match(/^http:\/\/www\.yso\.fi\/onto\/yso\/p[0-9]+$/u)) {
|
|
235
|
-
return true;
|
|
236
|
-
}
|
|
237
|
-
if (lex === 'slm' && subfield0.value.match(/^http:\/\/urn\.fi\/URN:NBN:fi:au:slm:s[0-9]+$/u)) {
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
165
|
|
|
243
166
|
function getMisses(fieldList1, fieldList2) {
|
|
244
167
|
return fieldList1.filter(f => !hasSubfield0Match(f, fieldList2));
|
|
@@ -250,12 +173,7 @@ export default function () {
|
|
|
250
173
|
}
|
|
251
174
|
|
|
252
175
|
|
|
253
|
-
|
|
254
|
-
if (tag === '655') {
|
|
255
|
-
return 'slm';
|
|
256
|
-
}
|
|
257
|
-
return 'yso';
|
|
258
|
-
}
|
|
176
|
+
|
|
259
177
|
|
|
260
178
|
|
|
261
179
|
/*
|
|
@@ -269,3 +187,144 @@ export default function () {
|
|
|
269
187
|
|
|
270
188
|
}
|
|
271
189
|
|
|
190
|
+
export function fieldHasValidSubfield0(field, defaultLex = undefined) {
|
|
191
|
+
const lex = defaultLex || mapTagToLex(field.tag);
|
|
192
|
+
return field.subfields.some(sf => isValidSubfield0(sf, lex));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function isValidSubfield0(subfield, lex = '???') {
|
|
196
|
+
if (subfield.code !== '0') {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
// 2025-12-10: supports both http and https as well. Note that translation will copy the original $0 idenfifier even though it might be non-standard.
|
|
200
|
+
// Note that currently 'http' is teh standard!!!
|
|
201
|
+
if (['yso', 'yso/fin', 'yso/swe'].includes(lex) && subfield.value.match(/^https?:\/\/www\.yso\.fi\/onto\/yso\/p[0-9]+$/u)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
if (['slm', 'slm/fin', 'slm/swe'].includes(lex) && subfield.value.match(/^https?:\/\/urn\.fi\/URN:NBN:fi:au:slm:s[0-9]+$/u)) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
export function buildUri(lex, id) {
|
|
212
|
+
if (['yso', 'yso/fin', 'yso/swe'].includes(lex)) {
|
|
213
|
+
//return `http%3A%2F%2Fwww.yso.fi%2Fonto%2Fyso%2Fp${id}`;
|
|
214
|
+
return `http://www.yso.fi/onto/yso/p${id}`;
|
|
215
|
+
}
|
|
216
|
+
if (['slm', 'slm/fin', 'slm/swe'].includes(lex)) {
|
|
217
|
+
return `http://urn.fi/URN:NBN:fi:au:slm:s${id}`;
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function mapTagToLex(tag) {
|
|
223
|
+
if (tag === '655') {
|
|
224
|
+
return 'slm';
|
|
225
|
+
}
|
|
226
|
+
return 'yso';
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export async function getTermData(uri) {
|
|
230
|
+
nvdebug(`getTermData(${uri})`, debugDev);
|
|
231
|
+
if (termCache[uri]) { // Don't think current implementation uses the cache any more.
|
|
232
|
+
//nvdebug(`CACHED ${uri}`, debugDev);
|
|
233
|
+
return termCache[uri];
|
|
234
|
+
}
|
|
235
|
+
const tmp = await getTermDataFromFinto(uri);
|
|
236
|
+
termCache[uri] = tmp;
|
|
237
|
+
return tmp;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function getTermDataFromFinto(uri) {
|
|
241
|
+
const headers = {'Accept': 'application/json'};
|
|
242
|
+
const uri2 = swaggerQuery(uri);
|
|
243
|
+
|
|
244
|
+
const response = await fetch(uri2, {method: 'GET', headers});
|
|
245
|
+
if (!response.ok) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
const json = await response.json();
|
|
249
|
+
|
|
250
|
+
if (!json.graph) {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
const arr = json.graph;
|
|
254
|
+
const [hit] = arr.filter(row => row.uri === uri);
|
|
255
|
+
const subset = {
|
|
256
|
+
prefLabel: processLabel(hit?.prefLabel || undefined),
|
|
257
|
+
altLabel: processLabel(hit?.altLabel || undefined)
|
|
258
|
+
};
|
|
259
|
+
//nvdebug(`NEW JSON: ${JSON.stringify(hit)}`, debugDev);
|
|
260
|
+
|
|
261
|
+
return subset;
|
|
262
|
+
|
|
263
|
+
function swaggerQuery(uri) {
|
|
264
|
+
// This would work for only yso, not yso-paikat etc `https://api.finto.fi/rest/v1/yso/data?format=application%2Fjson&uri=${uri}`;
|
|
265
|
+
return `https://api.finto.fi/rest/v1/data?uri=${uri}&format=application%2Fjson`; // This is simpler, but contains more irrelevant data
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function processLabel(label) {
|
|
269
|
+
if (typeof label === 'object') {
|
|
270
|
+
if (Array.isArray(label)) {
|
|
271
|
+
return label;
|
|
272
|
+
}
|
|
273
|
+
return [label];
|
|
274
|
+
}
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function getLexiconAndLanguage(field) {
|
|
280
|
+
// Assumes that field has exactly one $2
|
|
281
|
+
const subfield2 = field.subfields.find(sf => sf.code === '2');
|
|
282
|
+
if (subfield2) {
|
|
283
|
+
if (subfield2.value === 'slm/fin') {
|
|
284
|
+
return {'lex': 'slm', 'lang': 'fin'};
|
|
285
|
+
}
|
|
286
|
+
if (subfield2.value === 'slm/swe') {
|
|
287
|
+
return {'lex': 'slm', 'lang': 'swe'};
|
|
288
|
+
}
|
|
289
|
+
if (subfield2.value === 'yso/fin') {
|
|
290
|
+
return {'lex': 'yso', 'lang': 'fin'};
|
|
291
|
+
}
|
|
292
|
+
if (subfield2.value === 'yso/swe') {
|
|
293
|
+
return {'lex': 'yso', 'lang': 'swe'};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return {};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
export function isLabel(labels, term, lang = undefined) {
|
|
302
|
+
const twoLetterLanguageCode = lang && lang.length === 3 ? changeAbbr(lang) : lang;
|
|
303
|
+
return labels.some(l => isMatch(l));
|
|
304
|
+
|
|
305
|
+
function isMatch(label) {
|
|
306
|
+
if (label.value !== term) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
if (!twoLetterLanguageCode) { // If language code is not defined, any hit will do
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
return label.lang === twoLetterLanguageCode;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
function changeAbbr(abbr) {
|
|
318
|
+
if (changeAbbrHash[abbr]) {
|
|
319
|
+
return changeAbbrHash[abbr];
|
|
320
|
+
}
|
|
321
|
+
return abbr;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
function swapLanguageCodeBetweenLanguages(code) {
|
|
326
|
+
if (swapLanguageCode[code]) {
|
|
327
|
+
return swapLanguageCode[code];
|
|
328
|
+
}
|
|
329
|
+
return code;
|
|
330
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import createDebugLogger from 'debug';
|
|
2
|
+
//import createDebugLogger from 'debug';
|
|
3
3
|
import fetchMock from 'fetch-mock';
|
|
4
4
|
|
|
5
5
|
import validatorFactory from './translate-terms.js';
|
|
@@ -17,7 +17,7 @@ const uris = [
|
|
|
17
17
|
'http://urn.fi/URN:NBN:fi:au:slm:s161'
|
|
18
18
|
];
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const useMock = false;
|
|
21
21
|
|
|
22
22
|
generateTests({
|
|
23
23
|
callback,
|
|
@@ -30,20 +30,21 @@ generateTests({
|
|
|
30
30
|
hooks: {
|
|
31
31
|
before: async () => {
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
if (useMock){
|
|
34
|
+
fetchMock.mockGlobal()
|
|
35
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[0]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
36
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[1]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
37
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[2]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
38
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[3]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData})
|
|
39
|
+
.get(`https://api.finto.fi/rest/v1/data?uri=${uris[4]}&format=application%2Fjson`, {status: 200, headers: {}, body: fakeData});
|
|
40
|
+
}
|
|
40
41
|
|
|
41
42
|
testValidatorFactory();
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
});
|
|
45
46
|
|
|
46
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/translate-terms:test');
|
|
47
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/translate-terms:test');
|
|
47
48
|
|
|
48
49
|
async function testValidatorFactory() {
|
|
49
50
|
const validator = await validatorFactory();
|
|
@@ -53,12 +54,7 @@ async function testValidatorFactory() {
|
|
|
53
54
|
assert.equal(typeof validator.validate, 'function');
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
async function callback({getFixture,
|
|
57
|
-
if (enabled === false) {
|
|
58
|
-
debug('TEST SKIPPED!');
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
57
|
+
async function callback({getFixture, fix = false}) {
|
|
62
58
|
const validator = await validatorFactory();
|
|
63
59
|
const record = new MarcRecord(getFixture('record.json'));
|
|
64
60
|
const expectedResult = getFixture('expectedResult.json');
|
package/src/typeOfDate-008.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import createDebugLogger from 'debug';
|
|
2
|
+
import { nvdebug } from './utils.js';
|
|
2
3
|
|
|
3
4
|
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/typeOfDate-008');
|
|
5
|
+
//const debugData = debug.extend('data');
|
|
6
|
+
const debugDev = debug.extend('dev');
|
|
4
7
|
|
|
5
8
|
export default function () {
|
|
6
9
|
return {
|
|
@@ -15,7 +18,7 @@ export default function () {
|
|
|
15
18
|
const c1114 = f008.value.substring(11, 15);
|
|
16
19
|
// if 008 06 = s, and 11-14 = #### (not year/digits)
|
|
17
20
|
if (c06 === 't' && !(/[0-9u]{4}/u).test(c1114)) {
|
|
18
|
-
|
|
21
|
+
nvdebug('is t and not valid 1114', debugDev);
|
|
19
22
|
return {valid: false, message: 'Invalid 008 06'};
|
|
20
23
|
}
|
|
21
24
|
|
package/src/update-field-540.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
//import createDebugLogger from 'debug';
|
|
2
|
-
import {fieldToString} from './utils.js';
|
|
2
|
+
import {fieldToString /*, nvdebug*/} from './utils.js';
|
|
3
3
|
|
|
4
4
|
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/update-field-540');
|
|
5
|
+
//const debugData = debug.extend('data');
|
|
6
|
+
//const debugDev = debug.extend('dev');
|
|
5
7
|
|
|
6
8
|
// Author(s): Nicholas Volk
|
|
7
9
|
export default function () {
|
|
@@ -54,7 +56,7 @@ function validLicenseInSubfieldC(subfieldC, license) {
|
|
|
54
56
|
if (subfieldC.code !== 'c') {
|
|
55
57
|
return false;
|
|
56
58
|
}
|
|
57
|
-
//nvdebug(`Compare ${subfieldC.value} vs ${license.license}
|
|
59
|
+
//nvdebug(`Compare ${subfieldC.value} vs ${license.license}`, debugDev);
|
|
58
60
|
return license.license === subfieldC.value;
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -62,7 +64,7 @@ function validUrlInSubfieldU(subfieldU, license) {
|
|
|
62
64
|
if (subfieldU.code !== 'u') {
|
|
63
65
|
return false;
|
|
64
66
|
}
|
|
65
|
-
//nvdebug(`Compare ${subfieldU.value} vs ${license.url}
|
|
67
|
+
//nvdebug(`Compare ${subfieldU.value} vs ${license.url}`, debugDev);
|
|
66
68
|
return license.url === subfieldU.value;
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -78,12 +80,12 @@ function fieldHasOldCcLicense(field, fix) {
|
|
|
78
80
|
if (field.tag !== '540') {
|
|
79
81
|
return false;
|
|
80
82
|
}
|
|
81
|
-
//nvdebug(`NORM 540: ${fieldToString(field)}
|
|
83
|
+
//nvdebug(`NORM 540: ${fieldToString(field)}`, debugDev);
|
|
82
84
|
const validLicense = licences.find(license => field.subfields.some(sf => validLicenseInSubfieldC(sf, license)) && field.subfields.some(sf => validUrlInSubfieldU(sf, license)));
|
|
83
85
|
if (!validLicense) {
|
|
84
86
|
return false;
|
|
85
87
|
}
|
|
86
|
-
//nvdebug(` Found valid license
|
|
88
|
+
//nvdebug(` Found valid license`, debugDev);
|
|
87
89
|
if (fix) {
|
|
88
90
|
const subfieldsC = field.subfields.filter(sf => validLicenseInSubfieldC(sf, validLicense));
|
|
89
91
|
subfieldsC.forEach(c => fixC(field, c));
|
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './update-field-540.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -20,7 +20,7 @@ generateTests({
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/update-field-540:test');
|
|
23
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/update-field-540:test');
|
|
24
24
|
|
|
25
25
|
async function testValidatorFactory() {
|
|
26
26
|
const validator = await validatorFactory();
|
|
@@ -33,12 +33,7 @@ async function testValidatorFactory() {
|
|
|
33
33
|
assert(validator.validate).to.be.a('function');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async function callback({getFixture,
|
|
37
|
-
if (enabled === false) {
|
|
38
|
-
debug('TEST SKIPPED!');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
36
|
+
async function callback({getFixture, fix = false}) {
|
|
42
37
|
const validator = await validatorFactory();
|
|
43
38
|
const record = new MarcRecord(getFixture('record.json'));
|
|
44
39
|
const expectedResult = getFixture('expectedResult.json');
|
package/src/urn.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
//import fetch from 'node-fetch';
|
|
2
|
-
import {isElectronicMaterial} from './utils.js';
|
|
2
|
+
import {isElectronicMaterial, nvdebug} from './utils.js';
|
|
3
3
|
import createDebugLogger from 'debug';
|
|
4
4
|
|
|
5
5
|
const URN_GENERATOR_URL = 'https://generator.urn.fi/cgi-bin/urn_generator.cgi?type=nbn';
|
|
6
6
|
|
|
7
|
+
// eslint-disable-next-line max-lines-per-function
|
|
7
8
|
export default function (isLegalDeposit = false, useMelindaTemp = true) {
|
|
8
9
|
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:urn');
|
|
9
10
|
const debugData = debug.extend('data');
|
|
11
|
+
const debugDev = debug.extend('dev');
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
|
|
14
|
+
//nvdebug(`IS LEGAL DEPOSIT? ${isLegalDeposit ? 'YES' : 'NO'}`, debugDev); // eslint-disable-line no-console
|
|
12
15
|
|
|
13
16
|
// We should check that the f856 with URN has second indicator '0' (Resource), ' ' (No information provided) or '8' (No display constant generated)
|
|
14
17
|
// - if second indicator is '1' (Version of resource) or '2' (Related resource) the URN in f856 is not correct for the resource described in the record
|
|
@@ -35,12 +38,13 @@ export default function (isLegalDeposit = false, useMelindaTemp = true) {
|
|
|
35
38
|
fix
|
|
36
39
|
};
|
|
37
40
|
|
|
41
|
+
// eslint-disable-next-line max-lines-per-function
|
|
38
42
|
async function fix(record) {
|
|
39
43
|
const f856sUrn = record.fields.filter(hasLegalDepositURN);
|
|
40
|
-
|
|
44
|
+
nvdebug(`f856sUrn: ${JSON.stringify(f856sUrn)}`, debugDev);
|
|
41
45
|
|
|
42
46
|
const ldSubfields = isLegalDeposit ? createLDSubfields() : [];
|
|
43
|
-
|
|
47
|
+
nvdebug(`IsLegalDeposit: ${isLegalDeposit}, LegalDepositSubfields: ${JSON.stringify(ldSubfields)}`, debugDev);
|
|
44
48
|
|
|
45
49
|
// We add the URN even if we're not getting the legalDeposit - where does this URN resolve?
|
|
46
50
|
// We probably should not do these additions
|
|
@@ -111,7 +115,7 @@ export default function (isLegalDeposit = false, useMelindaTemp = true) {
|
|
|
111
115
|
return acc;
|
|
112
116
|
}, undefined);
|
|
113
117
|
|
|
114
|
-
|
|
118
|
+
nvdebug(`isbns: ${isbn}`, debugDev);
|
|
115
119
|
|
|
116
120
|
const {generated, value} = await createURN(isbn);
|
|
117
121
|
return {code: 'u', value, generated};
|
|
@@ -161,12 +165,12 @@ export default function (isLegalDeposit = false, useMelindaTemp = true) {
|
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
function validateLD(f856sUrn) {
|
|
164
|
-
|
|
168
|
+
nvdebug(`Validating the existence of legal deposit subfields`, debugDev);
|
|
165
169
|
const ldSubfields = createLDSubfields();
|
|
166
170
|
const f856sUrnWithLdSubfields = f856sUrn.filter(field => fieldHasLDSubfields(field, ldSubfields));
|
|
167
171
|
if (f856sUrnWithLdSubfields.length > 0) {
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
nvdebug(`Record has ${f856sUrnWithLdSubfields.length} URN fields with all necessary legal deposit subfields`, debugDev);
|
|
173
|
+
nvdebug(`f856sUrnWithLdSubfields: ${JSON.stringify(f856sUrnWithLdSubfields)}`, debugData);
|
|
170
174
|
return true;
|
|
171
175
|
}
|
|
172
176
|
return false;
|
|
@@ -175,22 +179,22 @@ export default function (isLegalDeposit = false, useMelindaTemp = true) {
|
|
|
175
179
|
function validate(record) {
|
|
176
180
|
// if not electronic skip this validator
|
|
177
181
|
if (!isElectronicMaterial(record)) {
|
|
178
|
-
|
|
182
|
+
nvdebug(`Record is not electronic - no need to validate legal deposit URNs`, debugDev);
|
|
179
183
|
return {valid: true};
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
const f856sUrn = record.fields.filter(hasLegalDepositURN);
|
|
183
187
|
|
|
184
188
|
if (f856sUrn.length > 0) {
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
nvdebug(`Record has ${f856sUrn.length} URN fields`, debugDev);
|
|
190
|
+
nvdebug(`f856sUrn: ${JSON.stringify(f856sUrn)}`, debugData);
|
|
187
191
|
|
|
188
192
|
if (!isLegalDeposit || validateLD(f856sUrn)) {
|
|
189
|
-
|
|
193
|
+
nvdebug(`Record is valid`, debugDev);
|
|
190
194
|
return {valid: true};
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
|
-
|
|
197
|
+
nvdebug(`No (valid) URN fields - Record is not valid`, debugDev);
|
|
194
198
|
return {valid: false};
|
|
195
199
|
}
|
|
196
200
|
}
|
package/src/urn.test.js
CHANGED
|
@@ -3,7 +3,7 @@ import {MarcRecord} from '@natlibfi/marc-record';
|
|
|
3
3
|
import validatorFactory from './urn.js';
|
|
4
4
|
import {READERS} from '@natlibfi/fixura';
|
|
5
5
|
import generateTests from '@natlibfi/fixugen';
|
|
6
|
-
import createDebugLogger from 'debug';
|
|
6
|
+
//import createDebugLogger from 'debug';
|
|
7
7
|
|
|
8
8
|
generateTests({
|
|
9
9
|
callback,
|
|
@@ -19,7 +19,7 @@ generateTests({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/urn:test');
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/urn:test');
|
|
23
23
|
|
|
24
24
|
async function testValidatorFactory() {
|
|
25
25
|
const validator = await validatorFactory();
|
|
@@ -29,12 +29,7 @@ async function testValidatorFactory() {
|
|
|
29
29
|
assert.equal(typeof validator.validate, 'function');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async function callback({getFixture,
|
|
33
|
-
if (enabled === false) {
|
|
34
|
-
debug('TEST SKIPPED!');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
32
|
+
async function callback({getFixture, fix = true, isLegalDeposit = false}) {
|
|
38
33
|
const validator = await validatorFactory(isLegalDeposit);
|
|
39
34
|
const record = new MarcRecord(getFixture('input.json'));
|
|
40
35
|
const expectedResult = getFixture('result.json');
|