@natlibfi/melinda-record-matching 1.0.10 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/candidate-search/candidate-search-utils.js +3 -2
  2. package/dist/candidate-search/candidate-search-utils.js.map +1 -1
  3. package/dist/candidate-search/index.js +16 -5
  4. package/dist/candidate-search/index.js.map +1 -1
  5. package/dist/candidate-search/index.spec.js +2 -2
  6. package/dist/candidate-search/index.spec.js.map +1 -1
  7. package/dist/candidate-search/query-list/bib.js +18 -7
  8. package/dist/candidate-search/query-list/bib.js.map +1 -1
  9. package/dist/candidate-search/query-list/bib.spec.js +2 -2
  10. package/dist/candidate-search/query-list/bib.spec.js.map +1 -1
  11. package/dist/candidate-search/query-list/index.js +3 -3
  12. package/dist/candidate-search/query-list/index.js.map +1 -1
  13. package/dist/index.js +3 -3
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.spec.js +2 -2
  16. package/dist/index.spec.js.map +1 -1
  17. package/dist/match-detection/features/bib/all-source-ids.js.map +1 -1
  18. package/dist/match-detection/features/bib/authors.js.map +1 -1
  19. package/dist/match-detection/features/bib/bibliographic-level.js.map +1 -1
  20. package/dist/match-detection/features/bib/host-component.js.map +1 -1
  21. package/dist/match-detection/features/bib/index.js +24 -24
  22. package/dist/match-detection/features/bib/index.spec.js +2 -2
  23. package/dist/match-detection/features/bib/index.spec.js.map +1 -1
  24. package/dist/match-detection/features/bib/isbn.js.map +1 -1
  25. package/dist/match-detection/features/bib/issn.js.map +1 -1
  26. package/dist/match-detection/features/bib/language.js.map +1 -1
  27. package/dist/match-detection/features/bib/melinda-id.js.map +1 -1
  28. package/dist/match-detection/features/bib/melinda-identifier-factory.js.map +1 -1
  29. package/dist/match-detection/features/bib/other-standard-identifier.js.map +1 -1
  30. package/dist/match-detection/features/bib/publication-time.js.map +1 -1
  31. package/dist/match-detection/features/bib/record-type.js.map +1 -1
  32. package/dist/match-detection/features/bib/standard-identifier-factory.js.map +1 -1
  33. package/dist/match-detection/features/bib/title.js.map +1 -1
  34. package/dist/match-detection/features/index.js +2 -2
  35. package/dist/match-detection/index.js +2 -2
  36. package/dist/match-detection/index.js.map +1 -1
  37. package/dist/match-detection/index.spec.js +2 -2
  38. package/dist/match-detection/index.spec.js.map +1 -1
  39. package/dist/matching-utils.js +1 -1
  40. package/dist/matching-utils.js.map +1 -1
  41. package/package.json +26 -29
  42. package/src/candidate-search/candidate-search-utils.js +3 -1
  43. package/src/candidate-search/index.js +11 -1
  44. package/src/candidate-search/query-list/bib.js +15 -1
@@ -38,9 +38,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
38
38
  */
