@natlibfi/melinda-rest-api-commons 2.3.2-alpha.3 → 2.3.2-alpha.5

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.
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.REPLACE_PREFIXES = exports.BIB_PREVALIDATION_FIX_SETTINGS = exports.BIB_PREIMPORT_FIX_SETTINGS = exports.BIB_POSTMERGE_FIX_SETTINGS = exports.BIB_HANDLE_TEMP_URNS_SETTINGS = exports.BIB_FORMAT_SETTINGS = exports.BIB_F035_TO_SID = exports.AUTNAME_PREIMPORT_FIX_SETTINGS = void 0;
6
+ var _exportNames = {
7
+ fixRecord: true
8
+ };
7
9
  exports.fixRecord = fixRecord;
8
10
 
9
11
  var _marcRecord = require("@natlibfi/marc-record");
@@ -12,6 +14,24 @@ var _melindaBackendCommons = require("@natlibfi/melinda-backend-commons");
12
14
 
13
15
  var _debug = _interopRequireDefault(require("debug"));
14
16
 
17
+ var _fixHandleTempurns = require("./fix-handle-tempurns");
18
+
19
+ var _fixStripF884s = require("./fix-strip-f884s");
20
+
21
+ var _fixConstants = require("./fix-constants");
22
+
23
+ Object.keys(_fixConstants).forEach(function (key) {
24
+ if (key === "default" || key === "__esModule") return;
25
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
26
+ if (key in exports && exports[key] === _fixConstants[key]) return;
27
+ Object.defineProperty(exports, key, {
28
+ enumerable: true,
29
+ get: function () {
30
+ return _fixConstants[key];
31
+ }
32
+ });
33
+ });
34
+
15
35
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
36
 
17
37
  /**
@@ -20,7 +40,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
20
40
  *
21
41
  * Shared modules for microservices of Melinda rest api batch import system
22
42
  *
23
- * Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)
43
+ * Copyright (C) 2020-2022 University Of Helsinki (The National Library Of Finland)
24
44
  *
25
45
  * This file is part of melinda-rest-api-commons
26
46
  *
@@ -41,281 +61,133 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
41
61
  * for the JavaScript code in this file.
42
62
  *
43
63
  */
