@natlibfi/marc-record-validators-melinda 12.0.7 → 12.0.8

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 (101) hide show
  1. package/dist/addMissingField041.js +6 -3
  2. package/dist/addMissingField041.js.map +2 -2
  3. package/dist/addMissingField336.js +7 -4
  4. package/dist/addMissingField336.js.map +2 -2
  5. package/dist/addMissingField337.js +6 -3
  6. package/dist/addMissingField337.js.map +2 -2
  7. package/dist/addMissingField338.js +8 -5
  8. package/dist/addMissingField338.js.map +2 -2
  9. package/dist/cyrillux-usemarcon-replacement.js +5 -2
  10. package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
  11. package/dist/cyrillux.js +10 -7
  12. package/dist/cyrillux.js.map +2 -2
  13. package/dist/disambiguateSeriesStatements.js +2 -1
  14. package/dist/disambiguateSeriesStatements.js.map +2 -2
  15. package/dist/drop-terms.js +5 -4
  16. package/dist/drop-terms.js.map +2 -2
  17. package/dist/fix-33X.js +7 -4
  18. package/dist/fix-33X.js.map +2 -2
  19. package/dist/fix-country-codes.js +5 -0
  20. package/dist/fix-country-codes.js.map +2 -2
  21. package/dist/fix-language-codes.js +5 -1
  22. package/dist/fix-language-codes.js.map +2 -2
  23. package/dist/fix-sami-041.js +11 -10
  24. package/dist/fix-sami-041.js.map +2 -2
  25. package/dist/indicator-fixes.js +5 -1
  26. package/dist/indicator-fixes.js.map +2 -2
  27. package/dist/merge-fields/counterpartField.js +6 -6
  28. package/dist/merge-fields/counterpartField.js.map +2 -2
  29. package/dist/merge-fields/mergableIndicator.js +0 -3
  30. package/dist/merge-fields/mergableIndicator.js.map +2 -2
  31. package/dist/merge-fields/worldKnowledge.js.map +2 -2
  32. package/dist/mergeRelatorTermFields.js +9 -6
  33. package/dist/mergeRelatorTermFields.js.map +2 -2
  34. package/dist/normalize-dashes.js +7 -4
  35. package/dist/normalize-dashes.js.map +2 -2
  36. package/dist/normalize-identifiers.js.map +2 -2
  37. package/dist/normalize-utf8-diacritics.js.map +2 -2
  38. package/dist/normalizeFieldForComparison.js.map +1 -1
  39. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  40. package/dist/punctuation2.js +5 -2
  41. package/dist/punctuation2.js.map +2 -2
  42. package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
  43. package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
  44. package/dist/removeDuplicateDataFields.js +3 -2
  45. package/dist/removeDuplicateDataFields.js.map +2 -2
  46. package/dist/removeInferiorDataFields.js.map +2 -2
  47. package/dist/resolveOrphanedSubfield6s.js +3 -2
  48. package/dist/resolveOrphanedSubfield6s.js.map +2 -2
  49. package/dist/sortSubfields.js +1 -1
  50. package/dist/sortSubfields.js.map +2 -2
  51. package/dist/stripPunctuation.js +4 -3
  52. package/dist/stripPunctuation.js.map +2 -2
  53. package/dist/subfield6Utils.js +4 -1
  54. package/dist/subfield6Utils.js.map +2 -2
  55. package/dist/subfield8Utils.js.map +2 -2
  56. package/dist/translate-terms.js +4 -3
  57. package/dist/translate-terms.js.map +2 -2
  58. package/dist/typeOfDate-008.js +3 -1
  59. package/dist/typeOfDate-008.js.map +2 -2
  60. package/dist/update-field-540.js.map +2 -2
  61. package/dist/urn.js +13 -12
  62. package/dist/urn.js.map +2 -2
  63. package/package.json +7 -7
  64. package/src/addMissingField041.js +8 -4
  65. package/src/addMissingField336.js +10 -5
  66. package/src/addMissingField337.js +9 -5
  67. package/src/addMissingField338.js +11 -6
  68. package/src/cyrillux-usemarcon-replacement.js +9 -5
  69. package/src/cyrillux.js +18 -12
  70. package/src/disambiguateSeriesStatements.js +4 -1
  71. package/src/drop-terms.js +8 -6
  72. package/src/fix-33X.js +10 -6
  73. package/src/fix-country-codes.js +7 -3
  74. package/src/fix-language-codes.js +8 -4
  75. package/src/fix-sami-041.js +13 -11
  76. package/src/indicator-fixes.js +10 -7
  77. package/src/merge-fields/counterpartField.js +10 -10
  78. package/src/merge-fields/mergableIndicator.js +3 -3
  79. package/src/merge-fields/worldKnowledge.js +11 -6
  80. package/src/mergeRelatorTermFields.js +12 -11
  81. package/src/normalize-dashes.js +11 -5
  82. package/src/normalize-identifiers.js +12 -19
  83. package/src/normalize-utf8-diacritics.js +6 -3
  84. package/src/normalizeFieldForComparison.js +2 -2
  85. package/src/normalizeSubfieldValueForComparison.js +2 -2
  86. package/src/punctuation2.js +34 -30
  87. package/src/reindexSubfield6OccurenceNumbers.js +13 -11
  88. package/src/removeDuplicateDataFields.js +29 -27
  89. package/src/removeInferiorDataFields.js +28 -24
  90. package/src/resolveOrphanedSubfield6s.js +6 -4
  91. package/src/sortSubfields.js +5 -5
  92. package/src/stripPunctuation.js +5 -3
  93. package/src/subfield6Utils.js +33 -35
  94. package/src/subfield8Utils.js +10 -7
  95. package/src/translate-terms.js +13 -9
  96. package/src/typeOfDate-008.js +4 -1
  97. package/src/update-field-540.js +7 -5
  98. package/src/urn.js +17 -13
  99. package/test-fixtures/drop-terms/02/metadata.json +1 -1
  100. package/test-fixtures/drop-terms/03/metadata.json +1 -1
  101. package/test-fixtures/drop-terms/04/metadata.json +1 -1
