@natlibfi/marc-record-validators-melinda 11.6.7-alpha.1 → 12.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.yml +1 -1
- package/dist/access-rights.js +63 -91
- package/dist/access-rights.js.map +7 -1
- package/dist/access-rights.test.js +137 -0
- package/dist/access-rights.test.js.map +7 -0
- package/dist/addMissingField041.js +21 -53
- package/dist/addMissingField041.js.map +7 -1
- package/dist/addMissingField041.test.js +39 -0
- package/dist/addMissingField041.test.js.map +7 -0
- package/dist/addMissingField336.js +99 -191
- package/dist/addMissingField336.js.map +7 -1
- package/dist/addMissingField336.test.js +39 -0
- package/dist/addMissingField336.test.js.map +7 -0
- package/dist/addMissingField337.js +63 -132
- package/dist/addMissingField337.js.map +7 -1
- package/dist/addMissingField337.test.js +39 -0
- package/dist/addMissingField337.test.js.map +7 -0
- package/dist/addMissingField338.js +147 -253
- package/dist/addMissingField338.js.map +7 -1
- package/dist/addMissingField338.test.js +39 -0
- package/dist/addMissingField338.test.js.map +7 -0
- package/dist/cyrillux-usemarcon-replacement.js +119 -272
- package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
- package/dist/cyrillux-usemarcon-replacement.test.js +46 -0
- package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
- package/dist/cyrillux.js +119 -223
- package/dist/cyrillux.js.map +7 -1
- package/dist/cyrillux.test.js +39 -0
- package/dist/cyrillux.test.js.map +7 -0
- package/dist/disambiguateSeriesStatements.js +40 -81
- package/dist/disambiguateSeriesStatements.js.map +7 -1
- package/dist/disambiguateSeriesStatements.test.js +44 -0
- package/dist/disambiguateSeriesStatements.test.js.map +7 -0
- package/dist/double-commas.js +7 -14
- package/dist/double-commas.js.map +7 -1
- package/dist/double-commas.test.js +48 -0
- package/dist/double-commas.test.js.map +7 -0
- package/dist/duplicates-ind1.js +10 -31
- package/dist/duplicates-ind1.js.map +7 -1
- package/dist/duplicates-ind1.test.js +40 -0
- package/dist/duplicates-ind1.test.js.map +7 -0
- package/dist/empty-fields.js +10 -22
- package/dist/empty-fields.js.map +7 -1
- package/dist/empty-fields.test.js +129 -0
- package/dist/empty-fields.test.js.map +7 -0
- package/dist/ending-punctuation-conf.js +871 -769
- package/dist/ending-punctuation-conf.js.map +7 -1
- package/dist/ending-punctuation.js +84 -167
- package/dist/ending-punctuation.js.map +7 -1
- package/dist/ending-punctuation.test.js +2290 -0
- package/dist/ending-punctuation.test.js.map +7 -0
- package/dist/ending-whitespace.js +10 -35
- package/dist/ending-whitespace.js.map +7 -1
- package/dist/ending-whitespace.test.js +38 -0
- package/dist/ending-whitespace.test.js.map +7 -0
- package/dist/field-008-18-34-character-groups.js +40 -125
- package/dist/field-008-18-34-character-groups.js.map +7 -1
- package/dist/field-008-18-34-character-groups.test.js +45 -0
- package/dist/field-008-18-34-character-groups.test.js.map +7 -0
- package/dist/field-505-separators.js +19 -39
- package/dist/field-505-separators.js.map +7 -1
- package/dist/field-505-separators.test.js +45 -0
- package/dist/field-505-separators.test.js.map +7 -0
- package/dist/field-521-fix.js +19 -47
- package/dist/field-521-fix.js.map +7 -1
- package/dist/field-521-fix.test.js +44 -0
- package/dist/field-521-fix.test.js.map +7 -0
- package/dist/field-exclusion.js +37 -91
- package/dist/field-exclusion.js.map +7 -1
- package/dist/field-exclusion.test.js +821 -0
- package/dist/field-exclusion.test.js.map +7 -0
- package/dist/field-structure.js +52 -104
- package/dist/field-structure.js.map +7 -1
- package/dist/field-structure.test.js +587 -0
- package/dist/field-structure.test.js.map +7 -0
- package/dist/field33XUtils.js +119 -503
- package/dist/field33XUtils.js.map +7 -1
- package/dist/fields-present.js +11 -23
- package/dist/fields-present.js.map +7 -1
- package/dist/fields-present.test.js +95 -0
- package/dist/fields-present.test.js.map +7 -0
- package/dist/fix-33X.js +393 -431
- package/dist/fix-33X.js.map +7 -1
- package/dist/fix-33X.test.js +39 -0
- package/dist/fix-33X.test.js.map +7 -0
- package/dist/fix-country-codes.js +20 -50
- package/dist/fix-country-codes.js.map +7 -1
- package/dist/fix-country-codes.test.js +44 -0
- package/dist/fix-country-codes.test.js.map +7 -0
- package/dist/fix-language-codes.js +23 -53
- package/dist/fix-language-codes.js.map +7 -1
- package/dist/fix-language-codes.test.js +38 -0
- package/dist/fix-language-codes.test.js.map +7 -0
- package/dist/fixRelatorTerms.js +82 -209
- package/dist/fixRelatorTerms.js.map +7 -1
- package/dist/fixRelatorTerms.test.js +44 -0
- package/dist/fixRelatorTerms.test.js.map +7 -0
- package/dist/fixed-fields.js +21 -30
- package/dist/fixed-fields.js.map +7 -1
- package/dist/fixed-fields.test.js +87 -0
- package/dist/fixed-fields.test.js.map +7 -0
- package/dist/identical-fields.js +8 -24
- package/dist/identical-fields.js.map +7 -1
- package/dist/identical-fields.test.js +119 -0
- package/dist/identical-fields.test.js.map +7 -0
- package/dist/index.js +119 -413
- package/dist/index.js.map +7 -1
- package/dist/indicator-fixes.js +57 -95
- package/dist/indicator-fixes.js.map +7 -1
- package/dist/indicator-fixes.test.js +42 -0
- package/dist/indicator-fixes.test.js.map +7 -0
- package/dist/isbn-issn.js +66 -126
- package/dist/isbn-issn.js.map +7 -1
- package/dist/isbn-issn.test.js +398 -0
- package/dist/isbn-issn.test.js.map +7 -0
- package/dist/item-language.js +32 -65
- package/dist/item-language.js.map +7 -1
- package/dist/item-language.test.js +322 -0
- package/dist/item-language.test.js.map +7 -0
- package/dist/melindaCustomMergeFields.js +5182 -11233
- package/dist/melindaCustomMergeFields.js.map +7 -1
- package/dist/merge-fields/controlSubfields.js +75 -142
- package/dist/merge-fields/controlSubfields.js.map +7 -1
- package/dist/merge-fields/counterpartField.js +182 -379
- package/dist/merge-fields/counterpartField.js.map +7 -1
- package/dist/merge-fields/index.js +15 -49
- package/dist/merge-fields/index.js.map +7 -1
- package/dist/merge-fields/mergableIndicator.js +18 -51
- package/dist/merge-fields/mergableIndicator.js.map +7 -1
- package/dist/merge-fields/mergableTag.js +78 -30
- package/dist/merge-fields/mergableTag.js.map +7 -1
- package/dist/merge-fields/mergeConfig.js +66 -171
- package/dist/merge-fields/mergeConfig.js.map +7 -1
- package/dist/merge-fields/mergeConstraints.js +323 -1214
- package/dist/merge-fields/mergeConstraints.js.map +7 -1
- package/dist/merge-fields/mergeField.js +47 -111
- package/dist/merge-fields/mergeField.js.map +7 -1
- package/dist/merge-fields/mergeIndicator.js +64 -118
- package/dist/merge-fields/mergeIndicator.js.map +7 -1
- package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
- package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
- package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
- package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
- package/dist/merge-fields/mergeSubfield.js +47 -95
- package/dist/merge-fields/mergeSubfield.js.map +7 -1
- package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
- package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
- package/dist/merge-fields/worldKnowledge.js +15 -40
- package/dist/merge-fields/worldKnowledge.js.map +7 -1
- package/dist/merge-fields.test.js +44 -0
- package/dist/merge-fields.test.js.map +7 -0
- package/dist/mergeField500Lisapainokset.js +28 -57
- package/dist/mergeField500Lisapainokset.js.map +7 -1
- package/dist/mergeField500Lisapainokset.test.js +44 -0
- package/dist/mergeField500Lisapainokset.test.js.map +7 -0
- package/dist/mergeRelatorTermFields.js +33 -69
- package/dist/mergeRelatorTermFields.js.map +7 -1
- package/dist/mergeRelatorTermFields.test.js +44 -0
- package/dist/mergeRelatorTermFields.test.js.map +7 -0
- package/dist/modernize-502.js +23 -55
- package/dist/modernize-502.js.map +7 -1
- package/dist/modernize-502.test.js +38 -0
- package/dist/modernize-502.test.js.map +7 -0
- package/dist/multiple-subfield-0.js +23 -48
- package/dist/multiple-subfield-0.js.map +7 -1
- package/dist/multiple-subfield-0.test.js +44 -0
- package/dist/multiple-subfield-0.test.js.map +7 -0
- package/dist/non-breaking-space.js +11 -32
- package/dist/non-breaking-space.js.map +7 -1
- package/dist/non-breaking-space.test.js +38 -0
- package/dist/non-breaking-space.test.js.map +7 -0
- package/dist/normalize-dashes.js +18 -37
- package/dist/normalize-dashes.js.map +7 -1
- package/dist/normalize-dashes.test.js +44 -0
- package/dist/normalize-dashes.test.js.map +7 -0
- package/dist/normalize-identifiers.js +54 -140
- package/dist/normalize-identifiers.js.map +7 -1
- package/dist/normalize-identifiers.test.js +44 -0
- package/dist/normalize-identifiers.test.js.map +7 -0
- package/dist/normalize-qualifying-information.js +23 -48
- package/dist/normalize-qualifying-information.js.map +7 -1
- package/dist/normalize-qualifying-information.test.js +44 -0
- package/dist/normalize-qualifying-information.test.js.map +7 -0
- package/dist/normalize-utf8-diacritics.js +19 -105
- package/dist/normalize-utf8-diacritics.js.map +7 -1
- package/dist/normalize-utf8-diacritics.test.js +44 -0
- package/dist/normalize-utf8-diacritics.test.js.map +7 -0
- package/dist/normalizeFieldForComparison.js +67 -158
- package/dist/normalizeFieldForComparison.js.map +7 -1
- package/dist/normalizeSubfieldValueForComparison.js +37 -77
- package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
- package/dist/prepublicationUtils.js +58 -111
- package/dist/prepublicationUtils.js.map +7 -1
- package/dist/punctuation/index.js +56 -72
- package/dist/punctuation/index.js.map +7 -1
- package/dist/punctuation/rules/aut.js +372 -331
- package/dist/punctuation/rules/aut.js.map +7 -1
- package/dist/punctuation/rules/bib.js +420 -373
- package/dist/punctuation/rules/bib.js.map +7 -1
- package/dist/punctuation/rules/index.js +7 -21
- package/dist/punctuation/rules/index.js.map +7 -1
- package/dist/punctuation.test.js +44 -0
- package/dist/punctuation.test.js.map +7 -0
- package/dist/punctuation2.js +251 -800
- package/dist/punctuation2.js.map +7 -1
- package/dist/punctuation2.test.js +44 -0
- package/dist/punctuation2.test.js.map +7 -0
- package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
- package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
- package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
- package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
- package/dist/removeDuplicateDataFields.js +102 -202
- package/dist/removeDuplicateDataFields.js.map +7 -1
- package/dist/removeDuplicateDataFields.test.js +44 -0
- package/dist/removeDuplicateDataFields.test.js.map +7 -0
- package/dist/removeInferiorDataFields.js +103 -227
- package/dist/removeInferiorDataFields.js.map +7 -1
- package/dist/removeInferiorDataFields.test.js +44 -0
- package/dist/removeInferiorDataFields.test.js.map +7 -0
- package/dist/resolvable-ext-references-melinda.js +25 -60
- package/dist/resolvable-ext-references-melinda.js.map +7 -1
- package/dist/resolvable-ext-references-melinda.test.js +160 -0
- package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
- package/dist/resolveOrphanedSubfield6s.js +33 -64
- package/dist/resolveOrphanedSubfield6s.js.map +7 -1
- package/dist/resolveOrphanedSubfield6s.test.js +44 -0
- package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
- package/dist/sanitize-vocabulary-source-codes.js +27 -55
- package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
- package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
- package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
- package/dist/sort-tags.js +13 -25
- package/dist/sort-tags.js.map +7 -1
- package/dist/sort-tags.test.js +261 -0
- package/dist/sort-tags.test.js.map +7 -0
- package/dist/sortFields.js +152 -222
- package/dist/sortFields.js.map +7 -1
- package/dist/sortFields.test.js +44 -0
- package/dist/sortFields.test.js.map +7 -0
- package/dist/sortRelatorTerms.js +30 -68
- package/dist/sortRelatorTerms.js.map +7 -1
- package/dist/sortRelatorTerms.test.js +44 -0
- package/dist/sortRelatorTerms.test.js.map +7 -0
- package/dist/sortSubfields.js +102 -255
- package/dist/sortSubfields.js.map +7 -1
- package/dist/sortSubfields.test.js +44 -0
- package/dist/sortSubfields.test.js.map +7 -0
- package/dist/stripPunctuation.js +13 -36
- package/dist/stripPunctuation.js.map +7 -1
- package/dist/stripPunctuation.test.js +44 -0
- package/dist/stripPunctuation.test.js.map +7 -0
- package/dist/subfield-exclusion.js +28 -75
- package/dist/subfield-exclusion.js.map +7 -1
- package/dist/subfield-exclusion.test.js +471 -0
- package/dist/subfield-exclusion.test.js.map +7 -0
- package/dist/subfield6Utils.js +107 -269
- package/dist/subfield6Utils.js.map +7 -1
- package/dist/subfield8Utils.js +26 -50
- package/dist/subfield8Utils.js.map +7 -1
- package/dist/subfieldValueNormalizations.js +40 -74
- package/dist/subfieldValueNormalizations.js.map +7 -1
- package/dist/subfieldValueNormalizations.test.js +45 -0
- package/dist/subfieldValueNormalizations.test.js.map +7 -0
- package/dist/sync-007-and-300.js +22 -53
- package/dist/sync-007-and-300.js.map +7 -1
- package/dist/sync-007-and-300.test.js +44 -0
- package/dist/sync-007-and-300.test.js.map +7 -0
- package/dist/translate-terms.js +67 -155
- package/dist/translate-terms.js.map +7 -1
- package/dist/translate-terms.test.js +44 -0
- package/dist/translate-terms.test.js.map +7 -0
- package/dist/typeOfDate-008.js +10 -25
- package/dist/typeOfDate-008.js.map +7 -1
- package/dist/typeOfDate-008.test.js +40 -0
- package/dist/typeOfDate-008.test.js.map +7 -0
- package/dist/unicode-decomposition.js +94 -107
- package/dist/unicode-decomposition.js.map +7 -1
- package/dist/unicode-decomposition.test.js +94 -0
- package/dist/unicode-decomposition.test.js.map +7 -0
- package/dist/update-field-540.js +30 -75
- package/dist/update-field-540.js.map +7 -1
- package/dist/update-field-540.test.js +44 -0
- package/dist/update-field-540.test.js.map +7 -0
- package/dist/urn.js +55 -128
- package/dist/urn.js.map +7 -1
- package/dist/urn.test.js +44 -0
- package/dist/urn.test.js.map +7 -0
- package/dist/utils.js +72 -126
- package/dist/utils.js.map +7 -1
- package/eslint.config.mjs +1 -2
- package/package.json +21 -93
- package/src/access-rights.js +1 -1
- package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
- package/src/addMissingField041.js +1 -1
- package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
- package/src/addMissingField336.js +3 -3
- package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
- package/src/addMissingField337.js +2 -2
- package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
- package/src/addMissingField338.js +2 -2
- package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
- package/src/cyrillux-usemarcon-replacement.js +18 -18
- package/src/cyrillux-usemarcon-replacement.test.js +55 -0
- package/src/cyrillux.js +19 -12
- package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
- package/src/disambiguateSeriesStatements.js +2 -2
- package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
- package/src/double-commas.js +1 -1
- package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
- package/src/duplicates-ind1.js +1 -1
- package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
- package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
- package/src/ending-punctuation.js +1 -1
- package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +172 -173
- package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
- package/src/field-008-18-34-character-groups.js +2 -2
- package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
- package/src/field-505-separators.js +3 -3
- package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
- package/src/field-521-fix.js +2 -2
- package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
- package/src/field-exclusion.js +1 -1
- package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
- package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
- package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
- package/src/fix-33X.js +4 -4
- package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
- package/src/fix-country-codes.js +1 -1
- package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
- package/src/fix-language-codes.js +5 -5
- package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
- package/src/fixRelatorTerms.js +5 -5
- package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
- package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
- package/src/identical-fields.js +1 -1
- package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
- package/src/indicator-fixes.js +3 -3
- package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
- package/src/isbn-issn.js +1 -1
- package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
- package/src/{item-language.spec.js → item-language.test.js} +21 -22
- package/src/merge-fields/controlSubfields.js +1 -1
- package/src/merge-fields/counterpartField.js +8 -9
- package/src/merge-fields/index.js +1 -1
- package/src/merge-fields/mergableIndicator.js +1 -1
- package/src/merge-fields/mergeField.js +6 -6
- package/src/merge-fields/mergeIndicator.js +1 -1
- package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
- package/src/merge-fields/mergeOrAddSubfield.js +2 -2
- package/src/merge-fields/mergeSubfield.js +4 -4
- package/src/merge-fields/removeDuplicateSubfields.js +2 -2
- package/src/{merge-fields.spec.js → merge-fields.test.js} +12 -13
- package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
- package/src/mergeRelatorTermFields.js +5 -7
- package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
- package/src/modernize-502.js +1 -1
- package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
- package/src/multiple-subfield-0.js +3 -3
- package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
- package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
- package/src/normalize-dashes.js +2 -2
- package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
- package/src/normalize-identifiers.js +1 -1
- package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
- package/src/normalize-qualifying-information.js +2 -2
- package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
- package/src/normalize-utf8-diacritics.js +2 -2
- package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
- package/src/normalizeFieldForComparison.js +6 -6
- package/src/normalizeSubfieldValueForComparison.js +1 -1
- package/src/prepublicationUtils.js +4 -4
- package/src/punctuation/index.js +1 -1
- package/src/punctuation/rules/index.js +2 -2
- package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
- package/src/punctuation2.js +4 -4
- package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
- package/src/reindexSubfield6OccurenceNumbers.js +5 -7
- package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
- package/src/removeDuplicateDataFields.js +11 -19
- package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
- package/src/removeInferiorDataFields.js +11 -11
- package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
- package/src/resolvable-ext-references-melinda.js +1 -1
- package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
- package/src/resolveOrphanedSubfield6s.js +5 -5
- package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
- package/src/sanitize-vocabulary-source-codes.js +4 -4
- package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
- package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
- package/src/sortFields.js +4 -4
- package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
- package/src/sortRelatorTerms.js +3 -3
- package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
- package/src/sortSubfields.js +1 -1
- package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
- package/src/stripPunctuation.js +3 -3
- package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
- package/src/subfield-exclusion.js +1 -1
- package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
- package/src/subfield6Utils.js +6 -10
- package/src/subfield8Utils.js +4 -4
- package/src/subfieldValueNormalizations.js +3 -3
- package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
- package/src/sync-007-and-300.js +2 -2
- package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
- package/src/translate-terms.js +3 -3
- package/src/{translate-terms.spec.js → translate-terms.test.js} +13 -13
- package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
- package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
- package/src/update-field-540.js +2 -2
- package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
- package/src/urn.js +2 -2
- package/src/{urn.spec.js → urn.test.js} +12 -13
- package/src/utils.js +3 -3
- package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
- package/test-fixtures/field-505-separators/03/record.json +3 -0
- package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
- package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
- package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
- package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
- package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
- package/dist/access-rights.spec.js +0 -195
- package/dist/access-rights.spec.js.map +0 -1
- package/dist/addMissingField041.spec.js +0 -45
- package/dist/addMissingField041.spec.js.map +0 -1
- package/dist/addMissingField336.spec.js +0 -45
- package/dist/addMissingField336.spec.js.map +0 -1
- package/dist/addMissingField337.spec.js +0 -43
- package/dist/addMissingField337.spec.js.map +0 -1
- package/dist/addMissingField338.spec.js +0 -45
- package/dist/addMissingField338.spec.js.map +0 -1
- package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
- package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
- package/dist/cyrillux.spec.js +0 -46
- package/dist/cyrillux.spec.js.map +0 -1
- package/dist/disambiguateSeriesStatements.spec.js +0 -51
- package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
- package/dist/double-commas.spec.js +0 -73
- package/dist/double-commas.spec.js.map +0 -1
- package/dist/duplicates-ind1.spec.js +0 -45
- package/dist/duplicates-ind1.spec.js.map +0 -1
- package/dist/empty-fields.spec.js +0 -118
- package/dist/empty-fields.spec.js.map +0 -1
- package/dist/ending-punctuation.spec.js +0 -2654
- package/dist/ending-punctuation.spec.js.map +0 -1
- package/dist/ending-whitespace.spec.js +0 -42
- package/dist/ending-whitespace.spec.js.map +0 -1
- package/dist/field-008-18-34-character-groups.spec.js +0 -51
- package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
- package/dist/field-505-separators.spec.js +0 -51
- package/dist/field-505-separators.spec.js.map +0 -1
- package/dist/field-521-fix.spec.js +0 -51
- package/dist/field-521-fix.spec.js.map +0 -1
- package/dist/field-exclusion.spec.js +0 -1054
- package/dist/field-exclusion.spec.js.map +0 -1
- package/dist/field-structure.spec.js +0 -535
- package/dist/field-structure.spec.js.map +0 -1
- package/dist/fields-present.spec.js +0 -121
- package/dist/fields-present.spec.js.map +0 -1
- package/dist/fix-33X.spec.js +0 -45
- package/dist/fix-33X.spec.js.map +0 -1
- package/dist/fix-country-codes.spec.js +0 -51
- package/dist/fix-country-codes.spec.js.map +0 -1
- package/dist/fix-language-codes.spec.js +0 -44
- package/dist/fix-language-codes.spec.js.map +0 -1
- package/dist/fixRelatorTerms.spec.js +0 -51
- package/dist/fixRelatorTerms.spec.js.map +0 -1
- package/dist/fixed-fields.spec.js +0 -140
- package/dist/fixed-fields.spec.js.map +0 -1
- package/dist/identical-fields.spec.js +0 -99
- package/dist/identical-fields.spec.js.map +0 -1
- package/dist/indicator-fixes.spec.js +0 -51
- package/dist/indicator-fixes.spec.js.map +0 -1
- package/dist/isbn-issn.spec.js +0 -595
- package/dist/isbn-issn.spec.js.map +0 -1
- package/dist/item-language.spec.js +0 -306
- package/dist/item-language.spec.js.map +0 -1
- package/dist/melindaCustomMergeFields.json +0 -5120
- package/dist/merge-fields.spec.js +0 -51
- package/dist/merge-fields.spec.js.map +0 -1
- package/dist/mergeField500Lisapainokset.spec.js +0 -51
- package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
- package/dist/mergeRelatorTermFields.spec.js +0 -51
- package/dist/mergeRelatorTermFields.spec.js.map +0 -1
- package/dist/modernize-502.spec.js +0 -49
- package/dist/modernize-502.spec.js.map +0 -1
- package/dist/multiple-subfield-0.spec.js +0 -51
- package/dist/multiple-subfield-0.spec.js.map +0 -1
- package/dist/non-breaking-space.spec.js +0 -42
- package/dist/non-breaking-space.spec.js.map +0 -1
- package/dist/normalize-dashes.spec.js +0 -51
- package/dist/normalize-dashes.spec.js.map +0 -1
- package/dist/normalize-identifiers.spec.js +0 -51
- package/dist/normalize-identifiers.spec.js.map +0 -1
- package/dist/normalize-qualifying-information.spec.js +0 -51
- package/dist/normalize-qualifying-information.spec.js.map +0 -1
- package/dist/normalize-utf8-diacritics.spec.js +0 -51
- package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
- package/dist/punctuation.spec.js +0 -51
- package/dist/punctuation.spec.js.map +0 -1
- package/dist/punctuation2.spec.js +0 -51
- package/dist/punctuation2.spec.js.map +0 -1
- package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
- package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
- package/dist/removeDuplicateDataFields.spec.js +0 -51
- package/dist/removeDuplicateDataFields.spec.js.map +0 -1
- package/dist/removeInferiorDataFields.spec.js +0 -51
- package/dist/removeInferiorDataFields.spec.js.map +0 -1
- package/dist/resolvable-ext-references-melinda.spec.js +0 -166
- package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
- package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
- package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
- package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
- package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
- package/dist/sort-tags.spec.js +0 -207
- package/dist/sort-tags.spec.js.map +0 -1
- package/dist/sortFields.spec.js +0 -51
- package/dist/sortFields.spec.js.map +0 -1
- package/dist/sortRelatorTerms.spec.js +0 -51
- package/dist/sortRelatorTerms.spec.js.map +0 -1
- package/dist/sortSubfields.spec.js +0 -52
- package/dist/sortSubfields.spec.js.map +0 -1
- package/dist/stripPunctuation.spec.js +0 -51
- package/dist/stripPunctuation.spec.js.map +0 -1
- package/dist/subfield-exclusion.spec.js +0 -523
- package/dist/subfield-exclusion.spec.js.map +0 -1
- package/dist/subfieldValueNormalizations.spec.js +0 -51
- package/dist/subfieldValueNormalizations.spec.js.map +0 -1
- package/dist/sync-007-and-300.spec.js +0 -51
- package/dist/sync-007-and-300.spec.js.map +0 -1
- package/dist/translate-terms.spec.js +0 -51
- package/dist/translate-terms.spec.js.map +0 -1
- package/dist/typeOfDate-008.spec.js +0 -47
- package/dist/typeOfDate-008.spec.js.map +0 -1
- package/dist/unicode-decomposition.spec.js +0 -91
- package/dist/unicode-decomposition.spec.js.map +0 -1
- package/dist/update-field-540.spec.js +0 -51
- package/dist/update-field-540.spec.js.map +0 -1
- package/dist/urn.spec.js +0 -52
- package/dist/urn.spec.js.map +0 -1
- package/src/cyrillux-usemarcon-replacement.spec.js +0 -47
package/dist/indicator-fixes.js
CHANGED
|
@@ -1,121 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = _default;
|
|
7
|
-
exports.recordNormalizeIndicators = recordNormalizeIndicators;
|
|
8
|
-
var _utils = require("./utils");
|
|
9
|
-
// Relocated from melinda-marc-record-merge-reducers (and renamed)
|
|
10
|
-
//import createDebugLogger from 'debug';
|
|
11
|
-
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');
|
|
12
|
-
|
|
13
|
-
function _default() {
|
|
1
|
+
import { fieldToString } from "./utils.js";
|
|
2
|
+
export default function() {
|
|
14
3
|
return {
|
|
15
|
-
description:
|
|
4
|
+
description: "Normalizes indicator values",
|
|
16
5
|
validate,
|
|
17
6
|
fix
|
|
18
7
|
};
|
|
19
8
|
function fix(record) {
|
|
20
|
-
const res = {
|
|
21
|
-
message: [],
|
|
22
|
-
fix: [],
|
|
23
|
-
valid: true
|
|
24
|
-
};
|
|
9
|
+
const res = { message: [], fix: [], valid: true };
|
|
25
10
|
recordNormalizeIndicators(record);
|
|
26
11
|
return res;
|
|
27
12
|
}
|
|
28
13
|
function validate(record) {
|
|
29
|
-
const res = {
|
|
30
|
-
message: []
|
|
31
|
-
};
|
|
14
|
+
const res = { message: [] };
|
|
32
15
|
validateRecord(record, res);
|
|
33
16
|
res.valid = res.message.length < 1;
|
|
34
17
|
return res;
|
|
35
18
|
}
|
|
36
19
|
function validateRecord(record, res) {
|
|
37
|
-
//nvdebug(record);
|
|
38
20
|
const clonedFields = JSON.parse(JSON.stringify(record.fields));
|
|
39
21
|
recordNormalizeIndicators(record);
|
|
40
|
-
record.fields.forEach((field, index) => compareFields(field, index));
|
|
41
|
-
|
|
22
|
+
record.fields.forEach((field, index) => compareFields(field, index));
|
|
42
23
|
function compareFields(field, index) {
|
|
43
|
-
const origFieldAsString =
|
|
44
|
-
//const clonedFieldAsString = fieldToString(field);
|
|
24
|
+
const origFieldAsString = fieldToString(clonedFields[index]);
|
|
45
25
|
if (clonedFields[index].ind1 !== field.ind1) {
|
|
46
|
-
//nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);
|
|
47
26
|
res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);
|
|
48
27
|
}
|
|
49
28
|
if (clonedFields[index].ind2 !== field.ind2) {
|
|
50
|
-
//nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);
|
|
51
29
|
res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);
|
|
52
30
|
}
|
|
53
31
|
}
|
|
54
|
-
// Validator should not change the original record:
|
|
55
32
|
record.fields = clonedFields;
|
|
56
33
|
return;
|
|
57
34
|
}
|
|
58
35
|
}
|
|
59
|
-
const ind1NonFilingChars = [
|
|
60
|
-
const ind2NonFilingChars = [
|
|
36
|
+
const ind1NonFilingChars = ["130", "630", "730", "740"];
|
|
37
|
+
const ind2NonFilingChars = ["222", "240", "242", "243", "245", "830"];
|
|
61
38
|
function hasNonFilingIndicator1(field) {
|
|
62
39
|
return ind1NonFilingChars.includes(field.tag);
|
|
63
40
|
}
|
|
64
41
|
function modifiableIndicatorValue(value) {
|
|
65
|
-
|
|
66
|
-
return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);
|
|
42
|
+
return !["9", "8", "7", "6", "5", "4", "3", "2", "1"].includes(value);
|
|
67
43
|
}
|
|
68
44
|
function hasNonFilingIndicator2(field) {
|
|
69
45
|
return ind2NonFilingChars.includes(field.tag);
|
|
70
46
|
}
|
|
71
47
|
function valueBeginsWithDeterminer(value, cands) {
|
|
72
|
-
return cands.find(cand => value.substring(0, cand.length) === cand);
|
|
48
|
+
return cands.find((cand) => value.substring(0, cand.length) === cand);
|
|
73
49
|
}
|
|
74
|
-
function determineNonFilingIndicatorValue(field, languages =
|
|
75
|
-
const subfieldA = field.subfields.find(sf => sf.code ===
|
|
50
|
+
function determineNonFilingIndicatorValue(field, languages = void 0) {
|
|
51
|
+
const subfieldA = field.subfields.find((sf) => sf.code === "a");
|
|
76
52
|
if (!subfieldA) {
|
|
77
|
-
// nvdebug(' Subfield $a miss!');
|
|
78
53
|
return;
|
|
79
54
|
}
|
|
80
55
|
const name = subfieldA.value.toLowerCase();
|
|
81
|
-
if (languages.includes(
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
84
|
-
return `${
|
|
56
|
+
if (languages.includes("eng")) {
|
|
57
|
+
const match2 = valueBeginsWithDeterminer(name, ["a ", "an ", "the "]);
|
|
58
|
+
if (match2) {
|
|
59
|
+
return `${match2.length}`;
|
|
85
60
|
}
|
|
86
61
|
}
|
|
87
|
-
if (languages.includes(
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
return `${
|
|
62
|
+
if (languages.includes("fre")) {
|
|
63
|
+
const match2 = valueBeginsWithDeterminer(name, ["l'", "le "]);
|
|
64
|
+
if (match2) {
|
|
65
|
+
return `${match2.length}`;
|
|
91
66
|
}
|
|
92
67
|
}
|
|
93
|
-
if (languages.includes(
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
return `${
|
|
68
|
+
if (languages.includes("ger")) {
|
|
69
|
+
const match2 = valueBeginsWithDeterminer(name, ["das ", "der ", "die "]);
|
|
70
|
+
if (match2) {
|
|
71
|
+
return `${match2.length}`;
|
|
97
72
|
}
|
|
98
73
|
}
|
|
99
|
-
if (languages.includes(
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
return `${
|
|
74
|
+
if (languages.includes("swe")) {
|
|
75
|
+
const match2 = valueBeginsWithDeterminer(name, ["en ", "ett "]);
|
|
76
|
+
if (match2) {
|
|
77
|
+
return `${match2.length}`;
|
|
103
78
|
}
|
|
104
79
|
if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {
|
|
105
|
-
return
|
|
80
|
+
return "4";
|
|
106
81
|
}
|
|
107
82
|
}
|
|
108
|
-
|
|
109
|
-
// Fallback-ish: try to guess even without languages:
|
|
110
|
-
const match = valueBeginsWithDeterminer(name, ['the ']);
|
|
83
|
+
const match = valueBeginsWithDeterminer(name, ["the "]);
|
|
111
84
|
if (match) {
|
|
112
85
|
return `${match.length}`;
|
|
113
86
|
}
|
|
114
|
-
if (name.match(/^a /u) && !languages.includes(
|
|
115
|
-
|
|
116
|
-
return '2';
|
|
87
|
+
if (name.match(/^a /u) && !languages.includes("hun") && !name.match(/^a (?:b |la )/u)) {
|
|
88
|
+
return "2";
|
|
117
89
|
}
|
|
118
|
-
return
|
|
90
|
+
return "0";
|
|
119
91
|
}
|
|
120
92
|
function normalizeNonFilingIndicator1(field, languages = []) {
|
|
121
93
|
if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {
|
|
@@ -129,84 +101,74 @@ function normalizeNonFilingIndicator2(field, languages = []) {
|
|
|
129
101
|
}
|
|
130
102
|
field.ind2 = determineNonFilingIndicatorValue(field, languages);
|
|
131
103
|
}
|
|
132
|
-
const fiktiivisenAineistonLisaluokatFI = [
|
|
104
|
+
const fiktiivisenAineistonLisaluokatFI = ["El\xE4imet", "Erotiikka", "Er\xE4", "Fantasia", "Historia", "Huumori", "J\xE4nnitys", "Kauhu", "Novellit", "Romantiikka", "Scifi", "Sota", "Urheilu", "Uskonto"];
|
|
133
105
|
function containsFiktiivisenAineistonLisaluokka(field) {
|
|
134
|
-
|
|
135
|
-
return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));
|
|
106
|
+
return field.subfields.some((sf) => sf.code === "a" && fiktiivisenAineistonLisaluokatFI.includes(sf.value));
|
|
136
107
|
}
|
|
137
108
|
function normalize084Indicator1(field) {
|
|
138
|
-
if (field.tag !==
|
|
109
|
+
if (field.tag !== "084") {
|
|
139
110
|
return;
|
|
140
111
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {
|
|
144
|
-
field.ind1 = '9';
|
|
112
|
+
if (field.ind1 !== "9" && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some((sf) => sf.code === "2" && sf.value === "ykl")) {
|
|
113
|
+
field.ind1 = "9";
|
|
145
114
|
return;
|
|
146
115
|
}
|
|
147
116
|
}
|
|
148
117
|
function normalize245Indicator1(field, record) {
|
|
149
|
-
if (field.tag !==
|
|
118
|
+
if (field.tag !== "245") {
|
|
150
119
|
return;
|
|
151
120
|
}
|
|
152
|
-
const field1XX = record.get(
|
|
153
|
-
field.ind1 = field1XX.length === 0 ?
|
|
121
|
+
const field1XX = record.get("^1..$");
|
|
122
|
+
field.ind1 = field1XX.length === 0 ? "0" : "1";
|
|
154
123
|
}
|
|
155
124
|
function normalize776Indicator2(field) {
|
|
156
|
-
if (field.tag !==
|
|
125
|
+
if (field.tag !== "776") {
|
|
157
126
|
return;
|
|
158
127
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
field.ind2 = '8';
|
|
128
|
+
if (field.subfields.some((sf) => sf.code === "i")) {
|
|
129
|
+
field.ind2 = "8";
|
|
162
130
|
return;
|
|
163
131
|
}
|
|
164
132
|
}
|
|
165
133
|
function recordNormalize490(record) {
|
|
166
|
-
const fields490 = record.get(
|
|
167
|
-
const fields8XX = record.get(
|
|
134
|
+
const fields490 = record.get("^490$");
|
|
135
|
+
const fields8XX = record.get("^(?:800|810|811|830)$");
|
|
168
136
|
if (fields490.length === 0) {
|
|
169
137
|
return;
|
|
170
138
|
}
|
|
171
139
|
if (fields490.length <= fields8XX.length) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
f.ind1 = '1';
|
|
140
|
+
fields490.forEach((f) => {
|
|
141
|
+
f.ind1 = "1";
|
|
175
142
|
});
|
|
176
143
|
return;
|
|
177
144
|
}
|
|
178
145
|
if (fields8XX.length === 0) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
f.ind1 = '0';
|
|
146
|
+
fields490.forEach((f) => {
|
|
147
|
+
f.ind1 = "0";
|
|
182
148
|
});
|
|
183
149
|
return;
|
|
184
150
|
}
|
|
185
|
-
// For other combinations we just can't be sure, so leave them as they are.
|
|
186
151
|
}
|
|
187
152
|
function getLanguages(record) {
|
|
188
|
-
const langFields = record.get(
|
|
153
|
+
const langFields = record.get("^041$");
|
|
189
154
|
if (langFields.length === 0) {
|
|
190
155
|
return [];
|
|
191
156
|
}
|
|
192
|
-
return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);
|
|
157
|
+
return langFields[0].subfields.filter((sf) => isRelevantSubfield(sf)).map((subfield) => subfield.value);
|
|
193
158
|
function isRelevantSubfield(subfield) {
|
|
194
|
-
if (![
|
|
159
|
+
if (!["a", "d", "h"].includes(subfield.code)) {
|
|
195
160
|
return false;
|
|
196
161
|
}
|
|
197
162
|
if (subfield.value.length !== 3) {
|
|
198
163
|
return false;
|
|
199
164
|
}
|
|
200
|
-
// We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.
|
|
201
165
|
return true;
|
|
202
166
|
}
|
|
203
167
|
}
|
|
204
|
-
function recordNormalizeIndicators(record) {
|
|
168
|
+
export function recordNormalizeIndicators(record) {
|
|
205
169
|
recordNormalize490(record);
|
|
206
|
-
|
|
207
|
-
// Language is used to handle non-filing indicators
|
|
208
170
|
const languages = getLanguages(record);
|
|
209
|
-
record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));
|
|
171
|
+
record.fields.forEach((field) => fieldNormalizeIndicators(field, record, languages));
|
|
210
172
|
}
|
|
211
173
|
function fieldNormalizeIndicators(field, record, languages) {
|
|
212
174
|
normalize084Indicator1(field);
|
|
@@ -215,4 +177,4 @@ function fieldNormalizeIndicators(field, record, languages) {
|
|
|
215
177
|
normalizeNonFilingIndicator2(field, languages);
|
|
216
178
|
normalize776Indicator2(field);
|
|
217
179
|
}
|
|
218
|
-
//# sourceMappingURL=indicator-fixes.js.map
|
|
180
|
+
//# sourceMappingURL=indicator-fixes.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"file":"indicator-fixes.js","names":["_utils","require","_default","description","validate","fix","record","res","message","valid","recordNormalizeIndicators","validateRecord","length","clonedFields","JSON","parse","stringify","fields","forEach","field","index","compareFields","origFieldAsString","fieldToString","ind1","push","ind2","ind1NonFilingChars","ind2NonFilingChars","hasNonFilingIndicator1","includes","tag","modifiableIndicatorValue","value","hasNonFilingIndicator2","valueBeginsWithDeterminer","cands","find","cand","substring","determineNonFilingIndicatorValue","languages","undefined","subfieldA","subfields","sf","code","name","toLowerCase","match","normalizeNonFilingIndicator1","normalizeNonFilingIndicator2","fiktiivisenAineistonLisaluokatFI","containsFiktiivisenAineistonLisaluokka","some","normalize084Indicator1","normalize245Indicator1","field1XX","get","normalize776Indicator2","recordNormalize490","fields490","fields8XX","f","getLanguages","langFields","filter","isRelevantSubfield","map","subfield","fieldNormalizeIndicators"],"sources":["../src/indicator-fixes.js"],"sourcesContent":["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\nimport {fieldToString} from './utils';\n\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n //nvdebug(record);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index)); // eslint-disable-line array-callback-return\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!');\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['Eläimet', 'Erotiikka', 'Erä', 'Fantasia', 'Historia', 'Huumori', 'Jännitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nexport function recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages)); // eslint-disable-line array-callback-return\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/indicator-fixes.js"],
|
|
4
|
+
"sourcesContent": ["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\nimport {fieldToString} from './utils.js';\n\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n //nvdebug(record);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index));\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!');\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['El\u00E4imet', 'Erotiikka', 'Er\u00E4', 'Fantasia', 'Historia', 'Huumori', 'J\u00E4nnitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nexport function recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["match"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { MarcRecord } from "@natlibfi/marc-record";
|
|
3
|
+
import validatorFactory from "./indicator-fixes.js";
|
|
4
|
+
import { READERS } from "@natlibfi/fixura";
|
|
5
|
+
import generateTests from "@natlibfi/fixugen";
|
|
6
|
+
import createDebugLogger from "debug";
|
|
7
|
+
generateTests({
|
|
8
|
+
callback,
|
|
9
|
+
path: [import.meta.dirname, "..", "test-fixtures", "indicator-fixes"],
|
|
10
|
+
useMetadataFile: true,
|
|
11
|
+
recurse: false,
|
|
12
|
+
fixura: {
|
|
13
|
+
reader: READERS.JSON
|
|
14
|
+
},
|
|
15
|
+
hooks: {
|
|
16
|
+
before: () => testValidatorFactory()
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda/indicator-fixes:test");
|
|
20
|
+
async function testValidatorFactory() {
|
|
21
|
+
const validator = await validatorFactory();
|
|
22
|
+
assert.equal(typeof validator, "object");
|
|
23
|
+
assert.equal(typeof validator.description, "string");
|
|
24
|
+
assert.equal(typeof validator.validate, "function");
|
|
25
|
+
}
|
|
26
|
+
async function callback({ getFixture, enabled = true, fix = false }) {
|
|
27
|
+
if (enabled === false) {
|
|
28
|
+
debug("TEST SKIPPED!");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const validator = await validatorFactory();
|
|
32
|
+
const record = new MarcRecord(getFixture("record.json"));
|
|
33
|
+
const expectedResult = getFixture("expectedResult.json");
|
|
34
|
+
if (!fix) {
|
|
35
|
+
const result = await validator.validate(record);
|
|
36
|
+
assert.deepEqual(result, expectedResult);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await validator.fix(record);
|
|
40
|
+
assert.deepEqual(record, expectedResult);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=indicator-fixes.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/indicator-fixes.test.js"],
|
|
4
|
+
"sourcesContent": ["import assert from 'node:assert';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './indicator-fixes.js';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [import.meta.dirname, '..', 'test-fixtures', 'indicator-fixes'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n hooks: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/indicator-fixes:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n assert.equal(typeof validator, 'object');\n assert.equal(typeof validator.description, 'string');\n assert.equal(typeof validator.validate, 'function');\n}\n\nasync function callback({getFixture, enabled = true, fix = false}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n assert.deepEqual(result, expectedResult);\n return;\n }\n\n await validator.fix(record);\n assert.deepEqual(record, expectedResult);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,YAAY;AACnB,SAAQ,kBAAiB;AACzB,OAAO,sBAAsB;AAC7B,SAAQ,eAAc;AACtB,OAAO,mBAAmB;AAC1B,OAAO,uBAAuB;AAE9B,cAAc;AAAA,EACZ;AAAA,EACA,MAAM,CAAC,YAAY,SAAS,MAAM,iBAAiB,iBAAiB;AAAA,EACpE,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,MAAM,qBAAqB;AAAA,EACrC;AACF,CAAC;AACD,MAAM,QAAQ,kBAAkB,+DAA+D;AAE/F,eAAe,uBAAuB;AACpC,QAAM,YAAY,MAAM,iBAAiB;AAEzC,SAAO,MAAM,OAAO,WAAW,QAAQ;AACvC,SAAO,MAAM,OAAO,UAAU,aAAa,QAAQ;AACnD,SAAO,MAAM,OAAO,UAAU,UAAU,UAAU;AACpD;AAEA,eAAe,SAAS,EAAC,YAAY,UAAU,MAAM,MAAM,MAAK,GAAG;AACjE,MAAI,YAAY,OAAO;AACrB,UAAM,eAAe;AACrB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,SAAS,IAAI,WAAW,WAAW,aAAa,CAAC;AACvD,QAAM,iBAAiB,WAAW,qBAAqB;AAGvD,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAC9C,WAAO,UAAU,QAAQ,cAAc;AACvC;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,MAAM;AAC1B,SAAO,UAAU,QAAQ,cAAc;AACzC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|