64
+ const logger = (0, _melindaBackendCommons.createLogger)();
65
+ const debug = (0, _debug.default)('@natlibfi/melinda-rest-api-commons:fixRecord');
66
+ const debugData = debug.extend('data');
67
+
44
68
  function fixRecord(record, settings = {}) {
45
- const logger = (0, _melindaBackendCommons.createLogger)();
46
- const debug = (0, _debug.default)('@natlibfi/melinda-rest-api-commons:fixRecord');
47
- const debugData = debug.extend('data');
48
69
  logger.verbose(`We will apply formatting to the record according to settings: ${JSON.stringify(settings)}`);
49
70
 
50
71
  const newRecord = _marcRecord.MarcRecord.clone(record, {
51
72
  subfieldValues: false
52
73
  });
53
74
 
54
- debugData(`settings: ${JSON.stringify(settings)}`);
55
- const generateMissingSIDsOptions = settings.generateMissingSIDs || undefined;
56
- generateMissingSIDs(generateMissingSIDsOptions);
57
- const replacePrefixesOptions = settings.replacePrefixes || [];
58
- debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);
59
- replacePrefixesOptions.forEach(options => {
60
- replacePrefixes(options);
61
- });
62
- handleTempUrns(settings.handleTempUrns);
63
- return newRecord.toObject(); // Replace prefix in all specified subfields
64
-
65
- function replacePrefixes(options) {
66
- const {
67
- oldPrefix,
68
- newPrefix,
69
- prefixReplaceCodes
70
- } = options;
71
- debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);
72
- const pattern = `(${oldPrefix})`;
73
- const replacement = `(${newPrefix})`;
74
- newRecord.getDatafields().forEach(field => {
75
- field.subfields.filter(({
76
- code
77
- }) => prefixReplaceCodes.includes(code)).forEach(subfield => {
78
- subfield.value = subfield.value.replace(pattern, replacement); // eslint-disable-line functional/immutable-data
79
- });
80
- });
81
- }
82
-
83
- function generateMissingSIDs(options) {
84
- debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);
85
- const f035Filters = options && options.f035Filters ? options.f035Filters : [];
86
- const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];
87
-
88
- if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {
89
- debug(`No sane options for generating missing SIDs`);
90
- return;
91
- }
92
-
93
- const f035s = f035ToSidInfo(newRecord.get(/^035$/u));
94
- const fSIDs = sidsToSidInfo(newRecord.get(/^SID$/u));
95
- const sidsToBeAdded = genNewSids(fSIDs.length === 0 ? f035s // test that SIDs are not there yet
96
- : f035s.filter(f035SidInfo => fSIDs.some(fSIDInfo => f035SidInfo.SID !== fSIDInfo.SID && f035SidInfo.value !== fSIDInfo.value))); // Add new SIDs
97
-
98
- return sidsToBeAdded.forEach(sidField => newRecord.insertField(sidField));
99
-
100
- function genNewSids(sidsToBeAdded) {
101
- return sidsToBeAdded.map(sidInfo => ({
102
- tag: 'SID',
103
- ind1: ' ',
104
- ind2: ' ',
105
- subfields: [{
106
- code: 'c',
107
- value: sidInfo.value
108
- }, {
109
- code: 'b',
110
- value: sidInfo.SID
111
- }]
112
- }));
113
- }
114
-
115
- function sidsToSidInfo(SIDs) {
116
- return SIDs.flatMap(({
117
- subfields
118
- }) => {
119
- const [SID] = subfields.filter(sub => sub.code === 'b' && fSIDFilters.includes(sub.value)).map(sub => sub.value);
120
- const [value] = subfields.filter(sub => sub.code === 'c' && sub.value !== undefined).map(sub => sub.value);
121
-
122
- if (SID && value) {
123
- return {
124
- SID,
125
- value
126
- };
127
- }
128
-
129
- return undefined;
130
- }).filter(value => value !== undefined);
131
- }
132
-
133
- function f035ToSidInfo(f035s) {
134
- return f035s.flatMap(({
135
- subfields
136
- }) => {
137
- const [wantedSub] = subfields.filter(sub => sub.code === 'a' && f035Filters.some(regexp => regexp.test(sub.value)));
138
-
139
- if (wantedSub) {
140
- return {
141
- SID: fSIDFilters[f035Filters.findIndex(regexp => regexp.test(wantedSub.value))],
142
- value: wantedSub.value.slice(wantedSub.value.indexOf(')') + 1)
143
- };
144
- }
145
-
146
- return undefined;
147
- }).filter(value => value !== undefined);
148
- }
149
- } // eslint-disable-next-line max-statements
150
-
151
-
152
- function handleTempUrns(options) {
153
- debugData(`Options for handleTempUrns: ${JSON.stringify(options)}`);
154
-
155
- if (options !== true) {
156
- return;
157
- } // If we have an non-temp URN, we can delete tempURNs, otherwise we should delete the temp subfield from URN
158
-
159
-
160
- const hasURN = f => f.tag === '856' && f.subfields.some(({
161
- code,
162
- value
163
- }) => code === 'u' && /urn.fi/u.test(value));
164
-
165
- const hasTempSubfield = f => f.subfields.some(({
166
- code,
167
- value
168
- }) => code === '9' && /^MELINDA<TEMP>$/u.test(value));
169
-
170
- const hasNoTempSubfield = f => !f.subfields.some(({
171
- code,
172
- value
173
- }) => code === '9' && /^MELINDA<TEMP>$/u.test(value));
174
-
175
- const f856sUrn = newRecord.fields.filter(hasURN);
176
- const f856sUrnsWithTempSubfields = f856sUrn.filter(hasTempSubfield);
177
- const f856sUrnsWithNoTempSubfields = f856sUrn.filter(hasNoTempSubfield);
178
- debugData(`URN f856s: ${JSON.stringify(f856sUrn)}`);
179
- debugData(`URN f856s with temp subfield: ${JSON.stringify(f856sUrnsWithTempSubfields)}`); // None of the URNs has temp subfields, we don't need to do anything
180
-
181
- if (f856sUrnsWithTempSubfields.length < 1) {
182
- debug(`No Urns with temp subfield`);
183
- return;
184
- } // Do we have an existing URN with legal deposit subfields, if we have, we can remove the temp URN field(s)
185
-
186
-
187
- const existingLegalDepositURN = validateLD(f856sUrnsWithNoTempSubfields);
188
- debug(`existingLegalDepositURN: ${existingLegalDepositURN}`);
189
-
190
- if (existingLegalDepositURN) {
191
- debug(`We have an existing LD URN, we can delete temp fields (${f856sUrnsWithTempSubfields.length})`);
192
- newRecord.removeFields(f856sUrnsWithTempSubfields);
193
- return;
194
- } // We do not have an existing legalDepositURN, we should use the tempURN and remove the temp subfields from it
75
+ debugData(`settings: ${JSON.stringify(settings)}`); // We should handle these in some prettier way ...
76
+ // Fix 1, generate SIDs
195
77
 
78
+ const generateMissingSIDsOptions = settings.generateMissingSIDs || undefined;
79
+ const newRecord1 = generateMissingSIDs(newRecord, generateMissingSIDsOptions); // Fix 2, replace identifier prefixes
196
80
 
197
- if (!existingLegalDepositURN && f856sUrnsWithTempSubfields.length > 0) {
198
- //debug(`All Urns (${f856sUrn.length}) have a temp subfield`);
199
- debugData(`Original temp URNs: (${JSON.stringify(f856sUrnsWithTempSubfields)})`);
200
- const fixedFields = f856sUrnsWithTempSubfields.map(removeTempSubfield).filter(field => field);
201
- debug(`We removed temp subfields: (${JSON.stringify(fixedFields)})`);
202
- newRecord.removeFields(f856sUrnsWithTempSubfields);
203
- newRecord.insertFields(fixedFields);
204
- return;
205
- } // Should we check that the non-temp URN has 2nd ind '0' - meaning that the URN handles the actual resource itself?
81
+ const replacePrefixesOptions = settings.replacePrefixes || [];
82
+ const newRecord2 = replaceAllPrefixes(newRecord1, replacePrefixesOptions); // Fix 3, handle temporary URNs from legal deposit record import
206
83
 
207
- } // ---- LD-functions below are same as in https://github.com/NatLibFi/marc-record-validators-melinda/blob/feature-updates-to-urn/src/urn.js
208
- // we propably should develop the urn/legaldeposit -validator to use also here
84
+ const newRecord3 = (0, _fixHandleTempurns.handleTempUrns)(newRecord2, settings.handleTempUrns); // Fix 4, strip extra field 884s
209
85
 
