@natlibfi/marc-record-validators-melinda 11.2.2-alpha.1 → 11.2.2
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/dist/access-rights.spec.js +1 -1
- package/dist/access-rights.spec.js.map +1 -1
- package/dist/addMissingField041.js.map +1 -1
- package/dist/addMissingField041.spec.js +1 -1
- package/dist/addMissingField041.spec.js.map +1 -1
- package/dist/addMissingField336.js.map +1 -1
- package/dist/addMissingField336.spec.js +1 -1
- package/dist/addMissingField336.spec.js.map +1 -1
- package/dist/addMissingField337.js.map +1 -1
- package/dist/addMissingField337.spec.js +1 -1
- package/dist/addMissingField337.spec.js.map +1 -1
- package/dist/addMissingField338.js.map +1 -1
- package/dist/addMissingField338.spec.js +1 -1
- package/dist/addMissingField338.spec.js.map +1 -1
- package/dist/cyrillux-usemarcon-replacement.js +82 -22
- package/dist/cyrillux-usemarcon-replacement.js.map +1 -1
- package/dist/cyrillux-usemarcon-replacement.spec.js +1 -1
- package/dist/cyrillux-usemarcon-replacement.spec.js.map +1 -1
- package/dist/double-commas.spec.js +1 -1
- package/dist/double-commas.spec.js.map +1 -1
- package/dist/duplicates-ind1.js.map +1 -1
- package/dist/duplicates-ind1.spec.js +1 -1
- package/dist/duplicates-ind1.spec.js.map +1 -1
- package/dist/empty-fields.js.map +1 -1
- package/dist/empty-fields.spec.js +1 -1
- package/dist/empty-fields.spec.js.map +1 -1
- package/dist/ending-punctuation.js +1 -1
- package/dist/ending-punctuation.js.map +1 -1
- package/dist/ending-punctuation.spec.js +1 -1
- package/dist/ending-punctuation.spec.js.map +1 -1
- package/dist/ending-whitespace.js.map +1 -1
- package/dist/ending-whitespace.spec.js +1 -1
- package/dist/ending-whitespace.spec.js.map +1 -1
- package/dist/field-008-18-34-character-groups.js +1 -1
- package/dist/field-008-18-34-character-groups.js.map +1 -1
- package/dist/field-008-18-34-character-groups.spec.js +1 -1
- package/dist/field-008-18-34-character-groups.spec.js.map +1 -1
- package/dist/field-505-separators.js +1 -1
- package/dist/field-505-separators.js.map +1 -1
- package/dist/field-505-separators.spec.js +1 -1
- package/dist/field-505-separators.spec.js.map +1 -1
- package/dist/field-521-fix.js +1 -1
- package/dist/field-521-fix.js.map +1 -1
- package/dist/field-521-fix.spec.js +1 -1
- package/dist/field-521-fix.spec.js.map +1 -1
- package/dist/field-exclusion.js.map +1 -1
- package/dist/field-exclusion.spec.js +1 -1
- package/dist/field-exclusion.spec.js.map +1 -1
- package/dist/field-structure.js.map +1 -1
- package/dist/field-structure.spec.js +1 -1
- package/dist/field-structure.spec.js.map +1 -1
- package/dist/fields-present.spec.js +1 -1
- package/dist/fields-present.spec.js.map +1 -1
- package/dist/fix-33X.js +1 -1
- package/dist/fix-33X.js.map +1 -1
- package/dist/fix-33X.spec.js +1 -1
- package/dist/fix-33X.spec.js.map +1 -1
- package/dist/fix-country-codes.js.map +1 -1
- package/dist/fix-country-codes.spec.js +1 -1
- package/dist/fix-country-codes.spec.js.map +1 -1
- package/dist/fix-language-codes.js +1 -1
- package/dist/fix-language-codes.js.map +1 -1
- package/dist/fix-language-codes.spec.js +1 -1
- package/dist/fix-language-codes.spec.js.map +1 -1
- package/dist/fixRelatorTerms.js +6 -3
- package/dist/fixRelatorTerms.js.map +1 -1
- package/dist/fixRelatorTerms.spec.js +1 -1
- package/dist/fixRelatorTerms.spec.js.map +1 -1
- package/dist/fixed-fields.js.map +1 -1
- package/dist/fixed-fields.spec.js +1 -1
- package/dist/fixed-fields.spec.js.map +1 -1
- package/dist/identical-fields.js.map +1 -1
- package/dist/identical-fields.spec.js +1 -1
- package/dist/identical-fields.spec.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/indicator-fixes.js +17 -0
- package/dist/indicator-fixes.js.map +1 -1
- package/dist/indicator-fixes.spec.js +1 -1
- package/dist/indicator-fixes.spec.js.map +1 -1
- package/dist/isbn-issn.js +1 -1
- package/dist/isbn-issn.js.map +1 -1
- package/dist/isbn-issn.spec.js +1 -1
- package/dist/isbn-issn.spec.js.map +1 -1
- package/dist/item-language.js +1 -1
- package/dist/item-language.js.map +1 -1
- package/dist/item-language.spec.js +1 -1
- package/dist/item-language.spec.js.map +1 -1
- package/dist/mergeField500Lisapainokset.js.map +1 -1
- package/dist/mergeField500Lisapainokset.spec.js +1 -1
- package/dist/mergeField500Lisapainokset.spec.js.map +1 -1
- package/dist/mergeRelatorTermFields.js +1 -1
- package/dist/mergeRelatorTermFields.js.map +1 -1
- package/dist/mergeRelatorTermFields.spec.js +1 -1
- package/dist/mergeRelatorTermFields.spec.js.map +1 -1
- package/dist/multiple-subfield-0.js.map +1 -1
- package/dist/multiple-subfield-0.spec.js +1 -1
- package/dist/multiple-subfield-0.spec.js.map +1 -1
- package/dist/non-breaking-space.js.map +1 -1
- package/dist/non-breaking-space.spec.js +1 -1
- package/dist/non-breaking-space.spec.js.map +1 -1
- package/dist/normalize-dashes.js +1 -1
- package/dist/normalize-dashes.js.map +1 -1
- package/dist/normalize-dashes.spec.js +1 -1
- package/dist/normalize-dashes.spec.js.map +1 -1
- package/dist/normalize-identifiers.js +1 -1
- package/dist/normalize-identifiers.js.map +1 -1
- package/dist/normalize-identifiers.spec.js +1 -1
- package/dist/normalize-identifiers.spec.js.map +1 -1
- package/dist/normalize-qualifying-information.js +1 -1
- package/dist/normalize-qualifying-information.js.map +1 -1
- package/dist/normalize-qualifying-information.spec.js +1 -1
- package/dist/normalize-qualifying-information.spec.js.map +1 -1
- package/dist/normalize-utf8-diacritics.js +1 -1
- package/dist/normalize-utf8-diacritics.js.map +1 -1
- package/dist/normalize-utf8-diacritics.spec.js +1 -1
- package/dist/normalize-utf8-diacritics.spec.js.map +1 -1
- package/dist/normalizeFieldForComparison.js +1 -1
- package/dist/normalizeFieldForComparison.js.map +1 -1
- package/dist/normalizeSubfieldValueForComparison.js +1 -1
- package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
- package/dist/prepublicationUtils.js +1 -1
- package/dist/prepublicationUtils.js.map +1 -1
- package/dist/punctuation/index.js +1 -1
- package/dist/punctuation/index.js.map +1 -1
- package/dist/punctuation/rules/index.js +1 -1
- package/dist/punctuation/rules/index.js.map +1 -1
- package/dist/punctuation.spec.js +1 -1
- package/dist/punctuation.spec.js.map +1 -1
- package/dist/punctuation2.js +1 -1
- package/dist/punctuation2.js.map +1 -1
- package/dist/punctuation2.spec.js +1 -1
- package/dist/punctuation2.spec.js.map +1 -1
- package/dist/reindexSubfield6OccurenceNumbers.js +1 -1
- package/dist/reindexSubfield6OccurenceNumbers.js.map +1 -1
- package/dist/reindexSubfield6OccurenceNumbers.spec.js +1 -1
- package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +1 -1
- package/dist/removeDuplicateDataFields.js +1 -1
- package/dist/removeDuplicateDataFields.js.map +1 -1
- package/dist/removeDuplicateDataFields.spec.js +1 -1
- package/dist/removeDuplicateDataFields.spec.js.map +1 -1
- package/dist/removeInferiorDataFields.js +1 -1
- package/dist/removeInferiorDataFields.js.map +1 -1
- package/dist/removeInferiorDataFields.spec.js +1 -1
- package/dist/removeInferiorDataFields.spec.js.map +1 -1
- package/dist/resolvable-ext-references-melinda.js +1 -1
- package/dist/resolvable-ext-references-melinda.js.map +1 -1
- package/dist/resolvable-ext-references-melinda.spec.js +1 -1
- package/dist/resolvable-ext-references-melinda.spec.js.map +1 -1
- package/dist/resolveOrphanedSubfield6s.js +1 -1
- package/dist/resolveOrphanedSubfield6s.js.map +1 -1
- package/dist/resolveOrphanedSubfield6s.spec.js +1 -1
- package/dist/resolveOrphanedSubfield6s.spec.js.map +1 -1
- package/dist/sanitize-vocabulary-source-codes.js +5 -1
- package/dist/sanitize-vocabulary-source-codes.js.map +1 -1
- package/dist/sanitize-vocabulary-source-codes.spec.js +1 -1
- package/dist/sanitize-vocabulary-source-codes.spec.js.map +1 -1
- package/dist/sort-tags.spec.js +1 -1
- package/dist/sort-tags.spec.js.map +1 -1
- package/dist/sortFields.js +1 -1
- package/dist/sortFields.js.map +1 -1
- package/dist/sortFields.spec.js +1 -1
- package/dist/sortFields.spec.js.map +1 -1
- package/dist/sortRelatorTerms.js +1 -1
- package/dist/sortRelatorTerms.js.map +1 -1
- package/dist/sortRelatorTerms.spec.js +1 -1
- package/dist/sortRelatorTerms.spec.js.map +1 -1
- package/dist/sortSubfields.js +1 -1
- package/dist/sortSubfields.js.map +1 -1
- package/dist/sortSubfields.spec.js +1 -1
- package/dist/sortSubfields.spec.js.map +1 -1
- package/dist/stripPunctuation.js.map +1 -1
- package/dist/stripPunctuation.spec.js +1 -1
- package/dist/stripPunctuation.spec.js.map +1 -1
- package/dist/subfield-exclusion.js.map +1 -1
- package/dist/subfield-exclusion.spec.js +1 -1
- package/dist/subfield-exclusion.spec.js.map +1 -1
- package/dist/subfield6Utils.js.map +1 -1
- package/dist/subfield8Utils.js.map +1 -1
- package/dist/subfieldValueNormalizations.js +1 -1
- package/dist/subfieldValueNormalizations.js.map +1 -1
- package/dist/subfieldValueNormalizations.spec.js +1 -1
- package/dist/subfieldValueNormalizations.spec.js.map +1 -1
- package/dist/sync-007-and-300.js +1 -1
- package/dist/sync-007-and-300.js.map +1 -1
- package/dist/sync-007-and-300.spec.js +1 -1
- package/dist/sync-007-and-300.spec.js.map +1 -1
- package/dist/typeOfDate-008.js +1 -1
- package/dist/typeOfDate-008.js.map +1 -1
- package/dist/typeOfDate-008.spec.js +1 -1
- package/dist/typeOfDate-008.spec.js.map +1 -1
- package/dist/unicode-decomposition.js.map +1 -1
- package/dist/unicode-decomposition.spec.js +1 -1
- package/dist/unicode-decomposition.spec.js.map +1 -1
- package/dist/update-field-540.spec.js +1 -1
- package/dist/update-field-540.spec.js.map +1 -1
- package/dist/urn.js +1 -1
- package/dist/urn.js.map +1 -1
- package/dist/urn.spec.js +1 -1
- package/dist/urn.spec.js.map +1 -1
- package/dist/utils.js +17 -0
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/cyrillux-usemarcon-replacement.js +87 -24
- package/src/fixRelatorTerms.js +5 -2
- package/src/indicator-fixes.js +19 -0
- package/src/sanitize-vocabulary-source-codes.js +4 -0
- package/src/utils.js +16 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f11/expectedResult.json +3 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f11/record.json +8 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f12/expectedResult.json +32 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f12/metadata.json +6 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f12/record.json +30 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f13/expectedResult.json +38 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f13/metadata.json +6 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f13/record.json +29 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f14/expectedResult.json +42 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f14/metadata.json +6 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f14/record.json +33 -0
- package/test-fixtures/indicator-fixes/09/expectedResult.json +10 -0
- package/test-fixtures/indicator-fixes/09/metadata.json +4 -0
- package/test-fixtures/indicator-fixes/09/record.json +11 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +74 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/metadata.json +8 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/record.json +75 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/expectedResult.json +5 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +8 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +75 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-identifiers.js","names":["_clone","_interopRequireDefault","require","_utils","obj","__esModule","default","_default","description","validate","fix","record","res","message","valid","fields","forEach","field","fieldNormalizeControlNumbers","validateField","length","subfields","normalizedField","clone","orig","fieldToString","mod","push","alephInternal01","alephInternal10","alephInternal11","alephInternal12","alephInternal13","standard01","standard10","standard11","standard12","standard13","both01","ALEPH_INTERNAL","STANDARD","both10","both11","both12","both13","mappings","normalizeNineDigitIDs","value","targetFormat","nineDigitTail","slice","test","currPrefix","isIsni","normalizeIsni","replace","normalizeControlSubfieldValue","normalizedValue","normalizeAs","tag","subfieldCode","includes","undefined","sf","code"],"sources":["../src/normalize-identifiers.js"],"sourcesContent":["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString} from './utils';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\n/*\nfunction nvdebug(message, func) {\n if (func) { // eslint-disable-line functional/no-conditional-statements\n func(message);\n }\n console.info(message); // eslint-disable-line no-console\n}\n*/\n\nexport default function () {\n\n // NB! We should and could handle ISNIs here as well.\n return {\n description: 'Normalizes identifiers such as subfield $0 values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n //message.fix = []; // eslint-disable-line functional/immutable-data\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n //nvdebug(`NORMALIZE CONTROL NUMBER FIX`, debug);\n record.fields.forEach(field => {\n //nvdebug(` NORMALIZE CONTROL NUMBER FIX ${fieldToString(field)}`, debug);\n\n fieldNormalizeControlNumbers(field);\n //validateField(field, true, message);\n });\n\n // message.valid = !(message.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n //nvdebug(`NORMALIZE CONTROL NUMBER VALIDATE`, debug);\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n //nvdebug(` NORMALIZE CONTROL NUMBER VALIDATE ${fieldToString(field)}`, debug);\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validateField(field, res) {\n if (!field.subfields) {\n return;\n }\n\n const normalizedField = clone(field);\n fieldNormalizeControlNumbers(normalizedField);\n\n const orig = fieldToString(field);\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'${orig}' could do with control number identifier normalization`); // eslint-disable-line functional/immutable-data\n return;\n }\n\n return;\n }\n}\n\nconst alephInternal01 = '(FIN01)';\nconst alephInternal10 = '(FIN10)';\nconst alephInternal11 = '(FIN11)';\nconst alephInternal12 = '(FIN12)';\nconst alephInternal13 = '(FIN13)';\n\nconst standard01 = '(FI-MELINDA)';\nconst standard10 = '(FI-ASTERI-S)';\nconst standard11 = '(FI-ASTERI-N)';\nconst standard12 = '(FI-ASTERI-A)';\nconst standard13 = '(FI-ASTERI-W)';\n\nconst both01 = {ALEPH_INTERNAL: alephInternal01, STANDARD: standard01};\nconst both10 = {ALEPH_INTERNAL: alephInternal10, STANDARD: standard10};\nconst both11 = {ALEPH_INTERNAL: alephInternal11, STANDARD: standard11};\nconst both12 = {ALEPH_INTERNAL: alephInternal12, STANDARD: standard12};\nconst both13 = {ALEPH_INTERNAL: alephInternal13, STANDARD: standard13};\n\nconst mappings = {\n 'FCC': both01,\n '(FI-ASTERI-A)': both12,\n '(FI-ASTERI-N)': both11,\n '(FI-ASTERI-S)': both10,\n '(FI-ASTERI-W)': both13,\n '(FI-MELINDA)': both01,\n '(FIN01)': both01,\n '(FIN10)': both10,\n '(FIN11)': both11,\n '(FIN12)': both12,\n '(FIN13)': both13,\n 'http://urn.fi/URN:NBN:fi:au:finaf:': both11,\n 'https://urn.fi/URN:NBN:fi:au:finaf:': both11\n};\n\nfunction normalizeNineDigitIDs(value, targetFormat = 'ALEPH_INTERNAL') {\n // $value should be prefix + nine-digits. Do nothing if nine-digit tail condition is not met:\n const nineDigitTail = value.slice(-9);\n if (!(/^[0-9]{9}$/u).test(nineDigitTail)) {\n return value;\n }\n // Normalize prefix:\n const currPrefix = value.slice(0, -9);\n\n if (currPrefix in mappings) {\n //nvdebug(`${currPrefix}, TF:${targetFormat}...`);\n //nvdebug(`${JSON.stringify(mappings[currPrefix])}`);\n return `${mappings[currPrefix][targetFormat]}${nineDigitTail}`;\n }\n return value;\n}\n\nexport function isIsni(value) {\n if ((/^\\(isni\\)(?: ?[0-9]{4}){4}$/u).test(value)) {\n return true;\n }\n if ((/^https:\\/\\/isni.org\\/isni\\/[0-9]{16}$/u).test(value)) {\n return true;\n }\n return false;\n}\n\nexport function normalizeIsni(value) {\n if (isIsni(value)) {\n return `https://isni.org/isni/${value.replace(/[^0-9]/gu, '')}`;\n }\n return value;\n}\n\n\nexport function normalizeControlSubfieldValue(value = '', targetFormat = 'ALEPH_INTERNAL') {\n if (isIsni(value)) {\n return normalizeIsni(value);\n }\n\n const normalizedValue = normalizeNineDigitIDs(value, targetFormat);\n if (normalizedValue !== value) {\n return normalizedValue;\n }\n\n // Something for isni IDs?\n return value;\n}\n\n//export function normalizableSubfieldPrefix(tag, sf) {\nexport function normalizeAs(tag, subfieldCode) {\n //nvdebug(`nAs ${tag}, ${subfieldCode}`);\n if (subfieldCode === '0' || subfieldCode === '1' || subfieldCode === 'w') {\n return 'ALEPH_INTERNAL';\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) {\n return 'STANDARD';\n }\n return undefined;\n}\n\nexport function fieldNormalizeControlNumbers(field) {\n // Rename \"Prefixes\" as \"ControlNumberIdentifiers\"?\n // No, since isni etc... however, just \"ControlNumber\" would do...\n // \"identifiers\" ?\n if (!field.subfields) {\n return;\n }\n\n field.subfields.forEach(sf => {\n const targetFormat = normalizeAs(field.tag, sf.code);\n if (targetFormat !== undefined) {\n //nvdebug(`NORMALIZE SUBFIELD $${sf.code} IN FIELD: '${fieldToString(field)}' TO ${targetFormat}`);\n sf.value = normalizeControlSubfieldValue(sf.value, targetFormat); // eslint-disable-line functional/immutable-data\n return;\n }\n });\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"normalize-identifiers.js","names":["_clone","_interopRequireDefault","require","_utils","e","__esModule","default","_default","description","validate","fix","record","res","message","valid","fields","forEach","field","fieldNormalizeControlNumbers","validateField","length","subfields","normalizedField","clone","orig","fieldToString","mod","push","alephInternal01","alephInternal10","alephInternal11","alephInternal12","alephInternal13","standard01","standard10","standard11","standard12","standard13","both01","ALEPH_INTERNAL","STANDARD","both10","both11","both12","both13","mappings","normalizeNineDigitIDs","value","targetFormat","nineDigitTail","slice","test","currPrefix","isIsni","normalizeIsni","replace","normalizeControlSubfieldValue","normalizedValue","normalizeAs","tag","subfieldCode","includes","undefined","sf","code"],"sources":["../src/normalize-identifiers.js"],"sourcesContent":["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString} from './utils';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\n/*\nfunction nvdebug(message, func) {\n if (func) { // eslint-disable-line functional/no-conditional-statements\n func(message);\n }\n console.info(message); // eslint-disable-line no-console\n}\n*/\n\nexport default function () {\n\n // NB! We should and could handle ISNIs here as well.\n return {\n description: 'Normalizes identifiers such as subfield $0 values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n //message.fix = []; // eslint-disable-line functional/immutable-data\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n //nvdebug(`NORMALIZE CONTROL NUMBER FIX`, debug);\n record.fields.forEach(field => {\n //nvdebug(` NORMALIZE CONTROL NUMBER FIX ${fieldToString(field)}`, debug);\n\n fieldNormalizeControlNumbers(field);\n //validateField(field, true, message);\n });\n\n // message.valid = !(message.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n //nvdebug(`NORMALIZE CONTROL NUMBER VALIDATE`, debug);\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n //nvdebug(` NORMALIZE CONTROL NUMBER VALIDATE ${fieldToString(field)}`, debug);\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validateField(field, res) {\n if (!field.subfields) {\n return;\n }\n\n const normalizedField = clone(field);\n fieldNormalizeControlNumbers(normalizedField);\n\n const orig = fieldToString(field);\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'${orig}' could do with control number identifier normalization`); // eslint-disable-line functional/immutable-data\n return;\n }\n\n return;\n }\n}\n\nconst alephInternal01 = '(FIN01)';\nconst alephInternal10 = '(FIN10)';\nconst alephInternal11 = '(FIN11)';\nconst alephInternal12 = '(FIN12)';\nconst alephInternal13 = '(FIN13)';\n\nconst standard01 = '(FI-MELINDA)';\nconst standard10 = '(FI-ASTERI-S)';\nconst standard11 = '(FI-ASTERI-N)';\nconst standard12 = '(FI-ASTERI-A)';\nconst standard13 = '(FI-ASTERI-W)';\n\nconst both01 = {ALEPH_INTERNAL: alephInternal01, STANDARD: standard01};\nconst both10 = {ALEPH_INTERNAL: alephInternal10, STANDARD: standard10};\nconst both11 = {ALEPH_INTERNAL: alephInternal11, STANDARD: standard11};\nconst both12 = {ALEPH_INTERNAL: alephInternal12, STANDARD: standard12};\nconst both13 = {ALEPH_INTERNAL: alephInternal13, STANDARD: standard13};\n\nconst mappings = {\n 'FCC': both01,\n '(FI-ASTERI-A)': both12,\n '(FI-ASTERI-N)': both11,\n '(FI-ASTERI-S)': both10,\n '(FI-ASTERI-W)': both13,\n '(FI-MELINDA)': both01,\n '(FIN01)': both01,\n '(FIN10)': both10,\n '(FIN11)': both11,\n '(FIN12)': both12,\n '(FIN13)': both13,\n 'http://urn.fi/URN:NBN:fi:au:finaf:': both11,\n 'https://urn.fi/URN:NBN:fi:au:finaf:': both11\n};\n\nfunction normalizeNineDigitIDs(value, targetFormat = 'ALEPH_INTERNAL') {\n // $value should be prefix + nine-digits. Do nothing if nine-digit tail condition is not met:\n const nineDigitTail = value.slice(-9);\n if (!(/^[0-9]{9}$/u).test(nineDigitTail)) {\n return value;\n }\n // Normalize prefix:\n const currPrefix = value.slice(0, -9);\n\n if (currPrefix in mappings) {\n //nvdebug(`${currPrefix}, TF:${targetFormat}...`);\n //nvdebug(`${JSON.stringify(mappings[currPrefix])}`);\n return `${mappings[currPrefix][targetFormat]}${nineDigitTail}`;\n }\n return value;\n}\n\nexport function isIsni(value) {\n if ((/^\\(isni\\)(?: ?[0-9]{4}){4}$/u).test(value)) {\n return true;\n }\n if ((/^https:\\/\\/isni.org\\/isni\\/[0-9]{16}$/u).test(value)) {\n return true;\n }\n return false;\n}\n\nexport function normalizeIsni(value) {\n if (isIsni(value)) {\n return `https://isni.org/isni/${value.replace(/[^0-9]/gu, '')}`;\n }\n return value;\n}\n\n\nexport function normalizeControlSubfieldValue(value = '', targetFormat = 'ALEPH_INTERNAL') {\n if (isIsni(value)) {\n return normalizeIsni(value);\n }\n\n const normalizedValue = normalizeNineDigitIDs(value, targetFormat);\n if (normalizedValue !== value) {\n return normalizedValue;\n }\n\n // Something for isni IDs?\n return value;\n}\n\n//export function normalizableSubfieldPrefix(tag, sf) {\nexport function normalizeAs(tag, subfieldCode) {\n //nvdebug(`nAs ${tag}, ${subfieldCode}`);\n if (subfieldCode === '0' || subfieldCode === '1' || subfieldCode === 'w') {\n return 'ALEPH_INTERNAL';\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) {\n return 'STANDARD';\n }\n return undefined;\n}\n\nexport function fieldNormalizeControlNumbers(field) {\n // Rename \"Prefixes\" as \"ControlNumberIdentifiers\"?\n // No, since isni etc... however, just \"ControlNumber\" would do...\n // \"identifiers\" ?\n if (!field.subfields) {\n return;\n }\n\n field.subfields.forEach(sf => {\n const targetFormat = normalizeAs(field.tag, sf.code);\n if (targetFormat !== undefined) {\n //nvdebug(`NORMALIZE SUBFIELD $${sf.code} IN FIELD: '${fieldToString(field)}' TO ${targetFormat}`);\n sf.value = normalizeControlSubfieldValue(sf.value, targetFormat); // eslint-disable-line functional/immutable-data\n return;\n }\n });\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,7 +6,7 @@ var _normalizeIdentifiers = _interopRequireDefault(require("./normalize-identifi
|
|
|
6
6
|
var _fixura = require("@natlibfi/fixura");
|
|
7
7
|
var _fixugen = _interopRequireDefault(require("@natlibfi/fixugen"));
|
|
8
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
function _interopRequireDefault(
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
(0, _fixugen.default)({
|
|
11
11
|
callback,
|
|
12
12
|
path: [__dirname, '..', 'test-fixtures', 'normalize-identifiers'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-identifiers.spec.js","names":["_chai","require","_marcRecord","_normalizeIdentifiers","_interopRequireDefault","_fixura","_fixugen","_debug","
|
|
1
|
+
{"version":3,"file":"normalize-identifiers.spec.js","names":["_chai","require","_marcRecord","_normalizeIdentifiers","_interopRequireDefault","_fixura","_fixugen","_debug","e","__esModule","default","generateTests","callback","path","__dirname","useMetadataFile","recurse","fixura","reader","READERS","JSON","mocha","before","testValidatorFactory","debug","createDebugLogger","validator","validatorFactory","expect","to","be","an","that","has","any","keys","description","a","validate","getFixture","enabled","fix","record","MarcRecord","expectedResult","result","eql"],"sources":["../src/normalize-identifiers.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './normalize-identifiers';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'normalize-identifiers'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n mocha: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-identifiers:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('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 expect(result).to.eql(expectedResult);\n return;\n }\n\n await validator.fix(record);\n expect(record).to.eql(expectedResult);\n}\n"],"mappings":";;AAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,qBAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,QAAA,GAAAF,sBAAA,CAAAH,OAAA;AACA,IAAAM,MAAA,GAAAH,sBAAA,CAAAH,OAAA;AAAsC,SAAAG,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEtC,IAAAG,gBAAa,EAAC;EACZC,QAAQ;EACRC,IAAI,EAAE,CAACC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,uBAAuB,CAAC;EACjEC,eAAe,EAAE,IAAI;EACrBC,OAAO,EAAE,KAAK;EACdC,MAAM,EAAE;IACNC,MAAM,EAAEC,eAAO,CAACC;EAClB,CAAC;EACDC,KAAK,EAAE;IACLC,MAAM,EAAEA,CAAA,KAAMC,oBAAoB,CAAC;EACrC;AACF,CAAC,CAAC;AACF,MAAMC,KAAK,GAAG,IAAAC,cAAiB,EAAC,qEAAqE,CAAC;AAEtG,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,6BAAgB,EAAC,CAAC;EAE1C,IAAAC,YAAM,EAACF,SAAS,CAAC,CACdG,EAAE,CAACC,EAAE,CAACC,EAAE,CAAC,QAAQ,CAAC,CAClBC,IAAI,CAACC,GAAG,CAACC,GAAG,CAACC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC;EAE/C,IAAAP,YAAM,EAACF,SAAS,CAACU,WAAW,CAAC,CAACP,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,QAAQ,CAAC;EAC/C,IAAAT,YAAM,EAACF,SAAS,CAACY,QAAQ,CAAC,CAACT,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,UAAU,CAAC;AAChD;AAEA,eAAezB,QAAQA,CAAC;EAAC2B,UAAU;EAAEC,OAAO,GAAG,IAAI;EAAEC,GAAG,GAAG;AAAK,CAAC,EAAE;EACjE,IAAID,OAAO,KAAK,KAAK,EAAE;IACrBhB,KAAK,CAAC,eAAe,CAAC;IACtB;EACF;EAEA,MAAME,SAAS,GAAG,MAAM,IAAAC,6BAAgB,EAAC,CAAC;EAC1C,MAAMe,MAAM,GAAG,IAAIC,sBAAU,CAACJ,UAAU,CAAC,aAAa,CAAC,CAAC;EACxD,MAAMK,cAAc,GAAGL,UAAU,CAAC,qBAAqB,CAAC;EACxD;;EAEA,IAAI,CAACE,GAAG,EAAE;IACR,MAAMI,MAAM,GAAG,MAAMnB,SAAS,CAACY,QAAQ,CAACI,MAAM,CAAC;IAC/C,IAAAd,YAAM,EAACiB,MAAM,CAAC,CAAChB,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;IACrC;EACF;EAEA,MAAMlB,SAAS,CAACe,GAAG,CAACC,MAAM,CAAC;EAC3B,IAAAd,YAAM,EAACc,MAAM,CAAC,CAACb,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;AACvC","ignoreList":[]}
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = _default;
|
|
7
7
|
var _clone = _interopRequireDefault(require("clone"));
|
|
8
8
|
var _utils = require("./utils");
|
|
9
|
-
function _interopRequireDefault(
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
//import createDebugLogger from 'debug';
|
|
11
11
|
|
|
12
12
|
// Author(s): Nicholas Volk
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-qualifying-information.js","names":["_clone","_interopRequireDefault","require","_utils","
|
|
1
|
+
{"version":3,"file":"normalize-qualifying-information.js","names":["_clone","_interopRequireDefault","require","_utils","e","__esModule","default","_default","description","validate","fix","record","fields","forEach","field","normalizeQualifyingInformationField","res","message","valid","validateField","length","orig","fieldToString","normalizedField","clone","mod","push","includes","tag","subfields","sf","fixSubfield","code","value","normalizeValue","val","match"],"sources":["../src/normalize-qualifying-information.js"],"sourcesContent":["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString} from './utils';\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n // Fixes MELINDA-8740\n description: 'Normalize qualifying information (020$q, 015$q, 024$q, 028$q)',\n validate, fix\n };\n\n function fix(record) {\n record.fields.forEach(field => {\n normalizeQualifyingInformationField(field);\n });\n\n const res = {message: [], fix: [], valid: true};\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n record.fields?.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validateField(field, res) {\n const orig = fieldToString(field);\n\n const normalizedField = clone(field);\n normalizeQualifyingInformationField(normalizedField);\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'TODO: ${orig}' => '${mod}'`); // eslint-disable-line functional/immutable-data\n return;\n }\n return;\n }\n}\n\n\nfunction normalizeQualifyingInformationField(field) {\n if (!['015', '020', '024', '028'].includes(field.tag) || !field.subfields) {\n return;\n }\n\n field.subfields.forEach(sf => fixSubfield(sf));\n return;\n\n function fixSubfield(sf) {\n if (sf.code !== 'q') {\n return;\n }\n sf.value = normalizeValue(sf.value); // eslint-disable-line functional/immutable-data\n }\n\n function normalizeValue(val) {\n // Should we do English as well: \"coil bound\" and \"comb-bound\" => \"spiral-bound\" (as per MTS)?\n\n if (val.match(/^(?:hft|häftad)[.,]*$/iu)) { // MELINDA-8740\n return 'mjuka pärmar';\n }\n\n if (val.match(/^inb(?:\\.|unden)[.,]*$/iu)) { // MELINDA-8740\n return 'hårda pärmar';\n }\n\n if (val === 'rengaskirja') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'kierreselkä';\n }\n\n if (val === 'ringpärm') { // https://www.kiwi.fi/display/melinda/Talonmies+tiedottaa+16.12.2021\n return 'spiralrygg';\n }\n\n if (val.match(/^nid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'pehmeäkantinen';\n }\n\n if (val.match(/^sid(?:\\.|ottu)[.,]*$/iu)) { // MELINDA-8740\n return 'kovakantinen';\n }\n return val;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,7 +6,7 @@ var _normalizeQualifyingInformation = _interopRequireDefault(require("./normaliz
|
|
|
6
6
|
var _fixura = require("@natlibfi/fixura");
|
|
7
7
|
var _fixugen = _interopRequireDefault(require("@natlibfi/fixugen"));
|
|
8
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
function _interopRequireDefault(
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
(0, _fixugen.default)({
|
|
11
11
|
callback,
|
|
12
12
|
path: [__dirname, '..', 'test-fixtures', 'normalize-qualifying-information'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-qualifying-information.spec.js","names":["_chai","require","_marcRecord","_normalizeQualifyingInformation","_interopRequireDefault","_fixura","_fixugen","_debug","
|
|
1
|
+
{"version":3,"file":"normalize-qualifying-information.spec.js","names":["_chai","require","_marcRecord","_normalizeQualifyingInformation","_interopRequireDefault","_fixura","_fixugen","_debug","e","__esModule","default","generateTests","callback","path","__dirname","useMetadataFile","recurse","fixura","reader","READERS","JSON","mocha","before","testValidatorFactory","debug","createDebugLogger","validator","validatorFactory","expect","to","be","an","that","has","any","keys","description","a","validate","getFixture","enabled","fix","record","MarcRecord","expectedResult","result","eql"],"sources":["../src/normalize-qualifying-information.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './normalize-qualifying-information';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'normalize-qualifying-information'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n mocha: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-qualifying-information:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('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 expect(result).to.eql(expectedResult);\n return;\n }\n\n await validator.fix(record);\n expect(record).to.eql(expectedResult);\n}\n"],"mappings":";;AAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,+BAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,QAAA,GAAAF,sBAAA,CAAAH,OAAA;AACA,IAAAM,MAAA,GAAAH,sBAAA,CAAAH,OAAA;AAAsC,SAAAG,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEtC,IAAAG,gBAAa,EAAC;EACZC,QAAQ;EACRC,IAAI,EAAE,CAACC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,kCAAkC,CAAC;EAC5EC,eAAe,EAAE,IAAI;EACrBC,OAAO,EAAE,KAAK;EACdC,MAAM,EAAE;IACNC,MAAM,EAAEC,eAAO,CAACC;EAClB,CAAC;EACDC,KAAK,EAAE;IACLC,MAAM,EAAEA,CAAA,KAAMC,oBAAoB,CAAC;EACrC;AACF,CAAC,CAAC;AACF,MAAMC,KAAK,GAAG,IAAAC,cAAiB,EAAC,gFAAgF,CAAC;AAEjH,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,uCAAgB,EAAC,CAAC;EAE1C,IAAAC,YAAM,EAACF,SAAS,CAAC,CACdG,EAAE,CAACC,EAAE,CAACC,EAAE,CAAC,QAAQ,CAAC,CAClBC,IAAI,CAACC,GAAG,CAACC,GAAG,CAACC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC;EAE/C,IAAAP,YAAM,EAACF,SAAS,CAACU,WAAW,CAAC,CAACP,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,QAAQ,CAAC;EAC/C,IAAAT,YAAM,EAACF,SAAS,CAACY,QAAQ,CAAC,CAACT,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,UAAU,CAAC;AAChD;AAEA,eAAezB,QAAQA,CAAC;EAAC2B,UAAU;EAAEC,OAAO,GAAG,IAAI;EAAEC,GAAG,GAAG;AAAK,CAAC,EAAE;EACjE,IAAID,OAAO,KAAK,KAAK,EAAE;IACrBhB,KAAK,CAAC,eAAe,CAAC;IACtB;EACF;EAEA,MAAME,SAAS,GAAG,MAAM,IAAAC,uCAAgB,EAAC,CAAC;EAC1C,MAAMe,MAAM,GAAG,IAAIC,sBAAU,CAACJ,UAAU,CAAC,aAAa,CAAC,CAAC;EACxD,MAAMK,cAAc,GAAGL,UAAU,CAAC,qBAAqB,CAAC;EACxD;;EAEA,IAAI,CAACE,GAAG,EAAE;IACR,MAAMI,MAAM,GAAG,MAAMnB,SAAS,CAACY,QAAQ,CAACI,MAAM,CAAC;IAC/C,IAAAd,YAAM,EAACiB,MAAM,CAAC,CAAChB,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;IACrC;EACF;EAEA,MAAMlB,SAAS,CAACe,GAAG,CAACC,MAAM,CAAC;EAC3B,IAAAd,YAAM,EAACc,MAAM,CAAC,CAACb,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;AACvC","ignoreList":[]}
|
|
@@ -10,7 +10,7 @@ exports.precomposeFinnishLetters = precomposeFinnishLetters;
|
|
|
10
10
|
var _clone = _interopRequireDefault(require("clone"));
|
|
11
11
|
var _unicodeDecomposition = require("./unicode-decomposition");
|
|
12
12
|
var _utils = require("./utils");
|
|
13
|
-
function _interopRequireDefault(
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
14
|
//import createDebugLogger from 'debug';
|
|
15
15
|
|
|
16
16
|
// Note that https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js contains
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-utf8-diacritics.js","names":["_clone","_interopRequireDefault","require","_unicodeDecomposition","_utils","
|
|
1
|
+
{"version":3,"file":"normalize-utf8-diacritics.js","names":["_clone","_interopRequireDefault","require","_unicodeDecomposition","_utils","e","__esModule","default","_default","description","validate","fix","record","res","message","valid","fields","forEach","field","fieldFixComposition","validateField","length","subfields","orig","fieldToString","normalizedField","clone","mod","push","precomposeFinnishLetters","value","replace","fixComposition","match","nongenericNormalization","String","normalize","subfield","index"],"sources":["../src/normalize-utf8-diacritics.js"],"sourcesContent":["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {convert as nongenericNormalization} from './unicode-decomposition';\nimport {fieldToString} from './utils';\n\n// Note that https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js contains\n// similar functionalities. It's less generic and lacks diacritic removal but has it advantages as well.\n\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-utf-diacritics');\n\n// See also https://github.com/NatLibFi/marc-record-validators-melinda/blob/master/src/unicode-decomposition.js .\n// It uses a list of convertable characters whilst this uses a generic stuff as well.\n// It handles various '.' and '©' type normalizations as well.\n// NB! This version has minor bug/feature issue regarding fixComposition()\n\n// Author(s): Nicholas Volk\nexport default function () {\n\n return {\n description: 'Generic normalization of latin UTF-8 diacritics. Precompose Finnish å, ä and ö. Decompose others.',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n //message.fix = []; // eslint-disable-line functional/immutable-data\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n fieldFixComposition(field);\n //validateField(field, true, message);\n });\n\n // message.valid = !(message.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n // Actual parsing of all fields\n /*\n if (!record.fields) {\n return false;\n }\n */\n\n record.fields.forEach(field => {\n validateField(field, res);\n });\n\n res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n\n function validateField(field, res) {\n if (!field.subfields) {\n return;\n }\n const orig = fieldToString(field);\n\n const normalizedField = fieldFixComposition(clone(field));\n const mod = fieldToString(normalizedField);\n if (orig !== mod) { // Fail as the input is \"broken\"/\"crap\"/sumthing\n res.message.push(`'${orig}' requires normalization`); // eslint-disable-line functional/immutable-data\n return;\n }\n return;\n }\n}\n\n\n// Traditionally these six are precomposed and all the rest decomposed\nexport function precomposeFinnishLetters(value = '') {\n return value.\n replace(/å/gu, 'å').\n replace(/ä/gu, 'ä').\n replace(/ö/gu, 'ö').\n replace(/Å/gu, 'Å').\n replace(/Ä/gu, 'Ä').\n replace(/Ö/gu, 'Ö');\n}\n\nexport function fixComposition(value = '') {\n // Target: Diacritics use Melinda internal notation.\n // General solution: Decompose everything and then compose 'å', 'ä', 'ö', 'Å', 'Ä' and 'Ö'.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n // Bug/Feature: the generic normalize() function also normalizes non-latin encodings as well, is this ok?\n // Exception: Input contains non-Latin script letters: don't decompose (see field 880 tests):\n if (value.match(/[^\\p{Script=Latin}\\p{Script=Common}\\p{Script=Inherited}]/u)) {\n // Problem with this approach: mixed language content (eg. cyrillic + latin) won't get normalized.\n // Hack/Damage control: we might add decomposition rules for most common diacritis here (eg. ü, é...).\n // OR we could split input to words and handle them separately?\n // NB! Hack not implemented yet. The main source of problematic case would probably be greek characters\n // within texts, that are written with latin alphabet.\n //return precomposeFinnishLetters(value);\n return nongenericNormalization(value);\n }\n return precomposeFinnishLetters(String(value).normalize('NFD'));\n}\n\n\nexport function fieldFixComposition(field) {\n if (!field.subfields) {\n return field;\n }\n //const originalValue = fieldToString(field);\n //nvdebug(`fFC: '${originalValue}'`, debug);\n field.subfields.forEach((subfield, index) => {\n field.subfields[index].value = fixComposition(subfield.value); // eslint-disable-line functional/immutable-data\n });\n //const newValue = fieldToString(field);\n //if (originalValue !== newValue) { // eslint-disable-line functional/no-conditional-statements\n // debug(`FIXCOMP: '${originalValue}' => '${newValue}'`);\n //}\n return field;\n}\n\n/*\nexport function fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n });\n\n function removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. String.normalize('NFD') can handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this.\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n }\n}\n*/\n\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,7 +6,7 @@ var _normalizeUtf8Diacritics = _interopRequireDefault(require("./normalize-utf8-
|
|
|
6
6
|
var _fixura = require("@natlibfi/fixura");
|
|
7
7
|
var _fixugen = _interopRequireDefault(require("@natlibfi/fixugen"));
|
|
8
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
function _interopRequireDefault(
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
(0, _fixugen.default)({
|
|
11
11
|
callback,
|
|
12
12
|
path: [__dirname, '..', 'test-fixtures', 'normalize-utf8-diacritics'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-utf8-diacritics.spec.js","names":["_chai","require","_marcRecord","_normalizeUtf8Diacritics","_interopRequireDefault","_fixura","_fixugen","_debug","
|
|
1
|
+
{"version":3,"file":"normalize-utf8-diacritics.spec.js","names":["_chai","require","_marcRecord","_normalizeUtf8Diacritics","_interopRequireDefault","_fixura","_fixugen","_debug","e","__esModule","default","generateTests","callback","path","__dirname","useMetadataFile","recurse","fixura","reader","READERS","JSON","mocha","before","testValidatorFactory","debug","createDebugLogger","validator","validatorFactory","expect","to","be","an","that","has","any","keys","description","a","validate","getFixture","enabled","fix","record","MarcRecord","expectedResult","result","eql"],"sources":["../src/normalize-utf8-diacritics.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './normalize-utf8-diacritics';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'normalize-utf8-diacritics'],\n useMetadataFile: true,\n recurse: false,\n fixura: {\n reader: READERS.JSON\n },\n mocha: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-utf8-diacritics:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('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 expect(result).to.eql(expectedResult);\n return;\n }\n\n await validator.fix(record);\n expect(record).to.eql(expectedResult);\n}\n"],"mappings":";;AAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,wBAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,QAAA,GAAAF,sBAAA,CAAAH,OAAA;AACA,IAAAM,MAAA,GAAAH,sBAAA,CAAAH,OAAA;AAAsC,SAAAG,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEtC,IAAAG,gBAAa,EAAC;EACZC,QAAQ;EACRC,IAAI,EAAE,CAACC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,2BAA2B,CAAC;EACrEC,eAAe,EAAE,IAAI;EACrBC,OAAO,EAAE,KAAK;EACdC,MAAM,EAAE;IACNC,MAAM,EAAEC,eAAO,CAACC;EAClB,CAAC;EACDC,KAAK,EAAE;IACLC,MAAM,EAAEA,CAAA,KAAMC,oBAAoB,CAAC;EACrC;AACF,CAAC,CAAC;AACF,MAAMC,KAAK,GAAG,IAAAC,cAAiB,EAAC,yEAAyE,CAAC;AAE1G,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,gCAAgB,EAAC,CAAC;EAE1C,IAAAC,YAAM,EAACF,SAAS,CAAC,CACdG,EAAE,CAACC,EAAE,CAACC,EAAE,CAAC,QAAQ,CAAC,CAClBC,IAAI,CAACC,GAAG,CAACC,GAAG,CAACC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC;EAE/C,IAAAP,YAAM,EAACF,SAAS,CAACU,WAAW,CAAC,CAACP,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,QAAQ,CAAC;EAC/C,IAAAT,YAAM,EAACF,SAAS,CAACY,QAAQ,CAAC,CAACT,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,UAAU,CAAC;AAChD;AAEA,eAAezB,QAAQA,CAAC;EAAC2B,UAAU;EAAEC,OAAO,GAAG,IAAI;EAAEC,GAAG,GAAG;AAAK,CAAC,EAAE;EACjE,IAAID,OAAO,KAAK,KAAK,EAAE;IACrBhB,KAAK,CAAC,eAAe,CAAC;IACtB;EACF;EAEA,MAAME,SAAS,GAAG,MAAM,IAAAC,gCAAgB,EAAC,CAAC;EAC1C,MAAMe,MAAM,GAAG,IAAIC,sBAAU,CAACJ,UAAU,CAAC,aAAa,CAAC,CAAC;EACxD,MAAMK,cAAc,GAAGL,UAAU,CAAC,qBAAqB,CAAC;EACxD;;EAEA,IAAI,CAACE,GAAG,EAAE;IACR,MAAMI,MAAM,GAAG,MAAMnB,SAAS,CAACY,QAAQ,CAACI,MAAM,CAAC;IAC/C,IAAAd,YAAM,EAACiB,MAAM,CAAC,CAAChB,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;IACrC;EACF;EAEA,MAAMlB,SAAS,CAACe,GAAG,CAACC,MAAM,CAAC;EAC3B,IAAAd,YAAM,EAACc,MAAM,CAAC,CAACb,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;AACvC","ignoreList":[]}
|
|
@@ -13,7 +13,7 @@ var _utils = require("./utils.js");
|
|
|
13
13
|
var _normalizeIdentifiers = require("./normalize-identifiers");
|
|
14
14
|
var _debug = _interopRequireDefault(require("debug"));
|
|
15
15
|
var _normalizeSubfieldValueForComparison = require("./normalizeSubfieldValueForComparison");
|
|
16
|
-
function _interopRequireDefault(
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
17
|
/*
|
|
18
18
|
Note that this file contains very powerful normalizations and spells that are:
|
|
19
19
|
- meant for comparing similarity/mergability of two fields (clone, normalize, compare),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","obj","__esModule","default","debug","createDebugLogger","debugDev","extend","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","value","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","code","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","subfield","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","match","normalizeISBN","relevantSubfields","filter","normalizeIsbnSubfield","fieldSpecificHacks","fieldTrimSubfieldValues","fieldRemoveDecomposedDiacritics","removeDecomposedDiacritics","String","normalizeSubfieldValue","normalizePartData","cloneAndRemovePunctuation","clonedField","clone","fieldSkipNormalization","fieldStripPunctuation","removeCharsThatDontCarryMeaning","normalizeField","fieldNormalizeControlNumbers","cloneAndNormalizeFieldForComparison"],"sources":["../src/normalizeFieldForComparison.js"],"sourcesContent":["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalize');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) { // eslint-disable-line functional/no-conditional-statements\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) { // eslint-disable-line functional/no-conditional-statements\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n\n if (subfieldCode === 'g' && value === 'ENNAKKOTIETO.') {\n return true;\n }\n\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag); // eslint-disable-line functional/immutable-data\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf));\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp; // eslint-disable-line functional/immutable-data\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf));\n\n function normalizeIsbnSubfield(sf) {\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/x/u, 'X'); // eslint-disable-line functional/immutable-data\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' '); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data, prefer-named-capture-group\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?\n // Ø => Ö?\n // ß => ss\n // þ => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // ü => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n /* eslint-disable */\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['‘’\"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|Å|Ä|Ö)\\. +/ugi, '$1.');\n }\n /* eslint-enable */\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag); // eslint-disable-line functional/immutable-data\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);// eslint-disable-line functional/immutable-data\n });\n\n normalizeField(clonedField); // eslint-disable-line functional/immutable-data\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","e","__esModule","default","debug","createDebugLogger","debugDev","extend","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","value","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","code","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","subfield","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","match","normalizeISBN","relevantSubfields","filter","normalizeIsbnSubfield","fieldSpecificHacks","fieldTrimSubfieldValues","fieldRemoveDecomposedDiacritics","removeDecomposedDiacritics","String","normalizeSubfieldValue","normalizePartData","cloneAndRemovePunctuation","clonedField","clone","fieldSkipNormalization","fieldStripPunctuation","removeCharsThatDontCarryMeaning","normalizeField","fieldNormalizeControlNumbers","cloneAndNormalizeFieldForComparison"],"sources":["../src/normalizeFieldForComparison.js"],"sourcesContent":["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalize');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) { // eslint-disable-line functional/no-conditional-statements\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) { // eslint-disable-line functional/no-conditional-statements\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n\n if (subfieldCode === 'g' && value === 'ENNAKKOTIETO.') {\n return true;\n }\n\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag); // eslint-disable-line functional/immutable-data\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf));\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp; // eslint-disable-line functional/immutable-data\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf));\n\n function normalizeIsbnSubfield(sf) {\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/x/u, 'X'); // eslint-disable-line functional/immutable-data\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, ''); // eslint-disable-line functional/immutable-data\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' '); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data, prefer-named-capture-group\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?\n // Ø => Ö?\n // ß => ss\n // þ => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // ü => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n /* eslint-disable */\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['‘’\"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|Å|Ä|Ö)\\. +/ugi, '$1.');\n }\n /* eslint-enable */\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value); // eslint-disable-line functional/immutable-data\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag); // eslint-disable-line functional/immutable-data\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);// eslint-disable-line functional/immutable-data\n });\n\n normalizeField(clonedField); // eslint-disable-line functional/immutable-data\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -8,7 +8,7 @@ exports.partsAgree = partsAgree;
|
|
|
8
8
|
exports.subfieldContainsPartData = subfieldContainsPartData;
|
|
9
9
|
var _utils = require("./utils");
|
|
10
10
|
var _debug = _interopRequireDefault(require("debug"));
|
|
11
|
-
function _interopRequireDefault(
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
// Normalizes at least 490$v and 773$g which contain information such as "Raita 5" vs "5", and "Osa 3" vs "Osa III".
|
|
13
13
|
|
|
14
14
|
const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalizePart');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeSubfieldValueForComparison.js","names":["_utils","require","_debug","_interopRequireDefault","obj","__esModule","default","debug","createDebugLogger","debugDev","extend","subfieldContainsPartData","tag","subfieldCode","includes","splitPartData","originalValue","value","replace","year","rest","extractYear","splitPoint","lastIndexOf","undefined","lhs","substr","rhs","match","len","length","normalizePartType","toLowerCase","romanNumbers","normalizePartNumber","arabicValue","nvdebug","splitAndNormalizePartData","partType","partYear","partNumber","partsAgree","value1","value2","partType1","partYear1","partNumber1","partType2","partYear2","partNumber2","normalizePartData"],"sources":["../src/normalizeSubfieldValueForComparison.js"],"sourcesContent":["import {nvdebug} from './utils';\nimport createDebugLogger from 'debug';\n\n// Normalizes at least 490$v and 773$g which contain information such as \"Raita 5\" vs \"5\", and \"Osa 3\" vs \"Osa III\".\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizePart');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function subfieldContainsPartData(tag, subfieldCode) {\n // NB! Used by reducers' mergeSubield.js\n if (subfieldCode === 'v' && ['490', '800', '810', '811', '830'].includes(tag)) {\n return true;\n }\n if (tag === '773' && subfieldCode === 'g') {\n return true;\n }\n return false;\n}\n\nfunction splitPartData(originalValue) {\n // This a very hacky function, but cand really help it, as the the data is very iffy as well...\n // Remove punctuation and brackets:\n const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\\[([0-9]+)\\]$/ui, '$1'); // eslint-disable-line prefer-named-capture-group\n\n const [year, rest] = extractYear(value);\n\n const splitPoint = rest.lastIndexOf(' '); // MRA-627: \"5, 2017\" should be split here. Think of this later on...\n if (splitPoint === -1) {\n return [undefined, year, rest];\n }\n const lhs = rest.substr(0, splitPoint);\n const rhs = rest.substr(splitPoint + 1);\n return [lhs, year, rhs];\n\n function extractYear(value) {\n // NB! Note that this is far for perfect. It cover just some very common cases...\n\n // \"2023, 3\" => [\"2023\", \"3\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9]), (?:nro |n:o)?[1-9][0-9]{0,2}$/ui)) {\n return [value.substr(0, 4), value.substr(6)];\n }\n // \"2023/12\" => [\"2023\", \"12\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9])[/:][1-9][0-9]{0,2}$/u)) {\n return [value.substr(0, 4), value.substr(5)];\n }\n // \"Vol. 3/2023\" => [\"2023\", \"Vol. 3\"]\n if (value.match(/^[^0-9]*[1-9][0-9]{0,2}\\/(?:1[89][0-9][0-9]|20[012][0-9])$/u)) {\n const len = value.length;\n return [value.substr(len - 4), value.substr(0, len - 5)];\n }\n\n\n return [undefined, value];\n }\n}\n\nfunction normalizePartType(originalValue) {\n if (originalValue === undefined) {\n return undefined;\n }\n const value = originalValue.toLowerCase();\n\n // Return Finnish singular nominative. Choise of language is arbitrary. This is best-ish for debug purposes...\n if (['n:o', 'no', 'nr', 'nro', 'number', 'numero', 'nummer'].includes(value)) {\n return 'numero';\n }\n if (['band', 'bd', 'häfte', 'nide', 'osa', 'part', 'teil', 'vol', 'vol.', 'volume'].includes(value)) {\n return 'osa';\n }\n\n if (['p.', 'page', 'pages', 'pp.', 's.', 'sidor', 'sivu', 'sivut'].includes(value)) {\n return 'sivu';\n }\n\n return value;\n}\n\nconst romanNumbers = {'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5', 'VI': '6', 'X': '10'};\n\nfunction normalizePartNumber(value) {\n // Should we handle all Roman numbers or some range of them?\n // There's probably a library for our purposes..\n if (value in romanNumbers) {\n const arabicValue = romanNumbers[value];\n nvdebug(` MAP ${value} to ${arabicValue}`, debugDev);\n return arabicValue;\n }\n return value.toLowerCase();\n}\n\nfunction splitAndNormalizePartData(value) {\n // This is just a stub. Does not handle eg. \"Levy 2, raita 15\"\n const [partType, partYear, partNumber] = splitPartData(value);\n //nvdebug(` LHS: '${lhs}'`, debugDev);\n //nvdebug(` RHS: '${rhs}'`, debugDev);\n return [normalizePartType(partType), partYear, normalizePartNumber(partNumber)];\n}\n\nexport function partsAgree(value1, value2, tag, subfieldCode) {\n // Note, that parts can not be normalized away, as \"2\" can agree with \"Part 2\" and \"Raita 2\" and \"Volume 2\"...\n // NB! Used by reducers' mergeSubield.js\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return false;\n }\n const [partType1, partYear1, partNumber1] = splitAndNormalizePartData(value1);\n const [partType2, partYear2, partNumber2] = splitAndNormalizePartData(value2);\n //nvdebug(`P1: ${partType1} | ${partYear1} | ${partNumber1}`);\n //nvdebug(`P2: ${partType2} | ${partYear2} | ${partNumber2}`);\n if (partNumber1 !== partNumber2) {\n return false;\n }\n if (partType1 !== undefined && partType2 !== undefined && partType1 !== partType2) {\n return false;\n }\n if (partYear1 !== undefined && partYear2 !== undefined && partYear1 !== partYear2) {\n return false;\n }\n\n\n return true;\n}\n\nexport function normalizePartData(value, subfieldCode, tag) {\n // This is for normalizing values for equality comparison only!\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return value;\n }\n\n const [partType, partYear, partNumber] = splitAndNormalizePartData(value);\n if (partType === undefined) {\n if (partYear === undefined) {\n return partNumber;\n }\n return `${partNumber}/${partYear}`;\n }\n if (partYear === undefined) {\n return `${partType} ${partNumber}`;\n }\n return `${partType} ${partNumber}/${partYear}`;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"normalizeSubfieldValueForComparison.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","subfieldContainsPartData","tag","subfieldCode","includes","splitPartData","originalValue","value","replace","year","rest","extractYear","splitPoint","lastIndexOf","undefined","lhs","substr","rhs","match","len","length","normalizePartType","toLowerCase","romanNumbers","normalizePartNumber","arabicValue","nvdebug","splitAndNormalizePartData","partType","partYear","partNumber","partsAgree","value1","value2","partType1","partYear1","partNumber1","partType2","partYear2","partNumber2","normalizePartData"],"sources":["../src/normalizeSubfieldValueForComparison.js"],"sourcesContent":["import {nvdebug} from './utils';\nimport createDebugLogger from 'debug';\n\n// Normalizes at least 490$v and 773$g which contain information such as \"Raita 5\" vs \"5\", and \"Osa 3\" vs \"Osa III\".\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizePart');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function subfieldContainsPartData(tag, subfieldCode) {\n // NB! Used by reducers' mergeSubield.js\n if (subfieldCode === 'v' && ['490', '800', '810', '811', '830'].includes(tag)) {\n return true;\n }\n if (tag === '773' && subfieldCode === 'g') {\n return true;\n }\n return false;\n}\n\nfunction splitPartData(originalValue) {\n // This a very hacky function, but cand really help it, as the the data is very iffy as well...\n // Remove punctuation and brackets:\n const value = originalValue.replace(/[-.,:; ]+$/ui, '').replace(/^\\[([0-9]+)\\]$/ui, '$1'); // eslint-disable-line prefer-named-capture-group\n\n const [year, rest] = extractYear(value);\n\n const splitPoint = rest.lastIndexOf(' '); // MRA-627: \"5, 2017\" should be split here. Think of this later on...\n if (splitPoint === -1) {\n return [undefined, year, rest];\n }\n const lhs = rest.substr(0, splitPoint);\n const rhs = rest.substr(splitPoint + 1);\n return [lhs, year, rhs];\n\n function extractYear(value) {\n // NB! Note that this is far for perfect. It cover just some very common cases...\n\n // \"2023, 3\" => [\"2023\", \"3\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9]), (?:nro |n:o)?[1-9][0-9]{0,2}$/ui)) {\n return [value.substr(0, 4), value.substr(6)];\n }\n // \"2023/12\" => [\"2023\", \"12\"]\n if (value.match(/^(?:1[89][0-9][0-9]|20[012][0-9])[/:][1-9][0-9]{0,2}$/u)) {\n return [value.substr(0, 4), value.substr(5)];\n }\n // \"Vol. 3/2023\" => [\"2023\", \"Vol. 3\"]\n if (value.match(/^[^0-9]*[1-9][0-9]{0,2}\\/(?:1[89][0-9][0-9]|20[012][0-9])$/u)) {\n const len = value.length;\n return [value.substr(len - 4), value.substr(0, len - 5)];\n }\n\n\n return [undefined, value];\n }\n}\n\nfunction normalizePartType(originalValue) {\n if (originalValue === undefined) {\n return undefined;\n }\n const value = originalValue.toLowerCase();\n\n // Return Finnish singular nominative. Choise of language is arbitrary. This is best-ish for debug purposes...\n if (['n:o', 'no', 'nr', 'nro', 'number', 'numero', 'nummer'].includes(value)) {\n return 'numero';\n }\n if (['band', 'bd', 'häfte', 'nide', 'osa', 'part', 'teil', 'vol', 'vol.', 'volume'].includes(value)) {\n return 'osa';\n }\n\n if (['p.', 'page', 'pages', 'pp.', 's.', 'sidor', 'sivu', 'sivut'].includes(value)) {\n return 'sivu';\n }\n\n return value;\n}\n\nconst romanNumbers = {'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5', 'VI': '6', 'X': '10'};\n\nfunction normalizePartNumber(value) {\n // Should we handle all Roman numbers or some range of them?\n // There's probably a library for our purposes..\n if (value in romanNumbers) {\n const arabicValue = romanNumbers[value];\n nvdebug(` MAP ${value} to ${arabicValue}`, debugDev);\n return arabicValue;\n }\n return value.toLowerCase();\n}\n\nfunction splitAndNormalizePartData(value) {\n // This is just a stub. Does not handle eg. \"Levy 2, raita 15\"\n const [partType, partYear, partNumber] = splitPartData(value);\n //nvdebug(` LHS: '${lhs}'`, debugDev);\n //nvdebug(` RHS: '${rhs}'`, debugDev);\n return [normalizePartType(partType), partYear, normalizePartNumber(partNumber)];\n}\n\nexport function partsAgree(value1, value2, tag, subfieldCode) {\n // Note, that parts can not be normalized away, as \"2\" can agree with \"Part 2\" and \"Raita 2\" and \"Volume 2\"...\n // NB! Used by reducers' mergeSubield.js\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return false;\n }\n const [partType1, partYear1, partNumber1] = splitAndNormalizePartData(value1);\n const [partType2, partYear2, partNumber2] = splitAndNormalizePartData(value2);\n //nvdebug(`P1: ${partType1} | ${partYear1} | ${partNumber1}`);\n //nvdebug(`P2: ${partType2} | ${partYear2} | ${partNumber2}`);\n if (partNumber1 !== partNumber2) {\n return false;\n }\n if (partType1 !== undefined && partType2 !== undefined && partType1 !== partType2) {\n return false;\n }\n if (partYear1 !== undefined && partYear2 !== undefined && partYear1 !== partYear2) {\n return false;\n }\n\n\n return true;\n}\n\nexport function normalizePartData(value, subfieldCode, tag) {\n // This is for normalizing values for equality comparison only!\n if (!subfieldContainsPartData(tag, subfieldCode)) {\n return value;\n }\n\n const [partType, partYear, partNumber] = splitAndNormalizePartData(value);\n if (partType === undefined) {\n if (partYear === undefined) {\n return partNumber;\n }\n return `${partNumber}/${partYear}`;\n }\n if (partYear === undefined) {\n return `${partType} ${partNumber}`;\n }\n return `${partType} ${partNumber}/${partYear}`;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -22,7 +22,7 @@ exports.removeWorsePrepubField500s = removeWorsePrepubField500s;
|
|
|
22
22
|
exports.removeWorsePrepubField594s = removeWorsePrepubField594s;
|
|
23
23
|
var _utils = require("./utils");
|
|
24
24
|
var _debug = _interopRequireDefault(require("debug"));
|
|
25
|
-
function _interopRequireDefault(
|
|
25
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
26
26
|
const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda:prepublicationUtils');
|
|
27
27
|
//const debugData = debug.extend('data');
|
|
28
28
|
const debugDev = debug.extend('dev');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepublicationUtils.js","names":["_utils","require","_debug","_interopRequireDefault","obj","__esModule","default","debug","createDebugLogger","debugDev","extend","KONEELLISESTI_TUOTETTU_TIETUE","TARKISTETTU_ENNAKKOTIETO","ENNAKKOTIETO","encodingLevelPreferenceArray","prepublicationLevelIndex","indexOf","prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto","prepublicationLevel","encodingLevelIsBetterThanPrepublication","encodingLevel","index","containsSubstringInSubfieldA","field","substring","subfields","some","sf","code","value","includes","fieldRefersToKoneellisestiTuotettuTietue","fieldRefersToTarkistettuEnnakkotieto","fieldRefersToEnnakkotieto","firstFieldHasBetterPrepubEncodingLevel","field1","field2","getRelevant5XXFields","record","f500","f594","cands","actualGetFields","filtered","filter","hasRelevantPrepubData","tag","every","get","getPrepublicationLevel","fields","f","baseHasEqualOrHigherEncodingLevel","baseEncodingLevel","sourceEncodingLevel","baseIndex","sourceIndex","hasFikkaLOW","fieldHasSubfield","hasNatLibFi042","isFikkaRecord","getEncodingLevel","leader","deleteAllPrepublicationNotesFromField500InNonPubRecord","length","nvdebug","forEach","removeField","removeWorsePrepubField500s","nvdebugFieldArray","nonBest","removeWorsePrepubField594s","fields594","isEnnakkotietoSubfield","subfield","substr","isEnnakkotietoField","isKingOfTheHill","opposingFields","opposingField"],"sources":["../src/prepublicationUtils.js"],"sourcesContent":["import {fieldHasSubfield, nvdebug, nvdebugFieldArray} from './utils';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:prepublicationUtils');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best\nconst TARKISTETTU_ENNAKKOTIETO = 2;\nconst ENNAKKOTIETO = 3;\n//const EI_TASOA = 4;\n\nconst encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145\nconst prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');\n\nexport function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {\n return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;\n}\n\n\nexport function encodingLevelIsBetterThanPrepublication(encodingLevel) {\n const index = encodingLevelPreferenceArray.indexOf(encodingLevel);\n return index > -1 && index < prepublicationLevelIndex;\n}\n\n\nfunction containsSubstringInSubfieldA(field, substring) {\n return field.subfields.some(sf => sf.code === 'a' && sf.value.includes(substring));\n}\n\n\n// These three functions below all refer to field 500:\nexport function fieldRefersToKoneellisestiTuotettuTietue(field) {\n return containsSubstringInSubfieldA(field, 'Koneellisesti tuotettu tietue');\n}\n\n\nexport function fieldRefersToTarkistettuEnnakkotieto(field) {\n return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO');\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?\n if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO') && !fieldRefersToTarkistettuEnnakkotieto(field)) {\n return true;\n }\n // MRA-420: \"EI VIELÄ ILMESTYNYT\" is a Helmet note, that is semantically similar to ENNAKKOTIETO:\n return containsSubstringInSubfieldA(field, 'EI VIELÄ ILMESTYNYT');\n}\n\n\nexport function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return false;\n}\n\n\n/*\nfunction hasEnnakkotietoSubfield(field) {\n return field.subfields.some(sf => ['g', '9'].includes(sf.code) && sf.value.includes('ENNAKKOTIETO'));\n}\n*/\n\n/*\nexport function isPrepublicationField6XX(field) {\n if (!field.tag.match(/^6(?:[0-4][0-9]|5[0-5])$/u)) { // Not within 600 ... 655 range\n return false;\n }\n return field.subfields.some(sf => hasEnnakkotietoSubfield(sf));\n}\n*/\n\n\nexport function getRelevant5XXFields(record, f500 = false, f594 = false) {\n const cands = actualGetFields();\n //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);\n const filtered = cands.filter(field => hasRelevantPrepubData(field));\n //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);\n return filtered;\n\n //return actualGetFields().filter(field => hasRelevantPrepubData(field));\n\n function hasRelevantPrepubData(field) {\n // Check prepub ($a):\n if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToTarkistettuEnnakkotieto(field) && !fieldRefersToEnnakkotieto(field)) {\n return false;\n }\n // Check relevance (594$5):\n if (field.tag === '500') {\n return field.subfields.every(sf => sf.code !== '5'); //true;\n }\n return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));\n }\n\n function actualGetFields() {\n if (f500 && f594) {\n return record.get(/^(?:500|594)$/u);\n }\n if (f500) {\n return record.get(/^500$/u);\n }\n if (f594) {\n return record.get(/^594$/u);\n }\n return [];\n }\n\n}\n\n\n// Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...\n// We should use that and not have a copy here...\nexport function getPrepublicationLevel(record, f500 = false, f594 = false) {\n // Smaller return value is better\n const fields = getRelevant5XXFields(record, f500, f594);\n\n if (!fields) {\n return null;\n }\n if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {\n return KONEELLISESTI_TUOTETTU_TIETUE;\n }\n\n if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {\n return TARKISTETTU_ENNAKKOTIETO;\n }\n\n if (fields.some(f => fieldRefersToEnnakkotieto(f))) {\n return ENNAKKOTIETO;\n }\n\n return null;\n}\n\n\nexport function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {\n const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);\n const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);\n\n if (baseIndex === -1) {\n // Base wins if both are bad:\n return sourceIndex === -1;\n }\n return baseIndex <= sourceIndex;\n}\n\n\nfunction hasFikkaLOW(record) {\n return record.fields.some(field => field.tag === 'LOW' && fieldHasSubfield(field, 'a', 'FIKKA'));\n}\n\n\nfunction hasNatLibFi042(record) {\n return record.fields.some(field => field.tag === '042' && (fieldHasSubfield(field, 'a', 'finb') || fieldHasSubfield(field, 'a', 'finbd')));\n}\n\n\nexport function isFikkaRecord(record) {\n // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?\n return hasFikkaLOW(record) && hasNatLibFi042(record);\n}\n\n\nexport function getEncodingLevel(record) {\n return record.leader.substring(17, 18);\n}\n\n\nexport function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {\n const encodingLevel = getEncodingLevel(record);\n // Skip prepublication (or theoretically even worse) records:\n if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {\n //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here\n return;\n }\n\n // MET-306: keep \"koneellisesti tuotettu tietue\" if encoding level is '2':\n const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);\n if (f500.length === 0) {\n return;\n }\n\n\n nvdebug(`Delete all ${f500.length} instance(s) of field 500`, debugDev);\n f500.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField500s(record) {\n // Remove lower-level entries:\n const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true\n nvdebugFieldArray(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);\n const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 500: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField594s(record) {\n // Remove lower-level entries:\n const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true\n nvdebugFieldArray(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);\n const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 594: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function isEnnakkotietoSubfield(subfield) {\n if (subfield.code !== '9' && subfield.code !== 'g') {\n return false;\n }\n // Length <= 13 allows punctuation, but does not require it:\n if (subfield.value.substr(0, 12) === 'ENNAKKOTIETO' && subfield.value.length <= 13) {\n return true;\n }\n return false;\n}\n\nexport function isEnnakkotietoField(field) {\n return field.subfields.some(sf => isEnnakkotietoSubfield(sf));\n}\n\nexport function isKingOfTheHill(field, opposingFields) {\n // Field is no better than at least one of the opposing fields\n return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));\n}\n\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"prepublicationUtils.js","names":["_utils","require","_debug","_interopRequireDefault","e","__esModule","default","debug","createDebugLogger","debugDev","extend","KONEELLISESTI_TUOTETTU_TIETUE","TARKISTETTU_ENNAKKOTIETO","ENNAKKOTIETO","encodingLevelPreferenceArray","prepublicationLevelIndex","indexOf","prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto","prepublicationLevel","encodingLevelIsBetterThanPrepublication","encodingLevel","index","containsSubstringInSubfieldA","field","substring","subfields","some","sf","code","value","includes","fieldRefersToKoneellisestiTuotettuTietue","fieldRefersToTarkistettuEnnakkotieto","fieldRefersToEnnakkotieto","firstFieldHasBetterPrepubEncodingLevel","field1","field2","getRelevant5XXFields","record","f500","f594","cands","actualGetFields","filtered","filter","hasRelevantPrepubData","tag","every","get","getPrepublicationLevel","fields","f","baseHasEqualOrHigherEncodingLevel","baseEncodingLevel","sourceEncodingLevel","baseIndex","sourceIndex","hasFikkaLOW","fieldHasSubfield","hasNatLibFi042","isFikkaRecord","getEncodingLevel","leader","deleteAllPrepublicationNotesFromField500InNonPubRecord","length","nvdebug","forEach","removeField","removeWorsePrepubField500s","nvdebugFieldArray","nonBest","removeWorsePrepubField594s","fields594","isEnnakkotietoSubfield","subfield","substr","isEnnakkotietoField","isKingOfTheHill","opposingFields","opposingField"],"sources":["../src/prepublicationUtils.js"],"sourcesContent":["import {fieldHasSubfield, nvdebug, nvdebugFieldArray} from './utils';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:prepublicationUtils');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best\nconst TARKISTETTU_ENNAKKOTIETO = 2;\nconst ENNAKKOTIETO = 3;\n//const EI_TASOA = 4;\n\nconst encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145\nconst prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');\n\nexport function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {\n return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;\n}\n\n\nexport function encodingLevelIsBetterThanPrepublication(encodingLevel) {\n const index = encodingLevelPreferenceArray.indexOf(encodingLevel);\n return index > -1 && index < prepublicationLevelIndex;\n}\n\n\nfunction containsSubstringInSubfieldA(field, substring) {\n return field.subfields.some(sf => sf.code === 'a' && sf.value.includes(substring));\n}\n\n\n// These three functions below all refer to field 500:\nexport function fieldRefersToKoneellisestiTuotettuTietue(field) {\n return containsSubstringInSubfieldA(field, 'Koneellisesti tuotettu tietue');\n}\n\n\nexport function fieldRefersToTarkistettuEnnakkotieto(field) {\n return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO');\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?\n if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO') && !fieldRefersToTarkistettuEnnakkotieto(field)) {\n return true;\n }\n // MRA-420: \"EI VIELÄ ILMESTYNYT\" is a Helmet note, that is semantically similar to ENNAKKOTIETO:\n return containsSubstringInSubfieldA(field, 'EI VIELÄ ILMESTYNYT');\n}\n\n\nexport function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return false;\n}\n\n\n/*\nfunction hasEnnakkotietoSubfield(field) {\n return field.subfields.some(sf => ['g', '9'].includes(sf.code) && sf.value.includes('ENNAKKOTIETO'));\n}\n*/\n\n/*\nexport function isPrepublicationField6XX(field) {\n if (!field.tag.match(/^6(?:[0-4][0-9]|5[0-5])$/u)) { // Not within 600 ... 655 range\n return false;\n }\n return field.subfields.some(sf => hasEnnakkotietoSubfield(sf));\n}\n*/\n\n\nexport function getRelevant5XXFields(record, f500 = false, f594 = false) {\n const cands = actualGetFields();\n //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);\n const filtered = cands.filter(field => hasRelevantPrepubData(field));\n //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);\n return filtered;\n\n //return actualGetFields().filter(field => hasRelevantPrepubData(field));\n\n function hasRelevantPrepubData(field) {\n // Check prepub ($a):\n if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToTarkistettuEnnakkotieto(field) && !fieldRefersToEnnakkotieto(field)) {\n return false;\n }\n // Check relevance (594$5):\n if (field.tag === '500') {\n return field.subfields.every(sf => sf.code !== '5'); //true;\n }\n return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));\n }\n\n function actualGetFields() {\n if (f500 && f594) {\n return record.get(/^(?:500|594)$/u);\n }\n if (f500) {\n return record.get(/^500$/u);\n }\n if (f594) {\n return record.get(/^594$/u);\n }\n return [];\n }\n\n}\n\n\n// Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...\n// We should use that and not have a copy here...\nexport function getPrepublicationLevel(record, f500 = false, f594 = false) {\n // Smaller return value is better\n const fields = getRelevant5XXFields(record, f500, f594);\n\n if (!fields) {\n return null;\n }\n if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {\n return KONEELLISESTI_TUOTETTU_TIETUE;\n }\n\n if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {\n return TARKISTETTU_ENNAKKOTIETO;\n }\n\n if (fields.some(f => fieldRefersToEnnakkotieto(f))) {\n return ENNAKKOTIETO;\n }\n\n return null;\n}\n\n\nexport function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {\n const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);\n const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);\n\n if (baseIndex === -1) {\n // Base wins if both are bad:\n return sourceIndex === -1;\n }\n return baseIndex <= sourceIndex;\n}\n\n\nfunction hasFikkaLOW(record) {\n return record.fields.some(field => field.tag === 'LOW' && fieldHasSubfield(field, 'a', 'FIKKA'));\n}\n\n\nfunction hasNatLibFi042(record) {\n return record.fields.some(field => field.tag === '042' && (fieldHasSubfield(field, 'a', 'finb') || fieldHasSubfield(field, 'a', 'finbd')));\n}\n\n\nexport function isFikkaRecord(record) {\n // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?\n return hasFikkaLOW(record) && hasNatLibFi042(record);\n}\n\n\nexport function getEncodingLevel(record) {\n return record.leader.substring(17, 18);\n}\n\n\nexport function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {\n const encodingLevel = getEncodingLevel(record);\n // Skip prepublication (or theoretically even worse) records:\n if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {\n //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here\n return;\n }\n\n // MET-306: keep \"koneellisesti tuotettu tietue\" if encoding level is '2':\n const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);\n if (f500.length === 0) {\n return;\n }\n\n\n nvdebug(`Delete all ${f500.length} instance(s) of field 500`, debugDev);\n f500.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField500s(record) {\n // Remove lower-level entries:\n const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true\n nvdebugFieldArray(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);\n const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 500: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField594s(record) {\n // Remove lower-level entries:\n const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true\n nvdebugFieldArray(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);\n const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 594: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function isEnnakkotietoSubfield(subfield) {\n if (subfield.code !== '9' && subfield.code !== 'g') {\n return false;\n }\n // Length <= 13 allows punctuation, but does not require it:\n if (subfield.value.substr(0, 12) === 'ENNAKKOTIETO' && subfield.value.length <= 13) {\n return true;\n }\n return false;\n}\n\nexport function isEnnakkotietoField(field) {\n return field.subfields.some(sf => isEnnakkotietoSubfield(sf));\n}\n\nexport function isKingOfTheHill(field, opposingFields) {\n // Field is no better than at least one of the opposing fields\n return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));\n}\n\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -7,7 +7,7 @@ exports.default = _default;
|
|
|
7
7
|
var _marcRecord = require("@natlibfi/marc-record");
|
|
8
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
9
|
var _rules = require("./rules");
|
|
10
|
-
function _interopRequireDefault(
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
const debug = (0, _debug.default)('@natlibfi/marc-record-validator-melinda/punctuation:dev');
|
|
12
12
|
function cloneDeep(field) {
|
|
13
13
|
const r = new _marcRecord.MarcRecord();
|