@natlibfi/marc-record-validators-melinda 11.4.8-alpha.3 → 11.5.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/disambiguateSeriesStatements.js +200 -0
  2. package/dist/disambiguateSeriesStatements.js.map +1 -0
  3. package/dist/disambiguateSeriesStatements.spec.js +51 -0
  4. package/dist/disambiguateSeriesStatements.spec.js.map +1 -0
  5. package/dist/fix-country-codes.spec.js +1 -1
  6. package/dist/fix-country-codes.spec.js.map +1 -1
  7. package/dist/index.js +7 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/merge-fields/mergeField.js +2 -2
  10. package/dist/merge-fields/mergeField.js.map +1 -1
  11. package/dist/merge-fields/mergeOrAddSubfield.js +5 -2
  12. package/dist/merge-fields/mergeOrAddSubfield.js.map +1 -1
  13. package/dist/merge-fields.spec.js +1 -1
  14. package/dist/merge-fields.spec.js.map +1 -1
  15. package/dist/normalize-identifiers.js +1 -1
  16. package/dist/normalize-identifiers.js.map +1 -1
  17. package/dist/normalizeFieldForComparison.js +12 -2
  18. package/dist/normalizeFieldForComparison.js.map +1 -1
  19. package/dist/normalizeSubfieldValueForComparison.js +1 -1
  20. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  21. package/dist/prepublicationUtils.js +17 -6
  22. package/dist/prepublicationUtils.js.map +1 -1
  23. package/dist/removeInferiorDataFields.js +27 -4
  24. package/dist/removeInferiorDataFields.js.map +1 -1
  25. package/dist/sortRelatorTerms.js +6 -4
  26. package/dist/sortRelatorTerms.js.map +1 -1
  27. package/dist/translate-terms.js +1 -3
  28. package/dist/translate-terms.js.map +1 -1
  29. package/package.json +5 -2
  30. package/src/disambiguateSeriesStatements.js +228 -0
  31. package/src/disambiguateSeriesStatements.spec.js +52 -0
  32. package/src/fix-country-codes.spec.js +1 -1
  33. package/src/index.js +2 -0
  34. package/src/merge-fields/mergeField.js +4 -4
  35. package/src/merge-fields/mergeOrAddSubfield.js +3 -3
  36. package/src/merge-fields.spec.js +1 -1
  37. package/src/normalize-identifiers.js +1 -1
  38. package/src/normalizeFieldForComparison.js +9 -4
  39. package/src/normalizeSubfieldValueForComparison.js +1 -1
  40. package/src/prepublicationUtils.js +17 -6
  41. package/src/removeInferiorDataFields.js +32 -5
  42. package/src/sortRelatorTerms.js +4 -4
  43. package/src/translate-terms.js +1 -2
  44. package/test-fixtures/disambiguate-series-statements/f01/expectedResult.json +16 -0
  45. package/test-fixtures/disambiguate-series-statements/f01/metadata.json +5 -0
  46. package/test-fixtures/disambiguate-series-statements/f01/record.json +16 -0
  47. package/test-fixtures/disambiguate-series-statements/f02/expectedResult.json +16 -0
  48. package/test-fixtures/disambiguate-series-statements/f02/metadata.json +5 -0
  49. package/test-fixtures/disambiguate-series-statements/f02/record.json +16 -0
  50. package/test-fixtures/disambiguate-series-statements/f03/expectedResult.json +16 -0
  51. package/test-fixtures/disambiguate-series-statements/f03/metadata.json +5 -0
  52. package/test-fixtures/disambiguate-series-statements/f03/record.json +15 -0
  53. package/test-fixtures/disambiguate-series-statements/f04/expectedResult.json +17 -0
  54. package/test-fixtures/disambiguate-series-statements/f04/metadata.json +6 -0
  55. package/test-fixtures/disambiguate-series-statements/f04/record.json +16 -0
  56. package/test-fixtures/disambiguate-series-statements/f05/expectedResult.json +17 -0
  57. package/test-fixtures/disambiguate-series-statements/f05/metadata.json +5 -0
  58. package/test-fixtures/disambiguate-series-statements/f05/record.json +17 -0
  59. package/test-fixtures/disambiguate-series-statements/v01/expectedResult.json +6 -0
  60. package/test-fixtures/disambiguate-series-statements/v01/metadata.json +5 -0
  61. package/test-fixtures/disambiguate-series-statements/v01/record.json +16 -0
  62. package/test-fixtures/disambiguate-series-statements/v04/expectedResult.json +4 -0
  63. package/test-fixtures/disambiguate-series-statements/v04/metadata.json +6 -0
  64. package/test-fixtures/disambiguate-series-statements/v04/record.json +16 -0
  65. package/test-fixtures/remove-inferior-datafields/f13/expectedResult.json +7 -0
  66. package/test-fixtures/remove-inferior-datafields/f13/record.json +11 -0
  67. package/test-fixtures/remove-inferior-datafields/f15/expectedResult.json +12 -0
  68. package/test-fixtures/remove-inferior-datafields/f15/metadata.json +6 -0
  69. package/test-fixtures/remove-inferior-datafields/f15/record.json +17 -0