86
+ const newRecord4 = (0, _fixStripF884s.stripF884s)(newRecord3, settings.stripF884s);
87
+ return newRecord4.toObject();
88
+ }
210
89
 
211
- function createLDSubfields() {
212
- return [{
213
- code: 'z',
214
- value: 'Käytettävissä vapaakappalekirjastoissa'
215
- }, {
216
- code: '5',
217
- value: 'FI-Vapaa'
218
- }];
90
+ function replaceAllPrefixes(record, replacePrefixesOptions) {
91
+ if (replacePrefixesOptions.length < 1) {
92
+ debug(`NOT running replacePrefixes, no options`);
93
+ return record;
219
94
  }
220
95
 
221
- function validateLD(f856sUrn) {
222
- debug(`Validating the existence of legal deposit subfields`);
223
- const ldSubfields = createLDSubfields();
224
- const f856sUrnWithLdSubfields = f856sUrn.filter(field => fieldHasLDSubfields(field, ldSubfields));
96
+ debug(`Running replacePrefixes fixer`);
97
+ debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);
98
+ replacePrefixesOptions.forEach(options => {
99
+ replacePrefix(record, options);
100
+ });
101
+ return record;
102
+ } // Replace prefix in all specified subfields
103
+
104
+
105
+ function replacePrefix(record, options) {
106
+ const {
107
+ oldPrefix,
108
+ newPrefix,
109
+ prefixReplaceCodes
110
+ } = options;
111
+ debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);
112
+ const pattern = `(${oldPrefix})`;
113
+ const replacement = `(${newPrefix})`;
114
+ record.getDatafields().forEach(field => {
115
+ field.subfields.filter(({
116
+ code
117
+ }) => prefixReplaceCodes.includes(code)).forEach(subfield => {
118
+ subfield.value = subfield.value.replace(pattern, replacement); // eslint-disable-line functional/immutable-data
119
+ });
120
+ });
121
+ return record;
122
+ }
225
123
 
226
- if (f856sUrnWithLdSubfields.length > 0) {
227
- debug(`Record has ${f856sUrnWithLdSubfields.length} URN fields with all necessary legal deposit subfields`);
228
- debugData(`f856sUrnWithLdSubfields: ${JSON.stringify(f856sUrnWithLdSubfields)}`);
229
- return true;
230
- }
124
+ function generateMissingSIDs(record, options) {
125
+ const f035Filters = options && options.f035Filters ? options.f035Filters : [];
126
+ const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];
231
127
 
232
- return false;
128
+ if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {
129
+ debug(`NOT running generateMissingsSIDs, no options`);
130
+ return record;
233
131
  }
234
132
 
