@natlibfi/marc-record-validators-melinda 9.0.4 → 9.0.5-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.
- package/dist/isbn-issn.js +152 -75
- package/dist/isbn-issn.js.map +1 -1
- package/dist/isbn-issn.spec.js +121 -5
- package/dist/isbn-issn.spec.js.map +1 -1
- package/package.json +1 -1
- package/src/isbn-issn.js +138 -68
- package/src/isbn-issn.spec.js +57 -9
package/dist/isbn-issn.js
CHANGED
|
@@ -17,7 +17,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
17
17
|
*
|
|
18
18
|
* MARC record validators used in Melinda
|
|
19
19
|
*
|
|
20
|
-
* Copyright (c) 2014-
|
|
20
|
+
* Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)
|
|
21
21
|
*
|
|
22
22
|
* This file is part of marc-record-validators-melinda
|
|
23
23
|
*
|
|
@@ -38,6 +38,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
38
38
|
* for the JavaScript code in this file.
|
|
39
39
|
*
|
|
40
40
|
*/
|
|
41
|
+
// handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y
|
|
41
42
|
var _default = ({
|
|
42
43
|
hyphenateISBN = false,
|
|
43
44
|
handleInvalid = false
|
|
@@ -48,62 +49,118 @@ var _default = ({
|
|
|
48
49
|
description: 'Validates ISBN and ISSN values'
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const subfield = field.subfields.find(sf => sf.code === 'a');
|
|
52
|
+
function invalidISBN(isbn) {
|
|
53
|
+
// If value contains space, it's not necessarily crap. (It's typically something like "1234567890 (nid.)".)
|
|
54
|
+
// Check the first word in string:
|
|
55
|
+
if (isbn.indexOf(' ') > -1) {
|
|
56
|
+
// const arr = isbn.split(' ');
|
|
57
|
+
// console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
|
|
58
|
+
// return invalidISBN(arr[0]);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
const auditedIsbn = _isbn.default.audit(isbn);
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} // Should we refactor code by adding a function that returns legal set of values,
|
|
67
|
-
// and then we compare subfield.value against that list?
|
|
64
|
+
if (!auditedIsbn.validIsbn) {
|
|
65
|
+
console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console
|
|
68
66
|
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
function invalidField020(field) {
|
|
74
|
+
if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
} // Check ISSN:
|
|
78
|
+
return false;
|
|
78
79
|
|
|
80
|
+
function invalidField020a(subfield) {
|
|
81
|
+
if (subfield.code !== 'a') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
79
84
|
|
|
80
|
-
if (
|
|
85
|
+
if (invalidISBN(subfield.value)) {
|
|
81
86
|
return true;
|
|
82
87
|
}
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
87
91
|
|
|
88
|
-
function
|
|
89
|
-
|
|
92
|
+
function invalidField020z(subfield) {
|
|
93
|
+
if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {
|
|
94
|
+
return false;
|
|
95
|
+
} // We are only interested in $z field if it is valid ISBN that requires hyphenation:
|
|
90
96
|
|
|
91
|
-
if (subfieldA === undefined) {
|
|
92
|
-
const subfieldZ = field.subfields.find(sf => sf.code === 'z');
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
return subfield.value.indexOf('-') === -1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function subfieldRequiresHyphenation(subfield) {
|
|
103
|
+
if (subfield.code !== 'a' && subfield.code !== 'z') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return requiresHyphenation(subfield.value);
|
|
108
|
+
|
|
109
|
+
function requiresHyphenation(isbn) {
|
|
110
|
+
if (isbn.indexOf(' ') > -1) {
|
|
111
|
+
const arr = isbn.split(' ');
|
|
112
|
+
console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
|
|
113
|
+
|
|
114
|
+
return requiresHyphenation(arr[0]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (invalidISBN(isbn)) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.info(`sfRH ${isbn}`); // eslint-disable-line no-console
|
|
122
|
+
|
|
123
|
+
const parsedIsbn = _isbn.default.parse(isbn);
|
|
124
|
+
|
|
125
|
+
if (hyphenateISBN) {
|
|
126
|
+
return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return false; //return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getInvalidFields(record) {
|
|
134
|
+
//return record.get(/^(?:020|022)$/u).filter(field => {
|
|
135
|
+
return record.fields.filter(field => {
|
|
136
|
+
if (!field.subfields) {
|
|
137
|
+
return false;
|
|
138
|
+
} // Check ISBN:
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if (field.tag === '020') {
|
|
142
|
+
if (invalidField020(field)) {
|
|
143
|
+
return true;
|
|
96
144
|
}
|
|
97
145
|
|
|
98
|
-
return
|
|
99
|
-
} //
|
|
146
|
+
return fieldRequiresHyphenation(field);
|
|
147
|
+
} // Check ISSN:
|
|
100
148
|
|
|
101
149
|
|
|
102
|
-
if (
|
|
103
|
-
|
|
150
|
+
if (field.tag === '022') {
|
|
151
|
+
if (invalidField022(field)) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
|
|
156
|
+
return !(0, _issnVerify.default)(subfield.value);
|
|
104
157
|
}
|
|
105
158
|
|
|
106
159
|
return false;
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
function fieldRequiresHyphenation(field) {
|
|
163
|
+
return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));
|
|
107
164
|
}
|
|
108
165
|
|
|
109
166
|
function invalidField022(field) {
|
|
@@ -181,66 +238,86 @@ var _default = ({
|
|
|
181
238
|
function fix(record) {
|
|
182
239
|
getInvalidFields(record).forEach(field => {
|
|
183
240
|
if (field.tag === '020') {
|
|
184
|
-
|
|
241
|
+
field.subfields.forEach(subfield => fixField020Subfield(field, subfield));
|
|
242
|
+
return;
|
|
243
|
+
} // 022 ISSN:
|
|
185
244
|
|
|
186
|
-
if (subfield) {
|
|
187
|
-
// ISBN is valid but is missing hyphens
|
|
188
|
-
const normalizedValue = normalizeIsbnValue(subfield.value);
|
|
189
245
|
|
|
190
|
-
|
|
191
|
-
// eslint-disable-line functional/no-conditional-statement
|
|
192
|
-
subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
|
|
193
|
-
} else if (handleInvalid) {
|
|
194
|
-
// eslint-disable-line functional/no-conditional-statement
|
|
195
|
-
field.subfields.push({
|
|
196
|
-
code: 'z',
|
|
197
|
-
value: subfield.value
|
|
198
|
-
}); // eslint-disable-line functional/immutable-data
|
|
246
|
+
const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
|
|
199
247
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
248
|
+
if (subfield && handleInvalid) {
|
|
249
|
+
// eslint-disable-line functional/no-conditional-statement
|
|
250
|
+
// $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)
|
|
251
|
+
field.subfields.push({
|
|
252
|
+
code: 'y',
|
|
253
|
+
value: subfield.value
|
|
254
|
+
}); // eslint-disable-line functional/immutable-data
|
|
205
255
|
|
|
206
|
-
|
|
256
|
+
record.removeSubfield(subfield, field);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
/*
|
|
260
|
+
function trimISBN(value) {
|
|
261
|
+
return trimSpaces(value.replace(/\s$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
|
|
262
|
+
}
|
|
263
|
+
*/
|
|
264
|
+
|
|
265
|
+
function fixField020Subfield(field, subfield) {
|
|
266
|
+
console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
|
|
267
|
+
|
|
268
|
+
if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {
|
|
269
|
+
console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
|
|
270
|
+
// ISBN is valid but is missing hyphens
|
|
271
|
+
|
|
272
|
+
const normalizedValue = normalizeIsbnValue(subfield.value);
|
|
273
|
+
|
|
274
|
+
if (normalizedValue !== undefined) {
|
|
275
|
+
// eslint-disable-line functional/no-conditional-statement
|
|
276
|
+
subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
|
|
277
|
+
} else if (subfield.code === 'a' && handleInvalid) {
|
|
207
278
|
// eslint-disable-line functional/no-conditional-statement
|
|
279
|
+
// $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)
|
|
208
280
|
field.subfields.push({
|
|
209
|
-
code: '
|
|
210
|
-
value:
|
|
281
|
+
code: 'z',
|
|
282
|
+
value: subfield.value
|
|
211
283
|
}); // eslint-disable-line functional/immutable-data
|
|
212
284
|
|
|
213
285
|
record.removeSubfield(subfield, field);
|
|
214
286
|
}
|
|
215
287
|
}
|
|
216
|
-
});
|
|
217
288
|
|
|
218
|
-
|
|
219
|
-
const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
|
|
289
|
+
return;
|
|
220
290
|
|
|
221
|
-
|
|
291
|
+
function normalizeIsbnValue2(trimmedValue) {
|
|
292
|
+
//const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
|
|
293
|
+
const auditResult = _isbn.default.audit(trimmedValue);
|
|
222
294
|
|
|
223
|
-
|
|
224
|
-
|
|
295
|
+
if (auditResult.validIsbn) {
|
|
296
|
+
const parsedIsbn = _isbn.default.parse(trimmedValue);
|
|
225
297
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
298
|
+
if (hyphenateISBN) {
|
|
299
|
+
// eslint-disable-line functional/no-conditional-statement
|
|
300
|
+
return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
|
|
301
|
+
} // Just trim
|
|
230
302
|
|
|
231
303
|
|
|
232
|
-
|
|
304
|
+
return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return undefined;
|
|
233
308
|
}
|
|
234
309
|
|
|
235
|
-
|
|
236
|
-
|
|
310
|
+
function normalizeIsbnValue(value) {
|
|
311
|
+
const trimmedValue = value.replace(/^\s+/gu, '');
|
|
237
312
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
313
|
+
if (trimmedValue.indexOf(' ') === -1) {
|
|
314
|
+
return normalizeIsbnValue2(trimmedValue);
|
|
315
|
+
}
|
|
241
316
|
|
|
242
|
-
|
|
243
|
-
|
|
317
|
+
const [head] = trimmedValue.split(' '); // NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?
|
|
318
|
+
|
|
319
|
+
return normalizeIsbnValue2(head);
|
|
320
|
+
}
|
|
244
321
|
}
|
|
245
322
|
}
|
|
246
323
|
};
|
package/dist/isbn-issn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/isbn-issn.js"],"names":["hyphenateISBN","handleInvalid","validate","fix","description","getInvalidFields","record","get","filter","field","tag","invalidField020","subfield","subfields","find","sf","code","auditedIsbn","ISBN","audit","value","validIsbn","parsedIsbn","parse","isbn10h","isbn13h","isbn10","isbn13","invalidField022","subfieldA","undefined","subfieldZ","indexOf","subfieldAorL","subfieldY","fields","length","valid","map","name","getISSN","reduce","acc","obj","msg","messages","concat","forEach","normalizedValue","normalizeIsbnValue","push","removeSubfield","trimSpaces","trimmedValue","trimISBN","auditResult","replace"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* MARC record validators used in Melinda\n*\n* Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of marc-record-validators-melinda\n*\n* marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Lesser General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* marc-record-validators-melinda is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport ISBN from 'isbn3';\nimport validateISSN from '@natlibfi/issn-verify';\n\nexport default ({hyphenateISBN = false, handleInvalid = false} = {}) => {\n return {\n validate, fix,\n description: 'Validates ISBN and ISSN values'\n };\n\n function getInvalidFields(record) {\n return record.get(/^(020|022)$/u).filter(field => { // eslint-disable-line prefer-named-capture-group\n // Check ISBN:\n if (field.tag === '020') {\n if (invalidField020(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a');\n const auditedIsbn = ISBN.audit(subfield.value);\n if (!auditedIsbn.validIsbn) {\n return true;\n }\n // Should we refactor code by adding a function that returns legal set of values,\n // and then we compare subfield.value against that list?\n const parsedIsbn = ISBN.parse(subfield.value);\n if (hyphenateISBN) {\n return !(subfield.value === parsedIsbn.isbn10h || subfield.value === parsedIsbn.isbn13h);\n }\n\n return !(subfield.value === parsedIsbn.isbn10 || subfield.value === parsedIsbn.isbn13);\n }\n // Check ISSN:\n if (invalidField022(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n return !validateISSN(subfield.value);\n });\n\n function invalidField020(field) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n\n if (subfieldA === undefined) {\n const subfieldZ = field.subfields.find(sf => sf.code === 'z');\n if (subfieldZ !== undefined) {\n return false;\n }\n return true;\n }\n\n // If value contains space, it's not ok (it's typically something like \"1234567890 (nid.)\")\n if (subfieldA.value.indexOf(' ') > -1) {\n return true;\n }\n return false;\n }\n\n function invalidField022(field) {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL === undefined) {\n const subfieldY = field.subfields.find(sf => sf.code === 'y');\n if (subfieldY) {\n return false;\n }\n\n return true;\n }\n return false;\n }\n }\n\n function validate(record) {\n const fields = getInvalidFields(record);\n\n if (fields.length === 0) {\n return {valid: true};\n }\n\n return fields\n .map(field => {\n if (field.tag === '020') {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (subfieldA) {\n return {name: 'ISBN', value: subfieldA.value};\n }\n\n return {name: 'ISBN', value: undefined};\n }\n\n return {name: 'ISSN', value: getISSN()};\n\n function getISSN() {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL) {\n return subfieldAorL.value;\n }\n\n return undefined;\n }\n })\n .reduce((acc, obj) => {\n const {name, value} = obj;\n const msg = `${name} (${value}) is not valid`;\n\n return {...acc, messages: acc.messages.concat(msg)};\n }, {valid: false, messages: []});\n }\n\n function fix(record) {\n getInvalidFields(record).forEach(field => {\n if (field.tag === '020') {\n const subfield = field.subfields.find(sf => sf.code === 'a');\n if (subfield) {\n // ISBN is valid but is missing hyphens\n const normalizedValue = normalizeIsbnValue(subfield.value);\n if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement\n subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data\n } else if (handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n } else {\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n field.subfields.push({code: 'y', value: trimSpaces(subfield.value)}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n });\n\n function normalizeIsbnValue(value) {\n const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...\n const auditResult = ISBN.audit(trimmedValue);\n if (auditResult.validIsbn) {\n const parsedIsbn = ISBN.parse(trimmedValue);\n if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement\n return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data\n }\n // Just trim\n return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data\n }\n return undefined;\n }\n\n function trimSpaces(value) {\n return value.replace(/\\s/gu, '');\n }\n\n function trimISBN(value) {\n return trimSpaces(value.replace(/\\s\\D+$/gu, '')); // handle \"1234567890 (nid.)\" => \"1234567890\" as well as spaces\n }\n }\n};\n"],"file":"isbn-issn.js"}
|
|
1
|
+
{"version":3,"sources":["../src/isbn-issn.js"],"names":["hyphenateISBN","handleInvalid","validate","fix","description","invalidISBN","isbn","indexOf","auditedIsbn","ISBN","audit","validIsbn","console","info","invalidField020","field","subfields","some","sf","invalidField020a","invalidField020z","subfield","code","value","subfieldRequiresHyphenation","requiresHyphenation","arr","split","parsedIsbn","parse","isbn10h","isbn13h","getInvalidFields","record","fields","filter","tag","fieldRequiresHyphenation","invalidField022","find","subfieldAorL","undefined","subfieldY","length","valid","map","subfieldA","name","getISSN","reduce","acc","obj","msg","messages","concat","forEach","fixField020Subfield","push","removeSubfield","normalizedValue","normalizeIsbnValue","normalizeIsbnValue2","trimmedValue","auditResult","isbn10","isbn13","replace","head"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* MARC record validators used in Melinda\n*\n* Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of marc-record-validators-melinda\n*\n* marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Lesser General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* marc-record-validators-melinda is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport ISBN from 'isbn3';\nimport validateISSN from '@natlibfi/issn-verify';\n\n// handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y\nexport default ({hyphenateISBN = false, handleInvalid = false} = {}) => {\n return {\n validate, fix,\n description: 'Validates ISBN and ISSN values'\n };\n\n function invalidISBN(isbn) {\n // If value contains space, it's not necessarily crap. (It's typically something like \"1234567890 (nid.)\".)\n // Check the first word in string:\n if (isbn.indexOf(' ') > -1) {\n // const arr = isbn.split(' ');\n // console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console\n // return invalidISBN(arr[0]);\n return true;\n }\n\n const auditedIsbn = ISBN.audit(isbn);\n if (!auditedIsbn.validIsbn) {\n console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console\n return true;\n }\n return false;\n }\n\n\n function invalidField020(field) {\n if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {\n return true;\n }\n return false;\n\n function invalidField020a(subfield) {\n if (subfield.code !== 'a') {\n return false;\n }\n if (invalidISBN(subfield.value)) {\n return true;\n }\n return false;\n }\n\n function invalidField020z(subfield) {\n if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {\n return false;\n }\n // We are only interested in $z field if it is valid ISBN that requires hyphenation:\n return subfield.value.indexOf('-') === -1;\n }\n }\n\n function subfieldRequiresHyphenation(subfield) {\n if (subfield.code !== 'a' && subfield.code !== 'z') {\n return false;\n }\n return requiresHyphenation(subfield.value);\n\n function requiresHyphenation(isbn) {\n if (isbn.indexOf(' ') > -1) {\n const arr = isbn.split(' ');\n console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console\n return requiresHyphenation(arr[0]);\n }\n\n if (invalidISBN(isbn)) {\n return false;\n }\n console.info(`sfRH ${isbn}`); // eslint-disable-line no-console\n const parsedIsbn = ISBN.parse(isbn);\n if (hyphenateISBN) {\n return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);\n }\n return false;\n //return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);\n }\n }\n\n function getInvalidFields(record) {\n //return record.get(/^(?:020|022)$/u).filter(field => {\n return record.fields.filter(field => {\n if (!field.subfields) {\n return false;\n }\n // Check ISBN:\n if (field.tag === '020') {\n if (invalidField020(field)) {\n return true;\n }\n return fieldRequiresHyphenation(field);\n }\n\n // Check ISSN:\n if (field.tag === '022') {\n if (invalidField022(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n return !validateISSN(subfield.value);\n }\n return false;\n });\n\n function fieldRequiresHyphenation(field) {\n return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));\n }\n\n function invalidField022(field) {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL === undefined) {\n const subfieldY = field.subfields.find(sf => sf.code === 'y');\n if (subfieldY) {\n return false;\n }\n\n return true;\n }\n return false;\n }\n }\n\n function validate(record) {\n const fields = getInvalidFields(record);\n\n if (fields.length === 0) {\n return {valid: true};\n }\n\n return fields\n .map(field => {\n if (field.tag === '020') {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (subfieldA) {\n return {name: 'ISBN', value: subfieldA.value};\n }\n\n return {name: 'ISBN', value: undefined};\n }\n\n return {name: 'ISSN', value: getISSN()};\n\n function getISSN() {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL) {\n return subfieldAorL.value;\n }\n\n return undefined;\n }\n })\n .reduce((acc, obj) => {\n const {name, value} = obj;\n const msg = `${name} (${value}) is not valid`;\n\n return {...acc, messages: acc.messages.concat(msg)};\n }, {valid: false, messages: []});\n }\n\n\n function fix(record) {\n getInvalidFields(record).forEach(field => {\n if (field.tag === '020') {\n field.subfields.forEach(subfield => fixField020Subfield(field, subfield));\n return;\n }\n // 022 ISSN:\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n // $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)\n field.subfields.push({code: 'y', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n });\n\n /*\n function trimISBN(value) {\n return trimSpaces(value.replace(/\\s$/gu, '')); // handle \"1234567890 (nid.)\" => \"1234567890\" as well as spaces\n }\n */\n\n function fixField020Subfield(field, subfield) {\n console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console\n if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {\n console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console\n // ISBN is valid but is missing hyphens\n const normalizedValue = normalizeIsbnValue(subfield.value);\n if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement\n subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data\n } else if (subfield.code === 'a' && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n // $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)\n field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n return;\n\n function normalizeIsbnValue2(trimmedValue) {\n //const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...\n const auditResult = ISBN.audit(trimmedValue);\n if (auditResult.validIsbn) {\n const parsedIsbn = ISBN.parse(trimmedValue);\n if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement\n return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data\n }\n // Just trim\n return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data\n }\n return undefined;\n }\n\n function normalizeIsbnValue(value) {\n const trimmedValue = value.replace(/^\\s+/gu, '');\n if (trimmedValue.indexOf(' ') === -1) {\n return normalizeIsbnValue2(trimmedValue);\n }\n const [head] = trimmedValue.split(' ');\n // NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?\n return normalizeIsbnValue2(head);\n }\n }\n }\n};\n"],"file":"isbn-issn.js"}
|
package/dist/isbn-issn.spec.js
CHANGED
|
@@ -64,6 +64,14 @@ describe('isbn-issn', () => {
|
|
|
64
64
|
code: 'a',
|
|
65
65
|
value: '90-6831-372-X'
|
|
66
66
|
}]
|
|
67
|
+
}, {
|
|
68
|
+
tag: '020',
|
|
69
|
+
ind1: ' ',
|
|
70
|
+
ind2: ' ',
|
|
71
|
+
subfields: [{
|
|
72
|
+
code: 'z',
|
|
73
|
+
value: '978-600-377-017-1'
|
|
74
|
+
}]
|
|
67
75
|
}, {
|
|
68
76
|
tag: '022',
|
|
69
77
|
ind1: ' ',
|
|
@@ -106,7 +114,7 @@ describe('isbn-issn', () => {
|
|
|
106
114
|
messages: ['ISBN (foo) is not valid', 'ISSN (bar) is not valid']
|
|
107
115
|
});
|
|
108
116
|
});
|
|
109
|
-
it('
|
|
117
|
+
it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {
|
|
110
118
|
const validator = await (0, _isbnIssn.default)();
|
|
111
119
|
const record = new _marcRecord.MarcRecord({
|
|
112
120
|
fields: [{
|
|
@@ -121,8 +129,7 @@ describe('isbn-issn', () => {
|
|
|
121
129
|
});
|
|
122
130
|
const result = await validator.validate(record);
|
|
123
131
|
(0, _chai.expect)(result).to.eql({
|
|
124
|
-
valid:
|
|
125
|
-
messages: ['ISBN (undefined) is not valid']
|
|
132
|
+
valid: true
|
|
126
133
|
});
|
|
127
134
|
});
|
|
128
135
|
it('Finds the invalid 022 field', async () => {
|
|
@@ -252,6 +259,23 @@ describe('isbn-issn', () => {
|
|
|
252
259
|
code: 'a',
|
|
253
260
|
value: 'crappy val'
|
|
254
261
|
}]
|
|
262
|
+
}, {
|
|
263
|
+
tag: '020',
|
|
264
|
+
ind1: ' ',
|
|
265
|
+
ind2: ' ',
|
|
266
|
+
subfields: [{
|
|
267
|
+
code: 'a',
|
|
268
|
+
value: '97895234216609'
|
|
269
|
+
}]
|
|
270
|
+
}, // Just a sanity check due to earlier issues:
|
|
271
|
+
{
|
|
272
|
+
tag: '020',
|
|
273
|
+
ind1: ' ',
|
|
274
|
+
ind2: ' ',
|
|
275
|
+
subfields: [{
|
|
276
|
+
code: 'z',
|
|
277
|
+
value: '97895234216609'
|
|
278
|
+
}]
|
|
255
279
|
}]
|
|
256
280
|
});
|
|
257
281
|
await validator.fix(record);
|
|
@@ -271,6 +295,22 @@ describe('isbn-issn', () => {
|
|
|
271
295
|
code: 'z',
|
|
272
296
|
value: 'crappy val'
|
|
273
297
|
}]
|
|
298
|
+
}, {
|
|
299
|
+
tag: '020',
|
|
300
|
+
ind1: ' ',
|
|
301
|
+
ind2: ' ',
|
|
302
|
+
subfields: [{
|
|
303
|
+
code: 'z',
|
|
304
|
+
value: '97895234216609'
|
|
305
|
+
}]
|
|
306
|
+
}, {
|
|
307
|
+
tag: '020',
|
|
308
|
+
ind1: ' ',
|
|
309
|
+
ind2: ' ',
|
|
310
|
+
subfields: [{
|
|
311
|
+
code: 'z',
|
|
312
|
+
value: '97895234216609'
|
|
313
|
+
}]
|
|
274
314
|
}]);
|
|
275
315
|
});
|
|
276
316
|
it('Moves invalid ISSN to y-subfield', async () => {
|
|
@@ -376,7 +416,13 @@ describe('isbn-issn', () => {
|
|
|
376
416
|
ind2: ' ',
|
|
377
417
|
subfields: [{
|
|
378
418
|
code: 'a',
|
|
379
|
-
value: '
|
|
419
|
+
value: '9786003770171 (nid.)'
|
|
420
|
+
}, {
|
|
421
|
+
code: 'z',
|
|
422
|
+
value: '9786003770171 (nid.)'
|
|
423
|
+
}, {
|
|
424
|
+
code: 'z',
|
|
425
|
+
value: 'foo bar'
|
|
380
426
|
}]
|
|
381
427
|
}]
|
|
382
428
|
});
|
|
@@ -388,10 +434,48 @@ describe('isbn-issn', () => {
|
|
|
388
434
|
subfields: [{
|
|
389
435
|
code: 'a',
|
|
390
436
|
value: '978-600-377-017-1'
|
|
437
|
+
}, {
|
|
438
|
+
code: 'z',
|
|
439
|
+
value: '978-600-377-017-1'
|
|
440
|
+
}, {
|
|
441
|
+
code: 'z',
|
|
442
|
+
value: 'foo bar'
|
|
443
|
+
}]
|
|
444
|
+
}]);
|
|
445
|
+
});
|
|
446
|
+
it('No relevant data', async () => {
|
|
447
|
+
const validator = await (0, _isbnIssn.default)({
|
|
448
|
+
hyphenateISBN: true
|
|
449
|
+
});
|
|
450
|
+
const record = new _marcRecord.MarcRecord({
|
|
451
|
+
fields: [{
|
|
452
|
+
tag: '005',
|
|
453
|
+
value: 'whatever'
|
|
454
|
+
}, {
|
|
455
|
+
tag: '024',
|
|
456
|
+
ind1: ' ',
|
|
457
|
+
ind2: ' ',
|
|
458
|
+
subfields: [{
|
|
459
|
+
code: 'a',
|
|
460
|
+
value: ' 9786003770171'
|
|
461
|
+
}]
|
|
462
|
+
}]
|
|
463
|
+
});
|
|
464
|
+
await validator.fix(record);
|
|
465
|
+
(0, _chai.expect)(record.fields).to.eql([{
|
|
466
|
+
tag: '005',
|
|
467
|
+
value: 'whatever'
|
|
468
|
+
}, {
|
|
469
|
+
tag: '024',
|
|
470
|
+
ind1: ' ',
|
|
471
|
+
ind2: ' ',
|
|
472
|
+
subfields: [{
|
|
473
|
+
code: 'a',
|
|
474
|
+
value: ' 9786003770171'
|
|
391
475
|
}]
|
|
392
476
|
}]);
|
|
393
477
|
});
|
|
394
|
-
it('
|
|
478
|
+
it('Add hyphens to ISBN', async () => {
|
|
395
479
|
const validator = await (0, _isbnIssn.default)({
|
|
396
480
|
hyphenateISBN: true
|
|
397
481
|
});
|
|
@@ -420,6 +504,22 @@ describe('isbn-issn', () => {
|
|
|
420
504
|
code: 'a',
|
|
421
505
|
value: '386006004X (nid.)'
|
|
422
506
|
}]
|
|
507
|
+
}, {
|
|
508
|
+
tag: '020',
|
|
509
|
+
ind1: ' ',
|
|
510
|
+
ind2: ' ',
|
|
511
|
+
subfields: [{
|
|
512
|
+
code: 'z',
|
|
513
|
+
value: '9789916605325'
|
|
514
|
+
}]
|
|
515
|
+
}, {
|
|
516
|
+
tag: '020',
|
|
517
|
+
ind1: ' ',
|
|
518
|
+
ind2: ' ',
|
|
519
|
+
subfields: [{
|
|
520
|
+
code: 'z',
|
|
521
|
+
value: '9789916605325 (sid.)'
|
|
522
|
+
}]
|
|
423
523
|
}]
|
|
424
524
|
});
|
|
425
525
|
await validator.fix(record);
|
|
@@ -447,6 +547,22 @@ describe('isbn-issn', () => {
|
|
|
447
547
|
code: 'a',
|
|
448
548
|
value: '3-86006-004-X'
|
|
449
549
|
}]
|
|
550
|
+
}, {
|
|
551
|
+
tag: '020',
|
|
552
|
+
ind1: ' ',
|
|
553
|
+
ind2: ' ',
|
|
554
|
+
subfields: [{
|
|
555
|
+
code: 'z',
|
|
556
|
+
value: '978-9916-605-32-5'
|
|
557
|
+
}]
|
|
558
|
+
}, {
|
|
559
|
+
tag: '020',
|
|
560
|
+
ind1: ' ',
|
|
561
|
+
ind2: ' ',
|
|
562
|
+
subfields: [{
|
|
563
|
+
code: 'z',
|
|
564
|
+
value: '978-9916-605-32-5'
|
|
565
|
+
}]
|
|
450
566
|
}]);
|
|
451
567
|
});
|
|
452
568
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/isbn-issn.spec.js"],"names":["describe","it","validator","to","be","an","that","has","any","keys","description","a","validate","hyphenateISBN","record","MarcRecord","fields","tag","ind1","ind2","subfields","code","value","result","eql","valid","messages","skip","handleInvalid","fix"],"mappings":"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","sourcesContent":["/**\n *\n * @licstart The following is the entire license notice for the JavaScript code in this file.\n *\n * MARC record validators used in Melinda\n *\n * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n *\n * This file is part of marc-record-validators-melinda\n *\n * marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * marc-record-validators-melinda is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n * @licend The above is the entire license notice\n * for the JavaScript code in this file.\n *\n */\n\n\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from '../src/isbn-issn';\n\ndescribe('isbn-issn', () => {\n it('Creates a validator', async () => {\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\n describe('#validate', () => {\n it('Finds the record valid', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '90-6831-372-X'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '0355-0893'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: true});\n });\n\n it('Finds the record invalid', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the invalid 020 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'q', value: 'nidottu'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISBN (undefined) is not valid']\n });\n });\n\n it('Finds the invalid 022 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'z', value: '0000-0000'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISSN (undefined) is not valid']\n });\n });\n\n it('Finds the record invalid (Spaces in ISBN)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1 (nid.)'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN ( 9789519155470) is not valid',\n 'ISBN (978-600-377-017-1 (nid.)) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (ISSN in \\'l\\'-subfield)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'l', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (valid ISBN without hyphens)', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '386006004X'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: false, messages: [\n 'ISBN (9789519155470) is not valid',\n 'ISBN (386006004X) is not valid'\n ]});\n });\n\n it.skip('Finds the record invalid (Missing ISBN)');\n it.skip('Finds the record invalid (Missing ISSN)');\n });\n\n describe('#fix', () => {\n it('Moves invalid ISBN to z-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'crappy val'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]}\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield (Origin l-subfield)', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'l', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Trims spaces from value (No hyphenate)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9786003770171 (nid.)'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]}\n ]);\n });\n\n it('Trims spaces and hyphenates value', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-600-377-017-1'}]\n }\n ]);\n });\n\n it('Adds hyphens to ISBN', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '9789916605325'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '917153086X'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '386006004X (nid.)'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]}\n ]);\n });\n });\n});\n"],"file":"isbn-issn.spec.js"}
|
|
1
|
+
{"version":3,"sources":["../src/isbn-issn.spec.js"],"names":["describe","it","validator","to","be","an","that","has","any","keys","description","a","validate","hyphenateISBN","record","MarcRecord","fields","tag","ind1","ind2","subfields","code","value","result","eql","valid","messages","skip","handleInvalid","fix"],"mappings":"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","sourcesContent":["/**\n *\n * @licstart The following is the entire license notice for the JavaScript code in this file.\n *\n * MARC record validators used in Melinda\n *\n * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n *\n * This file is part of marc-record-validators-melinda\n *\n * marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * marc-record-validators-melinda is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n * @licend The above is the entire license notice\n * for the JavaScript code in this file.\n *\n */\n\n\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from '../src/isbn-issn';\n\ndescribe('isbn-issn', () => {\n it('Creates a validator', async () => {\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\n describe('#validate', () => {\n it('Finds the record valid', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '90-6831-372-X'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-600-377-017-1'}]},\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '0355-0893'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: true});\n });\n\n it('Finds the record invalid', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'q', value: 'nidottu'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: true\n });\n });\n\n it('Finds the invalid 022 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'z', value: '0000-0000'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISSN (undefined) is not valid']\n });\n });\n\n it('Finds the record invalid (Spaces in ISBN)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1 (nid.)'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN ( 9789519155470) is not valid',\n 'ISBN (978-600-377-017-1 (nid.)) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (ISSN in \\'l\\'-subfield)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'l', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (valid ISBN without hyphens)', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '386006004X'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: false, messages: [\n 'ISBN (9789519155470) is not valid',\n 'ISBN (386006004X) is not valid'\n ]});\n });\n\n it.skip('Finds the record invalid (Missing ISBN)');\n it.skip('Finds the record invalid (Missing ISSN)');\n });\n\n describe('#fix', () => {\n it('Moves invalid ISBN to z-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'crappy val'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '97895234216609'}]},\n // Just a sanity check due to earlier issues:\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield (Origin l-subfield)', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'l', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Trims spaces from value (No hyphenate)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9786003770171 (nid.)'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]}\n ]);\n });\n\n it('Trims spaces and hyphenates value', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [\n {code: 'a', value: '9786003770171 (nid.)'},\n {code: 'z', value: '9786003770171 (nid.)'},\n {code: 'z', value: 'foo bar'}\n ]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [\n {code: 'a', value: '978-600-377-017-1'},\n {code: 'z', value: '978-600-377-017-1'},\n {code: 'z', value: 'foo bar'}\n ]\n }\n ]);\n });\n\n it('No relevant data', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '005',\n value: 'whatever'\n },\n {\n tag: '024',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '005', value: 'whatever'},\n {tag: '024', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]}\n ]);\n });\n\n it('Add hyphens to ISBN', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '9789916605325'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '917153086X'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '386006004X (nid.)'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'z', value: '9789916605325'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '9789916605325 (sid.)'}]}\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]}\n ]);\n });\n });\n});\n"],"file":"isbn-issn.spec.js"}
|
package/package.json
CHANGED
package/src/isbn-issn.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* MARC record validators used in Melinda
|
|
6
6
|
*
|
|
7
|
-
* Copyright (c) 2014-
|
|
7
|
+
* Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)
|
|
8
8
|
*
|
|
9
9
|
* This file is part of marc-record-validators-melinda
|
|
10
10
|
*
|
|
@@ -29,60 +29,112 @@
|
|
|
29
29
|
import ISBN from 'isbn3';
|
|
30
30
|
import validateISSN from '@natlibfi/issn-verify';
|
|
31
31
|
|
|
32
|
+
// handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y
|
|
32
33
|
export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
|
|
33
34
|
return {
|
|
34
35
|
validate, fix,
|
|
35
36
|
description: 'Validates ISBN and ISSN values'
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
function invalidISBN(isbn) {
|
|
40
|
+
// If value contains space, it's not necessarily crap. (It's typically something like "1234567890 (nid.)".)
|
|
41
|
+
// Check the first word in string:
|
|
42
|
+
if (isbn.indexOf(' ') > -1) {
|
|
43
|
+
// const arr = isbn.split(' ');
|
|
44
|
+
// console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
|
|
45
|
+
// return invalidISBN(arr[0]);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const parsedIsbn = ISBN.parse(subfield.value);
|
|
54
|
-
if (hyphenateISBN) {
|
|
55
|
-
return !(subfield.value === parsedIsbn.isbn10h || subfield.value === parsedIsbn.isbn13h);
|
|
56
|
-
}
|
|
49
|
+
const auditedIsbn = ISBN.audit(isbn);
|
|
50
|
+
if (!auditedIsbn.validIsbn) {
|
|
51
|
+
console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
|
|
58
|
+
function invalidField020(field) {
|
|
59
|
+
if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
|
|
64
|
+
function invalidField020a(subfield) {
|
|
65
|
+
if (subfield.code !== 'a') {
|
|
66
|
+
return false;
|
|
59
67
|
}
|
|
60
|
-
|
|
61
|
-
if (invalidField022(field)) {
|
|
68
|
+
if (invalidISBN(subfield.value)) {
|
|
62
69
|
return true;
|
|
63
70
|
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
function invalidField020z(subfield) {
|
|
75
|
+
if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
// We are only interested in $z field if it is valid ISBN that requires hyphenation:
|
|
79
|
+
return subfield.value.indexOf('-') === -1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
66
82
|
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
function subfieldRequiresHyphenation(subfield) {
|
|
84
|
+
if (subfield.code !== 'a' && subfield.code !== 'z') {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return requiresHyphenation(subfield.value);
|
|
69
88
|
|
|
70
|
-
function
|
|
71
|
-
|
|
89
|
+
function requiresHyphenation(isbn) {
|
|
90
|
+
if (isbn.indexOf(' ') > -1) {
|
|
91
|
+
const arr = isbn.split(' ');
|
|
92
|
+
console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
|
|
93
|
+
return requiresHyphenation(arr[0]);
|
|
94
|
+
}
|
|
72
95
|
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
if (invalidISBN(isbn)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
console.info(`sfRH ${isbn}`); // eslint-disable-line no-console
|
|
100
|
+
const parsedIsbn = ISBN.parse(isbn);
|
|
101
|
+
if (hyphenateISBN) {
|
|
102
|
+
return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
//return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getInvalidFields(record) {
|
|
110
|
+
//return record.get(/^(?:020|022)$/u).filter(field => {
|
|
111
|
+
return record.fields.filter(field => {
|
|
112
|
+
if (!field.subfields) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
// Check ISBN:
|
|
116
|
+
if (field.tag === '020') {
|
|
117
|
+
if (invalidField020(field)) {
|
|
118
|
+
return true;
|
|
77
119
|
}
|
|
78
|
-
return
|
|
120
|
+
return fieldRequiresHyphenation(field);
|
|
79
121
|
}
|
|
80
122
|
|
|
81
|
-
//
|
|
82
|
-
if (
|
|
83
|
-
|
|
123
|
+
// Check ISSN:
|
|
124
|
+
if (field.tag === '022') {
|
|
125
|
+
if (invalidField022(field)) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
|
|
130
|
+
|
|
131
|
+
return !validateISSN(subfield.value);
|
|
84
132
|
}
|
|
85
133
|
return false;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
function fieldRequiresHyphenation(field) {
|
|
137
|
+
return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));
|
|
86
138
|
}
|
|
87
139
|
|
|
88
140
|
function invalidField022(field) {
|
|
@@ -138,49 +190,67 @@ export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
|
|
|
138
190
|
}, {valid: false, messages: []});
|
|
139
191
|
}
|
|
140
192
|
|
|
193
|
+
|
|
141
194
|
function fix(record) {
|
|
142
195
|
getInvalidFields(record).forEach(field => {
|
|
143
196
|
if (field.tag === '020') {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
|
|
157
|
-
if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
|
|
158
|
-
field.subfields.push({code: 'y', value: trimSpaces(subfield.value)}); // eslint-disable-line functional/immutable-data
|
|
159
|
-
record.removeSubfield(subfield, field);
|
|
160
|
-
}
|
|
197
|
+
field.subfields.forEach(subfield => fixField020Subfield(field, subfield));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// 022 ISSN:
|
|
201
|
+
const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
|
|
202
|
+
if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
|
|
203
|
+
// $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)
|
|
204
|
+
field.subfields.push({code: 'y', value: subfield.value}); // eslint-disable-line functional/immutable-data
|
|
205
|
+
record.removeSubfield(subfield, field);
|
|
161
206
|
}
|
|
162
207
|
});
|
|
163
208
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
209
|
+
/*
|
|
210
|
+
function trimISBN(value) {
|
|
211
|
+
return trimSpaces(value.replace(/\s$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
|
|
212
|
+
}
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
function fixField020Subfield(field, subfield) {
|
|
216
|
+
console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
|
|
217
|
+
if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {
|
|
218
|
+
console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
|
|
219
|
+
// ISBN is valid but is missing hyphens
|
|
220
|
+
const normalizedValue = normalizeIsbnValue(subfield.value);
|
|
221
|
+
if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement
|
|
222
|
+
subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
|
|
223
|
+
} else if (subfield.code === 'a' && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
|
|
224
|
+
// $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)
|
|
225
|
+
field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data
|
|
226
|
+
record.removeSubfield(subfield, field);
|
|
171
227
|
}
|
|
172
|
-
// Just trim
|
|
173
|
-
return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
|
|
174
228
|
}
|
|
175
|
-
return
|
|
176
|
-
}
|
|
229
|
+
return;
|
|
177
230
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
231
|
+
function normalizeIsbnValue2(trimmedValue) {
|
|
232
|
+
//const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
|
|
233
|
+
const auditResult = ISBN.audit(trimmedValue);
|
|
234
|
+
if (auditResult.validIsbn) {
|
|
235
|
+
const parsedIsbn = ISBN.parse(trimmedValue);
|
|
236
|
+
if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement
|
|
237
|
+
return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
|
|
238
|
+
}
|
|
239
|
+
// Just trim
|
|
240
|
+
return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
|
|
241
|
+
}
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
181
244
|
|
|
182
|
-
|
|
183
|
-
|
|
245
|
+
function normalizeIsbnValue(value) {
|
|
246
|
+
const trimmedValue = value.replace(/^\s+/gu, '');
|
|
247
|
+
if (trimmedValue.indexOf(' ') === -1) {
|
|
248
|
+
return normalizeIsbnValue2(trimmedValue);
|
|
249
|
+
}
|
|
250
|
+
const [head] = trimmedValue.split(' ');
|
|
251
|
+
// NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?
|
|
252
|
+
return normalizeIsbnValue2(head);
|
|
253
|
+
}
|
|
184
254
|
}
|
|
185
255
|
}
|
|
186
256
|
};
|
package/src/isbn-issn.spec.js
CHANGED
|
@@ -60,6 +60,7 @@ describe('isbn-issn', () => {
|
|
|
60
60
|
ind2: ' ',
|
|
61
61
|
subfields: [{code: 'a', value: '90-6831-372-X'}]
|
|
62
62
|
},
|
|
63
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-600-377-017-1'}]},
|
|
63
64
|
{
|
|
64
65
|
tag: '022',
|
|
65
66
|
ind1: ' ',
|
|
@@ -101,7 +102,7 @@ describe('isbn-issn', () => {
|
|
|
101
102
|
});
|
|
102
103
|
});
|
|
103
104
|
|
|
104
|
-
it('
|
|
105
|
+
it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {
|
|
105
106
|
const validator = await validatorFactory();
|
|
106
107
|
const record = new MarcRecord({
|
|
107
108
|
fields: [
|
|
@@ -116,7 +117,7 @@ describe('isbn-issn', () => {
|
|
|
116
117
|
const result = await validator.validate(record);
|
|
117
118
|
|
|
118
119
|
expect(result).to.eql({
|
|
119
|
-
valid:
|
|
120
|
+
valid: true
|
|
120
121
|
});
|
|
121
122
|
});
|
|
122
123
|
|
|
@@ -237,7 +238,10 @@ describe('isbn-issn', () => {
|
|
|
237
238
|
{
|
|
238
239
|
tag: '020', ind1: ' ', ind2: ' ',
|
|
239
240
|
subfields: [{code: 'a', value: 'crappy val'}]
|
|
240
|
-
}
|
|
241
|
+
},
|
|
242
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '97895234216609'}]},
|
|
243
|
+
// Just a sanity check due to earlier issues:
|
|
244
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}
|
|
241
245
|
]
|
|
242
246
|
});
|
|
243
247
|
|
|
@@ -245,7 +249,9 @@ describe('isbn-issn', () => {
|
|
|
245
249
|
|
|
246
250
|
expect(record.fields).to.eql([
|
|
247
251
|
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},
|
|
248
|
-
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]}
|
|
252
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]},
|
|
253
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]},
|
|
254
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}
|
|
249
255
|
]);
|
|
250
256
|
});
|
|
251
257
|
|
|
@@ -323,7 +329,11 @@ describe('isbn-issn', () => {
|
|
|
323
329
|
tag: '020',
|
|
324
330
|
ind1: ' ',
|
|
325
331
|
ind2: ' ',
|
|
326
|
-
subfields: [
|
|
332
|
+
subfields: [
|
|
333
|
+
{code: 'a', value: '9786003770171 (nid.)'},
|
|
334
|
+
{code: 'z', value: '9786003770171 (nid.)'},
|
|
335
|
+
{code: 'z', value: 'foo bar'}
|
|
336
|
+
]
|
|
327
337
|
}
|
|
328
338
|
]
|
|
329
339
|
});
|
|
@@ -331,12 +341,43 @@ describe('isbn-issn', () => {
|
|
|
331
341
|
|
|
332
342
|
expect(record.fields).to.eql([
|
|
333
343
|
{
|
|
334
|
-
tag: '020',
|
|
344
|
+
tag: '020',
|
|
345
|
+
ind1: ' ',
|
|
346
|
+
ind2: ' ',
|
|
347
|
+
subfields: [
|
|
348
|
+
{code: 'a', value: '978-600-377-017-1'},
|
|
349
|
+
{code: 'z', value: '978-600-377-017-1'},
|
|
350
|
+
{code: 'z', value: 'foo bar'}
|
|
351
|
+
]
|
|
335
352
|
}
|
|
336
353
|
]);
|
|
337
354
|
});
|
|
338
355
|
|
|
339
|
-
it('
|
|
356
|
+
it('No relevant data', async () => {
|
|
357
|
+
const validator = await validatorFactory({hyphenateISBN: true});
|
|
358
|
+
const record = new MarcRecord({
|
|
359
|
+
fields: [
|
|
360
|
+
{
|
|
361
|
+
tag: '005',
|
|
362
|
+
value: 'whatever'
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
tag: '024',
|
|
366
|
+
ind1: ' ',
|
|
367
|
+
ind2: ' ',
|
|
368
|
+
subfields: [{code: 'a', value: ' 9786003770171'}]
|
|
369
|
+
}
|
|
370
|
+
]
|
|
371
|
+
});
|
|
372
|
+
await validator.fix(record);
|
|
373
|
+
|
|
374
|
+
expect(record.fields).to.eql([
|
|
375
|
+
{tag: '005', value: 'whatever'},
|
|
376
|
+
{tag: '024', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]}
|
|
377
|
+
]);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('Add hyphens to ISBN', async () => {
|
|
340
381
|
const validator = await validatorFactory({hyphenateISBN: true});
|
|
341
382
|
const record = new MarcRecord({
|
|
342
383
|
fields: [
|
|
@@ -351,7 +392,12 @@ describe('isbn-issn', () => {
|
|
|
351
392
|
{
|
|
352
393
|
tag: '020', ind1: ' ', ind2: ' ',
|
|
353
394
|
subfields: [{code: 'a', value: '386006004X (nid.)'}]
|
|
354
|
-
}
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
tag: '020', ind1: ' ', ind2: ' ',
|
|
398
|
+
subfields: [{code: 'z', value: '9789916605325'}]
|
|
399
|
+
},
|
|
400
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '9789916605325 (sid.)'}]}
|
|
355
401
|
]
|
|
356
402
|
});
|
|
357
403
|
|
|
@@ -360,7 +406,9 @@ describe('isbn-issn', () => {
|
|
|
360
406
|
expect(record.fields).to.eql([
|
|
361
407
|
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},
|
|
362
408
|
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},
|
|
363
|
-
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]}
|
|
409
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]},
|
|
410
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]},
|
|
411
|
+
{tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]}
|
|
364
412
|
]);
|
|
365
413
|
});
|
|
366
414
|
});
|