@@ -1 +1 @@
1
- {"version":3,"file":"mergeOrAddSubfield.js","names":["_debug","_interopRequireDefault","require","_normalizeFieldForComparison","_normalizeIdentifiers","_utils","_mergeSubfield","_sortSubfields","_worldKnowledge","_subfield6Utils","e","__esModule","default","debug","createDebugLogger","debugDev","extend","catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField","targetField","candSubfieldData","tag","code","nvdebug","fieldToString","originalValue","subfields","some","sf","value","ennakkotietoInSubfieldG","includes","mergeOrAddSubfieldNotRequiredSpecialCases","charAt","match","valueCarriesMeaning","normalizedValue","alephIdentifierType","normalizeAs","undefined","normalizedSubfieldValue","normalizeControlSubfieldValue","skipNormalizedComparison","subfieldCode","subfieldValue","substring","mergeOrAddSubfieldNotRequired","relevantTargetSubfields","filter","length","punctuationlessValue","normalizedTargetField","cloneAndNormalizeFieldForComparison","addSubfield","candSubfield","subfieldToString","push","merged","setPunctuationFlag","sortAdjacentSubfields","field","addedSubfield","isControlSubfieldCode","useExternalEndPunctuation","resetPaired880","candFieldPair880","punctlessCandSubfield","resetSubfield6Tag","mergeOrAddSubfield","candFieldPairs880","candSubfieldAsString","original","mergeSubfield","mergeSubfieldPostprocessor","addSubfieldWithPreviouslyUnseenSubfieldCode","subfieldIsRepeatable","fieldHasSubfield","forEach","pair"],"sources":["../../src/merge-fields/mergeOrAddSubfield.js"],"sourcesContent":["import createDebugLogger from 'debug';\nimport {cloneAndNormalizeFieldForComparison} from '../normalizeFieldForComparison.js';\nimport {normalizeAs, normalizeControlSubfieldValue} from '../normalize-identifiers';\nimport {fieldHasSubfield, fieldToString, isControlSubfieldCode, nvdebug, subfieldIsRepeatable, subfieldToString} from '../utils.js';\nimport {mergeSubfield} from './mergeSubfield.js';\nimport {sortAdjacentSubfields} from '../sortSubfields'; //'./sortSubfields.js';\n\nimport {valueCarriesMeaning} from './worldKnowledge.js';\nimport {resetSubfield6Tag} from '../subfield6Utils.js';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeOrAddSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField(targetField, candSubfieldData) {\n if (targetField.tag !== '040' || candSubfieldData.code !== 'd') {\n return false;\n }\n nvdebug(`${fieldToString(targetField)} vs $d ${candSubfieldData.originalValue}}`, debugDev);\n // Add hard-coded exceptions here\n if (targetField.subfields.some(sf => sf.code === 'a' && sf.value === candSubfieldData.originalValue)) {\n nvdebug('040‡d matched 040‡a', debugDev);\n return true;\n }\n return false;\n}\n\nfunction ennakkotietoInSubfieldG(candSubfieldData) {\n if (candSubfieldData.code === 'g' && ['ENNAKKOTIETO.', 'ENNAKKOTIETO'].includes(candSubfieldData.originalValue)) {\n // Skip just ‡g subfield or the whole field?\n // We decided to skip just this subfield. We want at least $0 and maybe even more from ennakkotieto.\n debugDev('Skip ‡g ENNAKKOTIETO.');\n return true;\n }\n return false;\n}\n\n\nfunction mergeOrAddSubfieldNotRequiredSpecialCases(targetField, candSubfieldData) {\n\n // Don't bring WHATEVER<KEEP> from source 7XX to base 1XX.\n // Exceptionally we can merge <KEEP>ed 7XX with un-<KEEP>ed 1XX as 1XX should not use <KEEP>s.\n if (targetField.tag.charAt(0) === '1' && candSubfieldData.tag.charAt(0) === '7' && candSubfieldData.code === '9' && candSubfieldData.originalValue.match(/<KEEP>/u)) {\n return true;\n }\n\n // Don't add 264$b 'Kustannuspaikka tuntematon' etc\n if (!valueCarriesMeaning(targetField.tag, candSubfieldData.code, candSubfieldData.normalizedValue)) {\n return true;\n }\n\n\n // Don't add $0 subfields that mean the same even if they look different:\n const alephIdentifierType = normalizeAs(targetField.tag, candSubfieldData.code);\n if (alephIdentifierType !== undefined) {\n const normalizedSubfieldValue = normalizeControlSubfieldValue(candSubfieldData.originalValue, alephIdentifierType);\n if (targetField.subfields.some(sf => normalizeControlSubfieldValue(sf.value) === normalizedSubfieldValue && sf.code === candSubfieldData.code)) {\n return true;\n }\n }\n return false;\n}\n\n\nfunction skipNormalizedComparison(tag, subfieldCode, subfieldValue) {\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n // Hackish: we want 'ntamo' to win 'Ntamo'...\n // If there are other similar excepting put them into an array.\n if (['110', '610', '710', '810'].includes(tag) && subfieldCode === 'a' && subfieldValue.substring(0, 5) === 'ntamo') {\n return true;\n }\n return false;\n}\n\nfunction mergeOrAddSubfieldNotRequired(targetField, candSubfieldData) {\n if (catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField(targetField, candSubfieldData) || ennakkotietoInSubfieldG(candSubfieldData)) {\n return true;\n }\n\n if (mergeOrAddSubfieldNotRequiredSpecialCases(targetField, candSubfieldData)) {\n return true;\n }\n\n const relevantTargetSubfields = targetField.subfields.filter(sf => sf.code === candSubfieldData.code);\n // Target field does not have this subfield yet:\n if (relevantTargetSubfields.length === 0) {\n return false;\n }\n nvdebug(` Look for identical subfields in '${fieldToString(targetField)}' using`, debugDev);\n nvdebug(` ORIG. ‡${candSubfieldData.code} ${candSubfieldData.originalValue}`, debugDev);\n nvdebug(` NO-PUNC ‡${candSubfieldData.code} ${candSubfieldData.punctuationlessValue}`, debugDev);\n if (relevantTargetSubfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.originalValue)) {\n return true;\n }\n if (relevantTargetSubfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.punctuationlessValue)) {\n return true;\n }\n\n if (!skipNormalizedComparison(targetField.tag, candSubfieldData.code, candSubfieldData.originalValue)) {\n const normalizedTargetField = cloneAndNormalizeFieldForComparison(targetField);\n nvdebug(` Look for identical normalized subfields in '${fieldToString(normalizedTargetField)}'`, debugDev);\n nvdebug(` NO-PUNC ‡${candSubfieldData.code} ${candSubfieldData.normalizedValue})`, debugDev);\n\n if (normalizedTargetField.subfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.normalizedValue)) {\n // Subfield with identical normalized value exists. Do nothing.\n // Not ideal 382‡n subfields, I guess... Nor 505‡trg repetitions... These need to be fixed...\n return true;\n }\n }\n\n return false; // (note that this is a double negation: not required is false)\n}\n\nfunction addSubfield(targetField, candSubfield) {\n nvdebug(` Added subfield '${subfieldToString(candSubfield)}' to field`, debugDev);\n // Add subfield to the end of all subfields. NB! Implement a separate function that does this + subfield reordering somehow...\n targetField.subfields.push(candSubfield); // eslint-disable-line functional/immutable-data\n\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n\n setPunctuationFlag(targetField, candSubfield);\n sortAdjacentSubfields(targetField);\n\n}\n\nfunction setPunctuationFlag(field, addedSubfield) {\n if (isControlSubfieldCode(addedSubfield.code)) { // These are never punctuation related\n return;\n }\n field.useExternalEndPunctuation = 1; // eslint-disable-line functional/immutable-data\n}\n\n\nfunction resetPaired880(candFieldPair880, targetField, punctlessCandSubfield) {\n // No relevant:\n if (punctlessCandSubfield.code !== '6') {\n return;\n }\n if (targetField.tag === '880') {\n return;\n }\n // NB! $6 comes first:\n if (candFieldPair880 === undefined || !candFieldPair880.subfields || candFieldPair880.subfields[0].code !== '6') {\n return;\n\n }\n nvdebug(`880 contents: ${fieldToString(candFieldPair880)}`, debugDev);\n resetSubfield6Tag(candFieldPair880.subfields[0], targetField.tag);\n}\n\nexport function mergeOrAddSubfield(targetField, candSubfieldData, candFieldPairs880 = []) {\n\n const candSubfieldAsString = `${candSubfieldData.code} ${candSubfieldData.originalValue}`;\n\n nvdebug(` Q: mergeOrAddSubfield '${candSubfieldAsString}'\\n with field '${fieldToString(targetField)}'?`, debugDev);\n if (mergeOrAddSubfieldNotRequired(targetField, candSubfieldData)) {\n nvdebug(` A: No. No need to merge nor to add the subfield '${candSubfieldAsString}'`, debugDev);\n return;\n }\n\n const candSubfield = {'code': candSubfieldData.code, 'value': candSubfieldData.punctuationlessValue};\n\n // Currently only for X00$d 1984- => 1984-2000 type of changes, where source version is better that what base has.\n // It all other cases the original subfield is kept.\n const original = fieldToString(targetField);\n\n if (mergeSubfield(targetField, candSubfield)) { // We might need the normalizedCandSubfield later on\n mergeSubfieldPostprocessor();\n return;\n }\n\n // Subfield codes missing from the original record can be added by default:\n if (addSubfieldWithPreviouslyUnseenSubfieldCode()) {\n return;\n }\n\n // melindaCustomMergeFields.json tells us whether the subfield is repeatable or not:\n if (subfieldIsRepeatable(targetField.tag, candSubfield.code)) {\n // We don't want to add multiple, say, 260$c\n if (['260', '264'].includes(targetField.tag)) {\n nvdebug(` A: Exceptionally skip repeatable existing subfield '${subfieldToString(candSubfield)}'`, debugDev);\n return;\n }\n nvdebug(` A: Yes. Add repeatable subfield '${subfieldToString(candSubfield)}'`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n addSubfield(targetField, candSubfield);\n return;\n }\n\n nvdebug(` A: No. Non-repeatable subfield '${subfieldToString(candSubfield)}'`, debugDev);\n return;\n\n function mergeSubfieldPostprocessor() {\n if (original !== fieldToString(targetField)) {\n nvdebug(` A: Merge. Subfield '${candSubfieldAsString}' replaces the original subfield.`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n return;\n }\n nvdebug(` A: No. Field ${original} already had the same or a synonymous or a better merge candidate than our subfield '${candSubfieldAsString}'.`, debugDev);\n return;\n }\n\n function addSubfieldWithPreviouslyUnseenSubfieldCode() {\n if (!fieldHasSubfield(targetField, candSubfield.code)) {\n nvdebug(` A: Yes. Add previously unseen subfield '${subfieldToString(candSubfield)}'`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n candFieldPairs880.forEach(pair => resetPaired880(pair, targetField, candSubfield));\n addSubfield(targetField, candSubfield);\n return true;\n }\n return false;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"mergeOrAddSubfield.js","names":["_debug","_interopRequireDefault","require","_normalizeFieldForComparison","_normalizeIdentifiers","_utils","_mergeSubfield","_sortSubfields","_worldKnowledge","_subfield6Utils","e","__esModule","default","debug","createDebugLogger","debugDev","extend","catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField","targetField","candSubfieldData","tag","code","nvdebug","fieldToString","originalValue","subfields","some","sf","value","ennakkotietoInSubfieldG","isEnnakkotietoSubfieldG","mergeOrAddSubfieldNotRequiredSpecialCases","charAt","match","valueCarriesMeaning","normalizedValue","alephIdentifierType","normalizeAs","undefined","normalizedSubfieldValue","normalizeControlSubfieldValue","skipNormalizedComparison","subfieldCode","subfieldValue","includes","substring","mergeOrAddSubfieldNotRequired","relevantTargetSubfields","filter","length","punctuationlessValue","normalizedTargetField","cloneAndNormalizeFieldForComparison","addSubfield","candSubfield","subfieldToString","push","merged","setPunctuationFlag","sortAdjacentSubfields","field","addedSubfield","isControlSubfieldCode","useExternalEndPunctuation","resetPaired880","candFieldPair880","punctlessCandSubfield","resetSubfield6Tag","mergeOrAddSubfield","candFieldPairs880","candSubfieldAsString","original","mergeSubfield","mergeSubfieldPostprocessor","addSubfieldWithPreviouslyUnseenSubfieldCode","subfieldIsRepeatable","fieldHasSubfield","forEach","pair"],"sources":["../../src/merge-fields/mergeOrAddSubfield.js"],"sourcesContent":["import createDebugLogger from 'debug';\nimport {cloneAndNormalizeFieldForComparison, isEnnakkotietoSubfieldG} from '../normalizeFieldForComparison.js';\nimport {normalizeAs, normalizeControlSubfieldValue} from '../normalize-identifiers';\nimport {fieldHasSubfield, fieldToString, isControlSubfieldCode, nvdebug, subfieldIsRepeatable, subfieldToString} from '../utils.js';\nimport {mergeSubfield} from './mergeSubfield.js';\nimport {sortAdjacentSubfields} from '../sortSubfields'; //'./sortSubfields.js';\n\nimport {valueCarriesMeaning} from './worldKnowledge.js';\nimport {resetSubfield6Tag} from '../subfield6Utils.js';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeOrAddSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nfunction catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField(targetField, candSubfieldData) {\n if (targetField.tag !== '040' || candSubfieldData.code !== 'd') {\n return false;\n }\n nvdebug(`${fieldToString(targetField)} vs $d ${candSubfieldData.originalValue}}`, debugDev);\n // Add hard-coded exceptions here\n if (targetField.subfields.some(sf => sf.code === 'a' && sf.value === candSubfieldData.originalValue)) {\n nvdebug('040‡d matched 040‡a', debugDev);\n return true;\n }\n return false;\n}\n\nfunction ennakkotietoInSubfieldG(candSubfieldData) {\n if (isEnnakkotietoSubfieldG({'code': candSubfieldData.code, 'value': candSubfieldData.originalValue})) {\n // Skip just ‡g subfield or the whole field?\n // We decided to skip just this subfield. We want at least $0 and maybe even more from ennakkotieto.\n debugDev(`Skip '‡g ${candSubfieldData.originalValue}'`);\n return true;\n }\n return false;\n}\n\n\nfunction mergeOrAddSubfieldNotRequiredSpecialCases(targetField, candSubfieldData) {\n\n // Don't bring WHATEVER<KEEP> from source 7XX to base 1XX.\n // Exceptionally we can merge <KEEP>ed 7XX with un-<KEEP>ed 1XX as 1XX should not use <KEEP>s.\n if (targetField.tag.charAt(0) === '1' && candSubfieldData.tag.charAt(0) === '7' && candSubfieldData.code === '9' && candSubfieldData.originalValue.match(/<KEEP>/u)) {\n return true;\n }\n\n // Don't add 264$b 'Kustannuspaikka tuntematon' etc\n if (!valueCarriesMeaning(targetField.tag, candSubfieldData.code, candSubfieldData.normalizedValue)) {\n return true;\n }\n\n\n // Don't add $0 subfields that mean the same even if they look different:\n const alephIdentifierType = normalizeAs(targetField.tag, candSubfieldData.code);\n if (alephIdentifierType !== undefined) {\n const normalizedSubfieldValue = normalizeControlSubfieldValue(candSubfieldData.originalValue, alephIdentifierType);\n if (targetField.subfields.some(sf => normalizeControlSubfieldValue(sf.value) === normalizedSubfieldValue && sf.code === candSubfieldData.code)) {\n return true;\n }\n }\n return false;\n}\n\n\nfunction skipNormalizedComparison(tag, subfieldCode, subfieldValue) {\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n // Hackish: we want 'ntamo' to win 'Ntamo'...\n // If there are other similar excepting put them into an array.\n if (['110', '610', '710', '810'].includes(tag) && subfieldCode === 'a' && subfieldValue.substring(0, 5) === 'ntamo') {\n return true;\n }\n return false;\n}\n\nfunction mergeOrAddSubfieldNotRequired(targetField, candSubfieldData) {\n if (catalogingSourceModifyingAgencyCandIsOriginalCatalogingSourceAgencyInTargetField(targetField, candSubfieldData) || ennakkotietoInSubfieldG(candSubfieldData)) {\n return true;\n }\n\n if (mergeOrAddSubfieldNotRequiredSpecialCases(targetField, candSubfieldData)) {\n return true;\n }\n\n const relevantTargetSubfields = targetField.subfields.filter(sf => sf.code === candSubfieldData.code);\n // Target field does not have this subfield yet:\n if (relevantTargetSubfields.length === 0) {\n return false;\n }\n nvdebug(` Look for identical subfields in '${fieldToString(targetField)}' using`, debugDev);\n nvdebug(` ORIG. ‡${candSubfieldData.code} ${candSubfieldData.originalValue}`, debugDev);\n nvdebug(` NO-PUNC ‡${candSubfieldData.code} ${candSubfieldData.punctuationlessValue}`, debugDev);\n if (relevantTargetSubfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.originalValue)) {\n return true;\n }\n if (relevantTargetSubfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.punctuationlessValue)) {\n return true;\n }\n\n if (!skipNormalizedComparison(targetField.tag, candSubfieldData.code, candSubfieldData.originalValue)) {\n const normalizedTargetField = cloneAndNormalizeFieldForComparison(targetField);\n nvdebug(` Look for identical normalized subfields in '${fieldToString(normalizedTargetField)}'`, debugDev);\n nvdebug(` NO-PUNC ‡${candSubfieldData.code} ${candSubfieldData.normalizedValue})`, debugDev);\n\n if (normalizedTargetField.subfields.some(sf => sf.code === candSubfieldData.code && sf.value === candSubfieldData.normalizedValue)) {\n // Subfield with identical normalized value exists. Do nothing.\n // Not ideal 382‡n subfields, I guess... Nor 505‡trg repetitions... These need to be fixed...\n return true;\n }\n }\n\n return false; // (note that this is a double negation: not required is false)\n}\n\nfunction addSubfield(targetField, candSubfield) {\n nvdebug(` Added subfield '${subfieldToString(candSubfield)}' to field`, debugDev);\n // Add subfield to the end of all subfields. NB! Implement a separate function that does this + subfield reordering somehow...\n targetField.subfields.push(candSubfield); // eslint-disable-line functional/immutable-data\n\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n\n setPunctuationFlag(targetField, candSubfield);\n sortAdjacentSubfields(targetField);\n\n}\n\nfunction setPunctuationFlag(field, addedSubfield) {\n if (isControlSubfieldCode(addedSubfield.code)) { // These are never punctuation related\n return;\n }\n field.useExternalEndPunctuation = 1; // eslint-disable-line functional/immutable-data\n}\n\n\nfunction resetPaired880(candFieldPair880, targetField, punctlessCandSubfield) {\n // No relevant:\n if (punctlessCandSubfield.code !== '6') {\n return;\n }\n if (targetField.tag === '880') {\n return;\n }\n // NB! $6 comes first:\n if (candFieldPair880 === undefined || !candFieldPair880.subfields || candFieldPair880.subfields[0].code !== '6') {\n return;\n\n }\n nvdebug(`880 contents: ${fieldToString(candFieldPair880)}`, debugDev);\n resetSubfield6Tag(candFieldPair880.subfields[0], targetField.tag);\n}\n\nexport function mergeOrAddSubfield(targetField, candSubfieldData, candFieldPairs880 = []) {\n\n const candSubfieldAsString = `${candSubfieldData.code} ${candSubfieldData.originalValue}`;\n\n nvdebug(` Q: mergeOrAddSubfield '${candSubfieldAsString}'\\n with field '${fieldToString(targetField)}'?`, debugDev);\n if (mergeOrAddSubfieldNotRequired(targetField, candSubfieldData)) {\n nvdebug(` A: No. No need to merge nor to add the subfield '${candSubfieldAsString}'`, debugDev);\n return;\n }\n\n const candSubfield = {'code': candSubfieldData.code, 'value': candSubfieldData.punctuationlessValue};\n\n // Currently only for X00$d 1984- => 1984-2000 type of changes, where source version is better that what base has.\n // It all other cases the original subfield is kept.\n const original = fieldToString(targetField);\n\n if (mergeSubfield(targetField, candSubfield)) { // We might need the normalizedCandSubfield later on\n mergeSubfieldPostprocessor();\n return;\n }\n\n // Subfield codes missing from the original record can be added by default:\n if (addSubfieldWithPreviouslyUnseenSubfieldCode()) {\n return;\n }\n\n // melindaCustomMergeFields.json tells us whether the subfield is repeatable or not:\n if (subfieldIsRepeatable(targetField.tag, candSubfield.code)) {\n // We don't want to add multiple, say, 260$c\n if (['260', '264'].includes(targetField.tag)) {\n nvdebug(` A: Exceptionally skip repeatable existing subfield '${subfieldToString(candSubfield)}'`, debugDev);\n return;\n }\n nvdebug(` A: Yes. Add repeatable subfield '${subfieldToString(candSubfield)}'`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n addSubfield(targetField, candSubfield);\n return;\n }\n\n nvdebug(` A: No. Non-repeatable subfield '${subfieldToString(candSubfield)}'`, debugDev);\n return;\n\n function mergeSubfieldPostprocessor() {\n if (original !== fieldToString(targetField)) {\n nvdebug(` A: Merge. Subfield '${candSubfieldAsString}' replaces the original subfield.`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n return;\n }\n nvdebug(` A: No. Field ${original} already had the same or a synonymous or a better merge candidate than our subfield '${candSubfieldAsString}'.`, debugDev);\n return;\n }\n\n function addSubfieldWithPreviouslyUnseenSubfieldCode() {\n if (!fieldHasSubfield(targetField, candSubfield.code)) {\n nvdebug(` A: Yes. Add previously unseen subfield '${subfieldToString(candSubfield)}'`, debugDev);\n targetField.merged = 1; // eslint-disable-line functional/immutable-data\n setPunctuationFlag(targetField, candSubfield);\n candFieldPairs880.forEach(pair => resetPaired880(pair, targetField, candSubfield));\n addSubfield(targetField, candSubfield);\n return true;\n }\n return false;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -19,7 +19,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
19
19
  before: () => testValidatorFactory()
20
20
  }
21
21
  });
