@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-alpha.12
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 → melinda-node-tests-and-publish.yml} +37 -12
- 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 +43 -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 +873 -769
- package/dist/ending-punctuation-conf.js.map +7 -1
- package/dist/ending-punctuation.js +156 -169
- package/dist/ending-punctuation.js.map +7 -1
- package/dist/ending-punctuation.test.js +2385 -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 +182 -413
- package/dist/index.js.map +7 -1
- package/dist/indicator-fixes.js +66 -94
- 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 +71 -128
- 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 +187 -379
- package/dist/merge-fields/counterpartField.js.map +7 -1
- package/dist/merge-fields/dataProvenance.js +29 -0
- package/dist/merge-fields/dataProvenance.js.map +7 -0
- package/dist/merge-fields/index.js +25 -50
- 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 +46 -0
- package/dist/merge-fields.test.js.map +7 -0
- package/dist/mergeField500Lisapainokset.js +27 -56
- 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 +91 -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 +259 -802
- 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 +104 -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 +32 -63
- 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 +54 -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 +78 -126
- package/dist/utils.js.map +7 -1
- package/eslint.config.mjs +1 -2
- package/package.json +28 -101
- 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.spec.js → cyrillux-usemarcon-replacement.test.js} +17 -14
- 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-conf.js +6 -5
- package/src/ending-punctuation.js +115 -24
- package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +357 -275
- 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/index.js +132 -59
- package/src/indicator-fixes.js +17 -4
- package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
- package/src/isbn-issn.js +12 -7
- 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/melindaCustomMergeFields.js +1 -1
- package/src/merge-fields/controlSubfields.js +1 -1
- package/src/merge-fields/counterpartField.js +14 -9
- package/src/merge-fields/dataProvenance.js +41 -0
- package/src/merge-fields/index.js +12 -3
- package/src/merge-fields/mergableIndicator.js +1 -1
- package/src/merge-fields/mergeField.js +8 -8
- 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} +18 -15
- package/src/mergeField500Lisapainokset.js +1 -1
- 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 +32 -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 +17 -8
- 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 +15 -12
- 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 +6 -6
- 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 +8 -6
- 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.test.js +75 -0
- 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 +21 -5
- 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/indicator-fixes/10/expectedResult.json +11 -0
- package/test-fixtures/indicator-fixes/10/metadata.json +4 -0
- package/test-fixtures/indicator-fixes/10/record.json +11 -0
- package/test-fixtures/merge-fields/f05/expectedResult.json +24 -0
- package/test-fixtures/merge-fields/f05/metadata.json +6 -0
- package/test-fixtures/merge-fields/f05/record.json +30 -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/remove-inferior-datafields/f16/expectedResult.json +12 -0
- package/test-fixtures/remove-inferior-datafields/f16/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f16/record.json +14 -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/test-fixtures/translate-terms-data.js +42 -0
- 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/melindaCustomMergeFields.json +0 -5120
- package/src/translate-terms.spec.js +0 -52
|
@@ -1,135 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var _marcRecord = require("@natlibfi/marc-record");
|
|
8
|
-
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
var _utils = require("../utils.js");
|
|
10
|
-
var _normalizeIdentifiers = require("../normalize-identifiers");
|
|
11
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
-
//import {normalizeControlSubfieldValue} from './normalizeIdentifier';
|
|
13
|
-
|
|
14
|
-
const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda:merge-fields:controlSubfields');
|
|
15
|
-
//const debugData = debug.extend('data');
|
|
16
|
-
const debugDev = debug.extend('dev');
|
|
1
|
+
import { MarcRecord } from "@natlibfi/marc-record";
|
|
2
|
+
import createDebugLogger from "debug";
|
|
3
|
+
import { fieldHasSubfield, fieldToString, nvdebug, nvdebugSubfieldArray, subfieldIsRepeatable, subfieldsAreIdentical } from "../utils.js";
|
|
4
|
+
import { normalizeControlSubfieldValue } from "../normalize-identifiers.js";
|
|
5
|
+
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:merge-fields:controlSubfields");
|
|
6
|
+
const debugDev = debug.extend("dev");
|
|
17
7
|
function subfieldsAreEqual(field1, field2, subfieldCode) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!(0, _utils.fieldHasSubfield)(field1, subfieldCode)) {
|
|
21
|
-
return !(0, _utils.fieldHasSubfield)(field2, subfieldCode);
|
|
8
|
+
if (!fieldHasSubfield(field1, subfieldCode)) {
|
|
9
|
+
return !fieldHasSubfield(field2, subfieldCode);
|
|
22
10
|
}
|
|
23
|
-
if (!
|
|
11
|
+
if (!fieldHasSubfield(field2, subfieldCode)) {
|
|
24
12
|
return false;
|
|
25
13
|
}
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
return _marcRecord.MarcRecord.isEqual(sfSet1, sfSet2);
|
|
14
|
+
const sfSet1 = field1.subfields.filter((subfield) => subfield.code === subfieldCode);
|
|
15
|
+
const sfSet2 = field2.subfields.filter((subfield) => subfield.code === subfieldCode);
|
|
16
|
+
return MarcRecord.isEqual(sfSet1, sfSet2);
|
|
30
17
|
}
|
|
31
18
|
function subfieldsAreEmpty(field1, field2, subfieldCode) {
|
|
32
|
-
if (!
|
|
19
|
+
if (!fieldHasSubfield(field1, subfieldCode) && !fieldHasSubfield(field2, subfieldCode)) {
|
|
33
20
|
return true;
|
|
34
21
|
}
|
|
35
22
|
return false;
|
|
36
23
|
}
|
|
37
24
|
function sixlessIsSubset(fieldWith6, fieldWithout6) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// NB! We could use punctuation-stripping here.
|
|
41
|
-
const subset = fieldWithout6.subfields.filter(subfield => !['0', '1'].includes(subfield.code));
|
|
42
|
-
return subset.every(sf => fieldWith6.subfields.some(sf2 => (0, _utils.subfieldsAreIdentical)(sf, sf2)));
|
|
43
|
-
//return MarcRecord.isEqual(strippedField1, strippedField2);
|
|
25
|
+
const subset = fieldWithout6.subfields.filter((subfield) => !["0", "1"].includes(subfield.code));
|
|
26
|
+
return subset.every((sf) => fieldWith6.subfields.some((sf2) => subfieldsAreIdentical(sf, sf2)));
|
|
44
27
|
}
|
|
45
28
|
function controlSubfield6PermitsMerge(field1, field2) {
|
|
46
|
-
if (subfieldsAreEmpty(field1, field2,
|
|
29
|
+
if (subfieldsAreEmpty(field1, field2, "6")) {
|
|
47
30
|
return true;
|
|
48
31
|
}
|
|
49
|
-
|
|
50
|
-
// Handle cases where one has a $6 and the other has not:
|
|
51
|
-
// Should this accept $0 (FI-ASTERI-N) vs none?
|
|
52
|
-
if (!(0, _utils.fieldHasSubfield)(field1, '6') && (0, _utils.fieldHasSubfield)(field2, '6') && sixlessIsSubset(field2, field1)) {
|
|
32
|
+
if (!fieldHasSubfield(field1, "6") && fieldHasSubfield(field2, "6") && sixlessIsSubset(field2, field1)) {
|
|
53
33
|
return true;
|
|
54
34
|
}
|
|
55
|
-
if (!
|
|
35
|
+
if (!fieldHasSubfield(field2, "6") && fieldHasSubfield(field1, "6") && sixlessIsSubset(field1, field2)) {
|
|
56
36
|
return true;
|
|
57
37
|
}
|
|
58
|
-
|
|
59
|
-
// There are at least two (plus) fields involved (Field XXX (one) and field 880 (one plus).
|
|
60
|
-
// Thus this generic solution can't handle them. Postprocess step removes some chains instead!
|
|
61
38
|
debugDev(` controlSubfield6PermitsMerge() fails always on generic part (feature).`);
|
|
62
39
|
return false;
|
|
63
40
|
}
|
|
64
41
|
function controlSubfield5PermitsMerge(field1, field2) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return true; // If neither one has $5, it's ok to merge
|
|
42
|
+
if (!fieldHasSubfield(field1, "5")) {
|
|
43
|
+
if (!fieldHasSubfield(field2, "5")) {
|
|
44
|
+
return true;
|
|
69
45
|
}
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
if (fives1.every(sf1 => fives2.some(sf2 => sf1.value === sf2.value)) && fives2.every(sf2 => fives1.some(sf1 => sf1.value === sf2.value))) {
|
|
46
|
+
const fives1 = field1.subfields.filter((sf) => sf.code === "5");
|
|
47
|
+
const fives2 = field2.subfields.filter((sf) => sf.code === "5");
|
|
48
|
+
if (fives1.every((sf1) => fives2.some((sf2) => sf1.value === sf2.value)) && fives2.every((sf2) => fives1.some((sf1) => sf1.value === sf2.value))) {
|
|
74
49
|
return true;
|
|
75
50
|
}
|
|
76
51
|
return false;
|
|
77
52
|
}
|
|
78
|
-
if (!
|
|
53
|
+
if (!fieldHasSubfield(field2, "5")) {
|
|
79
54
|
return false;
|
|
80
55
|
}
|
|
81
56
|
return true;
|
|
82
57
|
}
|
|
83
58
|
function controlSubfield9PermitsMerge(baseField, sourceField) {
|
|
84
|
-
const baseFieldSubfields9 = baseField.subfields.filter(sf => sf.code ===
|
|
85
|
-
const sourceFieldSubfields9 = sourceField.subfields.filter(sf => sf.code ===
|
|
86
|
-
|
|
87
|
-
//nvdebug('CHECK $9', debugDev);
|
|
88
|
-
// There are no $9s. Skip:
|
|
59
|
+
const baseFieldSubfields9 = baseField.subfields.filter((sf) => sf.code === "9");
|
|
60
|
+
const sourceFieldSubfields9 = sourceField.subfields.filter((sf) => sf.code === "9");
|
|
89
61
|
if (baseFieldSubfields9.length === 0 && sourceFieldSubfields9.length === 0) {
|
|
90
|
-
//nvdebug(` No subfield $9 detected`, debugDev);
|
|
91
62
|
return true;
|
|
92
63
|
}
|
|
93
64
|
if (keepOrDropPreventsMerge()) {
|
|
94
|
-
|
|
65
|
+
nvdebug(` Subfield $9 KEEPs and DROPs disallow merge`, debugDev);
|
|
95
66
|
return false;
|
|
96
67
|
}
|
|
97
68
|
if (transPreventsMerge()) {
|
|
98
|
-
|
|
69
|
+
nvdebug(` Subfield $9 <TRANS> mismatch disallows merge`, debugDev);
|
|
99
70
|
return false;
|
|
100
71
|
}
|
|
101
|
-
|
|
102
|
-
//nvdebug('CHECK $9 OK', debugDev);
|
|
103
|
-
|
|
104
72
|
return true;
|
|
105
73
|
function subfieldHasKeepOrDrop(subfield) {
|
|
106
|
-
|
|
107
|
-
return subfield.code === '9' && /(?:<KEEP>|<DROP>)/u.test(subfield.value);
|
|
74
|
+
return subfield.code === "9" && /(?:<KEEP>|<DROP>)/u.test(subfield.value);
|
|
108
75
|
}
|
|
109
76
|
function subfieldHasTrans(subfield) {
|
|
110
|
-
return subfield.code ===
|
|
77
|
+
return subfield.code === "9" && /<TRANS>/u.test(subfield.value);
|
|
111
78
|
}
|
|
112
79
|
function transPreventsMerge() {
|
|
113
|
-
const trans1 = baseFieldSubfields9.filter(sf => subfieldHasTrans(sf));
|
|
114
|
-
const trans2 = sourceFieldSubfields9.filter(sf => subfieldHasTrans(sf));
|
|
80
|
+
const trans1 = baseFieldSubfields9.filter((sf) => subfieldHasTrans(sf));
|
|
81
|
+
const trans2 = sourceFieldSubfields9.filter((sf) => subfieldHasTrans(sf));
|
|
115
82
|
if (trans1.length > 0 && trans2.length > 0) {
|
|
116
|
-
if (!
|
|
83
|
+
if (!MarcRecord.isEqual(trans1, trans2)) {
|
|
117
84
|
return true;
|
|
118
85
|
}
|
|
119
86
|
}
|
|
120
87
|
return false;
|
|
121
88
|
}
|
|
122
89
|
function retainSubfieldForKeepComparison(subfield) {
|
|
123
|
-
// Don't compare <KEEP>, <DROP> nor <TRANS> here (<TRANS> has it's own check)
|
|
124
90
|
if (subfieldHasKeepOrDrop(subfield) || subfieldHasTrans(subfield)) {
|
|
125
91
|
return false;
|
|
126
92
|
}
|
|
127
|
-
if ([
|
|
93
|
+
if (["0", "1"].includes(subfield.code)) {
|
|
128
94
|
return false;
|
|
129
95
|
}
|
|
130
|
-
if ([
|
|
131
|
-
|
|
132
|
-
if (['d'].includes(subfield.code)) {
|
|
96
|
+
if (["100", "600", "700", "800"].includes(baseField.tag)) {
|
|
97
|
+
if (["d"].includes(subfield.code)) {
|
|
133
98
|
return false;
|
|
134
99
|
}
|
|
135
100
|
}
|
|
@@ -139,96 +104,75 @@ function controlSubfield9PermitsMerge(baseField, sourceField) {
|
|
|
139
104
|
if (sourceSubfield.code !== subfieldCode) {
|
|
140
105
|
return false;
|
|
141
106
|
}
|
|
142
|
-
|
|
143
|
-
// If value is different, pairing will fail when comparing the subfield itself.
|
|
144
|
-
// This allows us to tolerate little differences in punctuation: different punctuation does not get copied to base,
|
|
145
|
-
// so they don't alter base and and thus redundant when comparing.
|
|
146
|
-
if (!(0, _utils.subfieldIsRepeatable)(tag, subfieldCode)) {
|
|
107
|
+
if (!subfieldIsRepeatable(tag, subfieldCode)) {
|
|
147
108
|
return true;
|
|
148
109
|
}
|
|
149
110
|
return sourceSubfield.value === subfieldValue;
|
|
150
111
|
}
|
|
151
112
|
function keepOrDropPreventsMerge() {
|
|
152
|
-
const keepOrDrop1 = baseFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));
|
|
153
|
-
const keepOrDrop2 = sourceFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));
|
|
113
|
+
const keepOrDrop1 = baseFieldSubfields9.filter((sf) => subfieldHasKeepOrDrop(sf));
|
|
114
|
+
const keepOrDrop2 = sourceFieldSubfields9.filter((sf) => subfieldHasKeepOrDrop(sf));
|
|
154
115
|
if (keepOrDrop1.length === 0 && keepOrDrop2.length === 0) {
|
|
155
116
|
return false;
|
|
156
117
|
}
|
|
157
|
-
if (baseField.tag.charAt(0) ===
|
|
118
|
+
if (baseField.tag.charAt(0) === "1" && !keepOrDrop2.some((sf) => /<DROP>/u.test(sf.value))) {
|
|
158
119
|
return false;
|
|
159
120
|
}
|
|
160
|
-
const sf9lessField1 = baseField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));
|
|
161
|
-
const sf9lessField2 = sourceField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// Keepless field can be a subset field with <KEEP>/<DROP>! Note that punctuation still causes remnants to fail.
|
|
121
|
+
const sf9lessField1 = baseField.subfields.filter((subfield) => retainSubfieldForKeepComparison(subfield));
|
|
122
|
+
const sf9lessField2 = sourceField.subfields.filter((subfield) => retainSubfieldForKeepComparison(subfield));
|
|
123
|
+
nvdebugSubfieldArray(baseField.subfields, "FIELD ", debugDev);
|
|
124
|
+
nvdebugSubfieldArray(sf9lessField1, "FILTER ", debugDev);
|
|
125
|
+
nvdebugSubfieldArray(sourceField.subfields, "FIELD2 ", debugDev);
|
|
126
|
+
nvdebugSubfieldArray(sf9lessField2, "FILTER2 ", debugDev);
|
|
168
127
|
if (keepOrDrop1.length === 0) {
|
|
169
|
-
return !sf9lessField1.every(sf => sf9lessField2.some(sf2 =>
|
|
128
|
+
return !sf9lessField1.every((sf) => sf9lessField2.some((sf2) => subfieldsAreIdentical(sf, sf2)));
|
|
170
129
|
}
|
|
171
|
-
// However, to alleviate the above-mentioned punctuation problem, we can check keep/drop-less *source* subfields
|
|
172
130
|
if (keepOrDrop2.length === 0) {
|
|
173
|
-
const unhandledSubfield = sf9lessField2.find(sf2 => !sf9lessField1.some(sf => acceptKeeplessSourceSubfield(sf2, baseField.tag, sf.code, sf.value)));
|
|
131
|
+
const unhandledSubfield = sf9lessField2.find((sf2) => !sf9lessField1.some((sf) => acceptKeeplessSourceSubfield(sf2, baseField.tag, sf.code, sf.value)));
|
|
174
132
|
if (unhandledSubfield) {
|
|
175
|
-
//nvdebug(`Failed to pair ${subfieldToString(unhandledSubfield)}`, debugDev);
|
|
176
133
|
return true;
|
|
177
134
|
}
|
|
178
|
-
//return !sf9lessField2.every(sf2 => sf9lessField1.some(sf => subfieldsAreIdentical(sf, sf2)));
|
|
179
135
|
return false;
|
|
180
136
|
}
|
|
181
|
-
|
|
182
|
-
//nvdebugSubfieldArray(sf9lessField2, 'SOURCE(?)', debugDev);
|
|
183
|
-
//nvdebugSubfieldArray(sf9lessField1, 'BASE(?) ', debugDev);
|
|
184
|
-
|
|
185
|
-
// $9 <KEEP> or <DROP> detected on both fields.
|
|
186
|
-
// Non-keeps and non-drops must be equal, otherwise fail:
|
|
187
|
-
if (_marcRecord.MarcRecord.isEqual(sf9lessField1, sf9lessField2)) {
|
|
137
|
+
if (MarcRecord.isEqual(sf9lessField1, sf9lessField2)) {
|
|
188
138
|
return false;
|
|
189
139
|
}
|
|
190
|
-
// Prevent:
|
|
191
140
|
return true;
|
|
192
141
|
}
|
|
193
142
|
}
|
|
194
143
|
function getPrefix(value) {
|
|
195
|
-
const normalizedValue =
|
|
144
|
+
const normalizedValue = normalizeControlSubfieldValue(value);
|
|
196
145
|
if (normalizedValue.match(/^\([^)]+\)[0-9]+$/u)) {
|
|
197
|
-
return normalizedValue.substr(0, normalizedValue.indexOf(
|
|
146
|
+
return normalizedValue.substr(0, normalizedValue.indexOf(")") + 1);
|
|
198
147
|
}
|
|
199
148
|
if (value.match(/^https?:\/\//u)) {
|
|
200
|
-
return normalizedValue.substr(0, normalizedValue.lastIndexOf(
|
|
149
|
+
return normalizedValue.substr(0, normalizedValue.lastIndexOf("/") + 1);
|
|
201
150
|
}
|
|
202
|
-
return
|
|
151
|
+
return "";
|
|
203
152
|
}
|
|
204
153
|
function isMatchAfterNormalization(currSubfield, otherField) {
|
|
205
|
-
|
|
206
|
-
const normalizedCurrSubfieldValue = (0, _normalizeIdentifiers.normalizeControlSubfieldValue)(currSubfield.value);
|
|
154
|
+
const normalizedCurrSubfieldValue = normalizeControlSubfieldValue(currSubfield.value);
|
|
207
155
|
const prefix = getPrefix(normalizedCurrSubfieldValue);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// Look for same prefix + different identifier
|
|
211
|
-
const hits = otherField.subfields.filter(sf2 => sf2.code === currSubfield.code && (0, _normalizeIdentifiers.normalizeControlSubfieldValue)(sf2.value).indexOf(prefix) === 0);
|
|
212
|
-
if (hits.length === 0 ||
|
|
213
|
-
// <-- Nothing found, so it can't be a mismatch
|
|
156
|
+
const hits = otherField.subfields.filter((sf2) => sf2.code === currSubfield.code && normalizeControlSubfieldValue(sf2.value).indexOf(prefix) === 0);
|
|
157
|
+
if (hits.length === 0 || // <-- Nothing found, so it can't be a mismatch
|
|
214
158
|
// Every opposing subfields match:
|
|
215
|
-
hits.every(sf2 => normalizedCurrSubfieldValue ===
|
|
216
|
-
debugDev(`Subfield
|
|
159
|
+
hits.every((sf2) => normalizedCurrSubfieldValue === normalizeControlSubfieldValue(sf2.value))) {
|
|
160
|
+
debugDev(`Subfield \u2021${currSubfield.code} check OK: No opposing ${prefix} prefixes found.`);
|
|
217
161
|
return true;
|
|
218
162
|
}
|
|
219
|
-
debugDev(`Subfield
|
|
163
|
+
debugDev(`Subfield \u2021${currSubfield.code} check FAILED: \u2021${currSubfield.code} '${currSubfield.value}' vs \u2021${currSubfield.code} '${hits[0].value}'.`);
|
|
220
164
|
return false;
|
|
221
165
|
}
|
|
222
166
|
function controlSubfieldContainingIdentifierPermitsMerge(field1, field2, subfieldCode) {
|
|
223
|
-
if (!
|
|
167
|
+
if (!fieldHasSubfield(field1, subfieldCode, null) || !fieldHasSubfield(field2, subfieldCode, null)) {
|
|
224
168
|
return true;
|
|
225
169
|
}
|
|
226
|
-
const result = field1.subfields.every(subfield => {
|
|
170
|
+
const result = field1.subfields.every((subfield) => {
|
|
227
171
|
if (subfield.code !== subfieldCode) {
|
|
228
172
|
return true;
|
|
229
173
|
}
|
|
230
|
-
debugDev(`Compare
|
|
231
|
-
if (
|
|
174
|
+
debugDev(`Compare \u2021${subfieldCode} '${subfield.value}' with '${fieldToString(field2)}'.`);
|
|
175
|
+
if (fieldHasSubfield(field2, field1.code, field1.value)) {
|
|
232
176
|
return true;
|
|
233
177
|
}
|
|
234
178
|
return isMatchAfterNormalization(subfield, field2, subfieldCode);
|
|
@@ -239,40 +183,29 @@ function controlSubfieldContainingIdentifierPermitsMerge(field1, field2, subfiel
|
|
|
239
183
|
}
|
|
240
184
|
return true;
|
|
241
185
|
}
|
|
242
|
-
const controlSubfieldsContainingIdentifier = [
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// Check $w, $0, $1, $2 (which isn't an identifier per se, but the sama logic can be applied)
|
|
246
|
-
if (!controlSubfieldsContainingIdentifier.every(subfieldCode => controlSubfieldContainingIdentifierPermitsMerge(baseField, sourceField, subfieldCode))) {
|
|
247
|
-
//debug(' control subfields with identifiers failed');
|
|
186
|
+
const controlSubfieldsContainingIdentifier = ["w", "0", "1", "2"];
|
|
187
|
+
export function controlSubfieldsPermitMerge(baseField, sourceField) {
|
|
188
|
+
if (!controlSubfieldsContainingIdentifier.every((subfieldCode) => controlSubfieldContainingIdentifierPermitsMerge(baseField, sourceField, subfieldCode))) {
|
|
248
189
|
return false;
|
|
249
190
|
}
|
|
250
|
-
if (!subfieldsAreEqual(baseField, sourceField,
|
|
251
|
-
//debug(' similar control subfield fails');
|
|
191
|
+
if (!subfieldsAreEqual(baseField, sourceField, "3")) {
|
|
252
192
|
return false;
|
|
253
193
|
}
|
|
254
194
|
if (!controlSubfield5PermitsMerge(baseField, sourceField) || !controlSubfield6PermitsMerge(baseField, sourceField) || !controlSubfield9PermitsMerge(baseField, sourceField)) {
|
|
255
195
|
return false;
|
|
256
196
|
}
|
|
257
|
-
|
|
258
|
-
// 38211 |8 3\u |a kuoro |2 seko
|
|
259
|
-
// 38211 |8 6\u |a kuoro |2 seko |9 VIOLA<DROP>
|
|
260
|
-
// Thus only copy works with $8...
|
|
261
|
-
if (!subfieldsAreEmpty(baseField, sourceField, '8')) {
|
|
262
|
-
// We could alleviate this a bit esp. for non-repeatable fields.
|
|
263
|
-
// At least, if the source has '8' and otherwise the two fields are identical...
|
|
197
|
+
if (!subfieldsAreEmpty(baseField, sourceField, "8")) {
|
|
264
198
|
const subsetOfSourceField = {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
subfields: sourceField.subfields.filter(sf => sf.code !==
|
|
199
|
+
"tag": sourceField.tag,
|
|
200
|
+
"ind1": sourceField.ind1,
|
|
201
|
+
"ind2": sourceField.ind2,
|
|
202
|
+
subfields: sourceField.subfields.filter((sf) => sf.code !== "8")
|
|
269
203
|
};
|
|
270
|
-
if (
|
|
204
|
+
if (fieldToString(baseField) === fieldToString(subsetOfSourceField)) {
|
|
271
205
|
return true;
|
|
272
206
|
}
|
|
273
|
-
//debug(' csf8 failed');
|
|
274
207
|
return false;
|
|
275
208
|
}
|
|
276
209
|
return true;
|
|
277
210
|
}
|
|
278
|
-
//# sourceMappingURL=controlSubfields.js.map
|
|
211
|
+
//# sourceMappingURL=controlSubfields.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"file":"controlSubfields.js","names":["_marcRecord","require","_debug","_interopRequireDefault","_utils","_normalizeIdentifiers","e","__esModule","default","debug","createDebugLogger","debugDev","extend","subfieldsAreEqual","field1","field2","subfieldCode","fieldHasSubfield","sfSet1","subfields","filter","subfield","code","sfSet2","MarcRecord","isEqual","subfieldsAreEmpty","sixlessIsSubset","fieldWith6","fieldWithout6","subset","includes","every","sf","some","sf2","subfieldsAreIdentical","controlSubfield6PermitsMerge","controlSubfield5PermitsMerge","fives1","fives2","sf1","value","controlSubfield9PermitsMerge","baseField","sourceField","baseFieldSubfields9","sourceFieldSubfields9","length","keepOrDropPreventsMerge","nvdebug","transPreventsMerge","subfieldHasKeepOrDrop","test","subfieldHasTrans","trans1","trans2","retainSubfieldForKeepComparison","tag","acceptKeeplessSourceSubfield","sourceSubfield","subfieldValue","subfieldIsRepeatable","keepOrDrop1","keepOrDrop2","charAt","sf9lessField1","sf9lessField2","nvdebugSubfieldArray","unhandledSubfield","find","getPrefix","normalizedValue","normalizeControlSubfieldValue","match","substr","indexOf","lastIndexOf","isMatchAfterNormalization","currSubfield","otherField","normalizedCurrSubfieldValue","prefix","hits","controlSubfieldContainingIdentifierPermitsMerge","result","fieldToString","controlSubfieldsContainingIdentifier","controlSubfieldsPermitMerge","subsetOfSourceField","ind1","ind2"],"sources":["../../src/merge-fields/controlSubfields.js"],"sourcesContent":["import {MarcRecord} from '@natlibfi/marc-record';\nimport createDebugLogger from 'debug';\nimport {fieldHasSubfield, fieldToString, nvdebug, nvdebugSubfieldArray, subfieldIsRepeatable, subfieldsAreIdentical} from '../utils.js';\n\n//import {normalizeControlSubfieldValue} from './normalizeIdentifier';\nimport {normalizeControlSubfieldValue} from '../normalize-identifiers';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:controlSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction subfieldsAreEqual(field1, field2, subfieldCode) {\n // Check OK if neither one has given subfield.\n // Check fails if one field has given subfield and the other one does not\n if (!fieldHasSubfield(field1, subfieldCode)) {\n return !fieldHasSubfield(field2, subfieldCode);\n }\n if (!fieldHasSubfield(field2, subfieldCode)) {\n return false;\n }\n // Compare $3 subfields. If everything matches, OK, else FAIL:\n const sfSet1 = field1.subfields.filter(subfield => subfield.code === subfieldCode);\n const sfSet2 = field2.subfields.filter(subfield => subfield.code === subfieldCode);\n return MarcRecord.isEqual(sfSet1, sfSet2);\n}\n\nfunction subfieldsAreEmpty(field1, field2, subfieldCode) {\n if (!fieldHasSubfield(field1, subfieldCode) && !fieldHasSubfield(field2, subfieldCode)) {\n return true;\n }\n return false;\n}\n\n\nfunction sixlessIsSubset(fieldWith6, fieldWithout6) {\n // Remove $0 and $1, and then check that remaining $6-less field is a subset of the one with $6.\n // No need to check indicators.\n // NB! We could use punctuation-stripping here.\n const subset = fieldWithout6.subfields.filter(subfield => !['0', '1'].includes(subfield.code));\n return subset.every(sf => fieldWith6.subfields.some(sf2 => subfieldsAreIdentical(sf, sf2)));\n //return MarcRecord.isEqual(strippedField1, strippedField2);\n}\n\nfunction controlSubfield6PermitsMerge(field1, field2) {\n if (subfieldsAreEmpty(field1, field2, '6')) {\n return true;\n }\n\n // Handle cases where one has a $6 and the other has not:\n // Should this accept $0 (FI-ASTERI-N) vs none?\n if (!fieldHasSubfield(field1, '6') && fieldHasSubfield(field2, '6') && sixlessIsSubset(field2, field1)) {\n return true;\n }\n if (!fieldHasSubfield(field2, '6') && fieldHasSubfield(field1, '6') && sixlessIsSubset(field1, field2)) {\n return true;\n }\n\n // There are at least two (plus) fields involved (Field XXX (one) and field 880 (one plus).\n // Thus this generic solution can't handle them. Postprocess step removes some chains instead!\n debugDev(` controlSubfield6PermitsMerge() fails always on generic part (feature).`);\n return false;\n}\n\nfunction controlSubfield5PermitsMerge(field1, field2) {\n // field1.$5 XOR field2.$5 means false, NEITHER and BOTH mean true, regardless of value\n if (!fieldHasSubfield(field1, '5')) {\n if (!fieldHasSubfield(field2, '5')) {\n return true; // If neither one has $5, it's ok to merge\n }\n // If $5 contents are same, merge can be perfomed:\n const fives1 = field1.subfields.filter(sf => sf.code === '5');\n const fives2 = field2.subfields.filter(sf => sf.code === '5');\n if (fives1.every(sf1 => fives2.some(sf2 => sf1.value === sf2.value)) && fives2.every(sf2 => fives1.some(sf1 => sf1.value === sf2.value))) {\n return true;\n }\n return false;\n }\n if (!fieldHasSubfield(field2, '5')) {\n return false;\n }\n return true;\n}\n\nfunction controlSubfield9PermitsMerge(baseField, sourceField) {\n const baseFieldSubfields9 = baseField.subfields.filter(sf => sf.code === '9');\n const sourceFieldSubfields9 = sourceField.subfields.filter(sf => sf.code === '9');\n\n //nvdebug('CHECK $9', debugDev);\n // There are no $9s. Skip:\n if (baseFieldSubfields9.length === 0 && sourceFieldSubfields9.length === 0) {\n //nvdebug(` No subfield $9 detected`, debugDev);\n return true;\n }\n\n if (keepOrDropPreventsMerge()) {\n nvdebug(` Subfield $9 KEEPs and DROPs disallow merge`, debugDev);\n return false;\n }\n\n if (transPreventsMerge()) {\n nvdebug(` Subfield $9 <TRANS> mismatch disallows merge`, debugDev);\n return false;\n }\n\n //nvdebug('CHECK $9 OK', debugDev);\n\n return true;\n\n function subfieldHasKeepOrDrop(subfield) {\n // nvdebug(`Has <KEEP>? ${subfieldToString(subfield)}`, debugDev);\n return subfield.code === '9' && (/(?:<KEEP>|<DROP>)/u).test(subfield.value);\n }\n\n function subfieldHasTrans(subfield) {\n return subfield.code === '9' && (/<TRANS>/u).test(subfield.value);\n }\n\n function transPreventsMerge() {\n const trans1 = baseFieldSubfields9.filter(sf => subfieldHasTrans(sf));\n const trans2 = sourceFieldSubfields9.filter(sf => subfieldHasTrans(sf));\n if (trans1.length > 0 && trans2.length > 0) {\n if (!MarcRecord.isEqual(trans1, trans2)) {\n return true;\n }\n }\n return false;\n }\n\n function retainSubfieldForKeepComparison(subfield) {\n // Don't compare <KEEP>, <DROP> nor <TRANS> here (<TRANS> has it's own check)\n if (subfieldHasKeepOrDrop(subfield) || subfieldHasTrans(subfield)) {\n return false;\n }\n\n if (['0', '1'].includes(subfield.code)) {\n return false;\n }\n if (['100', '600', '700', '800'].includes(baseField.tag)) {\n // Despite $9 KEEP/DROP, we are interested in merging $d years (better than two separate fields)\n if (['d'].includes(subfield.code)) {\n return false;\n }\n }\n\n\n return true;\n }\n\n function acceptKeeplessSourceSubfield(sourceSubfield, tag, subfieldCode, subfieldValue) {\n if (sourceSubfield.code !== subfieldCode) {\n return false;\n }\n // In this context, there's no need to check the value of a non-repeatable subfield.\n // If value is different, pairing will fail when comparing the subfield itself.\n // This allows us to tolerate little differences in punctuation: different punctuation does not get copied to base,\n // so they don't alter base and and thus redundant when comparing.\n if (!subfieldIsRepeatable(tag, subfieldCode)) {\n return true;\n }\n return sourceSubfield.value === subfieldValue;\n }\n\n function keepOrDropPreventsMerge() {\n const keepOrDrop1 = baseFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));\n const keepOrDrop2 = sourceFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));\n\n if (keepOrDrop1.length === 0 && keepOrDrop2.length === 0) {\n return false;\n }\n\n if (baseField.tag.charAt(0) === '1' && !keepOrDrop2.some(sf => (/<DROP>/u).test(sf.value))) {\n return false;\n }\n\n const sf9lessField1 = baseField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));\n const sf9lessField2 = sourceField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));\n\n nvdebugSubfieldArray(baseField.subfields, 'FIELD ', debugDev);\n nvdebugSubfieldArray(sf9lessField1, 'FILTER ', debugDev);\n\n nvdebugSubfieldArray(sourceField.subfields, 'FIELD2 ', debugDev);\n nvdebugSubfieldArray(sf9lessField2, 'FILTER2 ', debugDev);\n\n // Keepless field can be a subset field with <KEEP>/<DROP>! Note that punctuation still causes remnants to fail.\n if (keepOrDrop1.length === 0) {\n return !sf9lessField1.every(sf => sf9lessField2.some(sf2 => subfieldsAreIdentical(sf, sf2)));\n }\n // However, to alleviate the above-mentioned punctuation problem, we can check keep/drop-less *source* subfields\n if (keepOrDrop2.length === 0) {\n const unhandledSubfield = sf9lessField2.find(sf2 => !sf9lessField1.some(sf => acceptKeeplessSourceSubfield(sf2, baseField.tag, sf.code, sf.value)));\n if (unhandledSubfield) {\n //nvdebug(`Failed to pair ${subfieldToString(unhandledSubfield)}`, debugDev);\n return true;\n }\n //return !sf9lessField2.every(sf2 => sf9lessField1.some(sf => subfieldsAreIdentical(sf, sf2)));\n return false;\n }\n\n //nvdebugSubfieldArray(sf9lessField2, 'SOURCE(?)', debugDev);\n //nvdebugSubfieldArray(sf9lessField1, 'BASE(?) ', debugDev);\n\n // $9 <KEEP> or <DROP> detected on both fields.\n // Non-keeps and non-drops must be equal, otherwise fail:\n if (MarcRecord.isEqual(sf9lessField1, sf9lessField2)) {\n return false;\n }\n // Prevent:\n return true;\n }\n}\n\nfunction getPrefix(value) {\n const normalizedValue = normalizeControlSubfieldValue(value);\n\n if (normalizedValue.match(/^\\([^)]+\\)[0-9]+$/u)) {\n return normalizedValue.substr(0, normalizedValue.indexOf(')') + 1);\n }\n\n if (value.match(/^https?:\\/\\//u)) {\n return normalizedValue.substr(0, normalizedValue.lastIndexOf('/') + 1);\n }\n\n return '';\n}\n\nfunction isMatchAfterNormalization(currSubfield, otherField) {\n // NB! Add implement isni normalizations (to normalize.js) and apply here:\n const normalizedCurrSubfieldValue = normalizeControlSubfieldValue(currSubfield.value);\n const prefix = getPrefix(normalizedCurrSubfieldValue);\n\n //debug(`FFS-PREFIX '${prefix}'`);\n // Look for same prefix + different identifier\n const hits = otherField.subfields.filter(sf2 => sf2.code === currSubfield.code && normalizeControlSubfieldValue(sf2.value).indexOf(prefix) === 0);\n if (hits.length === 0 || // <-- Nothing found, so it can't be a mismatch\n // Every opposing subfields match:\n hits.every(sf2 => normalizedCurrSubfieldValue === normalizeControlSubfieldValue(sf2.value))) {\n debugDev(`Subfield ‡${currSubfield.code} check OK: No opposing ${prefix} prefixes found.`);\n return true;\n }\n\n debugDev(`Subfield ‡${currSubfield.code} check FAILED: ‡${currSubfield.code} '${currSubfield.value}' vs ‡${currSubfield.code} '${hits[0].value}'.`);\n return false;\n}\n\nfunction controlSubfieldContainingIdentifierPermitsMerge(field1, field2, subfieldCode) {\n if (!fieldHasSubfield(field1, subfieldCode, null) || !fieldHasSubfield(field2, subfieldCode, null)) {\n return true;\n }\n\n const result = field1.subfields.every(subfield => {\n if (subfield.code !== subfieldCode) {\n return true;\n }\n\n debugDev(`Compare ‡${subfieldCode} '${subfield.value}' with '${fieldToString(field2)}'.`);\n if (fieldHasSubfield(field2, field1.code, field1.value)) {\n return true;\n }\n\n return isMatchAfterNormalization(subfield, field2, subfieldCode);\n });\n\n if (!result) {\n debugDev(`Control subfield '${subfieldCode}' check failed.`);\n return false;\n }\n return true;\n}\n\nconst controlSubfieldsContainingIdentifier = ['w', '0', '1', '2']; // 2 ain't identifier, but the logic can be applied here as well\n\nexport function controlSubfieldsPermitMerge(baseField, sourceField) {\n // Check $w, $0, $1, $2 (which isn't an identifier per se, but the sama logic can be applied)\n if (!controlSubfieldsContainingIdentifier.every(subfieldCode => controlSubfieldContainingIdentifierPermitsMerge(baseField, sourceField, subfieldCode))) {\n //debug(' control subfields with identifiers failed');\n return false;\n }\n\n if (!subfieldsAreEqual(baseField, sourceField, '3')) {\n //debug(' similar control subfield fails');\n return false;\n }\n\n if (!controlSubfield5PermitsMerge(baseField, sourceField) || !controlSubfield6PermitsMerge(baseField, sourceField) || !controlSubfield9PermitsMerge(baseField, sourceField)) {\n return false;\n }\n // We fully prevent merging $8 subfields here, as they affect multiple fields! Also these would get screwed:\n // 38211 |8 3\\u |a kuoro |2 seko\n // 38211 |8 6\\u |a kuoro |2 seko |9 VIOLA<DROP>\n // Thus only copy works with $8...\n if (!subfieldsAreEmpty(baseField, sourceField, '8')) {\n // We could alleviate this a bit esp. for non-repeatable fields.\n // At least, if the source has '8' and otherwise the two fields are identical...\n const subsetOfSourceField = {\n 'tag': sourceField.tag,\n 'ind1': sourceField.ind1,\n 'ind2': sourceField.ind2, subfields: sourceField.subfields.filter(sf => sf.code !== '8')\n };\n if (fieldToString(baseField) === fieldToString(subsetOfSourceField)) {\n return true;\n }\n //debug(' csf8 failed');\n return false;\n }\n\n return true;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/merge-fields/controlSubfields.js"],
|
|
4
|
+
"sourcesContent": ["import {MarcRecord} from '@natlibfi/marc-record';\nimport createDebugLogger from 'debug';\nimport {fieldHasSubfield, fieldToString, nvdebug, nvdebugSubfieldArray, subfieldIsRepeatable, subfieldsAreIdentical} from '../utils.js';\n\n//import {normalizeControlSubfieldValue} from './normalizeIdentifier';\nimport {normalizeControlSubfieldValue} from '../normalize-identifiers.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:controlSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction subfieldsAreEqual(field1, field2, subfieldCode) {\n // Check OK if neither one has given subfield.\n // Check fails if one field has given subfield and the other one does not\n if (!fieldHasSubfield(field1, subfieldCode)) {\n return !fieldHasSubfield(field2, subfieldCode);\n }\n if (!fieldHasSubfield(field2, subfieldCode)) {\n return false;\n }\n // Compare $3 subfields. If everything matches, OK, else FAIL:\n const sfSet1 = field1.subfields.filter(subfield => subfield.code === subfieldCode);\n const sfSet2 = field2.subfields.filter(subfield => subfield.code === subfieldCode);\n return MarcRecord.isEqual(sfSet1, sfSet2);\n}\n\nfunction subfieldsAreEmpty(field1, field2, subfieldCode) {\n if (!fieldHasSubfield(field1, subfieldCode) && !fieldHasSubfield(field2, subfieldCode)) {\n return true;\n }\n return false;\n}\n\n\nfunction sixlessIsSubset(fieldWith6, fieldWithout6) {\n // Remove $0 and $1, and then check that remaining $6-less field is a subset of the one with $6.\n // No need to check indicators.\n // NB! We could use punctuation-stripping here.\n const subset = fieldWithout6.subfields.filter(subfield => !['0', '1'].includes(subfield.code));\n return subset.every(sf => fieldWith6.subfields.some(sf2 => subfieldsAreIdentical(sf, sf2)));\n //return MarcRecord.isEqual(strippedField1, strippedField2);\n}\n\nfunction controlSubfield6PermitsMerge(field1, field2) {\n if (subfieldsAreEmpty(field1, field2, '6')) {\n return true;\n }\n\n // Handle cases where one has a $6 and the other has not:\n // Should this accept $0 (FI-ASTERI-N) vs none?\n if (!fieldHasSubfield(field1, '6') && fieldHasSubfield(field2, '6') && sixlessIsSubset(field2, field1)) {\n return true;\n }\n if (!fieldHasSubfield(field2, '6') && fieldHasSubfield(field1, '6') && sixlessIsSubset(field1, field2)) {\n return true;\n }\n\n // There are at least two (plus) fields involved (Field XXX (one) and field 880 (one plus).\n // Thus this generic solution can't handle them. Postprocess step removes some chains instead!\n debugDev(` controlSubfield6PermitsMerge() fails always on generic part (feature).`);\n return false;\n}\n\nfunction controlSubfield5PermitsMerge(field1, field2) {\n // field1.$5 XOR field2.$5 means false, NEITHER and BOTH mean true, regardless of value\n if (!fieldHasSubfield(field1, '5')) {\n if (!fieldHasSubfield(field2, '5')) {\n return true; // If neither one has $5, it's ok to merge\n }\n // If $5 contents are same, merge can be perfomed:\n const fives1 = field1.subfields.filter(sf => sf.code === '5');\n const fives2 = field2.subfields.filter(sf => sf.code === '5');\n if (fives1.every(sf1 => fives2.some(sf2 => sf1.value === sf2.value)) && fives2.every(sf2 => fives1.some(sf1 => sf1.value === sf2.value))) {\n return true;\n }\n return false;\n }\n if (!fieldHasSubfield(field2, '5')) {\n return false;\n }\n return true;\n}\n\nfunction controlSubfield9PermitsMerge(baseField, sourceField) {\n const baseFieldSubfields9 = baseField.subfields.filter(sf => sf.code === '9');\n const sourceFieldSubfields9 = sourceField.subfields.filter(sf => sf.code === '9');\n\n //nvdebug('CHECK $9', debugDev);\n // There are no $9s. Skip:\n if (baseFieldSubfields9.length === 0 && sourceFieldSubfields9.length === 0) {\n //nvdebug(` No subfield $9 detected`, debugDev);\n return true;\n }\n\n if (keepOrDropPreventsMerge()) {\n nvdebug(` Subfield $9 KEEPs and DROPs disallow merge`, debugDev);\n return false;\n }\n\n if (transPreventsMerge()) {\n nvdebug(` Subfield $9 <TRANS> mismatch disallows merge`, debugDev);\n return false;\n }\n\n //nvdebug('CHECK $9 OK', debugDev);\n\n return true;\n\n function subfieldHasKeepOrDrop(subfield) {\n // nvdebug(`Has <KEEP>? ${subfieldToString(subfield)}`, debugDev);\n return subfield.code === '9' && (/(?:<KEEP>|<DROP>)/u).test(subfield.value);\n }\n\n function subfieldHasTrans(subfield) {\n return subfield.code === '9' && (/<TRANS>/u).test(subfield.value);\n }\n\n function transPreventsMerge() {\n const trans1 = baseFieldSubfields9.filter(sf => subfieldHasTrans(sf));\n const trans2 = sourceFieldSubfields9.filter(sf => subfieldHasTrans(sf));\n if (trans1.length > 0 && trans2.length > 0) {\n if (!MarcRecord.isEqual(trans1, trans2)) {\n return true;\n }\n }\n return false;\n }\n\n function retainSubfieldForKeepComparison(subfield) {\n // Don't compare <KEEP>, <DROP> nor <TRANS> here (<TRANS> has it's own check)\n if (subfieldHasKeepOrDrop(subfield) || subfieldHasTrans(subfield)) {\n return false;\n }\n\n if (['0', '1'].includes(subfield.code)) {\n return false;\n }\n if (['100', '600', '700', '800'].includes(baseField.tag)) {\n // Despite $9 KEEP/DROP, we are interested in merging $d years (better than two separate fields)\n if (['d'].includes(subfield.code)) {\n return false;\n }\n }\n\n\n return true;\n }\n\n function acceptKeeplessSourceSubfield(sourceSubfield, tag, subfieldCode, subfieldValue) {\n if (sourceSubfield.code !== subfieldCode) {\n return false;\n }\n // In this context, there's no need to check the value of a non-repeatable subfield.\n // If value is different, pairing will fail when comparing the subfield itself.\n // This allows us to tolerate little differences in punctuation: different punctuation does not get copied to base,\n // so they don't alter base and and thus redundant when comparing.\n if (!subfieldIsRepeatable(tag, subfieldCode)) {\n return true;\n }\n return sourceSubfield.value === subfieldValue;\n }\n\n function keepOrDropPreventsMerge() {\n const keepOrDrop1 = baseFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));\n const keepOrDrop2 = sourceFieldSubfields9.filter(sf => subfieldHasKeepOrDrop(sf));\n\n if (keepOrDrop1.length === 0 && keepOrDrop2.length === 0) {\n return false;\n }\n\n if (baseField.tag.charAt(0) === '1' && !keepOrDrop2.some(sf => (/<DROP>/u).test(sf.value))) {\n return false;\n }\n\n const sf9lessField1 = baseField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));\n const sf9lessField2 = sourceField.subfields.filter(subfield => retainSubfieldForKeepComparison(subfield));\n\n nvdebugSubfieldArray(baseField.subfields, 'FIELD ', debugDev);\n nvdebugSubfieldArray(sf9lessField1, 'FILTER ', debugDev);\n\n nvdebugSubfieldArray(sourceField.subfields, 'FIELD2 ', debugDev);\n nvdebugSubfieldArray(sf9lessField2, 'FILTER2 ', debugDev);\n\n // Keepless field can be a subset field with <KEEP>/<DROP>! Note that punctuation still causes remnants to fail.\n if (keepOrDrop1.length === 0) {\n return !sf9lessField1.every(sf => sf9lessField2.some(sf2 => subfieldsAreIdentical(sf, sf2)));\n }\n // However, to alleviate the above-mentioned punctuation problem, we can check keep/drop-less *source* subfields\n if (keepOrDrop2.length === 0) {\n const unhandledSubfield = sf9lessField2.find(sf2 => !sf9lessField1.some(sf => acceptKeeplessSourceSubfield(sf2, baseField.tag, sf.code, sf.value)));\n if (unhandledSubfield) {\n //nvdebug(`Failed to pair ${subfieldToString(unhandledSubfield)}`, debugDev);\n return true;\n }\n //return !sf9lessField2.every(sf2 => sf9lessField1.some(sf => subfieldsAreIdentical(sf, sf2)));\n return false;\n }\n\n //nvdebugSubfieldArray(sf9lessField2, 'SOURCE(?)', debugDev);\n //nvdebugSubfieldArray(sf9lessField1, 'BASE(?) ', debugDev);\n\n // $9 <KEEP> or <DROP> detected on both fields.\n // Non-keeps and non-drops must be equal, otherwise fail:\n if (MarcRecord.isEqual(sf9lessField1, sf9lessField2)) {\n return false;\n }\n // Prevent:\n return true;\n }\n}\n\nfunction getPrefix(value) {\n const normalizedValue = normalizeControlSubfieldValue(value);\n\n if (normalizedValue.match(/^\\([^)]+\\)[0-9]+$/u)) {\n return normalizedValue.substr(0, normalizedValue.indexOf(')') + 1);\n }\n\n if (value.match(/^https?:\\/\\//u)) {\n return normalizedValue.substr(0, normalizedValue.lastIndexOf('/') + 1);\n }\n\n return '';\n}\n\nfunction isMatchAfterNormalization(currSubfield, otherField) {\n // NB! Add implement isni normalizations (to normalize.js) and apply here:\n const normalizedCurrSubfieldValue = normalizeControlSubfieldValue(currSubfield.value);\n const prefix = getPrefix(normalizedCurrSubfieldValue);\n\n //debug(`FFS-PREFIX '${prefix}'`);\n // Look for same prefix + different identifier\n const hits = otherField.subfields.filter(sf2 => sf2.code === currSubfield.code && normalizeControlSubfieldValue(sf2.value).indexOf(prefix) === 0);\n if (hits.length === 0 || // <-- Nothing found, so it can't be a mismatch\n // Every opposing subfields match:\n hits.every(sf2 => normalizedCurrSubfieldValue === normalizeControlSubfieldValue(sf2.value))) {\n debugDev(`Subfield \u2021${currSubfield.code} check OK: No opposing ${prefix} prefixes found.`);\n return true;\n }\n\n debugDev(`Subfield \u2021${currSubfield.code} check FAILED: \u2021${currSubfield.code} '${currSubfield.value}' vs \u2021${currSubfield.code} '${hits[0].value}'.`);\n return false;\n}\n\nfunction controlSubfieldContainingIdentifierPermitsMerge(field1, field2, subfieldCode) {\n if (!fieldHasSubfield(field1, subfieldCode, null) || !fieldHasSubfield(field2, subfieldCode, null)) {\n return true;\n }\n\n const result = field1.subfields.every(subfield => {\n if (subfield.code !== subfieldCode) {\n return true;\n }\n\n debugDev(`Compare \u2021${subfieldCode} '${subfield.value}' with '${fieldToString(field2)}'.`);\n if (fieldHasSubfield(field2, field1.code, field1.value)) {\n return true;\n }\n\n return isMatchAfterNormalization(subfield, field2, subfieldCode);\n });\n\n if (!result) {\n debugDev(`Control subfield '${subfieldCode}' check failed.`);\n return false;\n }\n return true;\n}\n\nconst controlSubfieldsContainingIdentifier = ['w', '0', '1', '2']; // 2 ain't identifier, but the logic can be applied here as well\n\nexport function controlSubfieldsPermitMerge(baseField, sourceField) {\n // Check $w, $0, $1, $2 (which isn't an identifier per se, but the sama logic can be applied)\n if (!controlSubfieldsContainingIdentifier.every(subfieldCode => controlSubfieldContainingIdentifierPermitsMerge(baseField, sourceField, subfieldCode))) {\n //debug(' control subfields with identifiers failed');\n return false;\n }\n\n if (!subfieldsAreEqual(baseField, sourceField, '3')) {\n //debug(' similar control subfield fails');\n return false;\n }\n\n if (!controlSubfield5PermitsMerge(baseField, sourceField) || !controlSubfield6PermitsMerge(baseField, sourceField) || !controlSubfield9PermitsMerge(baseField, sourceField)) {\n return false;\n }\n // We fully prevent merging $8 subfields here, as they affect multiple fields! Also these would get screwed:\n // 38211 |8 3\\u |a kuoro |2 seko\n // 38211 |8 6\\u |a kuoro |2 seko |9 VIOLA<DROP>\n // Thus only copy works with $8...\n if (!subfieldsAreEmpty(baseField, sourceField, '8')) {\n // We could alleviate this a bit esp. for non-repeatable fields.\n // At least, if the source has '8' and otherwise the two fields are identical...\n const subsetOfSourceField = {\n 'tag': sourceField.tag,\n 'ind1': sourceField.ind1,\n 'ind2': sourceField.ind2, subfields: sourceField.subfields.filter(sf => sf.code !== '8')\n };\n if (fieldToString(baseField) === fieldToString(subsetOfSourceField)) {\n return true;\n }\n //debug(' csf8 failed');\n return false;\n }\n\n return true;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|