@inseefr/lunatic 0.3.1-experimental → 0.3.2-experimental

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 (51) hide show
  1. package/lib/index.js +192 -189
  2. package/lib/index.js.map +1 -1
  3. package/package.json +2 -2
  4. package/src/components/component-wrapper/controls/validators/datepicker.js +25 -14
  5. package/src/components/component-wrapper/missing/component.js +37 -17
  6. package/src/components/datepicker/component.js +8 -12
  7. package/src/components/declarations/wrappers/input-declarations-wrapper.js +3 -2
  8. package/src/components/loop-constructor/block/index.js +1 -1
  9. package/src/components/loop-constructor/index.js +1 -1
  10. package/src/components/loop-constructor/roster/index.js +1 -1
  11. package/src/components/loop-constructor/wrapper/body-component.js +3 -0
  12. package/src/components/loop-constructor/wrapper/build-components.js +33 -33
  13. package/src/components/loop-constructor/wrapper/index.js +1 -1
  14. package/src/components/suggester/components/panel/option-container.js +1 -1
  15. package/src/components/suggester/suggester-wrapper.js +3 -3
  16. package/src/components/table/table.js +3 -1
  17. package/src/stories/loop-constructor/README.md +27 -27
  18. package/src/stories/loop-constructor/data-input-forced.json +64 -64
  19. package/src/stories/loop-constructor/data-input.json +100 -100
  20. package/src/stories/loop-constructor/data-loop-forced.json +66 -66
  21. package/src/stories/loop-constructor/data-loop-static-forced.json +66 -66
  22. package/src/stories/loop-constructor/data-loop-static.json +81 -81
  23. package/src/stories/loop-constructor/data-loop.json +81 -81
  24. package/src/stories/loop-constructor/data-roster-forced.json +68 -68
  25. package/src/stories/loop-constructor/data-roster.json +83 -83
  26. package/src/stories/loop-constructor/loop-constructor.stories.js +180 -180
  27. package/src/stories/questionnaire/arithmetic-management.json +47 -0
  28. package/src/stories/questionnaire/logement-queen.json +23390 -22706
  29. package/src/stories/questionnaire/questionnaire.stories.js +14 -14
  30. package/src/stories/suggester/data.json +4 -1
  31. package/src/stories/suggester/suggester-workers.stories.js +4 -1
  32. package/src/stories/utils/orchestrator-split.js +117 -0
  33. package/src/tests/utils/to-expose/handler/results/res-input-edited.json +1 -1
  34. package/src/tests/utils/to-expose/state/state.spec.js +59 -59
  35. package/src/utils/lib/index.js +1 -0
  36. package/src/utils/lib/pagination/navigation/shared.js +5 -5
  37. package/src/utils/lib/splitting.js +110 -0
  38. package/src/utils/suggester-workers/commons-tokenizer/create-entity-tokenizer.js +4 -2
  39. package/src/utils/suggester-workers/commons-tokenizer/filters/{filter-accents-to-lower.js → filter-accents.js} +2 -2
  40. package/src/utils/suggester-workers/commons-tokenizer/filters/{filter-accents-to-lower.spec.js → filter-accents.spec.js} +1 -1
  41. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.js +27 -1
  42. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.js +10 -0
  43. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.spec.js +12 -0
  44. package/src/utils/suggester-workers/commons-tokenizer/index.js +1 -1
  45. package/src/utils/to-expose/handler.js +47 -28
  46. package/src/utils/to-expose/hooks/filter-components.js +106 -106
  47. package/src/utils/to-expose/hooks/index.js +2 -1
  48. package/src/utils/to-expose/hooks/lunatic-split.js +407 -0
  49. package/src/utils/to-expose/hooks/lunatic.js +16 -2
  50. package/src/utils/to-expose/index.js +11 -11
  51. package/src/utils/to-expose/state.js +23 -15
@@ -1,6 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { storiesOf } from '@storybook/react';
3
3
  import Orchestrator from '../utils/orchestrator';
4
+ import OrchestratorSplit from '../utils/orchestrator-split';
4
5
  import { titleDecorator } from 'utils/lib';
5
6
  import calcVar from './calc-var';