22
- const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda/merge-field:test');
22
+ const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda/merge-fields:test');
23
23
  async function testValidatorFactory() {
24
24
  const validator = await (0, _mergeFields.default)();
25
25
  (0, _chai.expect)(validator).to.be.an('object').that.has.any.keys('description', 'validate');
@@ -1 +1 @@
1
- {"version":3,"file":"merge-fields.spec.js","names":["_chai","require","_marcRecord","_mergeFields","_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/merge-fields.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './merge-fields/';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'merge-fields'],\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/merge-field: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,YAAA,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,cAAc,CAAC;EACxDC,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,2DAA2D,CAAC;AAE5F,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,oBAAgB,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,oBAAgB,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":[]}
1
+ {"version":3,"file":"merge-fields.spec.js","names":["_chai","require","_marcRecord","_mergeFields","_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/merge-fields.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './merge-fields/';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'merge-fields'],\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/merge-fields: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,YAAA,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,cAAc,CAAC;EACxDC,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,4DAA4D,CAAC;AAE7F,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,oBAAgB,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,oBAAgB,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":[]}
@@ -15,7 +15,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
15
15
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
16
16
  //import createDebugLogger from 'debug';
17
17
 
18
- //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');
18
+ //const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalize-identifiers');
19
19
 
20
20
  /*
21
21
  function nvdebug(message, func) {
@@ -1 +1 @@
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":[]}
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:normalize-identifiers');\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,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.cloneAndNormalizeFieldForComparison = cloneAndNormalizeFieldForComparison;
7
7
  exports.cloneAndRemovePunctuation = cloneAndRemovePunctuation;
8
8
  exports.fieldTrimSubfieldValues = fieldTrimSubfieldValues;
9
+ exports.isEnnakkotietoSubfieldG = isEnnakkotietoSubfieldG;
9
10
  exports.tagAndSubfieldCodeReferToIsbn = tagAndSubfieldCodeReferToIsbn;
10
11
  var _clone = _interopRequireDefault(require("clone"));
11
12
  var _punctuation = require("./punctuation2");
@@ -23,9 +24,15 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
23
24
  Thus it is here. However, most of the testing is done via merge-reducers...
24
25
  */
25
26
 
26
- const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalize');
27
+ const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');
27
28
  //const debugData = debug.extend('data');
28
29
  const debugDev = debug.extend('dev');
30
+ function isEnnakkotietoSubfieldG(subfield) {
31
+ if (subfield.code !== 'g') {
32
+ return false;
33
+ }
34
+ return subfield.value.match(/^ENNAKKOTIETO\.?$/gu);
35
+ }
29
36
  function debugFieldComparison(oldField, newField) {
30
37
  // NB: Debug-only function!
31
38
  /*
@@ -67,7 +74,10 @@ function containsCorporateName(tag = '???', subfieldCode = undefined) {
67
74
  return false;
68
75
  }
69
76
  function skipAllSubfieldNormalizations(value, subfieldCode, tag) {
70
- if (subfieldCode === 'g' && value === 'ENNAKKOTIETO.') {
77
+ if (isEnnakkotietoSubfieldG({
78
+ 'code': subfieldCode,
79
+ value
80
+ })) {
71
81
  return true;
72
82
  }
73
83
  if (tag === '035' && ['a', 'z'].includes(subfieldCode)) {
@@ -1 +1 @@
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":[]}
1
+ {"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","e","__esModule","default","debug","createDebugLogger","debugDev","extend","isEnnakkotietoSubfieldG","subfield","code","value","match","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","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:normalizeFieldForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function isEnnakkotietoSubfieldG(subfield) {\n if (subfield.code !== 'g') {\n return false;\n }\n return subfield.value.match(/^ENNAKKOTIETO\\.?$/gu);\n}\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 if (isEnnakkotietoSubfieldG({'code': subfieldCode, value})) {\n return true;\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":[]}
@@ -11,7 +11,7 @@ var _debug = _interopRequireDefault(require("debug"));
11
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
- const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalizePart');
14
+ const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalizeSubfieldValueForComparison');
15
15
  //const debugData = debug.extend('data');
16
16
  const debugDev = debug.extend('dev');
17
17
  function subfieldContainsPartData(tag, subfieldCode) {
@@ -1 +1 @@
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":[]}
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:normalizeSubfieldValueForComparison');\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":[]}
@@ -40,7 +40,11 @@ function encodingLevelIsBetterThanPrepublication(encodingLevel) {
40
40
  const index = encodingLevelPreferenceArray.indexOf(encodingLevel);
41
41
  return index > -1 && index < prepublicationLevelIndex;
42
42
  }
43
- function containsSubstringInSubfieldA(field, substring) {
43
+ function containsSubstringInSubfieldA(field, substring, ignoreCase = false) {
44
+ if (ignoreCase) {
45
+ const lowercasedSubstring = substring.toLowerCase();
46
+ return field.subfields.some(sf => sf.code === 'a' && sf.value.toLowerCase().includes(lowercasedSubstring));
47
+ }
44
48
  return field.subfields.some(sf => sf.code === 'a' && sf.value.includes(substring));
45
49
  }
46
50
 
@@ -49,12 +53,14 @@ function fieldRefersToKoneellisestiTuotettuTietue(field) {
49
53
  return containsSubstringInSubfieldA(field, 'Koneellisesti tuotettu tietue');
50
54
  }
51
55
  function fieldRefersToTarkistettuEnnakkotieto(field) {
52
- return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO');
56
+ return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO', true);
53
57
  }
54
58
  function fieldRefersToEnnakkotieto(field) {
55
59
  // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?
56
- if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO') && !fieldRefersToTarkistettuEnnakkotieto(field)) {
57
- return true;
60
+ if (!fieldRefersToTarkistettuEnnakkotieto(field)) {
61
+ if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO', true)) {
62
+ return true;
63
+ }
58
64
  }
59
65
  // MRA-420: "EI VIELÄ ILMESTYNYT" is a Helmet note, that is semantically similar to ENNAKKOTIETO:
60
66
  return containsSubstringInSubfieldA(field, 'EI VIELÄ ILMESTYNYT');
@@ -83,6 +89,7 @@ function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {
83
89
 
84
90
  /*
85
91
  function hasEnnakkotietoSubfield(field) {
92
+ // NB! This has apparently changed to lower case 'ennakkotieto'...
86
93
  return field.subfields.some(sf => ['g', '9'].includes(sf.code) && sf.value.includes('ENNAKKOTIETO'));
87
94
  }
88
95
  */
@@ -208,8 +215,12 @@ function isEnnakkotietoSubfield(subfield) {
208
215
  return false;
209
216
  }
210
217
  // Length <= 13 allows punctuation, but does not require it:
211
- if (subfield.value.substr(0, 12) === 'ENNAKKOTIETO' && subfield.value.length <= 13) {
212
- return true;
218
+ if (subfield.value.length <= 13) {
219
+ const coreString = subfield.value.substr(0, 12);
220
+ if (coreString === 'ENNAKKOTIETO' || coreString === 'ennakkotieto') {
221
+ // Lowercase term first seen in MET-575
222
+ return true;
223
+ }
213
224
  }
214
225
  return false;
215
226
  }
@@ -1 +1 @@
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":[]}
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","ignoreCase","lowercasedSubstring","toLowerCase","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","coreString","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, ignoreCase = false) {\n if (ignoreCase) {\n const lowercasedSubstring = substring.toLowerCase();\n return field.subfields.some(sf => sf.code === 'a' && sf.value.toLowerCase().includes(lowercasedSubstring));\n\n }\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', true);\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?\n if (!fieldRefersToTarkistettuEnnakkotieto(field)) {\n if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO', true)) {\n return true;\n }\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 // NB! This has apparently changed to lower case 'ennakkotieto'...\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.length <= 13) {\n const coreString = subfield.value.substr(0, 12);\n if (coreString === 'ENNAKKOTIETO' || coreString === 'ennakkotieto') { // Lowercase term first seen in MET-575\n return true;\n }\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":[]}