@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.
- package/dist/addMissingField041.js +6 -3
- package/dist/addMissingField041.js.map +2 -2
- package/dist/addMissingField336.js +7 -4
- package/dist/addMissingField336.js.map +2 -2
- package/dist/addMissingField337.js +6 -3
- package/dist/addMissingField337.js.map +2 -2
- package/dist/addMissingField338.js +8 -5
- package/dist/addMissingField338.js.map +2 -2
- package/dist/cyrillux-usemarcon-replacement.js +5 -2
- package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
- package/dist/cyrillux.js +10 -7
- package/dist/cyrillux.js.map +2 -2
- package/dist/disambiguateSeriesStatements.js +2 -1
- package/dist/disambiguateSeriesStatements.js.map +2 -2
- package/dist/drop-terms.js +5 -4
- package/dist/drop-terms.js.map +2 -2
- package/dist/fix-33X.js +7 -4
- package/dist/fix-33X.js.map +2 -2
- package/dist/fix-country-codes.js +5 -0
- package/dist/fix-country-codes.js.map +2 -2
- package/dist/fix-language-codes.js +5 -1
- package/dist/fix-language-codes.js.map +2 -2
- package/dist/fix-sami-041.js +11 -10
- package/dist/fix-sami-041.js.map +2 -2
- package/dist/indicator-fixes.js +5 -1
- package/dist/indicator-fixes.js.map +2 -2
- package/dist/merge-fields/counterpartField.js +6 -6
- package/dist/merge-fields/counterpartField.js.map +2 -2
- package/dist/merge-fields/mergableIndicator.js +0 -3
- package/dist/merge-fields/mergableIndicator.js.map +2 -2
- package/dist/merge-fields/worldKnowledge.js.map +2 -2
- package/dist/mergeRelatorTermFields.js +9 -6
- package/dist/mergeRelatorTermFields.js.map +2 -2
- package/dist/normalize-dashes.js +7 -4
- package/dist/normalize-dashes.js.map +2 -2
- package/dist/normalize-identifiers.js.map +2 -2
- package/dist/normalize-utf8-diacritics.js.map +2 -2
- package/dist/normalizeFieldForComparison.js.map +1 -1
- package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
- package/dist/punctuation2.js +5 -2
- package/dist/punctuation2.js.map +2 -2
- package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
- package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
- package/dist/removeDuplicateDataFields.js +3 -2
- package/dist/removeDuplicateDataFields.js.map +2 -2
- package/dist/removeInferiorDataFields.js.map +2 -2
- package/dist/resolveOrphanedSubfield6s.js +3 -2
- package/dist/resolveOrphanedSubfield6s.js.map +2 -2
- package/dist/sortSubfields.js +1 -1
- package/dist/sortSubfields.js.map +2 -2
- package/dist/stripPunctuation.js +4 -3
- package/dist/stripPunctuation.js.map +2 -2
- package/dist/subfield6Utils.js +4 -1
- package/dist/subfield6Utils.js.map +2 -2
- package/dist/subfield8Utils.js.map +2 -2
- package/dist/translate-terms.js +4 -3
- package/dist/translate-terms.js.map +2 -2
- package/dist/typeOfDate-008.js +3 -1
- package/dist/typeOfDate-008.js.map +2 -2
- package/dist/update-field-540.js.map +2 -2
- package/dist/urn.js +13 -12
- package/dist/urn.js.map +2 -2
- package/package.json +7 -7
- package/src/addMissingField041.js +8 -4
- package/src/addMissingField336.js +10 -5
- package/src/addMissingField337.js +9 -5
- package/src/addMissingField338.js +11 -6
- package/src/cyrillux-usemarcon-replacement.js +9 -5
- package/src/cyrillux.js +18 -12
- package/src/disambiguateSeriesStatements.js +4 -1
- package/src/drop-terms.js +8 -6
- package/src/fix-33X.js +10 -6
- package/src/fix-country-codes.js +7 -3
- package/src/fix-language-codes.js +8 -4
- package/src/fix-sami-041.js +13 -11
- package/src/indicator-fixes.js +10 -7
- package/src/merge-fields/counterpartField.js +10 -10
- package/src/merge-fields/mergableIndicator.js +3 -3
- package/src/merge-fields/worldKnowledge.js +11 -6
- package/src/mergeRelatorTermFields.js +12 -11
- package/src/normalize-dashes.js +11 -5
- package/src/normalize-identifiers.js +12 -19
- package/src/normalize-utf8-diacritics.js +6 -3
- package/src/normalizeFieldForComparison.js +2 -2
- package/src/normalizeSubfieldValueForComparison.js +2 -2
- package/src/punctuation2.js +34 -30
- package/src/reindexSubfield6OccurenceNumbers.js +13 -11
- package/src/removeDuplicateDataFields.js +29 -27
- package/src/removeInferiorDataFields.js +28 -24
- package/src/resolveOrphanedSubfield6s.js +6 -4
- package/src/sortSubfields.js +5 -5
- package/src/stripPunctuation.js +5 -3
- package/src/subfield6Utils.js +33 -35
- package/src/subfield8Utils.js +10 -7
- package/src/translate-terms.js +13 -9
- package/src/typeOfDate-008.js +4 -1
- package/src/update-field-540.js +7 -5
- package/src/urn.js +17 -13
- package/test-fixtures/drop-terms/02/metadata.json +1 -1
- package/test-fixtures/drop-terms/03/metadata.json +1 -1
- 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',
|
|
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',
|
|
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)',
|
|
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...`,
|
|
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}'`,
|
|
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}`,
|
|
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}`,
|
|
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',
|
|
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(', ')}`,
|
|
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}:`,
|
|
156
|
-
//nvdebug(`${linkedFieldsAsString}`,
|
|
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)}`,
|
|
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}`,
|
|
171
|
+
//nvdebug(`$8 VALIDATION: DUPLICATE DETECTED ${linkedFieldsAsString}`, debugDev);
|
|
170
172
|
return;
|
|
171
173
|
}
|
|
172
|
-
//nvdebug(`$8 DOUBLE REMOVAL OR VALIDATION: ADD2SEEN ${linkedFieldsAsString}`,
|
|
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(', ')}`,
|
|
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}:`,
|
|
207
|
-
//nvdebug(`${linkedFieldsAsString}`,
|
|
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)}`,
|
|
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}`,
|
|
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',
|
|
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',
|
|
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}}`,
|
|
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)}`,
|
|
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 ')}`,
|
|
449
|
-
//nvdebug(`REMOVABLES 6:\n ${removables6.join('\n ')}`,
|
|
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',
|
|
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) {
|
package/src/sortSubfields.js
CHANGED
|
@@ -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
|
}
|
package/src/stripPunctuation.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
33
|
+
nvdebug(`${description}: validate`, debugDev);
|
|
32
34
|
|
|
33
35
|
const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, false));
|
|
34
36
|
|