@legalplace/tagextractor 1.0.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/.eslintrc +52 -0
- package/.gitlab-ci.yml +43 -0
- package/.prettierrc.js +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/libs/ConditionsRunner.d.ts +17 -0
- package/dist/libs/ConditionsRunner.js +68 -0
- package/dist/libs/DataPopulator.d.ts +53 -0
- package/dist/libs/DataPopulator.js +194 -0
- package/dist/libs/Extractor.d.ts +17 -0
- package/dist/libs/Extractor.js +96 -0
- package/dist/libs/OvcConverter.d.ts +11 -0
- package/dist/libs/OvcConverter.js +132 -0
- package/dist/types/inputs.type.d.ts +9 -0
- package/dist/types/inputs.type.js +2 -0
- package/dist/types/ovc.type.d.ts +12 -0
- package/dist/types/ovc.type.js +2 -0
- package/dist/types/tags.type.d.ts +19 -0
- package/dist/types/tags.type.js +2 -0
- package/model.ts +84 -0
- package/package.json +41 -0
- package/src/index.ts +3 -0
- package/src/libs/ConditionsRunner.ts +99 -0
- package/src/libs/DataPopulator.ts +321 -0
- package/src/libs/Extractor.ts +146 -0
- package/src/libs/OvcConverter.ts +177 -0
- package/src/types/inputs.type.ts +10 -0
- package/src/types/ovc.type.ts +13 -0
- package/src/types/tags.type.ts +22 -0
- package/test.ts +8 -0
- package/tsconfig.eslint.json +12 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { Types } from '@legalplace/referencesparser'
|
|
2
|
+
import ConditionsRunner from './ConditionsRunner'
|
|
3
|
+
|
|
4
|
+
type OVC_TYPE = {
|
|
5
|
+
options: {
|
|
6
|
+
[key: string]: boolean[]
|
|
7
|
+
}
|
|
8
|
+
variables: {
|
|
9
|
+
[key: string]: (number | string)[]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class DataPopulator {
|
|
14
|
+
private references: Types.ReferencesType
|
|
15
|
+
|
|
16
|
+
private ovc: OVC_TYPE
|
|
17
|
+
|
|
18
|
+
private conditionsRunner: ConditionsRunner
|
|
19
|
+
|
|
20
|
+
private id?: number
|
|
21
|
+
|
|
22
|
+
private index?: number
|
|
23
|
+
|
|
24
|
+
private dataMap: ConditionDataMap
|
|
25
|
+
|
|
26
|
+
private data: ConditionData = {
|
|
27
|
+
o: {},
|
|
28
|
+
v: {},
|
|
29
|
+
c: {
|
|
30
|
+
o: {},
|
|
31
|
+
s: {},
|
|
32
|
+
v: {}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
constructor(conditionsRunner: ConditionsRunner, references: Types.ReferencesType, ovc: OVC_TYPE, dataMap: ConditionDataMap, id?: number, index?: number) {
|
|
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] = optionCondition === undefined ? [false] : optionCondition
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Variables
|
|
77
|
+
for (let i = 0; i < this.dataMap.c.v.length; i += 1) {
|
|
78
|
+
const variableId = this.dataMap.c.v[i]
|
|
79
|
+
const variableCondition = [...this.getVariablesConditions(variableId)]
|
|
80
|
+
this.data.c.v[variableId] = variableCondition === undefined ? [false] : variableCondition
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Returns a give option's conditions
|
|
85
|
+
* @param optionId Option's id
|
|
86
|
+
*/
|
|
87
|
+
private getOptionConditions(optionId: number): Readonly<boolean[]> {
|
|
88
|
+
const conditions = this.optionConditionValue(optionId);
|
|
89
|
+
if (conditions === undefined) return [true];
|
|
90
|
+
if (this.id === undefined || this.index === undefined) {
|
|
91
|
+
return conditions;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Getting variable parent option
|
|
95
|
+
const optionRootParent = this.getOptionRootParent(optionId);
|
|
96
|
+
const optionRootRelations = this.references.relations.options[optionRootParent];
|
|
97
|
+
if (
|
|
98
|
+
optionRootRelations.children.options.includes(this.id) ||
|
|
99
|
+
optionRootRelations.dependants.includes(this.id) ||
|
|
100
|
+
this.id === optionRootParent
|
|
101
|
+
) {
|
|
102
|
+
if (conditions !== undefined && conditions[this.index] === false)
|
|
103
|
+
return [false];
|
|
104
|
+
return [conditions[this.index]];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return conditions;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns a give variables conditions
|
|
112
|
+
* @param variableId Variable's id
|
|
113
|
+
*/
|
|
114
|
+
private getVariablesConditions(variableId: number): Readonly<boolean[]> {
|
|
115
|
+
const conditions = this.variableConditionValue(variableId);
|
|
116
|
+
if (conditions === undefined) return [true];
|
|
117
|
+
if (this.id === undefined || this.index === undefined) {
|
|
118
|
+
return conditions;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Getting variable parent option
|
|
122
|
+
const variableRootParent = this.getVariableRootParent(variableId);
|
|
123
|
+
const variableRootRelations = this.references.relations.options[variableRootParent];
|
|
124
|
+
if (
|
|
125
|
+
variableRootRelations.children.options.includes(this.id) ||
|
|
126
|
+
variableRootRelations.dependants.includes(this.id) ||
|
|
127
|
+
this.id === variableRootParent
|
|
128
|
+
) {
|
|
129
|
+
return [conditions[this.index]];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return conditions;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Populates variables according to the current dataMap object
|
|
137
|
+
*/
|
|
138
|
+
private populateVariables(): void {
|
|
139
|
+
for (let i = 0; i < this.dataMap.v.length; i += 1) {
|
|
140
|
+
const variableId = this.dataMap.v[i]
|
|
141
|
+
const variableReference = this.references.variables[variableId]
|
|
142
|
+
let values = this.getVariableValues(variableId)
|
|
143
|
+
|
|
144
|
+
const parseNumber = (v: string) => {
|
|
145
|
+
const result = parseFloat(v)
|
|
146
|
+
return Number.isNaN(result) ? '' : result
|
|
147
|
+
}
|
|
148
|
+
// If variable is of type number
|
|
149
|
+
if (variableReference.type === 'number') {
|
|
150
|
+
values = values.map(v => (typeof v === 'number' ? v : parseNumber(v)))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Adding variables
|
|
154
|
+
this.data.v[variableId] = [...values]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Returns a give variables value
|
|
160
|
+
* @param variableId Variable's id
|
|
161
|
+
*/
|
|
162
|
+
private getVariableValues(variableId: number): Readonly<(string | number)[]> {
|
|
163
|
+
const conditions = this.variableConditionValue(variableId)
|
|
164
|
+
const value = this.ovc.variables[variableId]
|
|
165
|
+
if (this.id === undefined || this.index === undefined) {
|
|
166
|
+
return value
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Getting variable parent option
|
|
170
|
+
const variableRootParent = this.getVariableRootParent(variableId)
|
|
171
|
+
const variableRootRelations = this.references.relations.options[variableRootParent]
|
|
172
|
+
if (variableRootRelations.children.options.includes(this.id) || variableRootRelations.dependants.includes(this.id) || this.id === variableRootParent) {
|
|
173
|
+
// TODO: Replace fAl$e with a safer solution
|
|
174
|
+
if (conditions !== undefined && conditions[this.index] === false) return ['fAl$e']
|
|
175
|
+
return [value[this.index]]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const cleanValues = this.cleanArrayFromNullValues([...value])
|
|
179
|
+
|
|
180
|
+
if (conditions === undefined) return cleanValues
|
|
181
|
+
|
|
182
|
+
return cleanValues.map((currentValue, index) => {
|
|
183
|
+
if (conditions[index] === false) return 'fAl$e'
|
|
184
|
+
return currentValue
|
|
185
|
+
})
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Return a given variable root option relations
|
|
190
|
+
* @param variableId Variable's id
|
|
191
|
+
*/
|
|
192
|
+
private getVariableRootParent(variableId: number) {
|
|
193
|
+
const variableParents = this.references.relations.variables[variableId].parents
|
|
194
|
+
return variableParents[variableParents.length - 1]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Cleans values array from any null value by replacing it
|
|
199
|
+
* with an empty string
|
|
200
|
+
* @param arr Values array
|
|
201
|
+
*/
|
|
202
|
+
private cleanArrayFromNullValues(arr: (string | number | null)[]): (string | number)[] {
|
|
203
|
+
return arr.map(v => (v === null ? '' : v))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Populates options data object accodring to current dataMap object
|
|
208
|
+
*/
|
|
209
|
+
populateOptions() {
|
|
210
|
+
for (let i = 0; i < this.dataMap.o.length; i += 1) {
|
|
211
|
+
const optionId = this.dataMap.o[i]
|
|
212
|
+
const inputs = this.getOptionInputs(optionId)
|
|
213
|
+
|
|
214
|
+
// Adding option
|
|
215
|
+
this.data.o[optionId] = [...inputs]
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Returns a give option's inputs
|
|
221
|
+
* @param optionId Option's id
|
|
222
|
+
*/
|
|
223
|
+
private getOptionInputs(optionId: number): Readonly<boolean[]> {
|
|
224
|
+
const conditions = this.optionConditionValue(optionId)
|
|
225
|
+
const inputs = this.ovc.options[optionId]
|
|
226
|
+
if (this.id === undefined || this.index === undefined) {
|
|
227
|
+
return inputs
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Getting variable parent option
|
|
231
|
+
const optionRootParent = this.getOptionRootParent(optionId)
|
|
232
|
+
const optionRootRelations = this.references.relations.options[optionRootParent]
|
|
233
|
+
if (optionRootRelations.children.options.includes(this.id) || optionRootRelations.dependants.includes(this.id) || this.id === optionRootParent) {
|
|
234
|
+
if (conditions !== undefined && conditions[this.index] === false) return [false]
|
|
235
|
+
return [inputs[this.index]]
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (conditions === undefined) return inputs
|
|
239
|
+
|
|
240
|
+
return inputs.map((value, index) => {
|
|
241
|
+
if (conditions[index] === false) return false
|
|
242
|
+
return value
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Returns option's root parent
|
|
248
|
+
* @param optionId Root parent
|
|
249
|
+
*/
|
|
250
|
+
private getOptionRootParent(optionId: number) {
|
|
251
|
+
const optionParents = this.references.relations.options[optionId].parents
|
|
252
|
+
return optionParents.length > 0 ? optionParents[optionParents.length - 1] : optionId
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Calculates option's condition
|
|
257
|
+
*/
|
|
258
|
+
private optionConditionValue(optionId: number) {
|
|
259
|
+
// Getting option conditions
|
|
260
|
+
const conditions = this.references.conditions.options[optionId]
|
|
261
|
+
if (conditions === undefined) return undefined
|
|
262
|
+
|
|
263
|
+
// Getting option inputs length
|
|
264
|
+
const inputs = this.ovc.options[optionId]
|
|
265
|
+
|
|
266
|
+
return inputs.map((input, index) => {
|
|
267
|
+
return this.conditionsRunner.executeCondition(conditions, optionId, index, 'options')
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Calculates variable's condition
|
|
273
|
+
*/
|
|
274
|
+
private variableConditionValue(variableId: number) {
|
|
275
|
+
// Getting variable conditions
|
|
276
|
+
const conditions = this.references.conditions.variables[variableId]
|
|
277
|
+
if (conditions === undefined) return undefined
|
|
278
|
+
|
|
279
|
+
// Getting variable inputs length
|
|
280
|
+
const inputs = this.ovc.variables[variableId]
|
|
281
|
+
|
|
282
|
+
const result = inputs.map((input, index) => {
|
|
283
|
+
return this.conditionsRunner.executeCondition(conditions, variableId, index, 'variables')
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
return result
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Calculates section's condition
|
|
291
|
+
*/
|
|
292
|
+
private sectionConditionValue(sectionId: number) {
|
|
293
|
+
// Getting section conditions
|
|
294
|
+
const conditions = this.references.conditions.sections.main[sectionId]
|
|
295
|
+
if (conditions === undefined) return undefined
|
|
296
|
+
|
|
297
|
+
return this.conditionsRunner.executeCondition(conditions, 0, 0, 'sections')
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface ConditionDataMap {
|
|
302
|
+
o: number[]
|
|
303
|
+
v: number[]
|
|
304
|
+
c: {
|
|
305
|
+
o: number[]
|
|
306
|
+
s: number[]
|
|
307
|
+
v: number[]
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export interface ConditionData {
|
|
312
|
+
o: Record<string, boolean[]>
|
|
313
|
+
v: Record<string, (string | number)[]>
|
|
314
|
+
c: {
|
|
315
|
+
o: Record<string, boolean[]>
|
|
316
|
+
s: Record<string, boolean[]>
|
|
317
|
+
v: Record<string, boolean[]>
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export default DataPopulator
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { ModelV3 } from "@legalplace/models-v3-types";
|
|
2
|
+
import { ReferencesParser, Types } from '@legalplace/referencesparser'
|
|
3
|
+
import InputsType from "../types/inputs.type";
|
|
4
|
+
import OvcType from "../types/ovc.type";
|
|
5
|
+
import TagsType from "../types/tags.type";
|
|
6
|
+
import ConditionsRunner from "./ConditionsRunner";
|
|
7
|
+
import OvcConverter from "./OvcConverter";
|
|
8
|
+
|
|
9
|
+
class TagsExtractor {
|
|
10
|
+
private references: Types.ReferencesType;
|
|
11
|
+
|
|
12
|
+
private inputs: InputsType;
|
|
13
|
+
|
|
14
|
+
private conditionsRunner: ConditionsRunner
|
|
15
|
+
|
|
16
|
+
private tags: TagsType = {
|
|
17
|
+
options: {},
|
|
18
|
+
variables: {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
constructor(model: ModelV3, ovc: OvcType | InputsType) {
|
|
22
|
+
// Parsing references
|
|
23
|
+
this.references = new ReferencesParser(model).references
|
|
24
|
+
|
|
25
|
+
// Converting inputs if needed
|
|
26
|
+
this.inputs = OvcConverter.isOptionsVariables(ovc) ? ovc : OvcConverter.convertToOptionsVariables(ovc, this.references)
|
|
27
|
+
|
|
28
|
+
// Initiaing Conditions runner
|
|
29
|
+
this.conditionsRunner = new ConditionsRunner(this.references, this.inputs);
|
|
30
|
+
|
|
31
|
+
// Extracting tags from options
|
|
32
|
+
this.extractFromOptions();
|
|
33
|
+
|
|
34
|
+
// Extracting tags from variables
|
|
35
|
+
this.extractFromVariables();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public get getTags() {
|
|
39
|
+
return this.tags
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Reads Options
|
|
44
|
+
*/
|
|
45
|
+
private extractFromOptions() {
|
|
46
|
+
Object.keys(this.references.options).forEach(id => {
|
|
47
|
+
const {tags, label} = this.references.options[id].meta
|
|
48
|
+
|
|
49
|
+
if(Array.isArray(tags) && tags.length > 0) {
|
|
50
|
+
|
|
51
|
+
// Getting condition
|
|
52
|
+
const conditions = this.optionConditionValue(parseInt(id, 10))
|
|
53
|
+
|
|
54
|
+
this.inputs.options[id].forEach((v, index) => {
|
|
55
|
+
|
|
56
|
+
tags.forEach((tag) => {
|
|
57
|
+
if(this.tags.options[tag] === undefined) this.tags.options[tag] = []
|
|
58
|
+
|
|
59
|
+
console.log(conditions[index], conditions)
|
|
60
|
+
this.tags.options[tag].push({
|
|
61
|
+
id: parseInt(id, 10),
|
|
62
|
+
index,
|
|
63
|
+
label: label,
|
|
64
|
+
condition: conditions[index],
|
|
65
|
+
value: this.inputs.options[id][index]
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Reads Variables
|
|
78
|
+
*/
|
|
79
|
+
private extractFromVariables() {
|
|
80
|
+
Object.keys(this.references.variables).forEach(id => {
|
|
81
|
+
const {tags, label} = this.references.variables[id]
|
|
82
|
+
|
|
83
|
+
if(Array.isArray(tags) && tags.length > 0) {
|
|
84
|
+
|
|
85
|
+
// Getting condition
|
|
86
|
+
const conditions = this.variableConditionValue(parseInt(id, 10))
|
|
87
|
+
|
|
88
|
+
this.inputs.variables[id].forEach((v, index) => {
|
|
89
|
+
|
|
90
|
+
tags.forEach((tag) => {
|
|
91
|
+
if(this.tags.variables[tag] === undefined) this.tags.variables[tag] = []
|
|
92
|
+
this.tags.variables[tag].push({
|
|
93
|
+
id: parseInt(id, 10),
|
|
94
|
+
index,
|
|
95
|
+
label: label,
|
|
96
|
+
condition: conditions[index],
|
|
97
|
+
value: this.inputs.variables[id][index]
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Calculates option's condition
|
|
111
|
+
*/
|
|
112
|
+
private optionConditionValue(optionId: number) {
|
|
113
|
+
// Getting option conditions
|
|
114
|
+
const conditions = this.references.conditions.options[optionId]
|
|
115
|
+
|
|
116
|
+
// Getting option inputs length
|
|
117
|
+
const inputs = this.inputs.options[optionId]
|
|
118
|
+
|
|
119
|
+
if (conditions === undefined) return inputs.map(() => true)
|
|
120
|
+
|
|
121
|
+
return inputs.map((input, index) => {
|
|
122
|
+
return this.conditionsRunner.executeCondition(conditions, optionId, index, 'options')
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Calculates variable's condition
|
|
128
|
+
*/
|
|
129
|
+
private variableConditionValue(variableId: number) {
|
|
130
|
+
// Getting variable conditions
|
|
131
|
+
const conditions = this.references.conditions.variables[variableId]
|
|
132
|
+
|
|
133
|
+
// Getting variable inputs length
|
|
134
|
+
const inputs = this.inputs.variables[variableId]
|
|
135
|
+
|
|
136
|
+
if (conditions === undefined) return inputs.map(() => true)
|
|
137
|
+
|
|
138
|
+
const result = inputs.map((input, index) => {
|
|
139
|
+
return this.conditionsRunner.executeCondition(conditions, variableId, index, 'variables')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
return result
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export default TagsExtractor
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Types } from '@legalplace/referencesparser'
|
|
2
|
+
import InputsType from '../types/inputs.type';
|
|
3
|
+
import OvcType from '../types/ovc.type';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OvcConverter {
|
|
7
|
+
public convertToOptionsVariables(
|
|
8
|
+
ovc: OvcType,
|
|
9
|
+
references: Types.ReferencesType
|
|
10
|
+
) {
|
|
11
|
+
const inputs: InputsType = {
|
|
12
|
+
options: {},
|
|
13
|
+
variables: {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (typeof ovc !== 'object') return inputs;
|
|
17
|
+
|
|
18
|
+
// Reading options
|
|
19
|
+
if (typeof ovc.o === 'object') {
|
|
20
|
+
Object.keys(ovc.o).forEach(id => {
|
|
21
|
+
const currentOption = ovc.o[id];
|
|
22
|
+
|
|
23
|
+
// If it's a multiple
|
|
24
|
+
if (Array.isArray(currentOption)) {
|
|
25
|
+
const occurences = currentOption.length;
|
|
26
|
+
// Adding static childrens
|
|
27
|
+
inputs.options = {
|
|
28
|
+
...inputs.options,
|
|
29
|
+
...this.pushStaticChildren(
|
|
30
|
+
inputs.options,
|
|
31
|
+
id,
|
|
32
|
+
occurences,
|
|
33
|
+
references
|
|
34
|
+
)
|
|
35
|
+
};
|
|
36
|
+
currentOption.forEach((childId, index) => {
|
|
37
|
+
const sanitizedId =
|
|
38
|
+
typeof childId === 'string' && childId.split('_').length > 0
|
|
39
|
+
? childId.split('_')[0]
|
|
40
|
+
: childId;
|
|
41
|
+
|
|
42
|
+
// Making sure the input exist
|
|
43
|
+
if (!Object.prototype.hasOwnProperty.call(inputs.options, id)) {
|
|
44
|
+
inputs.options[id] = new Array(occurences).fill(false);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Making sure the childId is not empty
|
|
48
|
+
if (
|
|
49
|
+
typeof sanitizedId === 'string' &&
|
|
50
|
+
sanitizedId.trim().length === 0
|
|
51
|
+
) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Creating input if it doesn't exist
|
|
56
|
+
if (
|
|
57
|
+
!Object.prototype.hasOwnProperty.call(inputs.options, sanitizedId)
|
|
58
|
+
) {
|
|
59
|
+
inputs.options[sanitizedId] = new Array(occurences).fill(false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Adding static childrens
|
|
63
|
+
inputs.options = {
|
|
64
|
+
...inputs.options,
|
|
65
|
+
...this.pushStaticChildren(
|
|
66
|
+
inputs.options,
|
|
67
|
+
sanitizedId,
|
|
68
|
+
occurences,
|
|
69
|
+
references
|
|
70
|
+
)
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Setting current index to true
|
|
74
|
+
inputs.options[sanitizedId][index] = true;
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
if (
|
|
78
|
+
typeof currentOption === 'string' &&
|
|
79
|
+
currentOption.trim().length === 0
|
|
80
|
+
)
|
|
81
|
+
return;
|
|
82
|
+
inputs.options[currentOption] = [true];
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Reading checkboxes
|
|
88
|
+
if (typeof ovc.c === 'object') {
|
|
89
|
+
Object.keys(ovc.c).forEach(id => {
|
|
90
|
+
const currentCheckbox = ovc.c[id];
|
|
91
|
+
if (typeof id === 'string' && id.trim().length === 0) return;
|
|
92
|
+
// If it's a multiple
|
|
93
|
+
if (Array.isArray(currentCheckbox)) {
|
|
94
|
+
inputs.options[id] = currentCheckbox;
|
|
95
|
+
} else {
|
|
96
|
+
inputs.options[id] = [currentCheckbox];
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Reading variables
|
|
102
|
+
if (typeof ovc.v === 'object') {
|
|
103
|
+
Object.keys(ovc.v).forEach(id => {
|
|
104
|
+
const currentVariable = ovc.v[id];
|
|
105
|
+
|
|
106
|
+
// If it's a multiple
|
|
107
|
+
if (Array.isArray(currentVariable)) {
|
|
108
|
+
inputs.variables[id] = currentVariable;
|
|
109
|
+
// Getting parentsTree & parent id
|
|
110
|
+
const parentsTree = references.relations.variables[id].parents;
|
|
111
|
+
const parentOption =
|
|
112
|
+
inputs.options[`${parentsTree[parentsTree.length - 1]}`];
|
|
113
|
+
if (Array.isArray(parentOption)) {
|
|
114
|
+
const occurences = parentOption.length;
|
|
115
|
+
if (currentVariable.length < occurences) {
|
|
116
|
+
inputs.variables[id] = [
|
|
117
|
+
...currentVariable,
|
|
118
|
+
...Array(occurences - currentVariable.length).fill('')
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
inputs.variables[id] = [currentVariable];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return inputs;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public isOvc(_obj: InputsType | OvcType): _obj is OvcType {
|
|
132
|
+
if (typeof _obj !== 'object' || _obj === null) return false
|
|
133
|
+
const ovcKeys = ['o', 'v', 'c']
|
|
134
|
+
const foundKeys = Object.keys(_obj)
|
|
135
|
+
.map((key): number => (ovcKeys.includes(key) ? 1 : 0))
|
|
136
|
+
.reduce((a, b) => a + b, 0)
|
|
137
|
+
return foundKeys > 1
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public isOptionsVariables(_obj: InputsType | OvcType): _obj is InputsType {
|
|
141
|
+
if (typeof _obj !== 'object' || _obj === null) return false
|
|
142
|
+
const optionsVariablesKeys = ['options', 'variables']
|
|
143
|
+
const foundKeys = Object.keys(_obj)
|
|
144
|
+
.map((key): number => (optionsVariablesKeys.includes(key) ? 1 : 0))
|
|
145
|
+
.reduce((a, b) => a + b, 0)
|
|
146
|
+
return foundKeys === 2
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private pushStaticChildren(
|
|
150
|
+
inputOptions: InputsType['options'],
|
|
151
|
+
id: number | string,
|
|
152
|
+
occurences: number,
|
|
153
|
+
references: Types.ReferencesType
|
|
154
|
+
) {
|
|
155
|
+
const result = { ...inputOptions };
|
|
156
|
+
const intId = typeof id === 'number' ? id : parseInt(id, 10);
|
|
157
|
+
|
|
158
|
+
// Getting children options and variables
|
|
159
|
+
const { options } = references.relations.options[intId].children;
|
|
160
|
+
|
|
161
|
+
// Getting static children
|
|
162
|
+
const staticOptions = options.filter(childId => {
|
|
163
|
+
return references.options[childId].meta.type === 'static';
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
staticOptions.forEach(childId => {
|
|
167
|
+
// Creating input if it doesn't exist
|
|
168
|
+
if (!Object.prototype.hasOwnProperty.call(result, childId)) {
|
|
169
|
+
result[childId] = new Array(occurences).fill(false);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export default new OvcConverter()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface TagsType {
|
|
2
|
+
options: Record<string, OptionTagType[]>
|
|
3
|
+
variables: Record<string, VariableTagType[]>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface OptionTagType {
|
|
7
|
+
id: number;
|
|
8
|
+
index: number;
|
|
9
|
+
label: string;
|
|
10
|
+
condition: boolean;
|
|
11
|
+
value: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface VariableTagType {
|
|
15
|
+
id: number;
|
|
16
|
+
index: number;
|
|
17
|
+
label: string;
|
|
18
|
+
condition: boolean;
|
|
19
|
+
value: string | number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default TagsType
|