6
7
  import logement from './logement';
@@ -10,6 +11,7 @@ import logementSequence from './logement-sequence';
10
11
  import dataLogement from './data-logement';
11
12
  import simpsons from './simpsons';
12
13
  import arithmetic from './arithmetic';
14
+ import arithmeticManagement from './arithmetic-management';
13
15
  import updateExternalQuestionnaire from './update-external/questionnaire';
14
16
  import updateExternalData from './update-external/data';
15
17
  import { positioningOptions, featuresOptions } from '../utils/options';
@@ -35,26 +37,24 @@ def.addWithJSX('Calculated Variables', () => (
35
37
  />
36
38
  ));
37
39
 
38
- def.addWithJSX('Logement', () => (
40
+ def.addWithJSX('Arithmetic', () => (
39
41
  <Orchestrator
40
42
  id="props"
41
- source={logement}
42
- missing={boolean('Missing', false)}
43
+ source={arithmetic}
43
44
  features={select('Features', featuresOptions, ['VTL', 'MD'])}
44
45
  positioning={select('Items positioning', positioningOptions, 'DEFAULT')}
45
46
  disabled={boolean('Disabled', false)}
46
- focused={boolean('Focused', false)}
47
- management={boolean('Management', false)}
48
47
  />
49
48
  ));
50
49
 
51
- def.addWithJSX('Arithmetic', () => (
50
+ def.addWithJSX('Arithmetic - Management', () => (
52
51
  <Orchestrator
53
52
  id="props"
54
- source={arithmetic}
53
+ source={arithmeticManagement}
55
54
  features={select('Features', featuresOptions, ['VTL', 'MD'])}
56
55
  positioning={select('Items positioning', positioningOptions, 'DEFAULT')}
57
56
  disabled={boolean('Disabled', false)}
57
+ management={boolean('Management', true)}
58
58
  />
59
59
  ));
60
60
 
@@ -79,7 +79,7 @@ const paginated = storiesOf('Questionnaire/Paginated', module).addDecorator(
79
79
  );
80
80
 
81
81
  paginated.addWithJSX('Calculated Variables', () => (
82
- <Orchestrator
82
+ <OrchestratorSplit
83
83
  id="props"
84
84
  source={calcVar}
85
85
  missing={boolean('Missing', false)}
@@ -93,7 +93,7 @@ paginated.addWithJSX('Calculated Variables', () => (
93
93
  ));
94
94
 
95
95
  paginated.addWithJSX('Logement', () => (
96
- <Orchestrator
96
+ <OrchestratorSplit
97
97
  id="props"
98
98
  source={logement}
99
99
  data={dataLogement}
@@ -110,11 +110,11 @@ paginated.addWithJSX('Logement', () => (
110
110
  ));
111
111
 
112
112
  paginated.addWithJSX('Logement - Queen', () => (
113
- <Orchestrator
113
+ <OrchestratorSplit
114
114
  id="props"
115
115
  source={logementQueen}
116
116
  data={dataLogement}
117
- missing={boolean('Missing', false)}
117
+ missing={boolean('Missing', true)}
118
118
  activeGoNextForMissing={boolean('Active go next for missing', false)}
119
119
  features={select('Features', featuresOptions, ['VTL', 'MD'])}
120
120
  positioning={select('Items positioning', positioningOptions, 'DEFAULT')}
@@ -126,7 +126,7 @@ paginated.addWithJSX('Logement - Queen', () => (
126
126
  ));
127
127
 
128
128
  paginated.addWithJSX('Logement - Sequence', () => (
129
- <Orchestrator
129
+ <OrchestratorSplit
130
130
  id="props"
131
131
  source={logementSequence}
132
132
  data={dataLogement}
@@ -142,7 +142,7 @@ paginated.addWithJSX('Logement - Sequence', () => (
142
142
  ));
143
143
 
144
144
  paginated.addWithJSX('Logement - S2', () => (
145
- <Orchestrator
145
+ <OrchestratorSplit
146
146
  id="props"
147
147
  source={logementS2}
148
148
  missing={boolean('Missing', false)}
@@ -157,7 +157,7 @@ paginated.addWithJSX('Logement - S2', () => (
157
157
  ));
158
158
 
159
159
  paginated.addWithJSX('Simpsons', () => (
160
- <Orchestrator
160
+ <OrchestratorSplit
161
161
  id="props"
162
162
  source={simpsons}
163
163
  missing={boolean('Missing', false)}
@@ -46,7 +46,10 @@
46
46
  "name": "libelle2",
47
47
  "rules": ["[\\w]+"],
48
48
  "language": "French",
49
- "synonyms": { "st": ["saint"] },
49
+ "synonyms": [
50
+ { "source": "saint", "target": ["st"] },
51
+ { "source": "oph", "target": ["renaud", "nicolas"] }
52
+ ],
50
53
  "stemmer": false
51
54
  },
52
55
  { "name": "code" }
@@ -53,7 +53,10 @@ const bailleursSociaux = {
53
53
  rules: ['[\\w]+'],
54
54
  language: 'French',
55
55
  stemmer: false,
56
- synonyms: { saint: ['st'], sainte: ['ste'] },
56
+ synonyms: [
57
+ { source: 'saint', target: ['st'] },
58
+ { source: 'oph', target: ['renaud', 'nicolas'] },
59
+ ],
57
60
  },
58
61
  { name: 'code' },
59
62
  ],
@@ -0,0 +1,117 @@
1
+ import React, { useEffect } from 'react';
2
+ import * as lunatic from 'components';
3
+ import './custom-lunatic.scss';
4
+
5
+ function getStoreInfoRequired() {
6
+ return {};
7
+ }
8
+
9
+ const OrchestratorForStories = ({
10
+ source,
11
+ suggesters,
12
+ data = {},
13
+ management = false,
14
+ pagination = false,
15
+ modalForControls = false,
16
+ features = ['VTL'],
17
+ bindings: initialBindings,
18
+ initialPage = '1',
19
+ getStoreInfo = getStoreInfoRequired,
20
+ missing = false,
21
+ shortcut = false,
22
+ activeGoNextForMissing = false,
23
+ suggesterFetcher,
24
+ autoSuggesterLoading,
25
+ addExternal,
26
+ ...rest
27
+ }) => {
28
+ const preferences = management
29
+ ? ['COLLECTED', 'FORCED', 'EDITED']
30
+ : ['COLLECTED'];
31
+ const savingType = management ? 'EDITED' : 'COLLECTED';
32
+ const {
33
+ handleChange,
34
+ handleExternals,
35
+ components,
36
+ bindings,
37
+ pagination: {
38
+ goNext,
39
+ goPrevious,
40
+ page,
41
+ setPage,
42
+ maxPage,
43
+ isFirstPage,
44
+ isLastPage,
45
+ flow,
46
+ },
47
+ } = lunatic.useLunaticSplit(source, data, {
48
+ suggesters,
49
+ savingType,
50
+ preferences,
51
+ features,
52
+ management,
53
+ pagination,
54
+ modalForControls,
55
+ initialPage,
56
+ suggesterFetcher,
57
+ autoSuggesterLoading,
58
+ });
59
+
60
+ useEffect(() => {
61
+ handleExternals(addExternal);
62
+ }, [addExternal, handleExternals]);
63
+
64
+ const Button = lunatic.Button;
65
+
66
+ const missingStrategy = (b) => goNext(null, b);
67
+
68
+ return (
69
+ <div className="container">
70
+ <div className="components">
71
+ {components.map((q) => {
72
+ const { id, componentType } = q;
73
+ const Component = lunatic[componentType];
74
+ const { storeName } = q;
75
+
76
+ return (
77
+ <div className="lunatic lunatic-component" key={`component-${id}`}>
78
+ <Component
79
+ {...rest}
80
+ {...q}
81
+ {...getStoreInfo(storeName)}
82
+ handleChange={handleChange}
83
+ preferences={preferences}
84
+ savingType={savingType}
85
+ management={management}
86
+ features={features}
87
+ bindings={{ ...bindings, ...initialBindings }}
88
+ currentPage={page}
89
+ setPage={setPage}
90
+ flow={flow}
91
+ pagination={pagination}
92
+ missing={missing}
93
+ shortcut={shortcut}
94
+ missingStrategy={activeGoNextForMissing && missingStrategy}
95
+ />
96
+ </div>
97
+ );
98
+ })}
99
+ </div>
100
+ {pagination && (
101
+ <>
102
+ <div className="pagination">
103
+ <Button
104
+ onClick={goPrevious}
105
+ disabled={isFirstPage}
106
+ value="Previous"
107
+ />
108
+ <Button onClick={goNext} disabled={isLastPage} value="Next" />
109
+ </div>
110
+ <div>{`Page : ${page}/${maxPage}`}</div>
111
+ </>
112
+ )}
113
+ </div>
114
+ );
115
+ };
116
+
117
+ export default OrchestratorForStories;
@@ -98,7 +98,7 @@
98
98
  "CALCULATED": {
99
99
  "Test": {
100
100
  "expression": "inputOk || \" ok\"",
101
- "value": "My input ok",
101
+ "value": "My new input ok",
102
102
  "bindingDependencies": ["inputOk"]
103
103
  }
104
104
  },
@@ -1,59 +1,59 @@
1
- import {
2
- getState,
3
- getCollectedState,
4
- getCollectedStateByValueType,
5
- getBindings,
6
- } from 'utils/to-expose/state';
7
- import questionnaire from './questionnaire';
8
- import * as R from './results';
9
-
10
- describe('state', () => {
11
- describe('getState', () => {
12
- it('should return empty object', () => {
13
- expect(getState([])).toEqual({
14
- COLLECTED: {},
15
- CALCULATED: {},
16
- EXTERNAL: {},
17
- });
18
- });
19
- it('should return object', () => {
20
- expect(getState(questionnaire)).toEqual(R.state);
21
- });
22
- });
23
- describe('getCollectedState', () => {
24
- it('should return empty object', () => {
25
- expect(getCollectedState([])).toEqual({});
26
- });
27
- it('should return object', () => {
28
- expect(getCollectedState(questionnaire)).toEqual(R.collectedState);
29
- });
30
- });
31
- describe('getCollectedStateByValueType', () => {
32
- it('should return empty object', () => {
33
- expect(getCollectedStateByValueType([])('')).toEqual({});
34
- expect(getCollectedStateByValueType(questionnaire)('')).toEqual({});
35
- });
36
- it('should return object', () => {
37
- expect(getCollectedStateByValueType(questionnaire)('COLLECTED')).toEqual(
38
- R.collectedStateCollected
39
- );
40
- expect(getCollectedStateByValueType(questionnaire)('FORCED')).toEqual(
41
- R.collectedStateForced
42
- );
43
- expect(
44
- getCollectedStateByValueType(questionnaire)('COLLECTED', true)
45
- ).toEqual(R.collectedStateCollectedWithNull);
46
- expect(
47
- getCollectedStateByValueType(questionnaire)('FORCED', true)
48
- ).toEqual(R.collectedStateForcedWithNull);
49
- });
50
- });
51
- describe('getBindings', () => {
52
- it('should return empty object', () => {
53
- expect(getBindings([])).toEqual({});
54
- });
55
- it('should return object', () => {
56
- expect(getBindings(questionnaire)).toEqual(R.bindingsResults);
57
- });
58
- });
59
- });
1
+ import {
2
+ getState,
3
+ getCollectedState,
4
+ getCollectedStateByValueType,
5
+ getBindings,
6
+ } from 'utils/to-expose/state';
7
+ import questionnaire from './questionnaire';
8
+ import * as R from './results';
9
+
10
+ describe('state', () => {
11
+ describe('getState', () => {
12
+ it('should return empty object', () => {
13
+ expect(getState([])).toEqual({
14
+ COLLECTED: {},
15
+ CALCULATED: {},
16
+ EXTERNAL: {},
17
+ });
18
+ });
19
+ it('should return object', () => {
20
+ expect(getState(questionnaire)).toEqual(R.state);
21
+ });
22
+ });
23
+ describe('getCollectedState', () => {
24
+ it('should return empty object', () => {
25
+ expect(getCollectedState([])).toEqual({});
26
+ });
27
+ it('should return object', () => {
28
+ expect(getCollectedState(questionnaire)).toEqual(R.collectedState);
29
+ });
30
+ });
31
+ describe('getCollectedStateByValueType', () => {
32
+ it('should return empty object', () => {
33
+ expect(getCollectedStateByValueType([])('')).toEqual({});
34
+ expect(getCollectedStateByValueType(questionnaire)('')).toEqual({});
35
+ });
36
+ it('should return object', () => {
37
+ expect(getCollectedStateByValueType(questionnaire)('COLLECTED')).toEqual(
38
+ R.collectedStateCollected
39
+ );
40
+ expect(getCollectedStateByValueType(questionnaire)('FORCED')).toEqual(
41
+ R.collectedStateForced
42
+ );
43
+ expect(
44
+ getCollectedStateByValueType(questionnaire)('COLLECTED', true)
45
+ ).toEqual(R.collectedStateCollectedWithNull);
46
+ expect(
47
+ getCollectedStateByValueType(questionnaire)('FORCED', true)
48
+ ).toEqual(R.collectedStateForcedWithNull);
49
+ });
50
+ });
51
+ describe('getBindings', () => {
52
+ it('should return empty object', () => {
53
+ expect(getBindings([])).toEqual({});
54
+ });
55
+ it('should return object', () => {
56
+ expect(getBindings(questionnaire)).toEqual(R.bindingsResults);
57
+ });
58
+ });
59
+ });
@@ -18,3 +18,4 @@ export * from './table';
18
18
  export * from './tooltip';
19
19
  export { isFunction } from './function';
20
20
  export { createObjectEvent } from './event';
21
+ export * from './splitting';
@@ -221,28 +221,28 @@ const getIterations = ({ component, bindings, featuresWithoutMD }) => {
221
221
  export const splitPage = (currentPage = '1', depth) => {
222
222
  const currentPageWithDepth = depth
223
223
  ? currentPage
224
- .split('.')
224
+ ?.split('.')
225
225
  .slice(0, depth + 1) // scoped
226
226
  .join('.')
227
227
  : currentPage;
228
228
 
229
229
  const currentPageWithoutIteration = currentPageWithDepth
230
- .split('#')
230
+ ?.split('#')
231
231
  .slice(0, -1)
232
232
  .join('#');
233
233
 
234
234
  const currentPageWithoutAnyIteration = currentPageWithDepth
235
- .split('.')
235
+ ?.split('.')
236
236
  .map((e) => e.split('#')[0])
237
237
  .join('.');
238
238
 
239
239
  const currentRootPage = currentPageWithoutIteration
240
- .split('.')
240
+ ?.split('.')
241
241
  .slice(0, -1)
242
242
  .join('.');
243
243
 
244
244
  const [currentComponentIndex, currentIteration] = currentPageWithDepth
245
- .split('.')
245
+ ?.split('.')
246
246
  .pop()
247
247
  .split('#')
248
248
  .map((c) => parseInt(c, 10));
@@ -0,0 +1,110 @@
1
+ const getBindingsDependenciesCalculated = (variables) => {
2
+ if (!variables) return {};
3
+ return variables.reduce(
4
+ (acc, { variableType, name, bindingDependencies, shapeFrom }) => {
5
+ if (variableType === 'CALCULATED')
6
+ if (shapeFrom && bindingDependencies)
7
+ return { ...acc, [name]: [...bindingDependencies, shapeFrom] };
8
+ if (bindingDependencies) return { ...acc, [name]: bindingDependencies };
9
+ if (shapeFrom) return { ...acc, [name]: [shapeFrom] };
10
+ return acc;
11
+ },
12
+ {}
13
+ );
14
+ };
15
+
16
+ const getAllDeps = (deps) => (variablesCalcDeps) => {
17
+ if (!deps || !variablesCalcDeps) return [];
18
+ return deps.reduce((acc, dep) => {
19
+ const depsOfDep = variablesCalcDeps[dep];
20
+ if (Array.isArray(depsOfDep)) {
21
+ return [...acc, dep, ...getAllDeps(depsOfDep)(variablesCalcDeps)];
22
+ }
23
+ return [...acc, dep];
24
+ }, []);
25
+ };
26
+
27
+ const getNestedVars =
28
+ (components = []) =>
29
+ (variables) => {
30
+ const variableCalculatedDependencies =
31
+ getBindingsDependenciesCalculated(variables);
32
+ const depsVarsTemp = components
33
+ .reduce((acc, comp) => {
34
+ const { bindingDependencies, conditionFilter } = comp;
35
+ var superBind = [];
36
+ if (Array.isArray(bindingDependencies))
37
+ superBind = [...superBind, ...bindingDependencies];
38
+ if (Array.isArray(conditionFilter?.bindingDependencies))
39
+ superBind = [...superBind, ...conditionFilter.bindingDependencies];
40
+ return [...acc, ...superBind];
41
+ }, [])
42
+ .filter((v, i, a) => a.indexOf(v) === i);
43
+ return getAllDeps(depsVarsTemp)(variableCalculatedDependencies).filter(
44
+ (v, i, a) => a.indexOf(v) === i
45
+ );
46
+ };
47
+
48
+ const getUsefullVariablesFromSource = (variables) => (nestedVars) => {
49
+ if (!variables) return true;
50
+ return variables.filter(({ variableType, name }) => {
51
+ if (variableType === 'CALCULATED' && !nestedVars.includes(name))
52
+ return false;
53
+ if (variableType === 'COLLECTED' && !nestedVars.includes(name))
54
+ return false;
55
+ return true;
56
+ });
57
+ };
58
+
59
+ export const getSplitQuestionnaireSource = (source) => {
60
+ const { components, variables, ...rest } = source;
61
+ var split = [];
62
+ var currentComponents = [];
63
+ components.map((c, i) => {
64
+ const { componentType } = c;
65
+ // splitting by Sequence or Loop
66
+ if (componentType === 'Sequence' || componentType === 'Loop') {
67
+ if (currentComponents.length > 0) split.push(currentComponents);
68
+ currentComponents = [c];
69
+ } else {
70
+ currentComponents.push(c);
71
+ }
72
+ return null;
73
+ });
74
+ if (currentComponents.length > 0) split.push(currentComponents);
75
+ return split.reduce((prev, currentSource) => {
76
+ const firstPage = currentSource[0].page;
77
+ const maxPage = currentSource[currentSource.length - 1].page;
78
+ const nestedVars = getNestedVars(currentSource)(variables);
79
+ const newVariables = getUsefullVariablesFromSource(variables)(nestedVars);
80
+
81
+ return [
82
+ ...prev,
83
+ {
84
+ ...rest,
85
+ variables: newVariables,
86
+ firstPage,
87
+ maxPage,
88
+ components: currentSource,
89
+ },
90
+ ];
91
+ }, []);
92
+ };
93
+
94
+ export const getRootPageInSources = (sources) => {
95
+ return sources.map((source) => {
96
+ const { components } = source;
97
+ return components.reduce((acc, { page }) => {
98
+ if (page) return [...acc, page];
99
+ return acc;
100
+ }, []);
101
+ });
102
+ };
103
+
104
+ export const mergeStateData = (oldData, newData) => {
105
+ return {
106
+ COLLECTED: { ...oldData.COLLECTED, ...newData.COLLECTED },
107
+ CALCULATED: { ...oldData.CALCULATED, ...newData.CALCULATED },
108
+ EXTERNAL: { ...oldData.EXTERNAL, ...newData.EXTERNAL },
109
+ };
110
+ };
@@ -3,7 +3,8 @@ import { composeFilters, createFilterStopWords } from './filters';
3
3
  import filterStemmer from './filters/filter-stemmer';
4
4
  import filterLength from './filters/filter-length';
5
5
  import filterSynonyms from './filters/filter-synonyms';
6
- import filterAccentsToLower from './filters/filter-accents-to-lower';
6
+ import filterAccents from './filters/filter-accents';
7
+ import filterToLower from './filters/filter-to-lower';
7
8
  import filterDouble from './filters/filter-double';
8
9
 
9
10
  function createMapFieldsTokenizer(fields, filters) {
@@ -20,9 +21,10 @@ function createFilterTokens(fields, stopWords) {
20
21
  const filterStopWords = createFilterStopWords(stopWords);
21
22
  const getFilters = composeFilters(
22
23
  filterDouble,
23
- filterAccentsToLower,
24
+ filterAccents,
24
25
  filterStemmer,
25
26
  filterSynonyms,
27
+ filterToLower,
26
28
  filterStopWords,
27
29
  filterLength
28
30
  );
@@ -1,6 +1,6 @@
1
1
  import removeAccents from 'remove-accents';
2
2
 
3
- function filterAccentsToLower(tokens = []) {
3
+ function filterAccents(tokens = []) {
4
4
  return tokens.map(function (token) {
5
5
  if (typeof token === 'string') {
6
6
  return removeAccents(token).toLowerCase();
@@ -9,4 +9,4 @@ function filterAccentsToLower(tokens = []) {
9
9
  });
10
10
  }
11
11
 
12
- export default filterAccentsToLower;
12
+ export default filterAccents;
@@ -1,4 +1,4 @@
1
- import filterATL from './filter-accents-to-lower';
1
+ import filterATL from './filter-accents';
2
2
 
3
3
  describe('filter-length', function () {
4
4
  it('maj accent', function () {
@@ -1,4 +1,6 @@
1
- function filterSynonyms(tokens, { synonyms }) {
1
+ const MAPS_FROM_ARRAY = new Map(); // Pour éviter de recalculer une map à chaque fois
2
+
3
+ function filterFromObject(tokens, synonyms) {
2
4
  return tokens.reduce(function (prec, token) {
3
5
  if (token in synonyms) {
4
6
  return [...prec, token, ...synonyms[token]];
@@ -7,4 +9,28 @@ function filterSynonyms(tokens, { synonyms }) {
7
9
  }, []);
8
10
  }
9
11
 
12
+ function buildSynonymsMap(array) {
13
+ return array.reduce(function (map, { source, target }) {
14
+ return { ...map, [source]: target };
15
+ }, {});
16
+ }
17
+
18
+ function filterFromArray(tokens, synonyms) {
19
+ if (!MAPS_FROM_ARRAY.has(synonyms)) {
20
+ MAPS_FROM_ARRAY.set(synonyms, buildSynonymsMap(synonyms));
21
+ }
22
+ return filterFromObject(tokens, MAPS_FROM_ARRAY.get(synonyms));
23
+ }
24
+
25
+ function filterSynonyms(tokens, { synonyms }) {
26
+ if (Array.isArray(synonyms) && synonyms.length) {
27
+ return filterFromArray(tokens, synonyms);
28
+ }
29
+ if (typeof synonyms === 'object') {
30
+ return filterFromObject(tokens, synonyms);
31
+ }
32
+
33
+ return tokens;
34
+ }
35
+
10
36
  export default filterSynonyms;
@@ -0,0 +1,10 @@
1
+ function filterToLower(tokens) {
2
+ return tokens.map(function (token) {
3
+ if (typeof token === 'string') {
4
+ return token.toLocaleLowerCase();
5
+ }
6
+ return token;
7
+ });
8
+ }
9
+
10
+ export default filterToLower;
@@ -0,0 +1,12 @@
1
+ import filterToLower from './filter-to-lower';
2
+
3
+ describe('filter-to-lower', function () {
4
+ it('UN', function () {
5
+ const tokens = ['UN', 'no'];
6
+ const results = filterToLower(tokens);
7
+ expect(Array.isArray(results)).toBe(true);
8
+ expect(results.length).toBe(2);
9
+ expect(results[0]).toBe('un');
10
+ expect(results[1]).toBe('no');
11
+ });
12
+ });
@@ -4,5 +4,5 @@ export { default as prepareStringIndexation } from './prepare-string-indexation'
4
4
  export { default as filterStemmer } from './filters/filter-stemmer';
5
5
  export { default as filterLength } from './filters/filter-length';
6
6
  export { default as filterDouble } from './filters/filter-double';
7
- export { default as filterAccentsToLower } from './filters/filter-accents-to-lower';
7
+ export { default as filterAccents } from './filters/filter-accents';
8
8
  export { default as getRegExpFromPattern } from './get-regexp-from-pattern';