@legalplace/prerenderx 2.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.
@@ -0,0 +1,24 @@
1
+ import { Types } from "@legalplace/referencesparser";
2
+ import ConditionsRunner from "./ConditionsRunner";
3
+ import OVC_TYPE from "./ovc.type";
4
+ import NumAuto from "./NumAuto";
5
+ declare class SectionRender {
6
+ outputs: string[];
7
+ references: Types.ReferencesType;
8
+ currentSection: number;
9
+ documentName: string;
10
+ conditions: ConditionsRunner;
11
+ ovc: OVC_TYPE;
12
+ private NumAuto;
13
+ constructor(options: {
14
+ references: Types.ReferencesType;
15
+ conditions: ConditionsRunner;
16
+ ovc: OVC_TYPE;
17
+ documentName: string;
18
+ currentSection: number;
19
+ numauto: NumAuto;
20
+ });
21
+ getOutputs(): string[];
22
+ private renderSection;
23
+ }
24
+ export default SectionRender;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __spreadArrays = (this && this.__spreadArrays) || function () {
3
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
4
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
5
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
6
+ r[k] = a[j];
7
+ return r;
8
+ };
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ var OptionRender_1 = __importDefault(require("./OptionRender"));
14
+ var SectionRender = (function () {
15
+ function SectionRender(options) {
16
+ this.outputs = [];
17
+ this.references = options.references;
18
+ this.conditions = options.conditions;
19
+ this.documentName = options.documentName;
20
+ this.currentSection = options.currentSection;
21
+ this.ovc = options.ovc;
22
+ this.NumAuto = options.numauto;
23
+ this.renderSection();
24
+ }
25
+ SectionRender.prototype.getOutputs = function () {
26
+ return this.outputs;
27
+ };
28
+ SectionRender.prototype.renderSection = function () {
29
+ var _this = this;
30
+ var section = this.references.sections[this.documentName][this.currentSection];
31
+ var conditionObject = this.references.conditions.sections[this.documentName][this.currentSection];
32
+ var condition = conditionObject === undefined
33
+ ? true
34
+ : this.conditions.executeCondition(conditionObject, 0, 0, "sections");
35
+ if (condition === true) {
36
+ section.options.forEach(function (optionId) {
37
+ var option = _this.references.options[optionId];
38
+ var repeatOption = optionId;
39
+ if (option.meta.type === "repeated") {
40
+ if (option.meta.repeatOption === undefined)
41
+ return;
42
+ repeatOption =
43
+ typeof option.meta.repeatOption === "number"
44
+ ? option.meta.repeatOption
45
+ : parseInt(option.meta.repeatOption, 10);
46
+ }
47
+ var inputs = _this.ovc.options[repeatOption] || [
48
+ !["radio", "checkbox"].includes(option.meta.type)
49
+ ];
50
+ inputs.forEach(function (value, index) {
51
+ if (value !== true)
52
+ return;
53
+ _this.outputs = __spreadArrays(_this.outputs, new OptionRender_1.default({
54
+ references: _this.references,
55
+ id: optionId,
56
+ ovc: _this.ovc,
57
+ index: index,
58
+ conditions: _this.conditions,
59
+ numauto: _this.NumAuto
60
+ }).getOutputs());
61
+ });
62
+ });
63
+ }
64
+ };
65
+ return SectionRender;
66
+ }());
67
+ exports.default = SectionRender;
@@ -0,0 +1,9 @@
1
+ declare type OVC_TYPE = {
2
+ options: {
3
+ [key: string]: boolean[];
4
+ };
5
+ variables: {
6
+ [key: string]: (number | string)[];
7
+ };
8
+ };
9
+ export default OVC_TYPE;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/jest.config.js ADDED
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ roots: ["./tests"],
3
+ transform: {
4
+ "^.+\\.tsx?$": "ts-jest"
5
+ },
6
+ globals: {
7
+ "ts-jest": {
8
+ tsConfig: "tsconfig.json"
9
+ }
10
+ }
11
+ };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@legalplace/prerenderx",
3
+ "version": "2.0.0",
4
+ "description": "PrerenderX",
5
+ "main": "dist/index.js",
6
+ "repository": "https://git.legalplace.eu/legalplace/prerenderx",
7
+ "author": "Moncef Hammou <moncef@legalplace.fr> <moncef@legalplace.fr>",
8
+ "license": "MIT",
9
+ "scripts": {
10
+ "lint": "npx eslint ./src/ --ext ts,js",
11
+ "test": "npx jest",
12
+ "build": "npx tsc"
13
+ },
14
+ "dependencies": {
15
+ "crypto": "^1.0.1",
16
+ "@legalplace/lplogic": "^2.0.0",
17
+ "@legalplace/models-v3-types": "^3.1.1",
18
+ "@legalplace/referencesparser": "^1.1.0"
19
+ },
20
+ "devDependencies": {
21
+ "@babel/core": "^7.7.2",
22
+ "@babel/preset-typescript": "^7.7.2",
23
+ "@types/jest": "^24.0.15",
24
+ "@types/node": "^12.12.6",
25
+ "@typescript-eslint/eslint-plugin": "^2.6.1",
26
+ "@typescript-eslint/parser": "^2.6.1",
27
+ "airbnb-standard": "^1.0.0",
28
+ "eslint": "^6.6.0",
29
+ "eslint-config-airbnb-base": "^14.0.0",
30
+ "eslint-config-prettier": "^6.5.0",
31
+ "eslint-plugin-import": "^2.18.2",
32
+ "eslint-plugin-prettier": "^3.1.1",
33
+ "jest": "^24.8.0",
34
+ "prettier": "1.19.1",
35
+ "redux-mock-store": "^1.5.3",
36
+ "ts-jest": "^24.0.2",
37
+ "typescript": "^3.7.2"
38
+ }
39
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import Prerender from "./libs/Prerender";
2
+
3
+ export { Prerender };
@@ -0,0 +1,237 @@
1
+ /* eslint-disable max-len */
2
+ import LpLogic from "@legalplace/lplogic";
3
+ import { Types } from "@legalplace/referencesparser";
4
+ import { ConditionV3 } from "@legalplace/models-v3-types";
5
+
6
+ type OVC_TYPE = {
7
+ options: {
8
+ [key: string]: boolean[];
9
+ };
10
+ variables: {
11
+ [key: string]: (number | string)[];
12
+ };
13
+ };
14
+
15
+ interface ConditionDataMap {
16
+ o: number[];
17
+ v: number[];
18
+ }
19
+
20
+ interface ConditionData {
21
+ o: Record<string, boolean[]>;
22
+ v: Record<string, (string | number)[]>;
23
+ }
24
+
25
+ class ConditionsRunner {
26
+ private references: Types.ReferencesType;
27
+
28
+ private ovc: OVC_TYPE;
29
+
30
+ constructor(references: Types.ReferencesType, ovc: OVC_TYPE) {
31
+ this.references = references;
32
+ this.ovc = ovc;
33
+ }
34
+
35
+ private populateData(
36
+ id: number,
37
+ index: number,
38
+ dataMap: ConditionDataMap,
39
+ withRelations = true
40
+ ) {
41
+ const data: ConditionData = {
42
+ o: {},
43
+ v: {}
44
+ };
45
+
46
+ // Populating options
47
+ dataMap.o.forEach(currentOptionId => {
48
+ // Getting option value
49
+ let value = this.ovc.options[currentOptionId];
50
+
51
+ // Getting current relations
52
+ const currentOptionParents = this.references.relations.options[
53
+ currentOptionId
54
+ ].parents;
55
+ const currentOptionRoot =
56
+ currentOptionParents[currentOptionParents.length - 1];
57
+ const currentOptionRootRelations = currentOptionRoot
58
+ ? this.references.relations.options[currentOptionId]
59
+ : undefined;
60
+
61
+ // Checking if current option is related to the option that changed
62
+ if (withRelations === true && currentOptionRootRelations) {
63
+ if (
64
+ id === currentOptionId ||
65
+ currentOptionRootRelations.children.options.includes(id) ||
66
+ currentOptionRootRelations.dependants.includes(id)
67
+ )
68
+ value = [value[index]];
69
+ }
70
+
71
+ data.o[currentOptionId] = value;
72
+ });
73
+
74
+ // Populating variables
75
+ dataMap.v.forEach(currentVariableId => {
76
+ // Getting variable data
77
+ const variableReference = this.references.variables[currentVariableId];
78
+ let value = this.ovc.variables[currentVariableId];
79
+ const variableParents = this.references.relations.variables[
80
+ currentVariableId
81
+ ].parents;
82
+ const currentOptionId = variableParents[0];
83
+
84
+ // Getting current relations
85
+ const currentOptionParents = this.references.relations.options[
86
+ currentOptionId
87
+ ].parents;
88
+ const currentOptionRoot =
89
+ currentOptionParents[currentOptionParents.length - 1];
90
+ const currentOptionRootRelations = currentOptionRoot
91
+ ? this.references.relations.options[currentOptionId]
92
+ : undefined;
93
+
94
+ // Checking if current option is related to the option that changed
95
+ if (withRelations === true && currentOptionRootRelations) {
96
+ if (
97
+ currentOptionRootRelations.children.options.includes(
98
+ currentOptionId
99
+ ) ||
100
+ currentOptionRootRelations.dependants.includes(currentOptionId)
101
+ ) {
102
+ value = [value[index]];
103
+ }
104
+ }
105
+
106
+ let dataValue: (string | number)[] = value.map(v =>
107
+ v === null ? "" : v
108
+ );
109
+
110
+ // If variable is of type number
111
+ if (variableReference.type === "number") {
112
+ dataValue = dataValue.map(v =>
113
+ typeof v === "number" ? v : parseFloat(v)
114
+ );
115
+ }
116
+
117
+ data.v[currentVariableId] = dataValue;
118
+ });
119
+
120
+ return data;
121
+ }
122
+
123
+ isOptionRelatedToOption(optionA: number, optionB: number): boolean {
124
+ // Getting B relations
125
+ const OptionBParents = this.references.relations.options[optionB].parents;
126
+ const OptionBRoot = OptionBParents[OptionBParents.length - 1];
127
+ const OptionBRootRelations = OptionBRoot
128
+ ? this.references.relations.options[OptionBRoot]
129
+ : undefined;
130
+
131
+ // Checking if B option is related to the option that changed
132
+ if (OptionBRootRelations) {
133
+ if (
134
+ optionA === optionB ||
135
+ OptionBRootRelations.children.options.includes(optionA) ||
136
+ OptionBRootRelations.dependants.includes(optionA)
137
+ ) {
138
+ return true;
139
+ }
140
+ }
141
+
142
+ return false;
143
+ }
144
+
145
+ isVariableRelatedToOption(variableId: number, optionId: number): boolean {
146
+ // Variable parent
147
+ const variableParentId = this.references.relations.variables[variableId]
148
+ .parents[0];
149
+
150
+ // Getting B relations
151
+ const optionParents = this.references.relations.options[variableParentId]
152
+ .parents;
153
+ const optionRoot = optionParents[optionParents.length - 1];
154
+ const optionRootRelations = optionRoot
155
+ ? this.references.relations.options[optionRoot]
156
+ : undefined;
157
+
158
+ // Checking if B option is related to the option that changed
159
+ if (optionRootRelations) {
160
+ if (
161
+ optionRootRelations.children.options.includes(optionId) ||
162
+ optionRootRelations.dependants.includes(optionId)
163
+ ) {
164
+ return true;
165
+ }
166
+ }
167
+
168
+ return false;
169
+ }
170
+
171
+ isVariableRelatedToVariable(variableA: number, variableB: number): boolean {
172
+ // Getting variables options
173
+ const optionA = this.references.relations.variables[variableA].parents[0];
174
+ const optionB = this.references.relations.variables[variableB].parents[0];
175
+
176
+ // Getting B relations
177
+ const OptionBParents = this.references.relations.options[optionB].parents;
178
+ const OptionBRoot = OptionBParents[OptionBParents.length - 1];
179
+ const OptionBRootRelations = OptionBRoot
180
+ ? this.references.relations.options[OptionBRoot]
181
+ : undefined;
182
+
183
+ // Checking if B option is related to the option that changed
184
+ if (OptionBRootRelations) {
185
+ if (
186
+ optionA === optionB ||
187
+ OptionBRootRelations.children.options.includes(optionA) ||
188
+ OptionBRootRelations.dependants.includes(optionA)
189
+ ) {
190
+ return true;
191
+ }
192
+ }
193
+
194
+ return false;
195
+ }
196
+
197
+ executeCondition(
198
+ condition: {
199
+ dataMap: { o: number[]; v: number[] };
200
+ conditions: ConditionV3;
201
+ },
202
+ id: number,
203
+ index: number,
204
+ conditionType:
205
+ | "options"
206
+ | "optionValidator"
207
+ | "variables"
208
+ | "prefillers"
209
+ | "variableValidator"
210
+ | "sections"
211
+ | "documents"
212
+ ): any {
213
+ if (Array.isArray(condition))
214
+ return condition.map(_condition =>
215
+ this.executeCondition(_condition, id, index, conditionType)
216
+ );
217
+
218
+ // Populating Data
219
+ let currentData;
220
+ if (conditionType === "options" || conditionType === "optionValidator") {
221
+ currentData = this.populateData(id, index, condition.dataMap);
222
+ } else if (
223
+ conditionType === "variables" ||
224
+ conditionType === "prefillers" ||
225
+ conditionType === "variableValidator"
226
+ ) {
227
+ const dataId = this.references.relations.variables[id].parents[0];
228
+ currentData = this.populateData(dataId, index, condition.dataMap);
229
+ } else if (conditionType === "sections" || conditionType === "documents") {
230
+ currentData = this.populateData(id, index, condition.dataMap, false);
231
+ }
232
+
233
+ return LpLogic(condition.conditions, currentData);
234
+ }
235
+ }
236
+
237
+ export default ConditionsRunner;
@@ -0,0 +1,52 @@
1
+ import { Types } from "@legalplace/referencesparser";
2
+ import ConditionsRunner from "./ConditionsRunner";
3
+ import SectionRender from "./SectionRender";
4
+ import OVC_TYPE from "./ovc.type";
5
+ import NumAuto from "./NumAuto";
6
+
7
+ class DocumentRender {
8
+ references: Types.ReferencesType;
9
+
10
+ conditions: ConditionsRunner;
11
+
12
+ ovc: OVC_TYPE;
13
+
14
+ documents: Record<string, string[]> = {};
15
+
16
+ documentsNamesHash: Record<string, string> = {};
17
+
18
+ private NumAuto: NumAuto;
19
+
20
+ constructor(
21
+ references: Types.ReferencesType,
22
+ conditions: ConditionsRunner,
23
+ ovc: OVC_TYPE,
24
+ numauto: NumAuto
25
+ ) {
26
+ this.references = references;
27
+ this.conditions = conditions;
28
+ this.ovc = ovc;
29
+ this.NumAuto = numauto;
30
+ }
31
+
32
+ public renderDocument(documentName: string) {
33
+ const documentOutputs: string[] = [];
34
+ this.NumAuto.resetIndexes();
35
+ Object.keys(this.references.sections[documentName]).forEach(sectionId => {
36
+ documentOutputs.push(
37
+ ...new SectionRender({
38
+ references: this.references,
39
+ conditions: this.conditions,
40
+ documentName,
41
+ ovc: this.ovc,
42
+ currentSection: parseInt(sectionId, 10),
43
+ numauto: this.NumAuto
44
+ }).getOutputs()
45
+ );
46
+ });
47
+
48
+ return documentOutputs.join("");
49
+ }
50
+ }
51
+
52
+ export default DocumentRender;
@@ -0,0 +1,48 @@
1
+ class NumAuto {
2
+ indexesList: Record<string, any> = {};
3
+
4
+ tagsIndex: Record<string, number> = {};
5
+
6
+ /**
7
+ * Increments the given index by 1 and
8
+ * returns the count
9
+ * @param index Index name
10
+ */
11
+ getNum = (index: string, tag: string | null): number => {
12
+ // In case the index doesn't exist
13
+ if (!Object.prototype.hasOwnProperty.call(this.indexesList, index)) {
14
+ // Let's first make sure it's not a tag and return it if it is
15
+ if (Object.prototype.hasOwnProperty.call(this.tagsIndex, index))
16
+ return this.tagsIndex[index];
17
+
18
+ // Otherwise we set a new index
19
+ this.indexesList[index] = 0;
20
+ }
21
+
22
+ this.indexesList[index] += 1;
23
+
24
+ if (typeof tag === "string") this.tagsIndex[tag] = this.indexesList[index];
25
+
26
+ return this.indexesList[index];
27
+ };
28
+
29
+ /**
30
+ * Returns the current count of the given index
31
+ * @param index Index name
32
+ */
33
+ getNumPre = (index: string): number => {
34
+ // In case the index doesn't exist
35
+ if (!Object.prototype.hasOwnProperty.call(this.indexesList, index)) {
36
+ // Let's first make sure it's not a tag and return it if it is
37
+ if (Object.prototype.hasOwnProperty.call(this.tagsIndex, index))
38
+ return this.tagsIndex[index];
39
+ }
40
+ return this.indexesList[index];
41
+ };
42
+
43
+ resetIndexes = () => {
44
+ this.indexesList = {};
45
+ };
46
+ }
47
+
48
+ export default NumAuto;
@@ -0,0 +1,124 @@
1
+ import { Types } from "@legalplace/referencesparser";
2
+ import ConditionsRunner from "./ConditionsRunner";
3
+ import OVC_TYPE from "./ovc.type";
4
+ import {
5
+ parseOutputWithVariables,
6
+ getRelatedVariablesValues
7
+ } from "./OutputParser";
8
+ import NumAuto from "./NumAuto";
9
+
10
+ class OptionRender {
11
+ outputs: string[] = [];
12
+
13
+ references: Types.ReferencesType;
14
+
15
+ index: number;
16
+
17
+ id: number;
18
+
19
+ conditions: ConditionsRunner;
20
+
21
+ ovc: OVC_TYPE;
22
+
23
+ private NumAuto: NumAuto;
24
+
25
+ constructor(options: {
26
+ references: Types.ReferencesType;
27
+ conditions: ConditionsRunner;
28
+ ovc: OVC_TYPE;
29
+ index: number;
30
+ id: number;
31
+ numauto: NumAuto;
32
+ }) {
33
+ this.references = options.references;
34
+ this.conditions = options.conditions;
35
+ this.index = options.index;
36
+ this.id = options.id;
37
+ this.ovc = options.ovc;
38
+ this.NumAuto = options.numauto;
39
+
40
+ this.renderOption();
41
+ }
42
+
43
+ getOutputs() {
44
+ return this.outputs;
45
+ }
46
+
47
+ private renderOption() {
48
+ const option = this.references.options[this.id];
49
+ const conditionObject = this.references.conditions.options[this.id];
50
+ const condition =
51
+ conditionObject === undefined
52
+ ? true
53
+ : this.conditions.executeCondition(
54
+ conditionObject,
55
+ this.id,
56
+ this.index,
57
+ "options"
58
+ );
59
+
60
+ // Rendering documents sections
61
+ if (condition === true) {
62
+ if (
63
+ typeof option.meta.output === "string" &&
64
+ option.meta.output.trim().length > 0
65
+ ) {
66
+ // output Reference
67
+ const outputReference = this.references.outputs[this.id];
68
+
69
+ // Autonums
70
+ let autonums: [string, string, number, string | null][] = [];
71
+ if (condition !== false) {
72
+ autonums = outputReference.autonums.map(currentAn => {
73
+ const fn =
74
+ currentAn[0] === "numauto-pre"
75
+ ? this.NumAuto.getNumPre
76
+ : this.NumAuto.getNum;
77
+ return [
78
+ currentAn[0],
79
+ currentAn[1],
80
+ fn(currentAn[1], currentAn[2]),
81
+ currentAn[2]
82
+ ];
83
+ });
84
+ }
85
+
86
+ // variables
87
+ const variables = getRelatedVariablesValues(
88
+ this.id,
89
+ this.index,
90
+ outputReference.variables,
91
+ this.ovc,
92
+ this.references
93
+ );
94
+
95
+ const output = parseOutputWithVariables(
96
+ option.meta.output,
97
+ variables,
98
+ autonums
99
+ );
100
+ this.outputs.push(output);
101
+ }
102
+ this.renderChildren();
103
+ }
104
+ }
105
+
106
+ private renderChildren() {
107
+ const option = this.references.options[this.id];
108
+ option.options.forEach(optionId => {
109
+ this.outputs = [
110
+ ...this.outputs,
111
+ ...new OptionRender({
112
+ references: this.references,
113
+ id: optionId,
114
+ ovc: this.ovc,
115
+ index: this.index,
116
+ conditions: this.conditions,
117
+ numauto: this.NumAuto
118
+ }).getOutputs()
119
+ ];
120
+ });
121
+ }
122
+ }
123
+
124
+ export default OptionRender;