@legalplace/conditions-runner 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -0
- package/.eslintrc +3 -0
- package/CHANGELOG.md +11 -0
- package/dist/ConditionsRunner.d.ts +19 -0
- package/dist/ConditionsRunner.js +84 -0
- package/dist/ConditionsRunner.test.d.ts +1 -0
- package/dist/ConditionsRunner.test.js +13 -0
- package/dist/DataPopulator.d.ts +29 -0
- package/dist/DataPopulator.js +165 -0
- package/dist/fixtures/inputs-type.json +1542 -0
- package/dist/fixtures/references.json +46030 -0
- package/dist/types/conditions.d.ts +19 -0
- package/jest.config.ts +205 -0
- package/package.json +31 -0
- package/setupJest.ts +8 -0
- package/src/ConditionsRunner.test.ts +15 -0
- package/src/ConditionsRunner.ts +179 -0
- package/src/DataPopulator.ts +316 -0
- package/src/fixtures/inputs-type.json +1542 -0
- package/src/fixtures/references.json +46030 -0
- package/src/types/conditions.d.ts +19 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { Types } from "@legalplace/referencesparser";
|
|
2
|
+
import type InputsType from "@legalplace/types/dist/inputs";
|
|
3
|
+
import ConditionsRunner from "./ConditionsRunner";
|
|
4
|
+
import { ConditionData, ConditionDataMap } from "./types/conditions.d";
|
|
5
|
+
|
|
6
|
+
class DataPopulator {
|
|
7
|
+
private references: Types.ReferencesType;
|
|
8
|
+
|
|
9
|
+
private ovc: InputsType;
|
|
10
|
+
|
|
11
|
+
private conditionsRunner: ConditionsRunner;
|
|
12
|
+
|
|
13
|
+
private id?: number;
|
|
14
|
+
|
|
15
|
+
private index?: number;
|
|
16
|
+
|
|
17
|
+
private dataMap: ConditionDataMap;
|
|
18
|
+
|
|
19
|
+
private data: ConditionData = {
|
|
20
|
+
o: {},
|
|
21
|
+
v: {},
|
|
22
|
+
c: {
|
|
23
|
+
o: {},
|
|
24
|
+
s: {},
|
|
25
|
+
v: {},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
conditionsRunner: ConditionsRunner,
|
|
31
|
+
references: Types.ReferencesType,
|
|
32
|
+
ovc: InputsType,
|
|
33
|
+
dataMap: ConditionDataMap,
|
|
34
|
+
id?: number,
|
|
35
|
+
index?: number
|
|
36
|
+
) {
|
|
37
|
+
this.id = id;
|
|
38
|
+
this.ovc = ovc;
|
|
39
|
+
this.index = index;
|
|
40
|
+
this.dataMap = dataMap;
|
|
41
|
+
this.references = references;
|
|
42
|
+
this.conditionsRunner = conditionsRunner;
|
|
43
|
+
|
|
44
|
+
// Populating variables
|
|
45
|
+
this.populateVariables();
|
|
46
|
+
|
|
47
|
+
// Populating options
|
|
48
|
+
this.populateOptions();
|
|
49
|
+
|
|
50
|
+
// Populating conditions
|
|
51
|
+
this.populateConditions();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns resulting data object
|
|
56
|
+
*/
|
|
57
|
+
public getData(): Readonly<ConditionData> {
|
|
58
|
+
return this.data;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private populateConditions(): void {
|
|
62
|
+
// Sections
|
|
63
|
+
for (let i = 0; i < this.dataMap.c.s.length; i += 1) {
|
|
64
|
+
const sectionId = this.dataMap.c.s[i];
|
|
65
|
+
const sectionCondition = this.sectionConditionValue(sectionId);
|
|
66
|
+
this.data.c.s[sectionId] = [sectionCondition !== false];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Options
|
|
70
|
+
for (let i = 0; i < this.dataMap.c.o.length; i += 1) {
|
|
71
|
+
const optionId = this.dataMap.c.o[i];
|
|
72
|
+
const optionCondition = [...this.getOptionConditions(optionId)];
|
|
73
|
+
this.data.c.o[optionId] =
|
|
74
|
+
optionCondition === undefined ? [false] : optionCondition;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Variables
|
|
78
|
+
for (let i = 0; i < this.dataMap.c.v.length; i += 1) {
|
|
79
|
+
const variableId = this.dataMap.c.v[i];
|
|
80
|
+
const variableCondition = [...this.getVariablesConditions(variableId)];
|
|
81
|
+
this.data.c.v[variableId] =
|
|
82
|
+
variableCondition === undefined ? [false] : variableCondition;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns a give option's conditions
|
|
88
|
+
* @param optionId Option's id
|
|
89
|
+
*/
|
|
90
|
+
private getOptionConditions(optionId: number): Readonly<boolean[]> {
|
|
91
|
+
const conditions = this.optionConditionValue(optionId);
|
|
92
|
+
if (conditions === undefined) return [true];
|
|
93
|
+
if (this.id === undefined || this.index === undefined) {
|
|
94
|
+
return conditions;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Getting variable parent option
|
|
98
|
+
const optionRootParent = this.getOptionRootParent(optionId);
|
|
99
|
+
const optionRootRelations =
|
|
100
|
+
this.references.relations.options[optionRootParent];
|
|
101
|
+
if (
|
|
102
|
+
optionRootRelations.children.options.includes(this.id) ||
|
|
103
|
+
optionRootRelations.dependants.includes(this.id) ||
|
|
104
|
+
this.id === optionRootParent
|
|
105
|
+
) {
|
|
106
|
+
if (conditions !== undefined && conditions[this.index] === false)
|
|
107
|
+
return [false];
|
|
108
|
+
return [conditions[this.index]];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return conditions;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Returns a give variables conditions
|
|
116
|
+
* @param variableId Variable's id
|
|
117
|
+
*/
|
|
118
|
+
private getVariablesConditions(variableId: number): Readonly<boolean[]> {
|
|
119
|
+
const conditions = this.variableConditionValue(variableId);
|
|
120
|
+
if (conditions === undefined) return [true];
|
|
121
|
+
if (this.id === undefined || this.index === undefined) {
|
|
122
|
+
return conditions;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Getting variable parent option
|
|
126
|
+
const variableRootParent = this.getVariableRootParent(variableId);
|
|
127
|
+
const variableRootRelations =
|
|
128
|
+
this.references.relations.options[variableRootParent];
|
|
129
|
+
if (
|
|
130
|
+
variableRootRelations.children.options.includes(this.id) ||
|
|
131
|
+
variableRootRelations.dependants.includes(this.id) ||
|
|
132
|
+
this.id === variableRootParent
|
|
133
|
+
) {
|
|
134
|
+
return [conditions[this.index]];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return conditions;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Populates variables according to the current dataMap object
|
|
142
|
+
*/
|
|
143
|
+
private populateVariables(): void {
|
|
144
|
+
for (let i = 0; i < this.dataMap.v.length; i += 1) {
|
|
145
|
+
const variableId = this.dataMap.v[i];
|
|
146
|
+
const variableReference = this.references.variables[variableId];
|
|
147
|
+
let values = this.getVariableValues(variableId);
|
|
148
|
+
|
|
149
|
+
const parseNumber = (v: string) => {
|
|
150
|
+
const result = parseFloat(v);
|
|
151
|
+
return Number.isNaN(result) ? "" : result;
|
|
152
|
+
};
|
|
153
|
+
// If variable is of type number
|
|
154
|
+
if (variableReference.type === "number") {
|
|
155
|
+
values = values.map((v) =>
|
|
156
|
+
typeof v === "number" ? v : parseNumber(v)
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Adding variables
|
|
161
|
+
this.data.v[variableId] = [...values];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Returns a give variables value
|
|
167
|
+
* @param variableId Variable's id
|
|
168
|
+
*/
|
|
169
|
+
private getVariableValues(variableId: number): Readonly<(string | number)[]> {
|
|
170
|
+
const value = this.ovc.variables[variableId];
|
|
171
|
+
if (this.id === undefined || this.index === undefined) {
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Getting variable parent option
|
|
176
|
+
const variableRootParent = this.getVariableRootParent(variableId);
|
|
177
|
+
const variableRootRelations =
|
|
178
|
+
this.references.relations.options[variableRootParent];
|
|
179
|
+
if (
|
|
180
|
+
variableRootRelations.children.options.includes(this.id) ||
|
|
181
|
+
variableRootRelations.dependants.includes(this.id) ||
|
|
182
|
+
this.id === variableRootParent
|
|
183
|
+
) {
|
|
184
|
+
return [value[this.index]];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return this.cleanArrayFromNullValues([...value]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Return a given variable root option relations
|
|
192
|
+
* @param variableId Variable's id
|
|
193
|
+
*/
|
|
194
|
+
private getVariableRootParent(variableId: number) {
|
|
195
|
+
const variableParents =
|
|
196
|
+
this.references.relations.variables[variableId].parents;
|
|
197
|
+
return variableParents[variableParents.length - 1];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Cleans values array from any null value by replacing it
|
|
202
|
+
* with an empty string
|
|
203
|
+
* @param arr Values array
|
|
204
|
+
*/
|
|
205
|
+
private cleanArrayFromNullValues(
|
|
206
|
+
arr: (string | number | null)[]
|
|
207
|
+
): (string | number)[] {
|
|
208
|
+
return arr.map((v) => (v === null ? "" : v));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Populates options data object accodring to current dataMap object
|
|
213
|
+
*/
|
|
214
|
+
populateOptions() {
|
|
215
|
+
for (let i = 0; i < this.dataMap.o.length; i += 1) {
|
|
216
|
+
const optionId = this.dataMap.o[i];
|
|
217
|
+
const inputs = this.getOptionInputs(optionId);
|
|
218
|
+
|
|
219
|
+
// Adding option
|
|
220
|
+
this.data.o[optionId] = [...inputs];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Returns a give option's inputs
|
|
226
|
+
* @param optionId Option's id
|
|
227
|
+
*/
|
|
228
|
+
private getOptionInputs(optionId: number): Readonly<boolean[]> {
|
|
229
|
+
const inputs = this.ovc.options[optionId];
|
|
230
|
+
if (this.id === undefined || this.index === undefined) {
|
|
231
|
+
return inputs;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Getting variable parent option
|
|
235
|
+
const optionRootParent = this.getOptionRootParent(optionId);
|
|
236
|
+
const optionRootRelations =
|
|
237
|
+
this.references.relations.options[optionRootParent];
|
|
238
|
+
if (
|
|
239
|
+
optionRootRelations.children.options.includes(this.id) ||
|
|
240
|
+
optionRootRelations.dependants.includes(this.id) ||
|
|
241
|
+
this.id === optionRootParent
|
|
242
|
+
) {
|
|
243
|
+
return [inputs[this.index]];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return inputs;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Returns option's root parent
|
|
251
|
+
* @param optionId Root parent
|
|
252
|
+
*/
|
|
253
|
+
private getOptionRootParent(optionId: number) {
|
|
254
|
+
const optionParents = this.references.relations.options[optionId].parents;
|
|
255
|
+
return optionParents.length > 0
|
|
256
|
+
? optionParents[optionParents.length - 1]
|
|
257
|
+
: optionId;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Calculates option's condition
|
|
262
|
+
*/
|
|
263
|
+
private optionConditionValue(optionId: number) {
|
|
264
|
+
// Getting option conditions
|
|
265
|
+
const conditions = this.references.conditions.options[optionId];
|
|
266
|
+
if (conditions === undefined) return undefined;
|
|
267
|
+
|
|
268
|
+
// Getting option inputs length
|
|
269
|
+
const inputs = this.ovc.options[optionId];
|
|
270
|
+
|
|
271
|
+
return inputs.map((input, index) =>
|
|
272
|
+
this.conditionsRunner.executeCondition(
|
|
273
|
+
conditions,
|
|
274
|
+
optionId,
|
|
275
|
+
index,
|
|
276
|
+
"options"
|
|
277
|
+
)
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Calculates variable's condition
|
|
283
|
+
*/
|
|
284
|
+
private variableConditionValue(variableId: number) {
|
|
285
|
+
// Getting variable conditions
|
|
286
|
+
const conditions = this.references.conditions.variables[variableId];
|
|
287
|
+
if (conditions === undefined) return undefined;
|
|
288
|
+
|
|
289
|
+
// Getting variable inputs length
|
|
290
|
+
const inputs = this.ovc.variables[variableId];
|
|
291
|
+
|
|
292
|
+
const result = inputs.map((input, index) =>
|
|
293
|
+
this.conditionsRunner.executeCondition(
|
|
294
|
+
conditions,
|
|
295
|
+
variableId,
|
|
296
|
+
index,
|
|
297
|
+
"variables"
|
|
298
|
+
)
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Calculates section's condition
|
|
306
|
+
*/
|
|
307
|
+
private sectionConditionValue(sectionId: number) {
|
|
308
|
+
// Getting section conditions
|
|
309
|
+
const conditions = this.references.conditions.sections.main[sectionId];
|
|
310
|
+
if (conditions === undefined) return undefined;
|
|
311
|
+
|
|
312
|
+
return this.conditionsRunner.executeCondition(conditions, 0, 0, "sections");
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export default DataPopulator;
|