| 1 |
import { v4 as uuidv4 } from 'uuid'; |
| 2 |
|
| 3 |
/** |
| 4 |
* Generate universally unique identifier. |
| 5 |
* |
| 6 |
* @returns {string} A universally unique identifier |
| 7 |
*/ |
| 8 |
const uuid = () => { |
| 9 |
return uuidv4(); |
| 10 |
}; |
| 11 |
|
| 12 |
/** |
| 13 |
* Map entry |
| 14 |
* |
| 15 |
* @param {Array} synonyms Array of synonyms. |
| 16 |
* @param {string} id The id, default generated by the application. |
| 17 |
* @returns {object} Map entry |
| 18 |
*/ |
| 19 |
const mapEntry = (synonyms = [], id = '') => { |
| 20 |
return { |
| 21 |
id: id.length ? id : uuidv4(), |
| 22 |
synonyms, |
| 23 |
valid: true, |
| 24 |
}; |
| 25 |
}; |
| 26 |
|
| 27 |
/** |
| 28 |
* Reduce state to Solr spec. |
| 29 |
* |
| 30 |
* @param {object} state Current state. |
| 31 |
* @param {object[]} state.sets Array of synonym sets. |
| 32 |
* @param {object[]} state.alternatives Array of alternative sets. |
| 33 |
* @returns {string} new state |
| 34 |
*/ |
| 35 |
const reduceStateToSolr = ({ sets, alternatives }) => { |
| 36 |
const synonymsList = []; |
| 37 |
|
| 38 |
// Handle sets. |
| 39 |
synonymsList.push('# Defined sets ( equivalent synonyms).'); |
| 40 |
synonymsList.push(...sets.map(({ synonyms }) => synonyms.map(({ value }) => value).join(', '))); |
| 41 |
|
| 42 |
// Handle alternatives. |
| 43 |
synonymsList.push('\r'); |
| 44 |
synonymsList.push('# Defined alternatives (explicit mappings).'); |
| 45 |
synonymsList.push( |
| 46 |
...alternatives.map((alternative) => |
| 47 |
alternative.synonyms.find((item) => item.primary && item.value.length) |
| 48 |
? alternative.synonyms |
| 49 |
.find((item) => item.primary) |
| 50 |
.value.concat(' => ') |
| 51 |
.concat( |
| 52 |
alternative.synonyms |
| 53 |
.filter((i) => !i.primary) |
| 54 |
.map(({ value }) => value) |
| 55 |
.join(', '), |
| 56 |
) |
| 57 |
: false, |
| 58 |
), |
| 59 |
); |
| 60 |
|
| 61 |
return synonymsList.filter(Boolean).join('\n'); |
| 62 |
}; |
| 63 |
|
| 64 |
/** |
| 65 |
* Reduce Solr text file to State. |
| 66 |
* |
| 67 |
* @param {string} solr A string in the Solr parseable synonym format. |
| 68 |
* @param {object} currentState The current sate. |
| 69 |
* @returns {object} State |
| 70 |
*/ |
| 71 |
const reduceSolrToState = (solr, currentState) => { |
| 72 |
/** |
| 73 |
* Format token. |
| 74 |
* |
| 75 |
* @param {string} value The value. |
| 76 |
* @param {boolean} primary Whether it's a primary. |
| 77 |
* @returns {object} Formated token |
| 78 |
*/ |
| 79 |
const formatToken = (value, primary = false) => { |
| 80 |
return { |
| 81 |
label: value, |
| 82 |
value, |
| 83 |
primary, |
| 84 |
}; |
| 85 |
}; |
| 86 |
|
| 87 |
return { |
| 88 |
...currentState, |
| 89 |
...solr.split(/\r?\n/).reduce( |
| 90 |
(newState, line) => { |
| 91 |
if (line.indexOf('#') === 0 || !line.trim().length) { |
| 92 |
return newState; |
| 93 |
} |
| 94 |
|
| 95 |
if (line.indexOf('=>') !== -1) { |
| 96 |
const parts = line.split('=>'); |
| 97 |
return { |
| 98 |
...newState, |
| 99 |
alternatives: [ |
| 100 |
...newState.alternatives, |
| 101 |
mapEntry([ |
| 102 |
formatToken(parts[0].trim(), true), |
| 103 |
...parts[1] |
| 104 |
.split(',') |
| 105 |
.filter((v) => v.trim()) |
| 106 |
.map((token) => formatToken(token.trim())), |
| 107 |
]), |
| 108 |
], |
| 109 |
}; |
| 110 |
} |
| 111 |
|
| 112 |
return { |
| 113 |
...newState, |
| 114 |
sets: [ |
| 115 |
...newState.sets, |
| 116 |
mapEntry([ |
| 117 |
...line |
| 118 |
.split(',') |
| 119 |
.filter((v) => v.trim()) |
| 120 |
.map((token) => formatToken(token.trim())), |
| 121 |
]), |
| 122 |
], |
| 123 |
}; |
| 124 |
}, |
| 125 |
{ alternatives: [], sets: [] }, |
| 126 |
), |
| 127 |
}; |
| 128 |
}; |
| 129 |
|
| 130 |
export { reduceStateToSolr, reduceSolrToState, uuid, mapEntry }; |
| 131 |
|