@@ -7,6 +7,8 @@ import {fieldGetOccurrenceNumberPairs, fieldGetUnambiguousOccurrenceNumber, fiel
7
7
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
8
8
 
9
9
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:reindexSubfield6OccurrenceNumbers');
10
+ //const debugData = debug.extend('data');
11
+ const debugDev = debug.extend('dev');
10
12
 
11
13
 
12
14
  // NB! This validator/fixer has two functionalities:
@@ -20,7 +22,7 @@ export default function () {
20
22
  };
21
23
 
22
24
  function fix(record) {
23
- nvdebug('Fix SF6 occurrence numbers', debug);
25
+ nvdebug('Fix SF6 occurrence numbers', debugDev);
24
26
  const res = {message: [], fix: [], valid: true};
25
27
  //message.fix = [];
26
28
 
@@ -36,13 +38,13 @@ export default function () {
36
38
  function validate(record) {
37
39
  const res = {message: []};
38
40
 
39
- nvdebug('Validate SF6 occurrence number multiuses', debug);
41
+ nvdebug('Validate SF6 occurrence number multiuses', debugDev);
40
42
  if (recordGetSharedOccurrenceNumbers(record).length) {
41
43
  res.message.push(`Multi-use of occurrence number(s) detected`);
42
44
  }
43
45
 
44
46
  // Check max, and check number of different indexes
45
- nvdebug('Validate SF6 occurrence number (max vs n instances)', debug);
47
+ nvdebug('Validate SF6 occurrence number (max vs n instances)', debugDev);
46
48
  const max = recordGetMaxSubfield6OccurrenceNumberAsInteger(record);
47
49
  const size = recordGetNumberOfUniqueSubfield6OccurrenceNumbers(record);
48
50
 
@@ -90,7 +92,7 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
90
92
  if (sharedOccurrenceNumberFields.length < 2) {
91
93
  return;
92
94
  }
93
- nvdebug(`Disambiguate occurrence numbers (N=${sharedOccurrenceNumberFields.length}) in...`, debug);
95
+ nvdebug(`Disambiguate occurrence numbers (N=${sharedOccurrenceNumberFields.length}) in...`, debugDev);
94
96
  sharedOccurrenceNumberFields.forEach(field => disambiguateOccurrenceNumber(field));
95
97
 
96
98
  function disambiguateable(field) {
@@ -98,20 +100,20 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
98
100
  return false;
99
101
  }
100
102
  const occurrenceNumber = fieldGetUnambiguousOccurrenceNumber(field);
101
- nvdebug(` Trying to disambiguate ${occurrenceNumber} in '${fieldToString(field)}`);
103
+ nvdebug(` Trying to disambiguate ${occurrenceNumber} in '${fieldToString(field)}`, debugDev);
102
104
  if (occurrenceNumber === undefined) {
103
105
  return false;
104
106
  }
105
107
  const allRelevantFields = getPotentialSharedOccurrenceNumberFields(occurrenceNumber, sharedOccurrenceNumberFields);
106
108
  if (allRelevantFields.length < 2) {
107
- nvdebug(` Currently only ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. No action required.`);
109
+ nvdebug(` Currently only ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. No action required.`, debugDev);
108
110
  return false;
109
111
  }
110
- nvdebug(` Currently ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. ACTION REQUIRED!`);
112
+ nvdebug(` Currently ${allRelevantFields.length} field(s) use occurrence number ${occurrenceNumber}. ACTION REQUIRED!`, debugDev);
111
113
  const relevantFieldsWithCurrFieldTag = allRelevantFields.filter(candField => field.tag === candField.tag);
112
114
 
113
115
  if (relevantFieldsWithCurrFieldTag.length !== 1) {
114
- nvdebug(` Number of them using tag ${field.tag} is ${relevantFieldsWithCurrFieldTag.length}. Can not disambiguate!`);
116
+ nvdebug(` Number of them using tag ${field.tag} is ${relevantFieldsWithCurrFieldTag.length}. Can not disambiguate!`, debugDev);
115
117
  return false;
116
118
  }
117
119
 
@@ -128,7 +130,7 @@ function recordDisambiguateSharedSubfield6OccurrenceNumbers(record) {
128
130
  const newOccurrenceNumber = intToOccurrenceNumberString(newOccurrenceNumberAsInt);
129
131
  const pairedFields = fieldGetOccurrenceNumberPairs(field, record.fields);
130
132
 
131
- nvdebug(` Reindex '${fieldToString(field)}' occurrence number and it's ${pairedFields.length} pair(s) using '${newOccurrenceNumber}'`, debug);
133
+ nvdebug(` Reindex '${fieldToString(field)}' occurrence number and it's ${pairedFields.length} pair(s) using '${newOccurrenceNumber}'`, debugDev);
132
134
 
133
135
  fieldResetOccurrenceNumber(field, newOccurrenceNumber, occurrenceNumber);
134
136
  pairedFields.forEach(pairedField => fieldResetOccurrenceNumber(pairedField, newOccurrenceNumber, occurrenceNumber));
@@ -172,7 +174,7 @@ export function recordResetSubfield6OccurrenceNumbers(record) { // Remove gaps
172
174
  record.fields.forEach(field => fieldResetSubfield6(field));
173
175
 
174
176
  function fieldResetSubfield6(field) {
175
- nvdebug(`fieldResetSubfield6(${fieldToString(field)}), CURR:${currentInt}`, debug);
177
+ nvdebug(`fieldResetSubfield6(${fieldToString(field)}), CURR:${currentInt}`, debugDev);
176
178
  if (!field.subfields) {
177
179
  return;
178
180
  }
@@ -189,7 +191,7 @@ export function recordResetSubfield6OccurrenceNumbers(record) { // Remove gaps
189
191
  }
190
192
 
191
193
  const newIndex = mapCurrIndexToNewIndex(currIndex);
192
- //nvdebug(`subfieldReset6(${subfieldToString(subfield)}): ${newIndex}`, debug);
194
+ //nvdebug(`subfieldReset6(${subfieldToString(subfield)}): ${newIndex}`, debugDev);
193
195
  subfield6ResetOccurrenceNumber(subfield, newIndex);
194
196
  }
195
197
 
@@ -11,6 +11,8 @@ const LINKED_NOT_PROCESSED = 1;
11
11
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
12
12
 
13
13
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:removeDuplicateDataFields');
14
+ //const debugData = debug.extend('data');
15
+ const debugDev = debug.extend('dev');
14
16
 
15
17
  export default function () {
16
18
  return {
@@ -19,7 +21,7 @@ export default function () {
19
21
  };
20
22
 
21
23
  function fix(record) {
22
- nvdebug('Remove duplicate data fields');
24
+ nvdebug('Remove duplicate data fields', debugDev);
23
25
  const res = {message: [], fix: [], valid: true};
24
26
  removeDuplicateDatafields(record, true);
25
27
  // This can not really fail...
@@ -28,7 +30,7 @@ export default function () {
28
30
 
29
31
  function validate(record) {
30
32
  // Check max, and check number of different indexes
31
- nvdebug('Validate record: duplicate data fields cause (t)error', debug);
33
+ nvdebug('Validate record: duplicate data fields cause (t)error', debugDev);
32
34
 
33
35
  const duplicates = removeDuplicateDatafields(record, false);
34
36
 
@@ -49,7 +51,7 @@ export default function () {
49
51
 
50
52
  /*
51
53
  function numberOfLinkageSubfields(field) {
52
- nvdebug(`N of Linkage Subs(${fieldToString(field)})`);
54
+ nvdebug(`N of Linkage Subs(${fieldToString(field)})`, debugDev);
53
55
  const subfields = field.subfields.filter(sf => sf.code === '6' || sf.code === '8');
54
56
  return subfields.length;
55
57
  }
@@ -139,21 +141,21 @@ export function removeDuplicateSubfield8Chains(record, fix = true) {
139
141
 
140
142
  let removables = []; // for validation
141
143
 
142
- //nvdebug("CHAIN-8");
144
+ //nvdebug("CHAIN-8", debugDev);
143
145
  const seenLinkingNumbers = recordGetAllSubfield8LinkingNumbers(record);
144
146
  if (seenLinkingNumbers.length === 0) {
145
147
  return removables;
146
148
  }
147
149
 
148
- //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debug);
150
+ //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debugDev);
149
151
 
150
152
  seenLinkingNumbers.forEach(currLinkingNumber => {
151
153
  const linkedFields = recordGetFieldsWithSubfield8LinkingNumber(record, currLinkingNumber) //getFieldsWithSubfield8Index(base, baseIndex);
152
154
  // As/If there's just one occurrence number it should be fine to use normalizeOccurrenceNumber = true
153
155
  const normalizeOccurrenceNumber = true;
154
156
  const linkedFieldsAsString = fieldsToNormalizedString(linkedFields, currLinkingNumber, normalizeOccurrenceNumber, true);
155
- //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debug);
156
- //nvdebug(`${linkedFieldsAsString}`, debug);
157
+ //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debugDev);
158
+ //nvdebug(`${linkedFieldsAsString}`, debugDev);
157
159
 
158
160
  if (linkedFieldsAsString in seen) {
159
161
  if (!removables.includes(linkedFieldsAsString)) {
@@ -161,15 +163,15 @@ export function removeDuplicateSubfield8Chains(record, fix = true) {
161
163
  }
162
164
 
163
165
  if (fix) {
164
- //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debug);
166
+ //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debugDev);
165
167
  linkedFields.forEach(field => recordRemoveFieldOrSubfield8(record, field, currLinkingNumber));
166
168
  return;
167
169
  }
168
170
 
169
- //nvdebug(`$8 VALIDATION: DUPLICATE DETECTED ${linkedFieldsAsString}`, debug);
171
+ //nvdebug(`$8 VALIDATION: DUPLICATE DETECTED ${linkedFieldsAsString}`, debugDev);
170
172
  return;
171
173
  }
172
- //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debug);
174
+ //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debugDev);
173
175
  seen[linkedFieldsAsString] = 1;
174
176
  return;
175
177
  });
@@ -190,28 +192,28 @@ export function handleDuplicateSubfield8Chains(record, fix) {
190
192
 
191
193
  let seen = {};
192
194
 
193
- //nvdebug("CHAIN-8");
195
+ //nvdebug("CHAIN-8", debugDev);
194
196
  const seenLinkingNumbers = recordGetAllSubfield8LinkingNumbers(record);
195
197
  if (seenLinkingNumbers.length === 0) {
196
198
  return;
197
199
  }
198
200
 
199
- //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debug);
201
+ //nvdebug(`seen linking numbers ($8): ${seenLinkingNumbers.join(', ')}`, debugDev);
200
202
 
201
203
  seenLinkingNumbers.forEach(currLinkingNumber => {
202
204
  const linkedFields = recordGetFieldsWithSubfield8LinkingNumber(record, currLinkingNumber) //getFieldsWithSubfield8Index(base, baseIndex);
203
205
  // As/If there's just one occurrence number it should be fine to use normalizeOccurrenceNumber = true
204
206
  const normalizeOccurrenceNumber = false; //true;
205
207
  const linkedFieldsAsString = fieldsToNormalizedString(linkedFields, currLinkingNumber, normalizeOccurrenceNumber, true);
206
- //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debug);
207
- //nvdebug(`${linkedFieldsAsString}`, debug);
208
+ //nvdebug(`Results for LINKING NUMBER ${currLinkingNumber}:`, debugDev);
209
+ //nvdebug(`${linkedFieldsAsString}`, debugDev);
208
210
 
209
211
  if (linkedFieldsAsString in seen) {
210
- //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debug);
212
+ //nvdebug(`$8 CHAIN FIX: REMOVE $8 GROUP: ${fieldsToString(linkedFields)}`, debugDev);
211
213
  linkedFields.forEach(field => newRecordRemoveFieldOrSubfield8(record, field, currLinkingNumber, fix));
212
214
  return;
213
215
  }
214
- //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debug);
216
+ //nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`, debugDev);
215
217
  seen[linkedFieldsAsString] = 1;
216
218
  return;
217
219
  });
@@ -223,12 +225,12 @@ function markIdenticalSubfield6Chains(chain, record) {
223
225
  const normalizeTag = chain.some(field => field.tag.substring(0, 1) === '1'); // 1XX can delete 7XX as well!
224
226
  const chainAsString = fieldsToNormalizedString(chain, 0, normalizeOccurrenceNumber, normalizeTag);
225
227
 
226
- //nvdebug(`markIdenticalSubfield6Chains: ${chainAsString}`);
228
+ //nvdebug(`markIdenticalSubfield6Chains: ${chainAsString}`, debugDev);
227
229
  record.fields.forEach(f => compareWithChain(f));
228
230
 
229
231
 
230
232
  function compareWithChain(f) {
231
- //nvdebug(`FIELD2CHAIN ${fieldToString(f)}`);
233
+ //nvdebug(`FIELD2CHAIN ${fieldToString(f)}`, debugDev);
232
234
  const otherChain = fieldToChain(f, record);
233
235
  // Not a lone field or chain (head) or ... or is-same-chain
234
236
  if (otherChain.length === 0 || sameField(chain[0], otherChain[0])) {
@@ -239,7 +241,7 @@ function markIdenticalSubfield6Chains(chain, record) {
239
241
  // Mark other chain as deleted:
240
242
  if (chainAsString === otherChainAsString) {
241
243
  otherChain.forEach(f => {
242
- //nvdebug(` mark ${fieldToString(f)} as deleted ($6-chain)...`);
244
+ //nvdebug(` mark ${fieldToString(f)} as deleted ($6-chain)...`, debugDev);
243
245
  f.deleted = 1;
244
246
  });
245
247
  return;
@@ -260,7 +262,7 @@ function markIdenticalLoneFieldsAsDeletable(field, record) {
260
262
 
261
263
  // Mark fields as deleted:
262
264
  identicalLoneFields.forEach(f => {
263
- //nvdebug(` mark ${fieldToString(f)} as deleted (lone field)...`);
265
+ //nvdebug(` mark ${fieldToString(f)} as deleted (lone field)...`, debugDev);
264
266
  f.deleted = 1;
265
267
  });
266
268
 
@@ -300,7 +302,7 @@ function acceptFieldsWithSubfield8(fieldsWithSubfield8, requireSingleTag = false
300
302
 
301
303
  // If linking number
302
304
  function anomaly8(linkingNumber) {
303
- //nvdebug(` Looking for anomalies in linkin number ${linkingNumber}`);
305
+ //nvdebug(` Looking for anomalies in linkin number ${linkingNumber}`, debugDev);
304
306
  const relevantFields = fieldsWithSubfield8.filter(f => fieldHasLinkingNumber(f, linkingNumber));
305
307
  if (requireSingleTag) {
306
308
  return !isSingleTagLinkingNumber(linkingNumber, relevantFields, relevantFields[0].tag);
@@ -332,7 +334,7 @@ export function fieldToChain(field, record) {
332
334
  }
333
335
  const chain = newGetAllLinkedFields(field, record, true, true);
334
336
 
335
- // nvdebug(` Chain contains ${chain.length} field(s)`);
337
+ // nvdebug(` Chain contains ${chain.length} field(s)`, debugDev);
336
338
  if (!isChainHead(field, chain)) { // newGetAllLinkedFields() marks relevant record.fields!
337
339
  return [];
338
340
  }
@@ -357,7 +359,7 @@ export function fieldToChain(field, record) {
357
359
  return [];
358
360
  }
359
361
 
360
- //nvdebug(`Proceed with ${fieldsToString(chain)}`);
362
+ //nvdebug(`Proceed with ${fieldsToString(chain)}`, debugDev);
361
363
 
362
364
 
363
365
  return chain;
@@ -366,7 +368,7 @@ export function fieldToChain(field, record) {
366
368
 
367
369
  function fieldHandleDuplicateDatafields(field, record) {
368
370
  const chain = fieldToChain(field, record);
369
- //nvdebug(` TRY TO HANDLE DUPLICATES OF '${fieldsToString(chain)}'`);
371
+ //nvdebug(` TRY TO HANDLE DUPLICATES OF '${fieldsToString(chain)}'`, debugDev);
370
372
 
371
373
  if (chain.length === 0) {
372
374
  return;
@@ -383,7 +385,7 @@ function fieldHandleDuplicateDatafields(field, record) {
383
385
  if (fieldsWithSubfield6.length === 0) {
384
386
 
385
387
  if (fieldsWithSubfield8.length === 0) { // chain.length === 1?
386
- //nvdebug(` Trying to find duplicates of single field '${fieldToString(chain[0])}'`);
388
+ //nvdebug(` Trying to find duplicates of single field '${fieldToString(chain[0])}'`, debugDev);
387
389
  markIdenticalLoneFieldsAsDeletable(chain[0], record);
388
390
  return;
389
391
  }
@@ -401,8 +403,8 @@ function fieldHandleDuplicateDatafields(field, record) {
401
403
  }
402
404
 
403
405
 
404
- //nvdebug(` NO HANDLER FOUND FOR '${fieldsToString(chain)}'`);
405
- //nvdebug(` N8s: ${fieldsWithSubfield6.length}`);
406
+ //nvdebug(` NO HANDLER FOUND FOR '${fieldsToString(chain)}'`, debugDev);
407
+ //nvdebug(` N8s: ${fieldsWithSubfield6.length}`, debugDev);
406
408
 
407
409
  }
408
410
 
@@ -12,7 +12,10 @@ import {fixComposition, precomposeFinnishLetters} from './normalize-utf8-diacrit
12
12
  // NB! This validator handles only full fields, and does not support subfield $8 removal.
13
13
  // Also, having multiple $8 subfields in same fields is not supported.
14
14
  // If this functionality is needed, see removeDuplicateDatafields.js for examples of subfield-only stuff.
15
+
15
16
  // const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:removeInferiorDataFields');
17
+ //const debugData = debug.extend('data');
18
+ //const debugDev = debug.extend('dev');
16
19
 
17
20
  export default function () {
18
21
  return {
@@ -21,7 +24,7 @@ export default function () {
21
24
  };
22
25
 
23
26
  function fix(record) {
24
- //nvdebug('Fix record: remove inferior (eg. subset) data fields', debug);
27
+ //nvdebug('Fix record: remove inferior (eg. subset) data fields', debugDev);
25
28
  const res = {message: [], fix: [], valid: true};
26
29
  removeInferiorDatafields(record, true);
27
30
  // This can not really fail...
@@ -30,7 +33,7 @@ export default function () {
30
33
 
31
34
  function validate(record) {
32
35
  // Check max, and check number of different indexes
33
- //nvdebug('Validate record: remove inferior (eg. subset) data fields', debug);
36
+ //nvdebug('Validate record: remove inferior (eg. subset) data fields', debugDev);
34
37
 
35
38
  const duplicates = removeInferiorDatafields(record, false);
36
39
 
@@ -43,14 +46,14 @@ export default function () {
43
46
 
44
47
 
45
48
  function deriveInferiorChains(fields, record) {
46
- //nvdebug(`======= GOT ${fields.length} FIELDS TO CHAINIFY`);
49
+ //nvdebug(`======= GOT ${fields.length} FIELDS TO CHAINIFY`, debugDev);
47
50
  const hash = {};
48
51
 
49
52
  fields.forEach(f => fieldToChainToDeletables(f));
50
53
 
51
54
  return hash;
52
55
 
53
- //nvdebug(`WP1: GOT ${todoList.length} CHAINS`);
56
+ //nvdebug(`WP1: GOT ${todoList.length} CHAINS`, debugDev);
54
57
 
55
58
 
56
59
  // here we map deletableStringObject[str] => field. The idea is to help debugging. We don't actually need the field object...
@@ -63,7 +66,7 @@ function deriveInferiorChains(fields, record) {
63
66
  }
64
67
  const chainAsString = fieldsToNormalizedString(chain, 0, true, true);
65
68
  const arr = deriveChainDeletables([chainAsString]);
66
- //nvdebug(`GOT ${arr.length} DELETABLES FOR ${chainAsString}`);
69
+ //nvdebug(`GOT ${arr.length} DELETABLES FOR ${chainAsString}`, debugDev);
67
70
  arr.forEach(val => {
68
71
  if (!(val in hash)) {
69
72
  hash[val] = field;
@@ -116,16 +119,16 @@ function isRelevantChain6(field, record) {
116
119
 
117
120
  export function removeInferiorChains(record, fix = true) {
118
121
  const fields = record.fields.filter(f => isRelevantChain6(f, record));
119
- //nvdebug(`WP2.0: GOT ${fields.length} chain(s)`);
122
+ //nvdebug(`WP2.0: GOT ${fields.length} chain(s)`, debugDev);
120
123
 
121
124
  const deletableChainsAsKeys = deriveInferiorChains(fields, record);
122
125
  const nChains = Object.keys(deletableChainsAsKeys).length;
123
- //nvdebug(`WP2: GOT ${nChains} chain(s)`);
126
+ //nvdebug(`WP2: GOT ${nChains} chain(s)`, debugDev);
124
127
  if (nChains === 0) {
125
128
  return [];
126
129
  }
127
130
 
128
- //nvdebug(`removeInferiorChains() has ${fields.length} fields-in-chain(s), and a list of ${nChains} deletable(s)`);
131
+ //nvdebug(`removeInferiorChains() has ${fields.length} fields-in-chain(s), and a list of ${nChains} deletable(s)`, debugDev);
129
132
 
130
133
  return innerRemoveInferiorChains(fields);
131
134
 
@@ -153,11 +156,11 @@ export function removeInferiorChains(record, fix = true) {
153
156
  if (chainContains1XX(chain)) {
154
157
  triggeringChain.forEach(f => sevenToOne(f, triggeringChain));
155
158
  }
156
- //nvdebug(`iRIS6C: ${chainAsString}`);
159
+ //nvdebug(`iRIS6C: ${chainAsString}`, debugDev);
157
160
  const deletedString = fieldsToString(chain);
158
161
  const message = `DEL: '${deletedString}' REASON: '${fieldsToString(triggeringChain)}'`;
159
162
  if (fix) {
160
- //nvdebug(`INFERIOR $6 CHAIN REMOVAL: ${message}}`, debug);
163
+ //nvdebug(`INFERIOR $6 CHAIN REMOVAL: ${message}}`, debugDev);
161
164
  chain.forEach(field => record.removeField(field));
162
165
  }
163
166
  return innerRemoveInferiorChains(remainingFields, [...deletedStringsArray, message]);
@@ -197,7 +200,7 @@ function deriveIndividualDeletables490(todoList, deletables = []) {
197
200
  if (fieldAsString === undefined) {
198
201
  return deletables;
199
202
  }
200
- //nvdebug(`PROCESS ${fieldAsString}`);
203
+ //nvdebug(`PROCESS ${fieldAsString}`, debugDev);
201
204
  if (!fieldAsString.match(/^490/u)) {
202
205
  return deriveIndividualDeletables490(stillToDo, deletables);
203
206
  }
@@ -220,13 +223,14 @@ function deriveIndividualDeletables490(todoList, deletables = []) {
220
223
 
221
224
  /*
222
225
  if (arr.length) {
223
- nvdebug(`${arr.length} derivation(s) for ${fieldAsString}`);
224
- nvdebug(arr.join('\n'));
226
+ nvdebug(`${arr.length} derivation(s) for ${fieldAsString}`, debugDev);
227
+ nvdebug(arr.join('\n'), debugDev);
225
228
  }
226
229
  */
227
230
  return arr;
228
231
  }
229
232
 
233
+ // eslint-disable-next-line max-lines-per-function
230
234
  function deriveIndividualDeletables(record) {
231
235
  const todoList = record.fields.map(f => fieldToString(f));
232
236
  //const finishedRecord = encodingLevelIsBetterThanPrepublication(getEncodingLevel(record));
@@ -305,8 +309,8 @@ function deriveIndividualDeletables(record) {
305
309
  if (tmp !== currString) {
306
310
  return processTodoList([tmp, ...stillToDo, ...moreToDo], [...deletables, tmp]);
307
311
  }
308
- //nvdebug(`505 ORIGINAL: '${fieldAsString}'`)
309
- //nvdebug(`505 DERIVATE: '${tmp}'`)
312
+ //nvdebug(`505 ORIGINAL: '${fieldAsString}'`, debugDev)
313
+ //nvdebug(`505 DERIVATE: '${tmp}'`, debugDev)
310
314
  }
311
315
 
312
316
  if (currString.match(/^594 ## ‡a Ei vastaanotettu ‡5 FENNI$/u)) { // MELKEHITYS-3147
@@ -319,11 +323,11 @@ function deriveIndividualDeletables(record) {
319
323
  // MET-381: remove occurence number TAG-00, if TAG-NN existists
320
324
  if (currString.match(/^880.* ‡6 [0-9][0-9][0-9]-(?:[1-9][0-9]|0[1-9])/u)) {
321
325
  const tmp = currString.replace(/( ‡6 [0-9][0-9][0-9])-[0-9]+/u, '$1-00');
322
- //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp}'`);
326
+ //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp}'`, debugDev);
323
327
  //deletableStringsArray.push(tmp);
324
328
  if (tmp.match(/ ‡6 [0-9][0-9][0-9]-00\/[^ ]+ /u)) {
325
329
  const tmp2 = tmp.replace(/( ‡6 [0-9][0-9][0-9]-00)[^ ]+/u, '$1');
326
- //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp2}'`);
330
+ //nvdebug(`MET-381: ADD TO DELETABLES: '${tmp2}'`, debugDev);
327
331
  return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp, tmp2]);
328
332
  }
329
333
  return processTodoList([...stillToDo, ...moreToDo], [...deletables, tmp]);
@@ -345,13 +349,13 @@ function deriveIndividualDeletables(record) {
345
349
  }
346
350
 
347
351
  function getAccentlessVersion(string) { // MET-527
348
- //nvdebug(`START: '${string}`);
352
+ //nvdebug(`START: '${string}`, debugDev);
349
353
  // This is a sanity check: if precomposition does something, there's something wrong, and we don't want to proceed..
350
354
  if (string !== precomposeFinnishLetters(string)) {
351
355
  return [];
352
356
  }
353
357
  const accentless = String(fixComposition(string)).replace(/\p{Diacritic}/gu, '');
354
- //nvdebug(`FROM '${string}'\n TO '${accentless}'`);
358
+ //nvdebug(`FROM '${string}'\n TO '${accentless}'`, debugDev);
355
359
  if (accentless === string) { // Don't self-destruct
356
360
  return [];
357
361
  }
@@ -408,8 +412,8 @@ export function removeIndividualInferiorDatafields(record, fix = true) { // No $
408
412
  const deletableFieldsAsStrings = deriveIndividualDeletables(record);
409
413
  const deletableFieldsAsNormalizedStrings = deriveIndividualNormalizedDeletables(record);
410
414
 
411
- // nvdebug(`Deletables:\n ${deletableFieldsAsStrings.join('\n ')}`);
412
- // nvdebug(`Normalized deletables:\n ${deletableFieldsAsNormalizedStrings.join('\n ')}`);
415
+ // nvdebug(`Deletables:\n ${deletableFieldsAsStrings.join('\n ')}`, debugDev);
416
+ // nvdebug(`Normalized deletables:\n ${deletableFieldsAsNormalizedStrings.join('\n ')}`, debugDev);
413
417
 
414
418
  const hits = record.fields.filter(field => isDeletableField(field));
415
419
 
@@ -417,7 +421,7 @@ export function removeIndividualInferiorDatafields(record, fix = true) { // No $
417
421
 
418
422
  if (fix) {
419
423
  hits.forEach(field => {
420
- //nvdebug(`Remove inferior field: ${fieldToString(field)}`, debug);
424
+ //nvdebug(`Remove inferior field: ${fieldToString(field)}`, debugDev);
421
425
  record.removeField(field);
422
426
  });
423
427
  }
@@ -445,8 +449,8 @@ export function removeInferiorDatafields(record, fix = true) {
445
449
  const removables6 = removeInferiorChains(record, fix); // Lone subfield $6 chains
446
450
  // HOW TO HANDLE $6+$8 combos? Skipping is relatively OK.
447
451
 
448
- //nvdebug(`REMOVABLES:\n ${removables.join('\n ')}`, debug);
449
- //nvdebug(`REMOVABLES 6:\n ${removables6.join('\n ')}`, debug);
452
+ //nvdebug(`REMOVABLES:\n ${removables.join('\n ')}`, debugDev);
453
+ //nvdebug(`REMOVABLES 6:\n ${removables6.join('\n ')}`, debugDev);
450
454
 
451
455
  const removablesAll = removables.concat(removables6); //.concat(removables8);
452
456
 
@@ -5,6 +5,8 @@ import {fieldHasWantedTagAndOccurrenceNumber, isValidSubfield6, subfield6GetOccu
5
5
  // Relocated from melinda-marc-record-merge-reducers (and renamed)
6
6
 
7
7
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:resolveOrphanedSubfield6s');
8
+ //const debugData = debug.extend('data');
9
+ const debugDev = debug.extend('dev');
8
10
 
9
11
  export default function () {
10
12
  return {
@@ -13,7 +15,7 @@ export default function () {
13
15
  };
14
16
 
15
17
  function fix(record) {
16
- nvdebug('Fix SF6 orphaned occurrence numbers');
18
+ nvdebug('Fix SF6 orphaned occurrence numbers', debugDev);
17
19
  const res = {message: [], fix: [], valid: true};
18
20
  //message.fix = [];
19
21
 
@@ -26,7 +28,7 @@ export default function () {
26
28
 
27
29
  function validate(record) {
28
30
  // Check max, and check number of different indexes
29
- nvdebug('Validate SF6 orphaned occurrence numbers', debug);
31
+ nvdebug('Validate SF6 orphaned occurrence numbers', debugDev);
30
32
  const fieldsContainingSubfield6 = record.fields.filter(field => fieldHasSubfield(field, '6'));
31
33
 
32
34
  const orphanedFields = getOrphanedFields(fieldsContainingSubfield6);
@@ -77,7 +79,7 @@ function findPairForSubfield6OccurrenceNumber(subfield6, myTag, candPairFields)
77
79
  if (!isValidSubfield6(subfield6)) {
78
80
  return undefined;
79
81
  }
80
- //nvdebug(`LOOKING FOR PAIR: ${myTag} ${subfieldToString(subfield6)}`);
82
+ //nvdebug(`LOOKING FOR PAIR: ${myTag} ${subfieldToString(subfield6)}`, debugDev);
81
83
  candPairFields.forEach(field => fieldToString(field));
82
84
 
83
85
  // Only valid $6 value that fails to map to another field is iffy...
@@ -88,7 +90,7 @@ function findPairForSubfield6OccurrenceNumber(subfield6, myTag, candPairFields)
88
90
  return undefined;
89
91
  }
90
92
  const tagAndOccurrenceNumber = `${myTag}-${occurrenceNumber}`;
91
- //nvdebug(`Try to find occurrence number ${tagAndOccurrenceNumber} in field ${referredTag}...`);
93
+ //nvdebug(`Try to find occurrence number ${tagAndOccurrenceNumber} in field ${referredTag}...`, debugDev);
92
94
  //const relevantFields = fields.filter(field => field.tag === referredTag && field.subfields.some(sf => subfield6GetOccurrenceNumber(sf) === occurrenceNumber));
93
95
  const relevantFields = candPairFields.filter(field => field.tag === referredTag && fieldHasWantedTagAndOccurrenceNumber(field, tagAndOccurrenceNumber));
94
96
  if (relevantFields.length === 0) {
@@ -141,7 +141,7 @@ function getSubfieldSortOrder(field) {
141
141
  return entry[0].sortOrder;
142
142
  }
143
143
  if (!['300'].includes(field.tag)) { // Lis tags which use normal $a...$z order here!
144
- nvdebug(`WARNING!\tNo subfield order found for ${field.tag}.`);
144
+ nvdebug(`WARNING!\tNo subfield order found for ${field.tag}.`, debugDev);
145
145
  }
146
146
  return [];
147
147
  }
@@ -230,15 +230,15 @@ export function sortAdjacentSubfields(field, externalSortOrder = []) {
230
230
  swapSubfields(field, controlSubfieldOrder);
231
231
 
232
232
  const sortOrderForField = externalSortOrder.length > 0 ? externalSortOrder : getSubfieldSortOrder(field);
233
- //nvdebug(`INTERMEDIATE SUBFIELD ORDER FOR ${field.tag}: ${sortOrderForField.join(', ')}`);
233
+ //nvdebug(`INTERMEDIATE SUBFIELD ORDER FOR ${field.tag}: ${sortOrderForField.join(', ')}`, debugDev);
234
234
 
235
235
  const defaultSortOrder = finnishWay ? defaultSortOrderFinns : defaultSortOrderOthers; // $2 vs $0
236
236
  const subfieldOrder = sortOrderForField.length > 0 ? sortOrderForField : defaultSortOrder;
237
- //nvdebug(`FINAL SUBFIELD ORDER (FINNISH=${finnishWay}) FOR ${field.tag}: ${subfieldOrder.join(', ')}`);
237
+ //nvdebug(`FINAL SUBFIELD ORDER (FINNISH=${finnishWay}) FOR ${field.tag}: ${subfieldOrder.join(', ')}`, debugDev);
238
238
  //if (sortOrder === null) { return field; } //// Currently always sort..
239
- //nvdebug(`IN: ${fieldToString(field)}`);
239
+ //nvdebug(`IN: ${fieldToString(field)}`, debugDev);
240
240
  swapSubfields(field, subfieldOrder);
241
- //nvdebug(`OUT: ${fieldToString(field)}`);
241
+ //nvdebug(`OUT: ${fieldToString(field)}`, debugDev);
242
242
 
243
243
  return field;
244
244
  }
@@ -8,9 +8,11 @@
8
8
  import {fieldGetFixedString, fieldNeedsModification, fieldStripPunctuation} from './punctuation2.js';
9
9
  import createDebugLogger from 'debug';
10
10
 
11
- import {fieldToString} from './utils.js';
11
+ import {fieldToString, nvdebug} from './utils.js';
12
12
 
13
13
  const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');
14
+ //const debugData = debug.extend('data');
15
+ const debugDev = debug.extend('dev');
14
16
 
15
17
  const description = 'Strip punctuation in data fields';
16
18
 
@@ -21,14 +23,14 @@ export default function () {
21
23
  };
22
24
 
23
25
  function fix(record) {
24
- debug(`${description}: fixer`);
26
+ nvdebug(`${description}: fixer`, debugDev);
25
27
  const res = {message: [], fix: [], valid: true};
26
28
  record.fields.forEach(f => fieldStripPunctuation(f));
27
29
  return res;
28
30
  }
29
31
 
30
32
  function validate(record) {
31
- debug(`${description}: validate`);
33
+ nvdebug(`${description}: validate`, debugDev);
32
34
 
33
35
  const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, false));
34
36