235
- function fieldHasLDSubfields(field, ldSubfields) {
236
- if (ldSubfields.every(ldsf => field.subfields.some(sf => sf.code === ldsf.code && sf.value === ldsf.value))) {
237
- return true;
238
- }
239
- } // ---
240
-
241
-
242
- function removeTempSubfield(field) {
243
- // Handle non-numeric fields, and fields with a numeric tag of 010 and greater
244
- // Aleph's FMT as a controlfield might be a problem
245
- if (!isNaN(field.tag) && parseInt(field.tag, 10) >= 10) {
246
- const filteredSubfields = field.subfields.filter(sf => sf.code !== '9' && !/^MELINDA<TEMP>$/u.test(sf.value)); // Remove whole field if there are no subfields left
133
+ debug(`Running generateMissingSIDs fixer`);
134
+ debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);
135
+ const f035s = f035ToSidInfo(record.get(/^035$/u));
136
+ const fSIDs = sidsToSidInfo(record.get(/^SID$/u));
137
+ const sidsToBeAdded = genNewSids(fSIDs.length === 0 ? f035s // test that SIDs are not there yet
138
+ : f035s.filter(f035SidInfo => fSIDs.some(fSIDInfo => f035SidInfo.SID !== fSIDInfo.SID && f035SidInfo.value !== fSIDInfo.value))); // Add new SIDs
139
+
140
+ sidsToBeAdded.forEach(sidField => record.insertField(sidField));
141
+ return record;
142
+
143
+ function genNewSids(sidsToBeAdded) {
144
+ return sidsToBeAdded.map(sidInfo => ({
145
+ tag: 'SID',
146
+ ind1: ' ',
147
+ ind2: ' ',
148
+ subfields: [{
149
+ code: 'c',
150
+ value: sidInfo.value
151
+ }, {
152
+ code: 'b',
153
+ value: sidInfo.SID
154
+ }]
155
+ }));
156
+ }
247
157
 
248
- if (filteredSubfields.length < 1) {
249
- return false;
158
+ function sidsToSidInfo(SIDs) {
159
+ return SIDs.flatMap(({
160
+ subfields
161
+ }) => {
162
+ const [SID] = subfields.filter(sub => sub.code === 'b' && fSIDFilters.includes(sub.value)).map(sub => sub.value);
163
+ const [value] = subfields.filter(sub => sub.code === 'c' && sub.value !== undefined).map(sub => sub.value);
164
+
165
+ if (SID && value) {
166
+ return {
167
+ SID,
168
+ value
169
+ };
250
170
  }
251
171
 
252
- return {
253
- tag: field.tag,
254
- ind1: field.ind1,
255
- ind2: field.ind2,
256
- subfields: filteredSubfields
257
- };
258
- } // return controlFields as is
172
+ return undefined;
173
+ }).filter(value => value !== undefined);
174
+ }
259
175
 
176
+ function f035ToSidInfo(f035s) {
177
+ return f035s.flatMap(({
178
+ subfields
179
+ }) => {
180
+ const [wantedSub] = subfields.filter(sub => sub.code === 'a' && f035Filters.some(regexp => regexp.test(sub.value)));
181
+
182
+ if (wantedSub) {
183
+ return {
184
+ SID: fSIDFilters[f035Filters.findIndex(regexp => regexp.test(wantedSub.value))],
185
+ value: wantedSub.value.slice(wantedSub.value.indexOf(')') + 1)
186
+ };
187
+ }
260
188
 
261
- return field;
189
+ return undefined;
190
+ }).filter(value => value !== undefined);
262
191
  }
263
- } // This could be formatted so that 035-prefix and SID contents would be better connected than by just an array index
264
-
265
-
266
- const BIB_F035_TO_SID = {
267
- f035Filters: [/^\(FI-BTJ\)/u, /^\(FI-TATI\)/u],
268
- fSIDFilters: ['FI-BTJ', 'tati']
269
- }; // There is somewhere other implementations of this same standardPrefixes to alephInternalPrefixes normalization
270
-
271
- exports.BIB_F035_TO_SID = BIB_F035_TO_SID;
272
- const REPLACE_PREFIXES = [{
273
- oldPrefix: 'FI-MELINDA',
274
- newPrefix: 'FIN01',
275
- prefixReplaceCodes: ['w']
276
- }, {
277
- oldPrefix: 'FI-ASTERI-S',
278
- newPrefix: 'FIN10',
279
- prefixReplaceCodes: ['0']
280
- }, {
281
- oldPrefix: 'FI-ASTERI-N',
282
- newPrefix: 'FIN11',
283
- prefixReplaceCodes: ['0']
284
- }, {
285
- oldPrefix: 'FI-ASTERI-A',
286
- newPrefix: 'FIN12',
287
- prefixReplaceCodes: ['0']
288
- }, {
289
- oldPrefix: 'FI-ASTERI-W',
290
- newPrefix: 'FIN13',
291
- prefixReplaceCodes: ['0']
292
- }]; // If placed in config.js testing needs envs
293
- // BIB_FORMAT_SETTINGS is outdated, use other settings instead
294
-
295
- exports.REPLACE_PREFIXES = REPLACE_PREFIXES;
296
- const BIB_FORMAT_SETTINGS = {
297
- replacePrefixes: REPLACE_PREFIXES,
298
- generateMissingSIDs: BIB_F035_TO_SID
299
- };
300
- exports.BIB_FORMAT_SETTINGS = BIB_FORMAT_SETTINGS;
301
- const BIB_PREVALIDATION_FIX_SETTINGS = {
302
- generateMissingSIDs: BIB_F035_TO_SID
303
- };
304
- exports.BIB_PREVALIDATION_FIX_SETTINGS = BIB_PREVALIDATION_FIX_SETTINGS;
305
- const BIB_POSTMERGE_FIX_SETTINGS = {
306
- handleTempUrns: true
307
- };
308
- exports.BIB_POSTMERGE_FIX_SETTINGS = BIB_POSTMERGE_FIX_SETTINGS;
309
- const BIB_PREIMPORT_FIX_SETTINGS = {
310
- replacePrefixes: REPLACE_PREFIXES
311
- };
312
- exports.BIB_PREIMPORT_FIX_SETTINGS = BIB_PREIMPORT_FIX_SETTINGS;
313
- const AUTNAME_PREIMPORT_FIX_SETTINGS = {
314
- replacePrefixes: REPLACE_PREFIXES
315
- };
316
- exports.AUTNAME_PREIMPORT_FIX_SETTINGS = AUTNAME_PREIMPORT_FIX_SETTINGS;
317
- const BIB_HANDLE_TEMP_URNS_SETTINGS = {
318
- handleTempUrns: true
319
- };
320
- exports.BIB_HANDLE_TEMP_URNS_SETTINGS = BIB_HANDLE_TEMP_URNS_SETTINGS;
192
+ }
321
193
  //# sourceMappingURL=fix.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix.js","names":["fixRecord","record","settings","logger","createLogger","debug","createDebugLogger","debugData","extend","verbose","JSON","stringify","newRecord","MarcRecord","clone","subfieldValues","generateMissingSIDsOptions","generateMissingSIDs","undefined","replacePrefixesOptions","replacePrefixes","forEach","options","handleTempUrns","toObject","oldPrefix","newPrefix","prefixReplaceCodes","pattern","replacement","getDatafields","field","subfields","filter","code","includes","subfield","value","replace","f035Filters","fSIDFilters","length","f035s","f035ToSidInfo","get","fSIDs","sidsToSidInfo","sidsToBeAdded","genNewSids","f035SidInfo","some","fSIDInfo","SID","sidField","insertField","map","sidInfo","tag","ind1","ind2","SIDs","flatMap","sub","wantedSub","regexp","test","findIndex","slice","indexOf","hasURN","f","hasTempSubfield","hasNoTempSubfield","f856sUrn","fields","f856sUrnsWithTempSubfields","f856sUrnsWithNoTempSubfields","existingLegalDepositURN","validateLD","removeFields","fixedFields","removeTempSubfield","insertFields","createLDSubfields","ldSubfields","f856sUrnWithLdSubfields","fieldHasLDSubfields","every","ldsf","sf","isNaN","parseInt","filteredSubfields","BIB_F035_TO_SID","REPLACE_PREFIXES","BIB_FORMAT_SETTINGS","BIB_PREVALIDATION_FIX_SETTINGS","BIB_POSTMERGE_FIX_SETTINGS","BIB_PREIMPORT_FIX_SETTINGS","AUTNAME_PREIMPORT_FIX_SETTINGS","BIB_HANDLE_TEMP_URNS_SETTINGS"],"sources":["../../src/helpers/fix.js"],"sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero 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* melinda-rest-api-commons 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 Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero 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 {MarcRecord} from '@natlibfi/marc-record';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport createDebugLogger from 'debug';\n\nexport function fixRecord(record, settings = {}) {\n const logger = createLogger();\n const debug = createDebugLogger('@natlibfi/melinda-rest-api-commons:fixRecord');\n const debugData = debug.extend('data');\n\n logger.verbose(`We will apply formatting to the record according to settings: ${JSON.stringify(settings)}`);\n const newRecord = MarcRecord.clone(record, {subfieldValues: false});\n debugData(`settings: ${JSON.stringify(settings)}`);\n\n const generateMissingSIDsOptions = settings.generateMissingSIDs || undefined;\n generateMissingSIDs(generateMissingSIDsOptions);\n\n const replacePrefixesOptions = settings.replacePrefixes || [];\n debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);\n\n replacePrefixesOptions.forEach(options => {\n replacePrefixes(options);\n });\n\n handleTempUrns(settings.handleTempUrns);\n\n return newRecord.toObject();\n\n // Replace prefix in all specified subfields\n function replacePrefixes(options) {\n const {oldPrefix, newPrefix, prefixReplaceCodes} = options;\n debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);\n const pattern = `(${oldPrefix})`;\n const replacement = `(${newPrefix})`;\n newRecord.getDatafields()\n .forEach(field => {\n field.subfields\n .filter(({code}) => prefixReplaceCodes.includes(code))\n .forEach(subfield => {\n subfield.value = subfield.value.replace(pattern, replacement); // eslint-disable-line functional/immutable-data\n });\n });\n }\n\n\n function generateMissingSIDs(options) {\n debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);\n\n const f035Filters = options && options.f035Filters ? options.f035Filters : [];\n const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];\n\n if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {\n debug(`No sane options for generating missing SIDs`);\n return;\n }\n\n const f035s = f035ToSidInfo(newRecord.get(/^035$/u));\n const fSIDs = sidsToSidInfo(newRecord.get(/^SID$/u));\n\n const sidsToBeAdded = genNewSids(fSIDs.length === 0\n ? f035s\n // test that SIDs are not there yet\n : f035s.filter(f035SidInfo => fSIDs.some(fSIDInfo => f035SidInfo.SID !== fSIDInfo.SID && f035SidInfo.value !== fSIDInfo.value)));\n\n // Add new SIDs\n return sidsToBeAdded.forEach(sidField => newRecord.insertField(sidField));\n\n function genNewSids(sidsToBeAdded) {\n return sidsToBeAdded.map(sidInfo => ({tag: 'SID', ind1: ' ', ind2: ' ', subfields: [{code: 'c', value: sidInfo.value}, {code: 'b', value: sidInfo.SID}]}));\n }\n\n function sidsToSidInfo(SIDs) {\n return SIDs.flatMap(({subfields}) => {\n const [SID] = subfields.filter(sub => sub.code === 'b' && fSIDFilters.includes(sub.value)).map(sub => sub.value);\n const [value] = subfields.filter(sub => sub.code === 'c' && sub.value !== undefined).map(sub => sub.value);\n\n if (SID && value) {\n return {\n SID,\n value\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n\n function f035ToSidInfo(f035s) {\n return f035s.flatMap(({subfields}) => {\n const [wantedSub] = subfields.filter(sub => sub.code === 'a' && f035Filters.some(regexp => regexp.test(sub.value)));\n\n if (wantedSub) {\n return {\n SID: fSIDFilters[f035Filters.findIndex(regexp => regexp.test(wantedSub.value))],\n value: wantedSub.value.slice(wantedSub.value.indexOf(')') + 1)\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n }\n\n\n // eslint-disable-next-line max-statements\n function handleTempUrns(options) {\n debugData(`Options for handleTempUrns: ${JSON.stringify(options)}`);\n\n if (options !== true) {\n return;\n }\n\n // If we have an non-temp URN, we can delete tempURNs, otherwise we should delete the temp subfield from URN\n\n const hasURN = f => f.tag === '856' && f.subfields.some(({code, value}) => code === 'u' && (/urn.fi/u).test(value));\n\n const hasTempSubfield = f => f.subfields.some(({code, value}) => code === '9' && (/^MELINDA<TEMP>$/u).test(value));\n const hasNoTempSubfield = f => !f.subfields.some(({code, value}) => code === '9' && (/^MELINDA<TEMP>$/u).test(value));\n\n const f856sUrn = newRecord.fields.filter(hasURN);\n const f856sUrnsWithTempSubfields = f856sUrn.filter(hasTempSubfield);\n const f856sUrnsWithNoTempSubfields = f856sUrn.filter(hasNoTempSubfield);\n\n debugData(`URN f856s: ${JSON.stringify(f856sUrn)}`);\n debugData(`URN f856s with temp subfield: ${JSON.stringify(f856sUrnsWithTempSubfields)}`);\n\n // None of the URNs has temp subfields, we don't need to do anything\n if (f856sUrnsWithTempSubfields.length < 1) {\n debug(`No Urns with temp subfield`);\n return;\n }\n\n // Do we have an existing URN with legal deposit subfields, if we have, we can remove the temp URN field(s)\n const existingLegalDepositURN = validateLD(f856sUrnsWithNoTempSubfields);\n debug(`existingLegalDepositURN: ${existingLegalDepositURN}`);\n\n if (existingLegalDepositURN) {\n debug(`We have an existing LD URN, we can delete temp fields (${f856sUrnsWithTempSubfields.length})`);\n newRecord.removeFields(f856sUrnsWithTempSubfields);\n return;\n }\n\n // We do not have an existing legalDepositURN, we should use the tempURN and remove the temp subfields from it\n if (!existingLegalDepositURN && f856sUrnsWithTempSubfields.length > 0) {\n //debug(`All Urns (${f856sUrn.length}) have a temp subfield`);\n debugData(`Original temp URNs: (${JSON.stringify(f856sUrnsWithTempSubfields)})`);\n const fixedFields = f856sUrnsWithTempSubfields.map(removeTempSubfield).filter(field => field);\n debug(`We removed temp subfields: (${JSON.stringify(fixedFields)})`);\n newRecord.removeFields(f856sUrnsWithTempSubfields);\n newRecord.insertFields(fixedFields);\n return;\n }\n\n // Should we check that the non-temp URN has 2nd ind '0' - meaning that the URN handles the actual resource itself?\n }\n\n // ---- LD-functions below are same as in https://github.com/NatLibFi/marc-record-validators-melinda/blob/feature-updates-to-urn/src/urn.js\n // we propably should develop the urn/legaldeposit -validator to use also here\n\n function createLDSubfields() {\n return [\n {\n code: 'z',\n value: 'Käytettävissä vapaakappalekirjastoissa'\n },\n {\n code: '5',\n value: 'FI-Vapaa'\n }\n ];\n }\n\n function validateLD(f856sUrn) {\n debug(`Validating the existence of legal deposit subfields`);\n const ldSubfields = createLDSubfields();\n const f856sUrnWithLdSubfields = f856sUrn.filter(field => fieldHasLDSubfields(field, ldSubfields));\n if (f856sUrnWithLdSubfields.length > 0) {\n debug(`Record has ${f856sUrnWithLdSubfields.length} URN fields with all necessary legal deposit subfields`);\n debugData(`f856sUrnWithLdSubfields: ${JSON.stringify(f856sUrnWithLdSubfields)}`);\n return true;\n }\n return false;\n }\n\n function fieldHasLDSubfields(field, ldSubfields) {\n if (ldSubfields.every(ldsf => field.subfields.some(sf => sf.code === ldsf.code && sf.value === ldsf.value))) {\n return true;\n }\n }\n\n // ---\n\n function removeTempSubfield(field) {\n\n // Handle non-numeric fields, and fields with a numeric tag of 010 and greater\n // Aleph's FMT as a controlfield might be a problem\n if (!isNaN(field.tag) && parseInt(field.tag, 10) >= 10) {\n\n const filteredSubfields = field.subfields.filter(sf => sf.code !== '9' && !(/^MELINDA<TEMP>$/u).test(sf.value));\n\n // Remove whole field if there are no subfields left\n if (filteredSubfields.length < 1) {\n return false;\n }\n\n return {\n tag: field.tag,\n ind1: field.ind1,\n ind2: field.ind2,\n subfields: filteredSubfields\n };\n }\n // return controlFields as is\n return field;\n }\n}\n\n// This could be formatted so that 035-prefix and SID contents would be better connected than by just an array index\nexport const BIB_F035_TO_SID = {\n f035Filters: [/^\\(FI-BTJ\\)/u, /^\\(FI-TATI\\)/u],\n fSIDFilters: ['FI-BTJ', 'tati']\n};\n\n// There is somewhere other implementations of this same standardPrefixes to alephInternalPrefixes normalization\nexport const REPLACE_PREFIXES = [\n {\n oldPrefix: 'FI-MELINDA',\n newPrefix: 'FIN01',\n prefixReplaceCodes: ['w']\n },\n {\n oldPrefix: 'FI-ASTERI-S',\n newPrefix: 'FIN10',\n prefixReplaceCodes: ['0']\n },\n {\n oldPrefix: 'FI-ASTERI-N',\n newPrefix: 'FIN11',\n prefixReplaceCodes: ['0']\n },\n {\n oldPrefix: 'FI-ASTERI-A',\n newPrefix: 'FIN12',\n prefixReplaceCodes: ['0']\n },\n {\n oldPrefix: 'FI-ASTERI-W',\n newPrefix: 'FIN13',\n prefixReplaceCodes: ['0']\n }\n];\n\n// If placed in config.js testing needs envs\n// BIB_FORMAT_SETTINGS is outdated, use other settings instead\nexport const BIB_FORMAT_SETTINGS = {\n replacePrefixes: REPLACE_PREFIXES,\n generateMissingSIDs: BIB_F035_TO_SID\n};\n\nexport const BIB_PREVALIDATION_FIX_SETTINGS = {\n generateMissingSIDs: BIB_F035_TO_SID\n};\n\nexport const BIB_POSTMERGE_FIX_SETTINGS = {\n handleTempUrns: true\n};\n\nexport const BIB_PREIMPORT_FIX_SETTINGS = {\n replacePrefixes: REPLACE_PREFIXES\n};\n\nexport const AUTNAME_PREIMPORT_FIX_SETTINGS = {\n replacePrefixes: REPLACE_PREFIXES\n};\n\nexport const BIB_HANDLE_TEMP_URNS_SETTINGS = {\n handleTempUrns: true\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"fix.js","names":["logger","createLogger","debug","createDebugLogger","debugData","extend","fixRecord","record","settings","verbose","JSON","stringify","newRecord","MarcRecord","clone","subfieldValues","generateMissingSIDsOptions","generateMissingSIDs","undefined","newRecord1","replacePrefixesOptions","replacePrefixes","newRecord2","replaceAllPrefixes","newRecord3","handleTempUrns","newRecord4","stripF884s","toObject","length","forEach","options","replacePrefix","oldPrefix","newPrefix","prefixReplaceCodes","pattern","replacement","getDatafields","field","subfields","filter","code","includes","subfield","value","replace","f035Filters","fSIDFilters","f035s","f035ToSidInfo","get","fSIDs","sidsToSidInfo","sidsToBeAdded","genNewSids","f035SidInfo","some","fSIDInfo","SID","sidField","insertField","map","sidInfo","tag","ind1","ind2","SIDs","flatMap","sub","wantedSub","regexp","test","findIndex","slice","indexOf"],"sources":["../../src/helpers/fix.js"],"sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2022 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero 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* melinda-rest-api-commons 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 Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero 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 {MarcRecord} from '@natlibfi/marc-record';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport createDebugLogger from 'debug';\n\nimport {handleTempUrns} from './fix-handle-tempurns';\nimport {stripF884s} from './fix-strip-f884s';\n\nexport * from './fix-constants';\n\nconst logger = createLogger();\nconst debug = createDebugLogger('@natlibfi/melinda-rest-api-commons:fixRecord');\nconst debugData = debug.extend('data');\n\nexport function fixRecord(record, settings = {}) {\n\n logger.verbose(`We will apply formatting to the record according to settings: ${JSON.stringify(settings)}`);\n const newRecord = MarcRecord.clone(record, {subfieldValues: false});\n debugData(`settings: ${JSON.stringify(settings)}`);\n\n // We should handle these in some prettier way ...\n\n // Fix 1, generate SIDs\n const generateMissingSIDsOptions = settings.generateMissingSIDs || undefined;\n const newRecord1 = generateMissingSIDs(newRecord, generateMissingSIDsOptions);\n\n // Fix 2, replace identifier prefixes\n const replacePrefixesOptions = settings.replacePrefixes || [];\n const newRecord2 = replaceAllPrefixes(newRecord1, replacePrefixesOptions);\n\n // Fix 3, handle temporary URNs from legal deposit record import\n const newRecord3 = handleTempUrns(newRecord2, settings.handleTempUrns);\n\n // Fix 4, strip extra field 884s\n const newRecord4 = stripF884s(newRecord3, settings.stripF884s);\n\n return newRecord4.toObject();\n\n}\n\n\nfunction replaceAllPrefixes(record, replacePrefixesOptions) {\n if (replacePrefixesOptions.length < 1) {\n debug(`NOT running replacePrefixes, no options`);\n return record;\n }\n\n debug(`Running replacePrefixes fixer`);\n debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);\n\n replacePrefixesOptions.forEach(options => {\n replacePrefix(record, options);\n });\n return record;\n}\n\n\n// Replace prefix in all specified subfields\nfunction replacePrefix(record, options) {\n const {oldPrefix, newPrefix, prefixReplaceCodes} = options;\n debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);\n const pattern = `(${oldPrefix})`;\n const replacement = `(${newPrefix})`;\n record.getDatafields()\n .forEach(field => {\n field.subfields\n .filter(({code}) => prefixReplaceCodes.includes(code))\n .forEach(subfield => {\n subfield.value = subfield.value.replace(pattern, replacement); // eslint-disable-line functional/immutable-data\n });\n });\n return record;\n}\n\n\nfunction generateMissingSIDs(record, options) {\n\n const f035Filters = options && options.f035Filters ? options.f035Filters : [];\n const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];\n\n if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {\n debug(`NOT running generateMissingsSIDs, no options`);\n return record;\n }\n\n debug(`Running generateMissingSIDs fixer`);\n debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);\n\n const f035s = f035ToSidInfo(record.get(/^035$/u));\n const fSIDs = sidsToSidInfo(record.get(/^SID$/u));\n\n const sidsToBeAdded = genNewSids(fSIDs.length === 0\n ? f035s\n // test that SIDs are not there yet\n : f035s.filter(f035SidInfo => fSIDs.some(fSIDInfo => f035SidInfo.SID !== fSIDInfo.SID && f035SidInfo.value !== fSIDInfo.value)));\n\n // Add new SIDs\n sidsToBeAdded.forEach(sidField => record.insertField(sidField));\n return record;\n\n function genNewSids(sidsToBeAdded) {\n return sidsToBeAdded.map(sidInfo => ({tag: 'SID', ind1: ' ', ind2: ' ', subfields: [{code: 'c', value: sidInfo.value}, {code: 'b', value: sidInfo.SID}]}));\n }\n\n function sidsToSidInfo(SIDs) {\n return SIDs.flatMap(({subfields}) => {\n const [SID] = subfields.filter(sub => sub.code === 'b' && fSIDFilters.includes(sub.value)).map(sub => sub.value);\n const [value] = subfields.filter(sub => sub.code === 'c' && sub.value !== undefined).map(sub => sub.value);\n\n if (SID && value) {\n return {\n SID,\n value\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n\n function f035ToSidInfo(f035s) {\n return f035s.flatMap(({subfields}) => {\n const [wantedSub] = subfields.filter(sub => sub.code === 'a' && f035Filters.some(regexp => regexp.test(sub.value)));\n\n if (wantedSub) {\n return {\n SID: fSIDFilters[f035Filters.findIndex(regexp => regexp.test(wantedSub.value))],\n value: wantedSub.value.slice(wantedSub.value.indexOf(')') + 1)\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n}\n\n\n"],"mappings":"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"}