39
39
  function toQueries(identifiers, queryString) {
40
40
  const debug = (0, _debug.default)('@natlibfi/melinda-record-matching:toQueries');
41
- const debugData = debug.extend('data'); // Aleph supports only two queries with or -operator (This is not actually true)
41
+ const debugData = debug.extend('data');
42
+ const quotedIdentifiers = identifiers.map(identifier => identifier.match(/\//u) ? `"${identifier}"` : `${identifier}`); // Aleph supports only two queries with or -operator (This is not actually true)
42
43
 
43
- const pairs = toPairs(identifiers);
44
+ const pairs = toPairs(quotedIdentifiers);
44
45
  const queries = pairs.map(([a, b]) => b ? `${queryString}=${a} or ${queryString}=${b}` : `${queryString}=${a}`);
45
46
  debugData(`Pairs (${pairs.length}): ${JSON.stringify(pairs)}`);
46
47
  debugData(`Queries (${queries.length}): ${JSON.stringify(queries)}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/candidate-search/candidate-search-utils.js"],"names":["toQueries","identifiers","queryString","debug","debugData","extend","pairs","toPairs","queries","map","a","b","length","JSON","stringify","array","slice","concat"],"mappings":";;;;;;;AA4BA;;;;AA5BA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BO,SAASA,SAAT,CAAmBC,WAAnB,EAAgCC,WAAhC,EAA6C;AAElD,QAAMC,KAAK,GAAG,oBAAkB,6CAAlB,CAAd;AACA,QAAMC,SAAS,GAAGD,KAAK,CAACE,MAAN,CAAa,MAAb,CAAlB,CAHkD,CAKlD;;AACA,QAAMC,KAAK,GAAGC,OAAO,CAACN,WAAD,CAArB;AACA,QAAMO,OAAO,GAAGF,KAAK,CAACG,GAAN,CAAU,CAAC,CAACC,CAAD,EAAIC,CAAJ,CAAD,KAAYA,CAAC,GAAI,GAAET,WAAY,IAAGQ,CAAE,OAAMR,WAAY,IAAGS,CAAE,EAA9C,GAAmD,GAAET,WAAY,IAAGQ,CAAE,EAA7F,CAAhB;AAEAN,EAAAA,SAAS,CAAE,UAASE,KAAK,CAACM,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAeR,KAAf,CAAsB,EAAnD,CAAT;AACAF,EAAAA,SAAS,CAAE,YAAWI,OAAO,CAACI,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAeN,OAAf,CAAwB,EAAzD,CAAT;AAEA,SAAOA,OAAP;AACD;;AAED,SAASD,OAAT,CAAiBQ,KAAjB,EAAwB;AACtB,MAAIA,KAAK,CAACH,MAAN,KAAiB,CAArB,EAAwB;AACtB,WAAO,EAAP;AACD;;AACD,SAAO,CAACG,KAAK,CAACC,KAAN,CAAY,CAAZ,EAAe,CAAf,CAAD,EAAoBC,MAApB,CAA2BV,OAAO,CAACQ,KAAK,CAACC,KAAN,CAAY,CAAZ,CAAD,EAAiB,CAAjB,CAAlC,CAAP;AACD","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\n\nexport function toQueries(identifiers, queryString) {\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:toQueries');\n const debugData = debug.extend('data');\n\n // Aleph supports only two queries with or -operator (This is not actually true)\n const pairs = toPairs(identifiers);\n const queries = pairs.map(([a, b]) => b ? `${queryString}=${a} or ${queryString}=${b}` : `${queryString}=${a}`);\n\n debugData(`Pairs (${pairs.length}): ${JSON.stringify(pairs)}`);\n debugData(`Queries (${queries.length}): ${JSON.stringify(queries)}`);\n\n return queries;\n}\n\nfunction toPairs(array) {\n if (array.length === 0) {\n return [];\n }\n return [array.slice(0, 2)].concat(toPairs(array.slice(2), 2));\n}\n"],"file":"candidate-search-utils.js"}
1
+ {"version":3,"sources":["../../src/candidate-search/candidate-search-utils.js"],"names":["toQueries","identifiers","queryString","debug","debugData","extend","quotedIdentifiers","map","identifier","match","pairs","toPairs","queries","a","b","length","JSON","stringify","array","slice","concat"],"mappings":";;;;;;;AA4BA;;;;AA5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIO,SAASA,SAAT,CAAmBC,WAAnB,EAAgCC,WAAhC,EAA6C;AAElD,QAAMC,KAAK,GAAG,oBAAkB,6CAAlB,CAAd;AACA,QAAMC,SAAS,GAAGD,KAAK,CAACE,MAAN,CAAa,MAAb,CAAlB;AAEA,QAAMC,iBAAiB,GAAGL,WAAW,CAACM,GAAZ,CAAgBC,UAAU,IAAIA,UAAU,CAACC,KAAX,CAAiB,KAAjB,IAA2B,IAAGD,UAAW,GAAzC,GAA+C,GAAEA,UAAW,EAA1F,CAA1B,CALkD,CAOlD;;AACA,QAAME,KAAK,GAAGC,OAAO,CAACL,iBAAD,CAArB;AACA,QAAMM,OAAO,GAAGF,KAAK,CAACH,GAAN,CAAU,CAAC,CAACM,CAAD,EAAIC,CAAJ,CAAD,KAAYA,CAAC,GAAI,GAAEZ,WAAY,IAAGW,CAAE,OAAMX,WAAY,IAAGY,CAAE,EAA9C,GAAmD,GAAEZ,WAAY,IAAGW,CAAE,EAA7F,CAAhB;AAEAT,EAAAA,SAAS,CAAE,UAASM,KAAK,CAACK,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAeP,KAAf,CAAsB,EAAnD,CAAT;AACAN,EAAAA,SAAS,CAAE,YAAWQ,OAAO,CAACG,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAeL,OAAf,CAAwB,EAAzD,CAAT;AAEA,SAAOA,OAAP;AACD;;AAED,SAASD,OAAT,CAAiBO,KAAjB,EAAwB;AACtB,MAAIA,KAAK,CAACH,MAAN,KAAiB,CAArB,EAAwB;AACtB,WAAO,EAAP;AACD;;AACD,SAAO,CAACG,KAAK,CAACC,KAAN,CAAY,CAAZ,EAAe,CAAf,CAAD,EAAoBC,MAApB,CAA2BT,OAAO,CAACO,KAAK,CAACC,KAAN,CAAY,CAAZ,CAAD,EAAiB,CAAjB,CAAlC,CAAP;AACD","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\n\nexport function toQueries(identifiers, queryString) {\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:toQueries');\n const debugData = debug.extend('data');\n\n const quotedIdentifiers = identifiers.map(identifier => identifier.match(/\\//u) ? `\"${identifier}\"` : `${identifier}`);\n\n // Aleph supports only two queries with or -operator (This is not actually true)\n const pairs = toPairs(quotedIdentifiers);\n const queries = pairs.map(([a, b]) => b ? `${queryString}=${a} or ${queryString}=${b}` : `${queryString}=${a}`);\n\n debugData(`Pairs (${pairs.length}): ${JSON.stringify(pairs)}`);\n debugData(`Queries (${queries.length}): ${JSON.stringify(queries)}`);\n\n return queries;\n}\n\nfunction toPairs(array) {\n if (array.length === 0) {\n return [];\n }\n return [array.slice(0, 2)].concat(toPairs(array.slice(2), 2));\n}\n"],"file":"candidate-search-utils.js"}
@@ -3,17 +3,17 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.default = exports.CandidateSearchError = void 0;
6
7
  Object.defineProperty(exports, "searchTypes", {
7
8
  enumerable: true,
8
9
  get: function () {
9
10
  return _queryList.searchTypes;
10
11
  }
11
12
  });
12
- exports.default = exports.CandidateSearchError = void 0;
13
13
 
14
14
  var _debug = _interopRequireDefault(require("debug"));
15
15
 
16
- var _sruClient = _interopRequireDefault(require("@natlibfi/sru-client"));
16
+ var _sruClient = _interopRequireWildcard(require("@natlibfi/sru-client"));
17
17
 
18
18
  var _marcRecord = require("@natlibfi/marc-record");
19
19
 
@@ -21,9 +21,9 @@ var _marcRecordSerializers = require("@natlibfi/marc-record-serializers");
21
21
 
22
22
  var _queryList = _interopRequireWildcard(require("./query-list"));
23
23
 
24
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
25
 
26
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
27
 
28
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
29
 
@@ -77,6 +77,7 @@ var _default = ({
77
77
  version: '2.0',
78
78
  retrieveAll: false
79
79
  });
80
+ debug(`Searching matches for ${inputRecordId}`);
80
81
  debug(`Generated queryList ${JSON.stringify(queryList)}`);
81
82
 
82
83
  if (queryList.length === 0) {
@@ -127,6 +128,13 @@ var _default = ({
127
128
  client.searchRetrieve(query, {
128
129
  startRecord: resultSetOffset
129
130
  }).on('error', err => {
131
+ // eslint-disable-next-line functional/no-conditional-statement
132
+ if (err instanceof _sruClient.SruSearchError) {
133
+ debug(`SRU SruSearchError for query: ${query}: ${err}`);
134
+ reject(new CandidateSearchError(`SRU SruSearchError for query: ${query}: ${err}`));
135
+ }
136
+
137
+ debug(`SRU error for query: ${query}: ${err}`);
130
138
  reject(new CandidateSearchError(`SRU error for query: ${query}: ${err}`));
131
139
  }).on('end', async nextOffset => {
132
140
  try {
@@ -148,7 +156,10 @@ var _default = ({
148
156
  const foundRecordMarc = await _marcRecordSerializers.MARCXML.from(foundRecord, {
149
157
  subfieldValues: false
150
158
  });
151
- const foundRecordId = getRecordId(foundRecordMarc);
159
+ const foundRecordId = getRecordId(foundRecordMarc); // This does not work and might cause problems:
160
+ // Record *should* match itself AND in REST the input record is given id 000000001 always
161
+
162
+ debug(`Checking ${inputRecordId} vs ${foundRecordId}`);
152
163
 
153
164
  if (inputRecordId === foundRecordId) {
154
165
  debug(`Input and candidate are the same record per 001. Discarding candidate`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/candidate-search/index.js"],"names":["CandidateSearchError","Error","record","searchSpec","url","maxRecordsPerRequest","MarcRecord","setValidationOptions","subfieldValues","debug","inputRecordId","getRecordId","queryList","client","version","retrieveAll","JSON","stringify","length","queryOffset","resultSetOffset","query","records","nextOffset","retrieveRecords","queriesLeft","Promise","resolve","reject","promises","searchRetrieve","startRecord","on","err","all","filtered","filter","r","foundRecord","push","handleRecord","foundRecordMarc","MARCXML","from","foundRecordId","id","field","get","value"],"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* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport createClient from '@natlibfi/sru-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {MARCXML} from '@natlibfi/marc-record-serializers';\nimport generateQueryList from './query-list';\n\nexport {searchTypes} from './query-list';\n\nexport class CandidateSearchError extends Error {}\n\nexport default ({record, searchSpec, url, maxRecordsPerRequest = 50}) => {\n MarcRecord.setValidationOptions({subfieldValues: false});\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search');\n const inputRecordId = getRecordId(record);\n const queryList = generateQueryList(record, searchSpec);\n const client = createClient({\n url, maxRecordsPerRequest,\n version: '2.0',\n retrieveAll: false\n });\n\n debug(`Generated queryList ${JSON.stringify(queryList)}`);\n if (queryList.length === 0) { // eslint-disable-line functional/no-conditional-statement\n throw new CandidateSearchError(`Generated query list contains no queries`);\n }\n\n // eslint-disable-next-line max-statements\n return async ({queryOffset = 0, resultSetOffset = 1}) => {\n const query = queryList[queryOffset];\n\n if (query) {\n const {records, nextOffset} = await retrieveRecords();\n\n if (typeof nextOffset === 'number') {\n debug(`Running next search for query ${queryOffset} ${query}`);\n return {records, queryOffset, resultSetOffset: nextOffset, queriesLeft: queryList.length - (queryOffset + 1)};\n }\n debug(`Query ${queryOffset} ${query} done, moving to next query. (${queryList.length - (queryOffset + 1)} queries left)`);\n return {records, queryOffset: queryOffset + 1, queriesLeft: queryList.length - (queryOffset + 1)};\n }\n\n debug(`All ${queryList.length} queries done, there's no query for ${queryOffset}`);\n return {records: []};\n\n function retrieveRecords() {\n return new Promise((resolve, reject) => {\n const promises = [];\n\n debug(`Searching for candidates with query: ${query} (Offset ${resultSetOffset})`);\n\n client.searchRetrieve(query, {startRecord: resultSetOffset})\n .on('error', err => {\n reject(new CandidateSearchError(`SRU error for query: ${query}: ${err}`));\n })\n .on('end', async nextOffset => {\n try {\n const records = await Promise.all(promises);\n const filtered = records.filter(r => r);\n\n debug(`Found ${filtered.length} candidates`);\n\n resolve({nextOffset, records: filtered});\n } catch (err) {\n reject(err);\n }\n })\n .on('record', foundRecord => {\n promises.push(handleRecord()); // eslint-disable-line functional/immutable-data\n\n async function handleRecord() {\n try {\n const foundRecordMarc = await MARCXML.from(foundRecord, {subfieldValues: false});\n const foundRecordId = getRecordId(foundRecordMarc);\n\n if (inputRecordId === foundRecordId) {\n debug(`Input and candidate are the same record per 001. Discarding candidate`);\n return;\n }\n\n return {record: foundRecordMarc, id: foundRecordId};\n } catch (err) {\n throw new Error(`Failed converting record: ${err}, record: ${foundRecord}`);\n }\n }\n });\n });\n }\n };\n\n function getRecordId(record) {\n const [field] = record.get(/^001$/u);\n return field ? field.value : '';\n }\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../../src/candidate-search/index.js"],"names":["CandidateSearchError","Error","record","searchSpec","url","maxRecordsPerRequest","MarcRecord","setValidationOptions","subfieldValues","debug","inputRecordId","getRecordId","queryList","client","version","retrieveAll","JSON","stringify","length","queryOffset","resultSetOffset","query","records","nextOffset","retrieveRecords","queriesLeft","Promise","resolve","reject","promises","searchRetrieve","startRecord","on","err","SruSearchError","all","filtered","filter","r","foundRecord","push","handleRecord","foundRecordMarc","MARCXML","from","foundRecordId","id","field","get","value"],"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* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport createClient, {SruSearchError} from '@natlibfi/sru-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {MARCXML} from '@natlibfi/marc-record-serializers';\nimport generateQueryList from './query-list';\n\nexport {searchTypes} from './query-list';\n\nexport class CandidateSearchError extends Error {}\n\nexport default ({record, searchSpec, url, maxRecordsPerRequest = 50}) => {\n MarcRecord.setValidationOptions({subfieldValues: false});\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search');\n const inputRecordId = getRecordId(record);\n const queryList = generateQueryList(record, searchSpec);\n const client = createClient({\n url, maxRecordsPerRequest,\n version: '2.0',\n retrieveAll: false\n });\n\n debug(`Searching matches for ${inputRecordId}`);\n debug(`Generated queryList ${JSON.stringify(queryList)}`);\n if (queryList.length === 0) { // eslint-disable-line functional/no-conditional-statement\n throw new CandidateSearchError(`Generated query list contains no queries`);\n }\n\n // eslint-disable-next-line max-statements\n return async ({queryOffset = 0, resultSetOffset = 1}) => {\n const query = queryList[queryOffset];\n\n if (query) {\n const {records, nextOffset} = await retrieveRecords();\n\n if (typeof nextOffset === 'number') {\n debug(`Running next search for query ${queryOffset} ${query}`);\n return {records, queryOffset, resultSetOffset: nextOffset, queriesLeft: queryList.length - (queryOffset + 1)};\n }\n debug(`Query ${queryOffset} ${query} done, moving to next query. (${queryList.length - (queryOffset + 1)} queries left)`);\n return {records, queryOffset: queryOffset + 1, queriesLeft: queryList.length - (queryOffset + 1)};\n }\n\n debug(`All ${queryList.length} queries done, there's no query for ${queryOffset}`);\n return {records: []};\n\n function retrieveRecords() {\n return new Promise((resolve, reject) => {\n const promises = [];\n\n debug(`Searching for candidates with query: ${query} (Offset ${resultSetOffset})`);\n\n client.searchRetrieve(query, {startRecord: resultSetOffset})\n .on('error', err => {\n // eslint-disable-next-line functional/no-conditional-statement\n if (err instanceof SruSearchError) {\n debug(`SRU SruSearchError for query: ${query}: ${err}`);\n reject(new CandidateSearchError(`SRU SruSearchError for query: ${query}: ${err}`));\n }\n debug(`SRU error for query: ${query}: ${err}`);\n reject(new CandidateSearchError(`SRU error for query: ${query}: ${err}`));\n })\n .on('end', async nextOffset => {\n try {\n const records = await Promise.all(promises);\n const filtered = records.filter(r => r);\n\n debug(`Found ${filtered.length} candidates`);\n\n resolve({nextOffset, records: filtered});\n } catch (err) {\n reject(err);\n }\n })\n .on('record', foundRecord => {\n promises.push(handleRecord()); // eslint-disable-line functional/immutable-data\n\n async function handleRecord() {\n try {\n const foundRecordMarc = await MARCXML.from(foundRecord, {subfieldValues: false});\n const foundRecordId = getRecordId(foundRecordMarc);\n\n // This does not work and might cause problems:\n // Record *should* match itself AND in REST the input record is given id 000000001 always\n debug(`Checking ${inputRecordId} vs ${foundRecordId}`);\n if (inputRecordId === foundRecordId) {\n debug(`Input and candidate are the same record per 001. Discarding candidate`);\n return;\n }\n\n return {record: foundRecordMarc, id: foundRecordId};\n } catch (err) {\n throw new Error(`Failed converting record: ${err}, record: ${foundRecord}`);\n }\n }\n });\n });\n }\n };\n\n function getRecordId(record) {\n const [field] = record.get(/^001$/u);\n return field ? field.value : '';\n }\n};\n"],"file":"index.js"}
@@ -10,9 +10,9 @@ var _marcRecord = require("@natlibfi/marc-record");
10
10
 
11
11
  var _ = _interopRequireWildcard(require("."));
12
12
 
13
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
14
 
15
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
16
 
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/candidate-search/index.spec.js"],"names":["describe","callback","path","__dirname","recurse","fixura","reader","READERS","JSON","getFixture","factoryOptions","searchOptions","expectedFactoryError","expectedSearchError","enabled","url","isCandidateSearchError","formatFactoryOptions","to","throw","CandidateSearchError","RegExp","search","iterate","maxRecordsPerRequest","record","MarcRecord","subfieldValues","count","expectedResults","Error","err","be","an","message","match","results","formatResults","eql","records","length","resultsToOptions","map","id","toObject","Object","entries","filter","k","reduce","acc","v"],"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* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 {expect} from 'chai';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen-http-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport createSearchInterface, {CandidateSearchError} from '.';\n\ndescribe('candidate-search', () => {\n generateTests({\n callback,\n path: [__dirname, '..', '..', 'test-fixtures', 'candidate-search', 'index'],\n recurse: false,\n fixura: {\n reader: READERS.JSON\n }\n });\n\n // eslint-disable-next-line max-statements\n async function callback({getFixture, factoryOptions, searchOptions, expectedFactoryError, expectedSearchError, enabled = true}) {\n const url = 'http://foo.bar';\n\n if (!enabled) {\n return;\n }\n\n if (expectedFactoryError) {\n if (expectedFactoryError.isCandidateSearchError) {\n expect(() => createSearchInterface({...formatFactoryOptions(), url})).to.throw(CandidateSearchError, new RegExp(expectedFactoryError, 'u'));\n return;\n }\n\n expect(() => createSearchInterface({...formatFactoryOptions(), url})).to.throw(new RegExp(expectedFactoryError, 'u'));\n return;\n }\n\n const search = createSearchInterface({...formatFactoryOptions(), url});\n await iterate({searchOptions});\n\n function formatFactoryOptions() {\n return {\n ...factoryOptions,\n maxRecordsPerRequest: 1,\n record: new MarcRecord(factoryOptions.record, {subfieldValues: false})\n };\n }\n\n // eslint-disable-next-line max-statements\n async function iterate({searchOptions, count = 1}) {\n const expectedResults = getFixture(`expectedResults${count}.json`);\n\n if (expectedSearchError) { // eslint-disable-line functional/no-conditional-statement\n try {\n await search(searchOptions);\n throw new Error('Expected an error');\n } catch (err) {\n expect(err).to.be.an('error');\n expect(err.message).to.match(new RegExp(expectedSearchError, 'u'));\n return;\n }\n }\n\n const results = await search(searchOptions);\n\n expect(formatResults(results)).to.eql(expectedResults);\n\n if (results.records.length > 0) {\n return iterate({\n searchOptions: resultsToOptions(results),\n count: count + 1\n });\n }\n\n function formatResults(results) {\n // console.log(results); //eslint-disable-line\n return {\n ...results,\n records: results.records.map(({record, id}) => ({id, record: record.toObject()}))\n };\n }\n\n function resultsToOptions(results) {\n return Object.entries(results)\n .filter(([k]) => k === 'records' === false) // If key is 'records' return false\n .reduce((acc, [k, v]) => ({...acc, [k]: v}), {});\n }\n }\n }\n});\n"],"file":"index.spec.js"}
1
+ {"version":3,"sources":["../../src/candidate-search/index.spec.js"],"names":["describe","callback","path","__dirname","recurse","fixura","reader","READERS","JSON","getFixture","factoryOptions","searchOptions","expectedFactoryError","expectedSearchError","enabled","url","isCandidateSearchError","formatFactoryOptions","to","throw","CandidateSearchError","RegExp","search","iterate","maxRecordsPerRequest","record","MarcRecord","subfieldValues","count","expectedResults","Error","err","be","an","message","match","results","formatResults","eql","records","length","resultsToOptions","map","id","toObject","Object","entries","filter","k","reduce","acc","v"],"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* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 {expect} from 'chai';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen-http-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport createSearchInterface, {CandidateSearchError} from '.';\n\ndescribe('candidate-search', () => {\n generateTests({\n callback,\n path: [__dirname, '..', '..', 'test-fixtures', 'candidate-search', 'index'],\n recurse: false,\n fixura: {\n reader: READERS.JSON\n }\n });\n\n // eslint-disable-next-line max-statements\n async function callback({getFixture, factoryOptions, searchOptions, expectedFactoryError, expectedSearchError, enabled = true}) {\n const url = 'http://foo.bar';\n\n if (!enabled) {\n return;\n }\n\n if (expectedFactoryError) {\n if (expectedFactoryError.isCandidateSearchError) {\n expect(() => createSearchInterface({...formatFactoryOptions(), url})).to.throw(CandidateSearchError, new RegExp(expectedFactoryError, 'u'));\n return;\n }\n\n expect(() => createSearchInterface({...formatFactoryOptions(), url})).to.throw(new RegExp(expectedFactoryError, 'u'));\n return;\n }\n\n const search = createSearchInterface({...formatFactoryOptions(), url});\n await iterate({searchOptions});\n\n function formatFactoryOptions() {\n return {\n ...factoryOptions,\n maxRecordsPerRequest: 1,\n record: new MarcRecord(factoryOptions.record, {subfieldValues: false})\n };\n }\n\n // eslint-disable-next-line max-statements\n async function iterate({searchOptions, count = 1}) {\n const expectedResults = getFixture(`expectedResults${count}.json`);\n\n if (expectedSearchError) { // eslint-disable-line functional/no-conditional-statement\n try {\n await search(searchOptions);\n throw new Error('Expected an error');\n } catch (err) {\n expect(err).to.be.an('error');\n expect(err.message).to.match(new RegExp(expectedSearchError, 'u'));\n return;\n }\n }\n\n const results = await search(searchOptions);\n\n expect(formatResults(results)).to.eql(expectedResults);\n\n if (results.records.length > 0) {\n return iterate({\n searchOptions: resultsToOptions(results),\n count: count + 1\n });\n }\n\n function formatResults(results) {\n // console.log(results); //eslint-disable-line\n return {\n ...results,\n records: results.records.map(({record, id}) => ({id, record: record.toObject()}))\n };\n }\n\n function resultsToOptions(results) {\n return Object.entries(results)\n .filter(([k]) => k === 'records' === false) // If key is 'records' return false\n .reduce((acc, [k, v]) => ({...acc, [k]: v}), {});\n }\n }\n }\n});\n"],"file":"index.spec.js"}
@@ -3,11 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.bibSourceIds = bibSourceIds;
7
- exports.bibMelindaIds = bibMelindaIds;
8
6
  exports.bibHostComponents = bibHostComponents;
9
- exports.bibTitle = bibTitle;
7
+ exports.bibMelindaIds = bibMelindaIds;
8
+ exports.bibSourceIds = bibSourceIds;
10
9
  exports.bibStandardIdentifiers = bibStandardIdentifiers;
10
+ exports.bibTitle = bibTitle;
11
11
 
12
12
  var _debug = _interopRequireDefault(require("debug"));
13
13
 
@@ -50,17 +50,21 @@ function bibSourceIds(record) {
50
50
  SID__ $c 123457 $b helka
51
51
  SID__ $c (ANDL100020)1077305 $b sata
52
52
  SID__ $c VER999999 $ FI-KV
53
+ SID__ $c /10024/508126 $ REPO_THESEUS
53
54
  In melinda.sourceid -index case is kept, sourceprefixes in brackets and hyphens are normalized away:
55
+ Note: slashes are not normalized away, but a SRU-search-string including slashes needs to be quoted
54
56
  1234567helka
55
57
  1077305sata
56
58
  VER999999FIKV
59
+ /10024/508126REPO_THESEUS
57
60
  Note: All Melinda records that have a matching records in a local db do NOT have SID for that local records,
58
61
  existence of a SID field depends on how the record has been added to Melinda and how it has been handled
59
62
  afterwards. SIDs are also not reliably maintained. A record might or might not have a SID for a local db
60
63
  after the matching record is removed from the local db.
61
64
  */
62
65
  const debug = (0, _debug.default)('@natlibfi/melinda-record-matching:candidate-search:query:source-ids');
63
- const debugData = debug.extend('data');
66
+ const debugData = debug.extend('data'); //const debugInfo = debug.extend('info');
67
+
64
68
  debug(`Creating queries for sourceid's`);
65
69
  const fSids = record.get('SID');
66
70
  debugData(`SID-fields (${fSids.length}): ${JSON.stringify(fSids)}`);
@@ -163,13 +167,19 @@ function bibHostComponents(record) {
163
167
 
164
168
  return false;
165
169
  }
166
- }
170
+ } // SRU search dc.title with a search phrase starting with ^ maps currently in Melinda to
171
+ // (probably) to *headings* index TIT
172
+ // Headings index TIT drops articles etc. from the start of the title according to the filing indicator
173
+ // Currently filing indicator is not implemented - if the title starts with an article and the Melinda
174
+ // record is correctly catalogued using a filing indicator -> dc.title search won't match
175
+
167
176
 
168
177
  function bibTitle(record) {
169
178
  const title = getTitle();
170
179
 
171
180
  if (title) {
172
- const formatted = title.replace(/[^\w\s\p{Alphabetic}]/gu, '').trim().slice(0, 30).trim(); // Prevent too many matches by having a minimum length requirement
181
+ const formatted = title.replace(/[^\w\s\p{Alphabetic}]/gu, '') // Clean up concurrent spaces from fe. subfield changes
182
+ .replace(/ +/gu, ' ').trim().slice(0, 30).trim(); // Prevent too many matches by having a minimum length requirement
173
183
 
174
184
  return formatted.length >= 5 ? [`dc.title="^${formatted}*"`] : [];
175
185
  }
@@ -184,7 +194,8 @@ function bibTitle(record) {
184
194
  code
185
195
  }) => ['a', 'b'].includes(code)).map(({
186
196
  value
187
- }) => value).join('');
197
+ }) => value) // In Melinda's index subfield separators are indexed as ' '
198
+ .join(' ');
188
199
  }
189
200
 
190
201
  return false;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/candidate-search/query-list/bib.js"],"names":["bibSourceIds","record","debug","debugData","extend","fSids","get","length","JSON","stringify","toSidQueries","sidStrings","getSidStrings","sidQueries","map","toSidString","filter","nonEmptySid","field","createSidString","sfC","sfB","cleanedSfC","removeSourcePrefix","normalizeSidSubfieldValue","cleanedSfB","concat","subfieldValue","sourcePrefixRegex","normalizedValue","replace","normalizeAwayRegex","bibMelindaIds","melindaIds","bibHostComponents","id","getHostId","value","subfields","find","code","test","bibTitle","title","getTitle","formatted","trim","slice","includes","join","bibStandardIdentifiers","fields","identifiers","toIdentifiers","uniqueIdentifiers","Set","tag","issnIsbnReqExp","otherIdReqExp","sub","undefined"],"mappings":"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","sourcesContent":["\n/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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*/\nimport createDebugLogger from 'debug';\nimport {toQueries} from '../candidate-search-utils';\nimport {getMelindaIdsF035, validateSidFieldSubfieldCounts, getSubfieldValues} from '../../matching-utils';\n\n\nexport function bibSourceIds(record) {\n\n /* Melinda's SRU-index melinda.sourceid includes source IDs from SID fields in Melinda records\n SID-fields in Melinda have sf $c with local id and sf $b with a code for the local db:\n\n SID__ $c 123457 $b helka\n SID__ $c (ANDL100020)1077305 $b sata\n SID__ $c VER999999 $ FI-KV\n\n In melinda.sourceid -index case is kept, sourceprefixes in brackets and hyphens are normalized away:\n\n 1234567helka\n 1077305sata\n VER999999FIKV\n\n Note: All Melinda records that have a matching records in a local db do NOT have SID for that local records,\n existence of a SID field depends on how the record has been added to Melinda and how it has been handled\n afterwards. SIDs are also not reliably maintained. A record might or might not have a SID for a local db\n after the matching record is removed from the local db.\n\n */\n\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:source-ids');\n const debugData = debug.extend('data');\n debug(`Creating queries for sourceid's`);\n\n const fSids = record.get('SID');\n debugData(`SID-fields (${fSids.length}): ${JSON.stringify(fSids)}`);\n\n return fSids.length > 0 ? toSidQueries(fSids) : [];\n\n function toSidQueries(fSids) {\n debug(`Creating actual queries for sourceid's`);\n\n const sidStrings = getSidStrings(fSids);\n\n if (sidStrings.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n const sidQueries = toQueries(sidStrings, 'melinda.sourceid');\n\n return sidQueries;\n\n function getSidStrings(fSids) {\n debug(`Getting Sid strings from SID fields`);\n\n // Map SID fields to valid sidStrings, filter out empty strings\n const sidStrings = fSids.map(toSidString).filter(nonEmptySid => nonEmptySid);\n return sidStrings;\n\n function toSidString(field) {\n debug(`Getting string from a field`);\n\n return validateSidFieldSubfieldCounts(field) ? createSidString(field) : '';\n\n function createSidString(field) {\n debug(`Creating string from a field`);\n const [sfC] = getSubfieldValues(field, 'c');\n const [sfB] = getSubfieldValues(field, 'b');\n\n const cleanedSfC = removeSourcePrefix(normalizeSidSubfieldValue(sfC));\n const cleanedSfB = normalizeSidSubfieldValue(sfB);\n\n debugData(`${JSON.stringify(sfC)} + ${JSON.stringify(sfB)}`);\n return cleanedSfC.concat(cleanedSfB);\n }\n\n function removeSourcePrefix(subfieldValue) {\n const sourcePrefixRegex = (/^(?<sourcePrefix>\\([A-Za-z0-9-]+\\))(?<id>.+)$/u);\n const normalizedValue = subfieldValue.replace(sourcePrefixRegex, '$<id>');\n debugData(`Normalized ${subfieldValue} to ${normalizedValue}`);\n return normalizedValue;\n }\n\n function normalizeSidSubfieldValue(subfieldValue) {\n debugData(`Normalizing ${subfieldValue}`);\n const normalizeAwayRegex = (/[- ]/u);\n return subfieldValue.replace(normalizeAwayRegex, '');\n }\n\n }\n }\n }\n}\n\nexport function bibMelindaIds(record) {\n // Melinda's SRU-index melinda.melindaid includes f001 controlnumbers and old Melinda-IDs from f035z's for all non-deleted Melinda-records\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:bibMelindaIds');\n const debugData = debug.extend('data');\n debug(`Creating queries for MelindaIds`);\n\n // Note: Melinda-ID's for search queries are created just from records f035a's and f035z's\n // Both (FI-MELINDA)- and FCC-prefixed forms are found\n // f001 controlnumber is not currently included, even if record's f003 is FI-MELINDA\n const melindaIds = getMelindaIdsF035(record);\n\n debugData(`Unique identifiers (${melindaIds.length}): ${JSON.stringify(melindaIds)}`);\n\n if (melindaIds.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n return toQueries(melindaIds, 'melinda.melindaid');\n}\n\n\n// bibHostComponents returns host id from the first subfield $w of first field f773, see test-fixtures 04 and 05\n// bibHostComponents should search all 773 $ws for possible host id, but what should it do in case of multiple host ids?\nexport function bibHostComponents(record) {\n const id = getHostId();\n return id ? [`melinda.partsofhost=${id}`] : [];\n\n function getHostId() {\n const [field] = record.get(/^773$/u);\n\n if (field) {\n const {value} = field.subfields.find(({code}) => code === 'w') || {};\n\n if (value && (/^\\(FI-MELINDA\\)/u).test(value)) {\n return value.replace(/^\\(FI-MELINDA\\)/u, '');\n }\n\n if (value && (/^\\(FIN01\\)/u).test(value)) {\n return value.replace(/^\\(FIN01\\)/u, '');\n }\n\n return false;\n }\n return false;\n }\n}\n\nexport function bibTitle(record) {\n const title = getTitle();\n\n if (title) {\n const formatted = title\n .replace(/[^\\w\\s\\p{Alphabetic}]/gu, '')\n .trim()\n .slice(0, 30)\n .trim();\n\n // Prevent too many matches by having a minimum length requirement\n return formatted.length >= 5 ? [`dc.title=\"^${formatted}*\"`] : [];\n }\n\n return [];\n\n function getTitle() {\n const [field] = record.get(/^245$/u);\n\n if (field) {\n return field.subfields\n .filter(({code}) => ['a', 'b'].includes(code))\n .map(({value}) => value)\n .join('');\n }\n return false;\n }\n}\n\n// eslint-disable-next-line max-statements\nexport function bibStandardIdentifiers(record) {\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:bibStandardIdentifiers');\n const debugData = debug.extend('data');\n debug(`Creating queries for standard identifiers`);\n\n const fields = record.get(/^(?<def>020|022|024)$/u);\n const identifiers = [].concat(...fields.map(toIdentifiers));\n const uniqueIdentifiers = [...new Set(identifiers)];\n\n debugData(`Standard identifier fields: ${JSON.stringify(fields)}`);\n debugData(`Identifiers (${identifiers.length}): ${JSON.stringify(identifiers)}`);\n debugData(`Unique identifiers (${uniqueIdentifiers.length}): ${JSON.stringify(uniqueIdentifiers)}`);\n\n if (uniqueIdentifiers.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n return toQueries(uniqueIdentifiers, 'dc.identifier');\n\n function toIdentifiers({tag, subfields}) {\n const issnIsbnReqExp = (/^[A-Za-z0-9-]+$/u);\n const otherIdReqExp = (/^[A-Za-z0-9-:]+$/u);\n\n if (tag === '022') {\n return subfields\n .filter(sub => ['a', 'z', 'y'].includes(sub.code) && issnIsbnReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n\n if (tag === '020') {\n return subfields\n .filter(sub => ['a', 'z'].includes(sub.code) && issnIsbnReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n\n return subfields\n .filter(sub => ['a', 'z'].includes(sub.code) && otherIdReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n}\n"],"file":"bib.js"}
1
+ {"version":3,"sources":["../../../src/candidate-search/query-list/bib.js"],"names":["bibSourceIds","record","debug","debugData","extend","fSids","get","length","JSON","stringify","toSidQueries","sidStrings","getSidStrings","sidQueries","map","toSidString","filter","nonEmptySid","field","createSidString","sfC","sfB","cleanedSfC","removeSourcePrefix","normalizeSidSubfieldValue","cleanedSfB","concat","subfieldValue","sourcePrefixRegex","normalizedValue","replace","normalizeAwayRegex","bibMelindaIds","melindaIds","bibHostComponents","id","getHostId","value","subfields","find","code","test","bibTitle","title","getTitle","formatted","trim","slice","includes","join","bibStandardIdentifiers","fields","identifiers","toIdentifiers","uniqueIdentifiers","Set","tag","issnIsbnReqExp","otherIdReqExp","sub","undefined"],"mappings":";;;;;;;;;;;AA4BA;;AACA;;AACA;;;;AA7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMO,SAASA,YAAT,CAAsBC,MAAtB,EAA8B;AAEnC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQE,QAAMC,KAAK,GAAG,oBAAkB,qEAAlB,CAAd;AACA,QAAMC,SAAS,GAAGD,KAAK,CAACE,MAAN,CAAa,MAAb,CAAlB,CA3BmC,CA4BnC;;AAEAF,EAAAA,KAAK,CAAE,iCAAF,CAAL;AAEA,QAAMG,KAAK,GAAGJ,MAAM,CAACK,GAAP,CAAW,KAAX,CAAd;AACAH,EAAAA,SAAS,CAAE,eAAcE,KAAK,CAACE,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAeJ,KAAf,CAAsB,EAAxD,CAAT;AAEA,SAAOA,KAAK,CAACE,MAAN,GAAe,CAAf,GAAmBG,YAAY,CAACL,KAAD,CAA/B,GAAyC,EAAhD;;AAEA,WAASK,YAAT,CAAsBL,KAAtB,EAA6B;AAC3BH,IAAAA,KAAK,CAAE,wCAAF,CAAL;AAEA,UAAMS,UAAU,GAAGC,aAAa,CAACP,KAAD,CAAhC;;AAEA,QAAIM,UAAU,CAACJ,MAAX,GAAoB,CAAxB,EAA2B;AACzBL,MAAAA,KAAK,CAAE,2CAAF,CAAL;AACA,aAAO,EAAP;AACD;;AAED,UAAMW,UAAU,GAAG,qCAAUF,UAAV,EAAsB,kBAAtB,CAAnB;AAEA,WAAOE,UAAP;;AAEA,aAASD,aAAT,CAAuBP,KAAvB,EAA8B;AAC5BH,MAAAA,KAAK,CAAE,qCAAF,CAAL,CAD4B,CAG5B;;AACA,YAAMS,UAAU,GAAGN,KAAK,CAACS,GAAN,CAAUC,WAAV,EAAuBC,MAAvB,CAA8BC,WAAW,IAAIA,WAA7C,CAAnB;AACA,aAAON,UAAP;;AAEA,eAASI,WAAT,CAAqBG,KAArB,EAA4B;AAC1BhB,QAAAA,KAAK,CAAE,6BAAF,CAAL;AAEA,eAAO,mDAA+BgB,KAA/B,IAAwCC,eAAe,CAACD,KAAD,CAAvD,GAAiE,EAAxE;;AAEA,iBAASC,eAAT,CAAyBD,KAAzB,EAAgC;AAC9BhB,UAAAA,KAAK,CAAE,8BAAF,CAAL;AACA,gBAAM,CAACkB,GAAD,IAAQ,sCAAkBF,KAAlB,EAAyB,GAAzB,CAAd;AACA,gBAAM,CAACG,GAAD,IAAQ,sCAAkBH,KAAlB,EAAyB,GAAzB,CAAd;AAEA,gBAAMI,UAAU,GAAGC,kBAAkB,CAACC,yBAAyB,CAACJ,GAAD,CAA1B,CAArC;AACA,gBAAMK,UAAU,GAAGD,yBAAyB,CAACH,GAAD,CAA5C;AAEAlB,UAAAA,SAAS,CAAE,GAAEK,IAAI,CAACC,SAAL,CAAeW,GAAf,CAAoB,MAAKZ,IAAI,CAACC,SAAL,CAAeY,GAAf,CAAoB,EAAjD,CAAT;AACA,iBAAOC,UAAU,CAACI,MAAX,CAAkBD,UAAlB,CAAP;AACD;;AAED,iBAASF,kBAAT,CAA4BI,aAA5B,EAA2C;AACzC,gBAAMC,iBAAiB,GAAI,gDAA3B;AACA,gBAAMC,eAAe,GAAGF,aAAa,CAACG,OAAd,CAAsBF,iBAAtB,EAAyC,OAAzC,CAAxB;AACAzB,UAAAA,SAAS,CAAE,cAAawB,aAAc,OAAME,eAAgB,EAAnD,CAAT;AACA,iBAAOA,eAAP;AACD;;AAED,iBAASL,yBAAT,CAAmCG,aAAnC,EAAkD;AAChDxB,UAAAA,SAAS,CAAE,eAAcwB,aAAc,EAA9B,CAAT;AACA,gBAAMI,kBAAkB,GAAI,OAA5B;AACA,iBAAOJ,aAAa,CAACG,OAAd,CAAsBC,kBAAtB,EAA0C,EAA1C,CAAP;AACD;AAEF;AACF;AACF;AACF;;AAEM,SAASC,aAAT,CAAuB/B,MAAvB,EAA+B;AACpC;AAEA,QAAMC,KAAK,GAAG,oBAAkB,wEAAlB,CAAd;AACA,QAAMC,SAAS,GAAGD,KAAK,CAACE,MAAN,CAAa,MAAb,CAAlB;AACAF,EAAAA,KAAK,CAAE,iCAAF,CAAL,CALoC,CAOpC;AACA;AACA;;AACA,QAAM+B,UAAU,GAAG,sCAAkBhC,MAAlB,CAAnB;AAEAE,EAAAA,SAAS,CAAE,uBAAsB8B,UAAU,CAAC1B,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAewB,UAAf,CAA2B,EAA1E,CAAT;;AAEA,MAAIA,UAAU,CAAC1B,MAAX,GAAoB,CAAxB,EAA2B;AACzBL,IAAAA,KAAK,CAAE,2CAAF,CAAL;AACA,WAAO,EAAP;AACD;;AAED,SAAO,qCAAU+B,UAAV,EAAsB,mBAAtB,CAAP;AACD,C,CAGD;AACA;;;AACO,SAASC,iBAAT,CAA2BjC,MAA3B,EAAmC;AACxC,QAAMkC,EAAE,GAAGC,SAAS,EAApB;AACA,SAAOD,EAAE,GAAG,CAAE,uBAAsBA,EAAG,EAA3B,CAAH,GAAmC,EAA5C;;AAEA,WAASC,SAAT,GAAqB;AACnB,UAAM,CAAClB,KAAD,IAAUjB,MAAM,CAACK,GAAP,CAAW,QAAX,CAAhB;;AAEA,QAAIY,KAAJ,EAAW;AACT,YAAM;AAACmB,QAAAA;AAAD,UAAUnB,KAAK,CAACoB,SAAN,CAAgBC,IAAhB,CAAqB,CAAC;AAACC,QAAAA;AAAD,OAAD,KAAYA,IAAI,KAAK,GAA1C,KAAkD,EAAlE;;AAEA,UAAIH,KAAK,IAAK,kBAAD,CAAqBI,IAArB,CAA0BJ,KAA1B,CAAb,EAA+C;AAC7C,eAAOA,KAAK,CAACP,OAAN,CAAc,kBAAd,EAAkC,EAAlC,CAAP;AACD;;AAED,UAAIO,KAAK,IAAK,aAAD,CAAgBI,IAAhB,CAAqBJ,KAArB,CAAb,EAA0C;AACxC,eAAOA,KAAK,CAACP,OAAN,CAAc,aAAd,EAA6B,EAA7B,CAAP;AACD;;AAED,aAAO,KAAP;AACD;;AACD,WAAO,KAAP;AACD;AACF,C,CAED;AACA;AACA;AACA;AACA;;;AAEO,SAASY,QAAT,CAAkBzC,MAAlB,EAA0B;AAC/B,QAAM0C,KAAK,GAAGC,QAAQ,EAAtB;;AAEA,MAAID,KAAJ,EAAW;AACT,UAAME,SAAS,GAAGF,KAAK,CACpBb,OADe,CACP,yBADO,EACoB,EADpB,EAEhB;AAFgB,KAGfA,OAHe,CAGP,MAHO,EAGC,GAHD,EAIfgB,IAJe,GAKfC,KALe,CAKT,CALS,EAKN,EALM,EAMfD,IANe,EAAlB,CADS,CAST;;AACA,WAAOD,SAAS,CAACtC,MAAV,IAAoB,CAApB,GAAwB,CAAE,cAAasC,SAAU,IAAzB,CAAxB,GAAwD,EAA/D;AACD;;AAED,SAAO,EAAP;;AAEA,WAASD,QAAT,GAAoB;AAClB,UAAM,CAAC1B,KAAD,IAAUjB,MAAM,CAACK,GAAP,CAAW,QAAX,CAAhB;;AAEA,QAAIY,KAAJ,EAAW;AACT,aAAOA,KAAK,CAACoB,SAAN,CACJtB,MADI,CACG,CAAC;AAACwB,QAAAA;AAAD,OAAD,KAAY,CAAC,GAAD,EAAM,GAAN,EAAWQ,QAAX,CAAoBR,IAApB,CADf,EAEJ1B,GAFI,CAEA,CAAC;AAACuB,QAAAA;AAAD,OAAD,KAAaA,KAFb,EAGL;AAHK,OAIJY,IAJI,CAIC,GAJD,CAAP;AAKD;;AACD,WAAO,KAAP;AACD;AACF,C,CAED;;;AACO,SAASC,sBAAT,CAAgCjD,MAAhC,EAAwC;AAE7C,QAAMC,KAAK,GAAG,oBAAkB,iFAAlB,CAAd;AACA,QAAMC,SAAS,GAAGD,KAAK,CAACE,MAAN,CAAa,MAAb,CAAlB;AACAF,EAAAA,KAAK,CAAE,2CAAF,CAAL;AAEA,QAAMiD,MAAM,GAAGlD,MAAM,CAACK,GAAP,CAAW,wBAAX,CAAf;AACA,QAAM8C,WAAW,GAAG,GAAG1B,MAAH,CAAU,GAAGyB,MAAM,CAACrC,GAAP,CAAWuC,aAAX,CAAb,CAApB;AACA,QAAMC,iBAAiB,GAAG,CAAC,GAAG,IAAIC,GAAJ,CAAQH,WAAR,CAAJ,CAA1B;AAEAjD,EAAAA,SAAS,CAAE,+BAA8BK,IAAI,CAACC,SAAL,CAAe0C,MAAf,CAAuB,EAAvD,CAAT;AACAhD,EAAAA,SAAS,CAAE,gBAAeiD,WAAW,CAAC7C,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAe2C,WAAf,CAA4B,EAArE,CAAT;AACAjD,EAAAA,SAAS,CAAE,uBAAsBmD,iBAAiB,CAAC/C,MAAO,MAAKC,IAAI,CAACC,SAAL,CAAe6C,iBAAf,CAAkC,EAAxF,CAAT;;AAEA,MAAIA,iBAAiB,CAAC/C,MAAlB,GAA2B,CAA/B,EAAkC;AAChCL,IAAAA,KAAK,CAAE,2CAAF,CAAL;AACA,WAAO,EAAP;AACD;;AAED,SAAO,qCAAUoD,iBAAV,EAA6B,eAA7B,CAAP;;AAEA,WAASD,aAAT,CAAuB;AAACG,IAAAA,GAAD;AAAMlB,IAAAA;AAAN,GAAvB,EAAyC;AACvC,UAAMmB,cAAc,GAAI,kBAAxB;AACA,UAAMC,aAAa,GAAI,mBAAvB;;AAEA,QAAIF,GAAG,KAAK,KAAZ,EAAmB;AACjB,aAAOlB,SAAS,CACbtB,MADI,CACG2C,GAAG,IAAI,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,EAAgBX,QAAhB,CAAyBW,GAAG,CAACnB,IAA7B,KAAsCiB,cAAc,CAAChB,IAAf,CAAoBkB,GAAG,CAACtB,KAAxB,CAAtC,IAAwEsB,GAAG,CAACtB,KAAJ,KAAcuB,SADhG,EAEJ9C,GAFI,CAEA,CAAC;AAACuB,QAAAA;AAAD,OAAD,KAAaA,KAFb,CAAP;AAGD;;AAED,QAAImB,GAAG,KAAK,KAAZ,EAAmB;AACjB,aAAOlB,SAAS,CACbtB,MADI,CACG2C,GAAG,IAAI,CAAC,GAAD,EAAM,GAAN,EAAWX,QAAX,CAAoBW,GAAG,CAACnB,IAAxB,KAAiCiB,cAAc,CAAChB,IAAf,CAAoBkB,GAAG,CAACtB,KAAxB,CAAjC,IAAmEsB,GAAG,CAACtB,KAAJ,KAAcuB,SAD3F,EAEJ9C,GAFI,CAEA,CAAC;AAACuB,QAAAA;AAAD,OAAD,KAAaA,KAFb,CAAP;AAGD;;AAED,WAAOC,SAAS,CACbtB,MADI,CACG2C,GAAG,IAAI,CAAC,GAAD,EAAM,GAAN,EAAWX,QAAX,CAAoBW,GAAG,CAACnB,IAAxB,KAAiCkB,aAAa,CAACjB,IAAd,CAAmBkB,GAAG,CAACtB,KAAvB,CAAjC,IAAkEsB,GAAG,CAACtB,KAAJ,KAAcuB,SAD1F,EAEJ9C,GAFI,CAEA,CAAC;AAACuB,MAAAA;AAAD,KAAD,KAAaA,KAFb,CAAP;AAGD;AACF","sourcesContent":["\n/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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*/\nimport createDebugLogger from 'debug';\nimport {toQueries} from '../candidate-search-utils';\nimport {getMelindaIdsF035, validateSidFieldSubfieldCounts, getSubfieldValues} from '../../matching-utils';\n\n\nexport function bibSourceIds(record) {\n\n /* Melinda's SRU-index melinda.sourceid includes source IDs from SID fields in Melinda records\n SID-fields in Melinda have sf $c with local id and sf $b with a code for the local db:\n\n SID__ $c 123457 $b helka\n SID__ $c (ANDL100020)1077305 $b sata\n SID__ $c VER999999 $ FI-KV\n SID__ $c /10024/508126 $ REPO_THESEUS\n\n In melinda.sourceid -index case is kept, sourceprefixes in brackets and hyphens are normalized away:\n Note: slashes are not normalized away, but a SRU-search-string including slashes needs to be quoted\n\n 1234567helka\n 1077305sata\n VER999999FIKV\n /10024/508126REPO_THESEUS\n\n Note: All Melinda records that have a matching records in a local db do NOT have SID for that local records,\n existence of a SID field depends on how the record has been added to Melinda and how it has been handled\n afterwards. SIDs are also not reliably maintained. A record might or might not have a SID for a local db\n after the matching record is removed from the local db.\n\n */\n\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:source-ids');\n const debugData = debug.extend('data');\n //const debugInfo = debug.extend('info');\n\n debug(`Creating queries for sourceid's`);\n\n const fSids = record.get('SID');\n debugData(`SID-fields (${fSids.length}): ${JSON.stringify(fSids)}`);\n\n return fSids.length > 0 ? toSidQueries(fSids) : [];\n\n function toSidQueries(fSids) {\n debug(`Creating actual queries for sourceid's`);\n\n const sidStrings = getSidStrings(fSids);\n\n if (sidStrings.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n const sidQueries = toQueries(sidStrings, 'melinda.sourceid');\n\n return sidQueries;\n\n function getSidStrings(fSids) {\n debug(`Getting Sid strings from SID fields`);\n\n // Map SID fields to valid sidStrings, filter out empty strings\n const sidStrings = fSids.map(toSidString).filter(nonEmptySid => nonEmptySid);\n return sidStrings;\n\n function toSidString(field) {\n debug(`Getting string from a field`);\n\n return validateSidFieldSubfieldCounts(field) ? createSidString(field) : '';\n\n function createSidString(field) {\n debug(`Creating string from a field`);\n const [sfC] = getSubfieldValues(field, 'c');\n const [sfB] = getSubfieldValues(field, 'b');\n\n const cleanedSfC = removeSourcePrefix(normalizeSidSubfieldValue(sfC));\n const cleanedSfB = normalizeSidSubfieldValue(sfB);\n\n debugData(`${JSON.stringify(sfC)} + ${JSON.stringify(sfB)}`);\n return cleanedSfC.concat(cleanedSfB);\n }\n\n function removeSourcePrefix(subfieldValue) {\n const sourcePrefixRegex = (/^(?<sourcePrefix>\\([A-Za-z0-9-]+\\))(?<id>.+)$/u);\n const normalizedValue = subfieldValue.replace(sourcePrefixRegex, '$<id>');\n debugData(`Normalized ${subfieldValue} to ${normalizedValue}`);\n return normalizedValue;\n }\n\n function normalizeSidSubfieldValue(subfieldValue) {\n debugData(`Normalizing ${subfieldValue}`);\n const normalizeAwayRegex = (/[- ]/u);\n return subfieldValue.replace(normalizeAwayRegex, '');\n }\n\n }\n }\n }\n}\n\nexport function bibMelindaIds(record) {\n // Melinda's SRU-index melinda.melindaid includes f001 controlnumbers and old Melinda-IDs from f035z's for all non-deleted Melinda-records\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:bibMelindaIds');\n const debugData = debug.extend('data');\n debug(`Creating queries for MelindaIds`);\n\n // Note: Melinda-ID's for search queries are created just from records f035a's and f035z's\n // Both (FI-MELINDA)- and FCC-prefixed forms are found\n // f001 controlnumber is not currently included, even if record's f003 is FI-MELINDA\n const melindaIds = getMelindaIdsF035(record);\n\n debugData(`Unique identifiers (${melindaIds.length}): ${JSON.stringify(melindaIds)}`);\n\n if (melindaIds.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n return toQueries(melindaIds, 'melinda.melindaid');\n}\n\n\n// bibHostComponents returns host id from the first subfield $w of first field f773, see test-fixtures 04 and 05\n// bibHostComponents should search all 773 $ws for possible host id, but what should it do in case of multiple host ids?\nexport function bibHostComponents(record) {\n const id = getHostId();\n return id ? [`melinda.partsofhost=${id}`] : [];\n\n function getHostId() {\n const [field] = record.get(/^773$/u);\n\n if (field) {\n const {value} = field.subfields.find(({code}) => code === 'w') || {};\n\n if (value && (/^\\(FI-MELINDA\\)/u).test(value)) {\n return value.replace(/^\\(FI-MELINDA\\)/u, '');\n }\n\n if (value && (/^\\(FIN01\\)/u).test(value)) {\n return value.replace(/^\\(FIN01\\)/u, '');\n }\n\n return false;\n }\n return false;\n }\n}\n\n// SRU search dc.title with a search phrase starting with ^ maps currently in Melinda to\n// (probably) to *headings* index TIT\n// Headings index TIT drops articles etc. from the start of the title according to the filing indicator\n// Currently filing indicator is not implemented - if the title starts with an article and the Melinda\n// record is correctly catalogued using a filing indicator -> dc.title search won't match\n\nexport function bibTitle(record) {\n const title = getTitle();\n\n if (title) {\n const formatted = title\n .replace(/[^\\w\\s\\p{Alphabetic}]/gu, '')\n // Clean up concurrent spaces from fe. subfield changes\n .replace(/ +/gu, ' ')\n .trim()\n .slice(0, 30)\n .trim();\n\n // Prevent too many matches by having a minimum length requirement\n return formatted.length >= 5 ? [`dc.title=\"^${formatted}*\"`] : [];\n }\n\n return [];\n\n function getTitle() {\n const [field] = record.get(/^245$/u);\n\n if (field) {\n return field.subfields\n .filter(({code}) => ['a', 'b'].includes(code))\n .map(({value}) => value)\n // In Melinda's index subfield separators are indexed as ' '\n .join(' ');\n }\n return false;\n }\n}\n\n// eslint-disable-next-line max-statements\nexport function bibStandardIdentifiers(record) {\n\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:candidate-search:query:bibStandardIdentifiers');\n const debugData = debug.extend('data');\n debug(`Creating queries for standard identifiers`);\n\n const fields = record.get(/^(?<def>020|022|024)$/u);\n const identifiers = [].concat(...fields.map(toIdentifiers));\n const uniqueIdentifiers = [...new Set(identifiers)];\n\n debugData(`Standard identifier fields: ${JSON.stringify(fields)}`);\n debugData(`Identifiers (${identifiers.length}): ${JSON.stringify(identifiers)}`);\n debugData(`Unique identifiers (${uniqueIdentifiers.length}): ${JSON.stringify(uniqueIdentifiers)}`);\n\n if (uniqueIdentifiers.length < 1) {\n debug(`No identifiers found, no queries created.`);\n return [];\n }\n\n return toQueries(uniqueIdentifiers, 'dc.identifier');\n\n function toIdentifiers({tag, subfields}) {\n const issnIsbnReqExp = (/^[A-Za-z0-9-]+$/u);\n const otherIdReqExp = (/^[A-Za-z0-9-:]+$/u);\n\n if (tag === '022') {\n return subfields\n .filter(sub => ['a', 'z', 'y'].includes(sub.code) && issnIsbnReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n\n if (tag === '020') {\n return subfields\n .filter(sub => ['a', 'z'].includes(sub.code) && issnIsbnReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n\n return subfields\n .filter(sub => ['a', 'z'].includes(sub.code) && otherIdReqExp.test(sub.value) && sub.value !== undefined)\n .map(({value}) => value);\n }\n}\n"],"file":"bib.js"}
@@ -10,9 +10,9 @@ var _marcRecord = require("@natlibfi/marc-record");
10
10
 
11
11
  var generators = _interopRequireWildcard(require("./bib"));
12
12
 
13
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
14
 
15
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
16
 
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/candidate-search/query-list/bib.spec.js"],"names":["describe","path","__dirname","useMetadataFile","fixura","reader","READERS","JSON","callback","type","inputRecord","expectedQuery","enabled","generate","generators","record","MarcRecord","subfieldValues","to","eql"],"mappings":";;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;;;;;AAhCA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCAA,QAAQ,CAAC,kCAAD,EAAqC,MAAM;AACjD,wBAAc;AACZC,IAAAA,IAAI,EAAE,CAACC,SAAD,EAAY,IAAZ,EAAkB,IAAlB,EAAwB,IAAxB,EAA8B,eAA9B,EAA+C,kBAA/C,EAAmE,YAAnE,EAAiF,KAAjF,CADM;AAEZC,IAAAA,eAAe,EAAE,IAFL;AAGZC,IAAAA,MAAM,EAAE;AACNC,MAAAA,MAAM,EAAEC,gBAAQC;AADV,KAHI;AAMZC,IAAAA,QAAQ,EAAE,CAAC;AAACC,MAAAA,IAAD;AAAOC,MAAAA,WAAP;AAAoBC,MAAAA,aAApB;AAAmCC,MAAAA,OAAO,GAAG;AAA7C,KAAD,KAAwD;AAChE,YAAMC,QAAQ,GAAGC,UAAU,CAACL,IAAD,CAA3B;AACA,YAAMM,MAAM,GAAG,IAAIC,sBAAJ,CAAeN,WAAf,EAA4B;AAACO,QAAAA,cAAc,EAAE;AAAjB,OAA5B,CAAf;;AAEA,UAAI,CAACL,OAAL,EAAc;AACZ;AACD;;AAED,wBAAOC,QAAQ,CAACE,MAAD,CAAf,EAAyBG,EAAzB,CAA4BC,GAA5B,CAAgCR,aAAhC;AACD;AAfW,GAAd;AAiBD,CAlBO,CAAR","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 generateTests from '@natlibfi/fixugen';\nimport {READERS} from '@natlibfi/fixura';\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport * as generators from './bib';\n\ndescribe('candidate-search/query-list/bib/', () => {\n generateTests({\n path: [__dirname, '..', '..', '..', 'test-fixtures', 'candidate-search', 'query-list', 'bib'],\n useMetadataFile: true,\n fixura: {\n reader: READERS.JSON\n },\n callback: ({type, inputRecord, expectedQuery, enabled = true}) => {\n const generate = generators[type];\n const record = new MarcRecord(inputRecord, {subfieldValues: false});\n\n if (!enabled) {\n return;\n }\n\n expect(generate(record)).to.eql(expectedQuery);\n }\n });\n});\n"],"file":"bib.spec.js"}
1
+ {"version":3,"sources":["../../../src/candidate-search/query-list/bib.spec.js"],"names":["describe","path","__dirname","useMetadataFile","fixura","reader","READERS","JSON","callback","type","inputRecord","expectedQuery","enabled","generate","generators","record","MarcRecord","subfieldValues","to","eql"],"mappings":";;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;;;;;AAhCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQAA,QAAQ,CAAC,kCAAD,EAAqC,MAAM;AACjD,wBAAc;AACZC,IAAAA,IAAI,EAAE,CAACC,SAAD,EAAY,IAAZ,EAAkB,IAAlB,EAAwB,IAAxB,EAA8B,eAA9B,EAA+C,kBAA/C,EAAmE,YAAnE,EAAiF,KAAjF,CADM;AAEZC,IAAAA,eAAe,EAAE,IAFL;AAGZC,IAAAA,MAAM,EAAE;AACNC,MAAAA,MAAM,EAAEC,gBAAQC;AADV,KAHI;AAMZC,IAAAA,QAAQ,EAAE,CAAC;AAACC,MAAAA,IAAD;AAAOC,MAAAA,WAAP;AAAoBC,MAAAA,aAApB;AAAmCC,MAAAA,OAAO,GAAG;AAA7C,KAAD,KAAwD;AAChE,YAAMC,QAAQ,GAAGC,UAAU,CAACL,IAAD,CAA3B;AACA,YAAMM,MAAM,GAAG,IAAIC,sBAAJ,CAAeN,WAAf,EAA4B;AAACO,QAAAA,cAAc,EAAE;AAAjB,OAA5B,CAAf;;AAEA,UAAI,CAACL,OAAL,EAAc;AACZ;AACD;;AAED,wBAAOC,QAAQ,CAACE,MAAD,CAAf,EAAyBG,EAAzB,CAA4BC,GAA5B,CAAgCR,aAAhC;AACD;AAfW,GAAd;AAiBD,CAlBO,CAAR","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 generateTests from '@natlibfi/fixugen';\nimport {READERS} from '@natlibfi/fixura';\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport * as generators from './bib';\n\ndescribe('candidate-search/query-list/bib/', () => {\n generateTests({\n path: [__dirname, '..', '..', '..', 'test-fixtures', 'candidate-search', 'query-list', 'bib'],\n useMetadataFile: true,\n fixura: {\n reader: READERS.JSON\n },\n callback: ({type, inputRecord, expectedQuery, enabled = true}) => {\n const generate = generators[type];\n const record = new MarcRecord(inputRecord, {subfieldValues: false});\n\n if (!enabled) {\n return;\n }\n\n expect(generate(record)).to.eql(expectedQuery);\n }\n });\n});\n"],"file":"bib.spec.js"}
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.searchTypes = void 0;
6
+ exports.searchTypes = exports.default = void 0;
7
7
 
8
8
  var bib = _interopRequireWildcard(require("./bib"));
9
9
 
10
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
10
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
11
11
 
12
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
12
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
13
13
 
14
14
  /**
15
15
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/candidate-search/query-list/index.js"],"names":["searchTypes","bib","standardIdentifiers","hostComponents","title","melindaId","sourceIds","record","searchSpec","extractors","map","generateQueryExtractor","cb","flat","type","Error"],"mappings":";;;;;;;AA4BA;;;;;;AA5BA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BO,MAAMA,WAAW,GAAG;AACzBC,EAAAA,GAAG,EAAE;AACHC,IAAAA,mBAAmB,EAAE,wBADlB;AAEHC,IAAAA,cAAc,EAAE,mBAFb;AAGHC,IAAAA,KAAK,EAAE,UAHJ;AAIHC,IAAAA,SAAS,EAAE,eAJR;AAKHC,IAAAA,SAAS,EAAE;AALR;AADoB,CAApB;;;eAUQ,CAACC,MAAD,EAASC,UAAT,KAAwB;AACrC,QAAMC,UAAU,GAAG,EAAC,GAAGR;AAAJ,GAAnB;AAEA,SAAOO,UAAU,CACdE,GADI,CACAC,sBADA,EAEJD,GAFI,CAEAE,EAAE,IAAIA,EAAE,CAACL,MAAD,CAFR,EAGJM,IAHI,EAAP;;AAKA,WAASF,sBAAT,CAAgCG,IAAhC,EAAsC;AACpC,QAAIL,UAAU,CAACK,IAAD,CAAd,EAAsB;AACpB,aAAOL,UAAU,CAACK,IAAD,CAAjB;AACD;;AAED,UAAM,IAAIC,KAAJ,CAAW,wBAAuBD,IAAK,EAAvC,CAAN;AACD;AACF,C","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 * as bib from './bib';\n\nexport const searchTypes = {\n bib: {\n standardIdentifiers: 'bibStandardIdentifiers',\n hostComponents: 'bibHostComponents',\n title: 'bibTitle',\n melindaId: 'bibMelindaIds',\n sourceIds: 'bibSourceIds'\n }\n};\n\nexport default (record, searchSpec) => {\n const extractors = {...bib};\n\n return searchSpec\n .map(generateQueryExtractor)\n .map(cb => cb(record))\n .flat();\n\n function generateQueryExtractor(type) {\n if (extractors[type]) {\n return extractors[type];\n }\n\n throw new Error(`Unknown search type: ${type}`);\n }\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../../../src/candidate-search/query-list/index.js"],"names":["searchTypes","bib","standardIdentifiers","hostComponents","title","melindaId","sourceIds","record","searchSpec","extractors","map","generateQueryExtractor","cb","flat","type","Error"],"mappings":";;;;;;;AA4BA;;;;;;AA5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIO,MAAMA,WAAW,GAAG;AACzBC,EAAAA,GAAG,EAAE;AACHC,IAAAA,mBAAmB,EAAE,wBADlB;AAEHC,IAAAA,cAAc,EAAE,mBAFb;AAGHC,IAAAA,KAAK,EAAE,UAHJ;AAIHC,IAAAA,SAAS,EAAE,eAJR;AAKHC,IAAAA,SAAS,EAAE;AALR;AADoB,CAApB;;;eAUQ,CAACC,MAAD,EAASC,UAAT,KAAwB;AACrC,QAAMC,UAAU,GAAG,EAAC,GAAGR;AAAJ,GAAnB;AAEA,SAAOO,UAAU,CACdE,GADI,CACAC,sBADA,EAEJD,GAFI,CAEAE,EAAE,IAAIA,EAAE,CAACL,MAAD,CAFR,EAGJM,IAHI,EAAP;;AAKA,WAASF,sBAAT,CAAgCG,IAAhC,EAAsC;AACpC,QAAIL,UAAU,CAACK,IAAD,CAAd,EAAsB;AACpB,aAAOL,UAAU,CAACK,IAAD,CAAjB;AACD;;AAED,UAAM,IAAIC,KAAJ,CAAW,wBAAuBD,IAAK,EAAvC,CAAN;AACD;AACF,C","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 * as bib from './bib';\n\nexport const searchTypes = {\n bib: {\n standardIdentifiers: 'bibStandardIdentifiers',\n hostComponents: 'bibHostComponents',\n title: 'bibTitle',\n melindaId: 'bibMelindaIds',\n sourceIds: 'bibSourceIds'\n }\n};\n\nexport default (record, searchSpec) => {\n const extractors = {...bib};\n\n return searchSpec\n .map(generateQueryExtractor)\n .map(cb => cb(record))\n .flat();\n\n function generateQueryExtractor(type) {\n if (extractors[type]) {\n return extractors[type];\n }\n\n throw new Error(`Unknown search type: ${type}`);\n }\n};\n"],"file":"index.js"}
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.matchDetection = exports.candidateSearch = exports.default = void 0;
6
+ exports.matchDetection = exports.default = exports.candidateSearch = void 0;
7
7
 
8
8
  var _debug = _interopRequireDefault(require("debug"));
9
9
 
@@ -15,9 +15,9 @@ var matchDetection = _interopRequireWildcard(require("./match-detection"));
15
15
 
16
16
  exports.matchDetection = matchDetection;
17
17
 
18
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
18
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
19
 
20
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
21
 
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["detection","detectionOptions","search","searchOptions","maxMatches","maxCandidates","debug","detect","record","iterate","initialState","matches","candidateCount","records","state","length","queriesLeft","matchResult","iterateRecords","newMatches","concat","maxCandidatesRetrieved","candidate","candidateRecord","id","candidateId","match","probability","slice"],"mappings":";;;;;;;AA4BA;;AACA;;;;AACA;;;;;;;;;;AA9BA;;;;;;;;;;;;;;;;;;;;;;;;;;;eAkCe,CAAC;AAACA,EAAAA,SAAS,EAAEC,gBAAZ;AAA8BC,EAAAA,MAAM,EAAEC,aAAtC;AAAqDC,EAAAA,UAAU,GAAG,CAAlE;AAAqEC,EAAAA,aAAa,GAAG;AAArF,CAAD,KAA8F;AAC3G,QAAMC,KAAK,GAAG,oBAAkB,yCAAlB,CAAd;AACA,QAAMC,MAAM,GAAG,4BAAyBN,gBAAzB,CAAf;AAEA,SAAOO,MAAM,IAAI;AACf,UAAMN,MAAM,GAAG,6BAAsB,EAAC,GAAGC,aAAJ;AAAmBK,MAAAA;AAAnB,KAAtB,CAAf;AACA,WAAOC,OAAO,EAAd,CAFe,CAIf;;AACA,mBAAeA,OAAf,CAAuBC,YAAY,GAAG,EAAtC,EAA0CC,OAAO,GAAG,EAApD,EAAwDC,cAAc,GAAG,CAAzE,EAA4E;AAC1E,YAAM;AAACC,QAAAA,OAAD;AAAU,WAAGC;AAAb,UAAsB,MAAMZ,MAAM,CAACQ,YAAD,CAAxC;;AAEA,UAAIG,OAAO,CAACE,MAAR,GAAiB,CAAjB,IAAsBD,KAAK,CAACE,WAAN,GAAoB,CAA9C,EAAiD;AAC/CV,QAAAA,KAAK,CAAE,YAAWO,OAAO,CAACE,MAAO,yBAA5B,CAAL;AAEA,cAAME,WAAW,GAAGC,cAAc,CAACL,OAAD,CAAlC;;AAEA,YAAII,WAAJ,EAAiB;AACf,gBAAME,UAAU,GAAGR,OAAO,CAACS,MAAR,CAAeH,WAAf,CAAnB;;AAEA,cAAIE,UAAU,CAACJ,MAAX,KAAsBX,UAA1B,EAAsC;AACpC,mBAAOe,UAAP;AACD;;AAED,iBAAOE,sBAAsB,KAAKF,UAAL,GAAkBV,OAAO,CAACK,KAAD,EAAQK,UAAR,EAAoBP,cAAc,GAAGC,OAAO,CAACE,MAA7C,CAAtD;AACD;;AAED,eAAOM,sBAAsB,KAAKV,OAAL,GAAeF,OAAO,CAACK,KAAD,EAAQH,OAAR,EAAiBC,cAAc,GAAGC,OAAO,CAACE,MAA1C,CAAnD;AACD;;AAEDT,MAAAA,KAAK,CAAE,kDAAiDK,OAAO,CAACI,MAAO,EAAlE,CAAL;AACA,aAAOJ,OAAP;;AAEA,eAASU,sBAAT,GAAkC;AAChC,YAAIT,cAAc,GAAGC,OAAO,CAACE,MAAzB,GAAkCV,aAAtC,EAAqD;AACnDC,UAAAA,KAAK,CAAE,4EAAF,CAAL;AACA,iBAAO,IAAP;AACD;AACF;;AAED,eAASY,cAAT,CAAwBL,OAAxB,EAAiC;AAC/B,cAAM,CAACS,SAAD,IAAcT,OAApB;;AAEA,YAAIS,SAAJ,EAAe;AACb,gBAAM;AAACd,YAAAA,MAAM,EAAEe,eAAT;AAA0BC,YAAAA,EAAE,EAAEC;AAA9B,cAA6CH,SAAnD;AACA,gBAAM;AAACI,YAAAA,KAAD;AAAQC,YAAAA;AAAR,cAAuBpB,MAAM,CAACC,MAAD,EAASe,eAAT,CAAnC;;AAEA,cAAIG,KAAJ,EAAW;AACT,mBAAO;AACLC,cAAAA,WADK;AAELL,cAAAA,SAAS,EAAE;AACTE,gBAAAA,EAAE,EAAEC,WADK;AAETjB,gBAAAA,MAAM,EAAEe;AAFC;AAFN,aAAP;AAOD;;AAED,iBAAOL,cAAc,CAACL,OAAO,CAACe,KAAR,CAAc,CAAd,CAAD,CAArB;AACD;AACF;AACF;AACF,GAzDD;AA0DD,C","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport createSearchInterface, * as candidateSearch from './candidate-search';\nimport createDetectionInterface, * as matchDetection from './match-detection';\n\nexport {candidateSearch, matchDetection};\n\nexport default ({detection: detectionOptions, search: searchOptions, maxMatches = 1, maxCandidates = 25}) => {\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:index');\n const detect = createDetectionInterface(detectionOptions);\n\n return record => {\n const search = createSearchInterface({...searchOptions, record});\n return iterate();\n\n // eslint-disable-next-line max-statements\n async function iterate(initialState = {}, matches = [], candidateCount = 0) {\n const {records, ...state} = await search(initialState);\n\n if (records.length > 0 || state.queriesLeft > 0) {\n debug(`Checking ${records.length} candidates for matches`);\n\n const matchResult = iterateRecords(records);\n\n if (matchResult) {\n const newMatches = matches.concat(matchResult);\n\n if (newMatches.length === maxMatches) {\n return newMatches;\n }\n\n return maxCandidatesRetrieved() ? newMatches : iterate(state, newMatches, candidateCount + records.length);\n }\n\n return maxCandidatesRetrieved() ? matches : iterate(state, matches, candidateCount + records.length);\n }\n\n debug(`No (more) candidate records to check, matches: ${matches.length}`);\n return matches;\n\n function maxCandidatesRetrieved() {\n if (candidateCount + records.length > maxCandidates) {\n debug(`Stopped searching because maximum number of candidates have been retrieved`);\n return true;\n }\n }\n\n function iterateRecords(records) {\n const [candidate] = records;\n\n if (candidate) {\n const {record: candidateRecord, id: candidateId} = candidate;\n const {match, probability} = detect(record, candidateRecord);\n\n if (match) {\n return {\n probability,\n candidate: {\n id: candidateId,\n record: candidateRecord\n }\n };\n }\n\n return iterateRecords(records.slice(1));\n }\n }\n }\n };\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["detection","detectionOptions","search","searchOptions","maxMatches","maxCandidates","debug","detect","record","iterate","initialState","matches","candidateCount","records","state","length","queriesLeft","matchResult","iterateRecords","newMatches","concat","maxCandidatesRetrieved","candidate","candidateRecord","id","candidateId","match","probability","slice"],"mappings":";;;;;;;AA4BA;;AACA;;;;AACA;;;;;;;;;;AA9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;eAQe,CAAC;AAACA,EAAAA,SAAS,EAAEC,gBAAZ;AAA8BC,EAAAA,MAAM,EAAEC,aAAtC;AAAqDC,EAAAA,UAAU,GAAG,CAAlE;AAAqEC,EAAAA,aAAa,GAAG;AAArF,CAAD,KAA8F;AAC3G,QAAMC,KAAK,GAAG,oBAAkB,yCAAlB,CAAd;AACA,QAAMC,MAAM,GAAG,4BAAyBN,gBAAzB,CAAf;AAEA,SAAOO,MAAM,IAAI;AACf,UAAMN,MAAM,GAAG,6BAAsB,EAAC,GAAGC,aAAJ;AAAmBK,MAAAA;AAAnB,KAAtB,CAAf;AACA,WAAOC,OAAO,EAAd,CAFe,CAIf;;AACA,mBAAeA,OAAf,CAAuBC,YAAY,GAAG,EAAtC,EAA0CC,OAAO,GAAG,EAApD,EAAwDC,cAAc,GAAG,CAAzE,EAA4E;AAC1E,YAAM;AAACC,QAAAA,OAAD;AAAU,WAAGC;AAAb,UAAsB,MAAMZ,MAAM,CAACQ,YAAD,CAAxC;;AAEA,UAAIG,OAAO,CAACE,MAAR,GAAiB,CAAjB,IAAsBD,KAAK,CAACE,WAAN,GAAoB,CAA9C,EAAiD;AAC/CV,QAAAA,KAAK,CAAE,YAAWO,OAAO,CAACE,MAAO,yBAA5B,CAAL;AAEA,cAAME,WAAW,GAAGC,cAAc,CAACL,OAAD,CAAlC;;AAEA,YAAII,WAAJ,EAAiB;AACf,gBAAME,UAAU,GAAGR,OAAO,CAACS,MAAR,CAAeH,WAAf,CAAnB;;AAEA,cAAIE,UAAU,CAACJ,MAAX,KAAsBX,UAA1B,EAAsC;AACpC,mBAAOe,UAAP;AACD;;AAED,iBAAOE,sBAAsB,KAAKF,UAAL,GAAkBV,OAAO,CAACK,KAAD,EAAQK,UAAR,EAAoBP,cAAc,GAAGC,OAAO,CAACE,MAA7C,CAAtD;AACD;;AAED,eAAOM,sBAAsB,KAAKV,OAAL,GAAeF,OAAO,CAACK,KAAD,EAAQH,OAAR,EAAiBC,cAAc,GAAGC,OAAO,CAACE,MAA1C,CAAnD;AACD;;AAEDT,MAAAA,KAAK,CAAE,kDAAiDK,OAAO,CAACI,MAAO,EAAlE,CAAL;AACA,aAAOJ,OAAP;;AAEA,eAASU,sBAAT,GAAkC;AAChC,YAAIT,cAAc,GAAGC,OAAO,CAACE,MAAzB,GAAkCV,aAAtC,EAAqD;AACnDC,UAAAA,KAAK,CAAE,4EAAF,CAAL;AACA,iBAAO,IAAP;AACD;AACF;;AAED,eAASY,cAAT,CAAwBL,OAAxB,EAAiC;AAC/B,cAAM,CAACS,SAAD,IAAcT,OAApB;;AAEA,YAAIS,SAAJ,EAAe;AACb,gBAAM;AAACd,YAAAA,MAAM,EAAEe,eAAT;AAA0BC,YAAAA,EAAE,EAAEC;AAA9B,cAA6CH,SAAnD;AACA,gBAAM;AAACI,YAAAA,KAAD;AAAQC,YAAAA;AAAR,cAAuBpB,MAAM,CAACC,MAAD,EAASe,eAAT,CAAnC;;AAEA,cAAIG,KAAJ,EAAW;AACT,mBAAO;AACLC,cAAAA,WADK;AAELL,cAAAA,SAAS,EAAE;AACTE,gBAAAA,EAAE,EAAEC,WADK;AAETjB,gBAAAA,MAAM,EAAEe;AAFC;AAFN,aAAP;AAOD;;AAED,iBAAOL,cAAc,CAACL,OAAO,CAACe,KAAR,CAAc,CAAd,CAAD,CAArB;AACD;AACF;AACF;AACF,GAzDD;AA0DD,C","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport createSearchInterface, * as candidateSearch from './candidate-search';\nimport createDetectionInterface, * as matchDetection from './match-detection';\n\nexport {candidateSearch, matchDetection};\n\nexport default ({detection: detectionOptions, search: searchOptions, maxMatches = 1, maxCandidates = 25}) => {\n const debug = createDebugLogger('@natlibfi/melinda-record-matching:index');\n const detect = createDetectionInterface(detectionOptions);\n\n return record => {\n const search = createSearchInterface({...searchOptions, record});\n return iterate();\n\n // eslint-disable-next-line max-statements\n async function iterate(initialState = {}, matches = [], candidateCount = 0) {\n const {records, ...state} = await search(initialState);\n\n if (records.length > 0 || state.queriesLeft > 0) {\n debug(`Checking ${records.length} candidates for matches`);\n\n const matchResult = iterateRecords(records);\n\n if (matchResult) {\n const newMatches = matches.concat(matchResult);\n\n if (newMatches.length === maxMatches) {\n return newMatches;\n }\n\n return maxCandidatesRetrieved() ? newMatches : iterate(state, newMatches, candidateCount + records.length);\n }\n\n return maxCandidatesRetrieved() ? matches : iterate(state, matches, candidateCount + records.length);\n }\n\n debug(`No (more) candidate records to check, matches: ${matches.length}`);\n return matches;\n\n function maxCandidatesRetrieved() {\n if (candidateCount + records.length > maxCandidates) {\n debug(`Stopped searching because maximum number of candidates have been retrieved`);\n return true;\n }\n }\n\n function iterateRecords(records) {\n const [candidate] = records;\n\n if (candidate) {\n const {record: candidateRecord, id: candidateId} = candidate;\n const {match, probability} = detect(record, candidateRecord);\n\n if (match) {\n return {\n probability,\n candidate: {\n id: candidateId,\n record: candidateRecord\n }\n };\n }\n\n return iterateRecords(records.slice(1));\n }\n }\n }\n };\n};\n"],"file":"index.js"}
@@ -10,9 +10,9 @@ var _marcRecord = require("@natlibfi/marc-record");
10
10
 
11
11
  var _ = _interopRequireWildcard(require("."));
12
12
 
13
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
14
 
15
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
16
 
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.spec.js"],"names":["describe","callback","path","__dirname","recurse","fixura","reader","READERS","JSON","getFixture","options","enabled","record","MarcRecord","subfieldValues","expectedMatches","match","formatOptions","matches","formatResults","to","eql","contextFeatures","matchDetection","features","detection","strategy","type","search","maxRecordsPerRequest","detect","map","v","maxMatches","maxCandidates","candidate","probability","id","toObject"],"mappings":";;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;;;;;AAhCA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCAA,QAAQ,CAAC,OAAD,EAAU,MAAM;AACtB,kCAAc;AACZC,IAAAA,QADY;AAEZC,IAAAA,IAAI,EAAE,CAACC,SAAD,EAAY,IAAZ,EAAkB,eAAlB,EAAmC,OAAnC,CAFM;AAGZC,IAAAA,OAAO,EAAE,KAHG;AAIZC,IAAAA,MAAM,EAAE;AACNC,MAAAA,MAAM,EAAEC,gBAAQC;AADV;AAJI,GAAd;;AASA,iBAAeP,QAAf,CAAwB;AAACQ,IAAAA,UAAD;AAAaC,IAAAA,OAAb;AAAsBC,IAAAA,OAAO,GAAG;AAAhC,GAAxB,EAA+D;AAE7D,QAAI,CAACA,OAAL,EAAc;AACZ;AACD;;AAED,UAAMC,MAAM,GAAG,IAAIC,sBAAJ,CAAeJ,UAAU,CAAC,kBAAD,CAAzB,EAA+C;AAACK,MAAAA,cAAc,EAAE;AAAjB,KAA/C,CAAf;AACA,UAAMC,eAAe,GAAGN,UAAU,CAAC,sBAAD,CAAlC;AAEA,UAAMO,KAAK,GAAG,eAAqBC,aAAa,EAAlC,CAAd;AACA,UAAMC,OAAO,GAAG,MAAMF,KAAK,CAACJ,MAAD,CAA3B;AAEA,sBAAOO,aAAa,EAApB,EAAwBC,EAAxB,CAA2BC,GAA3B,CAA+BN,eAA/B;;AAEA,aAASE,aAAT,GAAyB;AACvB,YAAMK,eAAe,GAAGC,iBAAeC,QAAf,CAAwBd,OAAO,CAACe,SAAR,CAAkBC,QAAlB,CAA2BC,IAAnD,CAAxB;AAEA,aAAO,EACL,GAAGjB,OADE;AAELkB,QAAAA,MAAM,EAAE,EACN,GAAGlB,OAAO,CAACkB,MADL;AAENC,UAAAA,oBAAoB,EAAE;AAFhB,SAFH;AAMLJ,QAAAA,SAAS,EAAE,EACT,GAAGf,OAAO,CAACoB,MADF;AAETJ,UAAAA,QAAQ,EAAEhB,OAAO,CAACe,SAAR,CAAkBC,QAAlB,CAA2BF,QAA3B,CAAoCO,GAApC,CAAwCC,CAAC,IAAIV,eAAe,CAACU,CAAD,CAAf,EAA7C;AAFD,SANN;AAULC,QAAAA,UAAU,EAAE,CAVP;AAWLC,QAAAA,aAAa,EAAE;AAXV,OAAP;AAaD;;AAED,aAASf,aAAT,GAAyB;AACvB,aAAOD,OAAO,CAACa,GAAR,CAAY,CAAC;AAACI,QAAAA,SAAD;AAAYC,QAAAA;AAAZ,OAAD,MAA+B;AAChDA,QAAAA,WADgD;AAEhDD,QAAAA,SAAS,EAAE;AACTE,UAAAA,EAAE,EAAEF,SAAS,CAACE,EADL;AAETzB,UAAAA,MAAM,EAAEuB,SAAS,CAACvB,MAAV,CAAiB0B,QAAjB;AAFC;AAFqC,OAA/B,CAAZ,CAAP;AAOD;AACF;AACF,CApDO,CAAR","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 {expect} from 'chai';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen-http-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport createMatchInterface, {matchDetection} from '.';\n\ndescribe('INDEX', () => {\n generateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'index'],\n recurse: false,\n fixura: {\n reader: READERS.JSON\n }\n });\n\n async function callback({getFixture, options, enabled = true}) {\n\n if (!enabled) {\n return;\n }\n\n const record = new MarcRecord(getFixture('inputRecord.json'), {subfieldValues: false});\n const expectedMatches = getFixture('expectedMatches.json');\n\n const match = createMatchInterface(formatOptions());\n const matches = await match(record);\n\n expect(formatResults()).to.eql(expectedMatches);\n\n function formatOptions() {\n const contextFeatures = matchDetection.features[options.detection.strategy.type];\n\n return {\n ...options,\n search: {\n ...options.search,\n maxRecordsPerRequest: 1\n },\n detection: {\n ...options.detect,\n strategy: options.detection.strategy.features.map(v => contextFeatures[v]())\n },\n maxMatches: 2,\n maxCandidates: 1\n };\n }\n\n function formatResults() {\n return matches.map(({candidate, probability}) => ({\n probability,\n candidate: {\n id: candidate.id,\n record: candidate.record.toObject()\n }\n }));\n }\n }\n});\n"],"file":"index.spec.js"}
1
+ {"version":3,"sources":["../src/index.spec.js"],"names":["describe","callback","path","__dirname","recurse","fixura","reader","READERS","JSON","getFixture","options","enabled","record","MarcRecord","subfieldValues","expectedMatches","match","formatOptions","matches","formatResults","to","eql","contextFeatures","matchDetection","features","detection","strategy","type","search","maxRecordsPerRequest","detect","map","v","maxMatches","maxCandidates","candidate","probability","id","toObject"],"mappings":";;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;;;;;AAhCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQAA,QAAQ,CAAC,OAAD,EAAU,MAAM;AACtB,kCAAc;AACZC,IAAAA,QADY;AAEZC,IAAAA,IAAI,EAAE,CAACC,SAAD,EAAY,IAAZ,EAAkB,eAAlB,EAAmC,OAAnC,CAFM;AAGZC,IAAAA,OAAO,EAAE,KAHG;AAIZC,IAAAA,MAAM,EAAE;AACNC,MAAAA,MAAM,EAAEC,gBAAQC;AADV;AAJI,GAAd;;AASA,iBAAeP,QAAf,CAAwB;AAACQ,IAAAA,UAAD;AAAaC,IAAAA,OAAb;AAAsBC,IAAAA,OAAO,GAAG;AAAhC,GAAxB,EAA+D;AAE7D,QAAI,CAACA,OAAL,EAAc;AACZ;AACD;;AAED,UAAMC,MAAM,GAAG,IAAIC,sBAAJ,CAAeJ,UAAU,CAAC,kBAAD,CAAzB,EAA+C;AAACK,MAAAA,cAAc,EAAE;AAAjB,KAA/C,CAAf;AACA,UAAMC,eAAe,GAAGN,UAAU,CAAC,sBAAD,CAAlC;AAEA,UAAMO,KAAK,GAAG,eAAqBC,aAAa,EAAlC,CAAd;AACA,UAAMC,OAAO,GAAG,MAAMF,KAAK,CAACJ,MAAD,CAA3B;AAEA,sBAAOO,aAAa,EAApB,EAAwBC,EAAxB,CAA2BC,GAA3B,CAA+BN,eAA/B;;AAEA,aAASE,aAAT,GAAyB;AACvB,YAAMK,eAAe,GAAGC,iBAAeC,QAAf,CAAwBd,OAAO,CAACe,SAAR,CAAkBC,QAAlB,CAA2BC,IAAnD,CAAxB;AAEA,aAAO,EACL,GAAGjB,OADE;AAELkB,QAAAA,MAAM,EAAE,EACN,GAAGlB,OAAO,CAACkB,MADL;AAENC,UAAAA,oBAAoB,EAAE;AAFhB,SAFH;AAMLJ,QAAAA,SAAS,EAAE,EACT,GAAGf,OAAO,CAACoB,MADF;AAETJ,UAAAA,QAAQ,EAAEhB,OAAO,CAACe,SAAR,CAAkBC,QAAlB,CAA2BF,QAA3B,CAAoCO,GAApC,CAAwCC,CAAC,IAAIV,eAAe,CAACU,CAAD,CAAf,EAA7C;AAFD,SANN;AAULC,QAAAA,UAAU,EAAE,CAVP;AAWLC,QAAAA,aAAa,EAAE;AAXV,OAAP;AAaD;;AAED,aAASf,aAAT,GAAyB;AACvB,aAAOD,OAAO,CAACa,GAAR,CAAY,CAAC;AAACI,QAAAA,SAAD;AAAYC,QAAAA;AAAZ,OAAD,MAA+B;AAChDA,QAAAA,WADgD;AAEhDD,QAAAA,SAAS,EAAE;AACTE,UAAAA,EAAE,EAAEF,SAAS,CAACE,EADL;AAETzB,UAAAA,MAAM,EAAEuB,SAAS,CAACvB,MAAV,CAAiB0B,QAAjB;AAFC;AAFqC,OAA/B,CAAZ,CAAP;AAOD;AACF;AACF,CApDO,CAAR","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 {expect} from 'chai';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen-http-client';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport createMatchInterface, {matchDetection} from '.';\n\ndescribe('INDEX', () => {\n generateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'index'],\n recurse: false,\n fixura: {\n reader: READERS.JSON\n }\n });\n\n async function callback({getFixture, options, enabled = true}) {\n\n if (!enabled) {\n return;\n }\n\n const record = new MarcRecord(getFixture('inputRecord.json'), {subfieldValues: false});\n const expectedMatches = getFixture('expectedMatches.json');\n\n const match = createMatchInterface(formatOptions());\n const matches = await match(record);\n\n expect(formatResults()).to.eql(expectedMatches);\n\n function formatOptions() {\n const contextFeatures = matchDetection.features[options.detection.strategy.type];\n\n return {\n ...options,\n search: {\n ...options.search,\n maxRecordsPerRequest: 1\n },\n detection: {\n ...options.detect,\n strategy: options.detection.strategy.features.map(v => contextFeatures[v]())\n },\n maxMatches: 2,\n maxCandidates: 1\n };\n }\n\n function formatResults() {\n return matches.map(({candidate, probability}) => ({\n probability,\n candidate: {\n id: candidate.id,\n record: candidate.record.toObject()\n }\n }));\n }\n }\n});\n"],"file":"index.spec.js"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/match-detection/features/bib/all-source-ids.js"],"names":["debug","debugData","extend","name","extract","record","fSids","get","length","JSON","stringify","sidFeatures","getSidFeatures","map","toSidFeature","filter","nonEmptySid","field","createSidFeature","sfC","sfB","compare","a","b","matches","sidA","some","sidB","sourceDb","sourceId","mismatches"],"mappings":"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","sourcesContent":["/* eslint-disable max-statements */\n/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport {validateSidFieldSubfieldCounts, getSubfieldValues} from '../../../matching-utils';\n\nconst debug = createDebugLogger('@natlibfi/melinda-record-matching:match-detection:features:all-source-ids');\nconst debugData = debug.extend('data');\n\n/*\n\nSID-fields in Melinda have sf $c with local id and sf $b with a code for the local db:\n\n SID__ $c 123457 $b helka\n SID__ $c (ANDL100020)1077305 $b sata\n SID__ $c VER999999 $ FI-KV\n\nallSourceIds matching feature is formatted as [{sourceDb: \"helka\", sourceId: \"123457\"}, {sourceDb: \"sata\", sourceId: \"(ANDL100020)1077305\"}, {sourceDb: \"FI-KV\", sourceId: \"VER999999\"}]\n- no normalization / prefix deletions etc. in the feature\n\nNote: All Melinda records that have a matching records in a local db do NOT have SID for that local records,\n existence of a SID field depends on how the record has been added to Melinda and how it has been handled\n afterwards. SIDs are also not reliably maintained. A record might or might not have a SID for a local db\n after the matching record is removed from the local db.\n\nRecords with mismatching local ids for matching local db are a strong mismatch.\nRecords with matching local ids for matching local db are a very good match.\n\n*/\n\nexport default () => ({\n name: 'All source IDs',\n extract: record => {\n debug(`Creating match detection features for all local source id's`);\n\n const fSids = record.get('SID');\n debugData(`SID-fields (${fSids.length}): ${JSON.stringify(fSids)}`);\n\n const sidFeatures = getSidFeatures(fSids);\n debugData(`SID-features (${sidFeatures.length}): ${JSON.stringify(sidFeatures)}`);\n\n return sidFeatures;\n\n function getSidFeatures(fSids) {\n debug(`Getting Sid strings from SID fields`);\n\n // Map SID fields to sidFeatures, filter out empty strings\n const sidFeatures = fSids.map(toSidFeature).filter(nonEmptySid => nonEmptySid);\n return sidFeatures;\n\n function toSidFeature(field) {\n debug(`Getting feature from a field`);\n\n return validateSidFieldSubfieldCounts(field) ? createSidFeature(field) : '';\n\n function createSidFeature(field) {\n debug(`Creating feature from a field`);\n const [sfC] = getSubfieldValues(field, 'c');\n const [sfB] = getSubfieldValues(field, 'b');\n\n debugData(`${JSON.stringify(sfC)} + ${JSON.stringify(sfB)}`);\n debugData(`sourceDb: ${sfB}, sourceId: ${sfC}`);\n return {'sourceDb': sfB, 'sourceId': sfC};\n }\n }\n\n }\n\n },\n compare: (a, b) => {\n\n debugData(`Comparing ${JSON.stringify(a)} and ${JSON.stringify(b)}`);\n\n const matches = a.filter(sidA => b.some(sidB => sidA.sourceDb === sidB.sourceDb &&\n sidA.sourceId === sidB.sourceId));\n debugData(`Matches (${matches.length}): ${JSON.stringify(matches)}`);\n\n const mismatches = a.filter(sidA => b.some(sidB => sidA.sourceDb === sidB.sourceDb &&\n sidA.sourceId !== sidB.sourceId));\n debugData(`Mismatches (${mismatches.length}): ${JSON.stringify(mismatches)}`);\n\n // If there's at least one mismatching source ID from matching source db\n if (mismatches.length > 0) {\n return -1;\n }\n\n // If there's at least one matching source ID from matching source db\n if (matches.length > 0) {\n return 1;\n }\n\n // If there are no source IDs with matching sources\n return 0;\n\n }\n});\n"],"file":"all-source-ids.js"}
1
+ {"version":3,"sources":["../../../../src/match-detection/features/bib/all-source-ids.js"],"names":["debug","debugData","extend","name","extract","record","fSids","get","length","JSON","stringify","sidFeatures","getSidFeatures","map","toSidFeature","filter","nonEmptySid","field","createSidFeature","sfC","sfB","compare","a","b","matches","sidA","some","sidB","sourceDb","sourceId","mismatches"],"mappings":"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","sourcesContent":["/* eslint-disable max-statements */\n/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Melinda record matching modules for Javascript\n*\n* Copyright (C) 2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-record-matching-js\n*\n* melinda-record-matching-js 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* melinda-record-matching-js 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 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 createDebugLogger from 'debug';\nimport {validateSidFieldSubfieldCounts, getSubfieldValues} from '../../../matching-utils';\n\nconst debug = createDebugLogger('@natlibfi/melinda-record-matching:match-detection:features:all-source-ids');\nconst debugData = debug.extend('data');\n\n/*\n\nSID-fields in Melinda have sf $c with local id and sf $b with a code for the local db:\n\n SID__ $c 123457 $b helka\n SID__ $c (ANDL100020)1077305 $b sata\n SID__ $c VER999999 $ FI-KV\n\nallSourceIds matching feature is formatted as [{sourceDb: \"helka\", sourceId: \"123457\"}, {sourceDb: \"sata\", sourceId: \"(ANDL100020)1077305\"}, {sourceDb: \"FI-KV\", sourceId: \"VER999999\"}]\n- no normalization / prefix deletions etc. in the feature\n\nNote: All Melinda records that have a matching records in a local db do NOT have SID for that local records,\n existence of a SID field depends on how the record has been added to Melinda and how it has been handled\n afterwards. SIDs are also not reliably maintained. A record might or might not have a SID for a local db\n after the matching record is removed from the local db.\n\nRecords with mismatching local ids for matching local db are a strong mismatch.\nRecords with matching local ids for matching local db are a very good match.\n\n*/\n\nexport default () => ({\n name: 'All source IDs',\n extract: record => {\n debug(`Creating match detection features for all local source id's`);\n\n const fSids = record.get('SID');\n debugData(`SID-fields (${fSids.length}): ${JSON.stringify(fSids)}`);\n\n const sidFeatures = getSidFeatures(fSids);\n debugData(`SID-features (${sidFeatures.length}): ${JSON.stringify(sidFeatures)}`);\n\n return sidFeatures;\n\n function getSidFeatures(fSids) {\n debug(`Getting Sid strings from SID fields`);\n\n // Map SID fields to sidFeatures, filter out empty strings\n const sidFeatures = fSids.map(toSidFeature).filter(nonEmptySid => nonEmptySid);\n return sidFeatures;\n\n function toSidFeature(field) {\n debug(`Getting feature from a field`);\n\n return validateSidFieldSubfieldCounts(field) ? createSidFeature(field) : '';\n\n function createSidFeature(field) {\n debug(`Creating feature from a field`);\n const [sfC] = getSubfieldValues(field, 'c');\n const [sfB] = getSubfieldValues(field, 'b');\n\n debugData(`${JSON.stringify(sfC)} + ${JSON.stringify(sfB)}`);\n debugData(`sourceDb: ${sfB}, sourceId: ${sfC}`);\n return {'sourceDb': sfB, 'sourceId': sfC};\n }\n }\n\n }\n\n },\n compare: (a, b) => {\n\n debugData(`Comparing ${JSON.stringify(a)} and ${JSON.stringify(b)}`);\n\n const matches = a.filter(sidA => b.some(sidB => sidA.sourceDb === sidB.sourceDb &&\n sidA.sourceId === sidB.sourceId));\n debugData(`Matches (${matches.length}): ${JSON.stringify(matches)}`);\n\n const mismatches = a.filter(sidA => b.some(sidB => sidA.sourceDb === sidB.sourceDb &&\n sidA.sourceId !== sidB.sourceId));\n debugData(`Mismatches (${mismatches.length}): ${JSON.stringify(mismatches)}`);\n\n // If there's at least one mismatching source ID from matching source db\n if (mismatches.length > 0) {\n return -1;\n }\n\n // If there's at least one matching source ID from matching source db\n if (matches.length > 0) {\n return 1;\n }\n\n // If there are no source IDs with matching sources\n return 0;\n\n }\n});\n"],"file":"all-source-ids.js"}