@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,122 @@
1
+ import { Types } from "@legalplace/referencesparser";
2
+ import OVC_TYPE from "./ovc.type";
3
+
4
+ /**
5
+ * Returns option's related variable values
6
+ * @param optionId Option's id
7
+ * @param index Occurency index
8
+ * @param variables Variables ids list
9
+ */
10
+ type relVarsValsT = Record<string, string | number>;
11
+ type getRelatedVarsT = (
12
+ optionId: number,
13
+ index: number,
14
+ variables: number[],
15
+ ovc: OVC_TYPE,
16
+ references: Types.ReferencesType
17
+ ) => relVarsValsT;
18
+ export const getRelatedVariablesValues: getRelatedVarsT = (
19
+ optionId,
20
+ index,
21
+ variables,
22
+ ovc,
23
+ references
24
+ ) => {
25
+ // Getting variables values
26
+ const variablesValues: Record<string, string> = {};
27
+ variables.forEach(currentVariableId => {
28
+ // Getting option value
29
+ let value = ovc.variables[currentVariableId] || [""];
30
+ const variableParents =
31
+ references.relations.variables[currentVariableId].parents;
32
+ if (variableParents === undefined)
33
+ throw new Error(
34
+ `Variable ${currentVariableId} parents object does not exist`
35
+ );
36
+ const rootVariableParentId = variableParents[variableParents.length - 1];
37
+ const rootVariableParentRelations =
38
+ references.relations.options[rootVariableParentId];
39
+ if (rootVariableParentRelations === undefined)
40
+ throw new Error(`Option ${rootVariableParentId} does not exist`);
41
+
42
+ if (typeof variableParents === "undefined") return;
43
+
44
+ // Getting rootOption parent
45
+
46
+ // Checking if current option is related to the option that changed
47
+ if (
48
+ rootVariableParentRelations.children.options.includes(optionId) ||
49
+ rootVariableParentRelations.dependants.includes(optionId) ||
50
+ optionId === rootVariableParentId
51
+ )
52
+ value = [value[index]];
53
+
54
+ // Making sure all values are strings
55
+ const cleanValues = value.map(currentValue => {
56
+ if (typeof currentValue === "number") return currentValue.toString();
57
+ if (typeof currentValue === "string") return currentValue;
58
+ return "";
59
+ });
60
+
61
+ // Joining multiple variables
62
+ variablesValues[currentVariableId] =
63
+ cleanValues.length === 1 ? cleanValues[0] : cleanValues.join(", ");
64
+ });
65
+
66
+ return variablesValues;
67
+ };
68
+
69
+ /**
70
+ * Parses output with variables
71
+ * @param output Raw output
72
+ * @param id Box id
73
+ * @param index Occurency Index
74
+ * @param variables Variables values list
75
+ * @param autonums Autonums values
76
+ */
77
+ type autonumsType = [string, string, number, string | null][];
78
+ type parseOutputT = (
79
+ output: string,
80
+ variables: relVarsValsT,
81
+ autonums: autonumsType
82
+ ) => string;
83
+ export const parseOutputWithVariables: parseOutputT = (
84
+ output,
85
+ variables,
86
+ autonums
87
+ ) => {
88
+ // Inserting values
89
+ let parsedOutput = `${output}`;
90
+ Object.keys(variables).forEach(variableId => {
91
+ let value: string = variables[variableId].toString();
92
+ if (value.trim().length === 0) {
93
+ value = new Array(16).join("_");
94
+ }
95
+ parsedOutput = parsedOutput.replace(
96
+ new RegExp(`\\[var:${variableId}\\]`, "g"),
97
+ value
98
+ );
99
+ });
100
+
101
+ // Inserting page breaks
102
+ parsedOutput = parsedOutput.replace(
103
+ "[[PAGE_BREAK]]",
104
+ '<p class="pagebreak"><!-- pagebreak --></p>'
105
+ );
106
+
107
+ // Inserting autonums
108
+ autonums.forEach(currentAn => {
109
+ if (currentAn[3] === null)
110
+ parsedOutput = parsedOutput.replace(
111
+ `[${currentAn[0]}:${currentAn[1]}]`,
112
+ `<span class="${currentAn[0]}">${currentAn[2]}</span>`
113
+ );
114
+ else
115
+ parsedOutput = parsedOutput.replace(
116
+ `[${currentAn[0]}:${currentAn[1]}](${currentAn[3]})`,
117
+ `<span class="${currentAn[0]}">${currentAn[2]}</span>`
118
+ );
119
+ });
120
+
121
+ return parsedOutput;
122
+ };
@@ -0,0 +1,107 @@
1
+ import { ModelV3 } from "@legalplace/models-v3-types";
2
+ import { Types, ReferencesParser } from "@legalplace/referencesparser";
3
+ import crypto from "crypto";
4
+ import DocumentRender from "./DocumentRender";
5
+ import ConditionsRunner from "./ConditionsRunner";
6
+ import OVC_TYPE from "./ovc.type";
7
+ import NumAuto from "./NumAuto";
8
+
9
+ class Prerender {
10
+ private model: ModelV3;
11
+
12
+ private references: Types.ReferencesType;
13
+
14
+ private ovc: OVC_TYPE;
15
+
16
+ private conditions: ConditionsRunner;
17
+
18
+ private documentRender: DocumentRender;
19
+
20
+ private NumAuto: NumAuto;
21
+
22
+ private documentsIndex: Record<
23
+ string,
24
+ {
25
+ name: string;
26
+ pdf: boolean;
27
+ docx: boolean;
28
+ }
29
+ > = {};
30
+
31
+ private renderedDocuments: Record<string, string> = {};
32
+
33
+ constructor(model: ModelV3, ovc: OVC_TYPE) {
34
+ this.model = model;
35
+ this.ovc = ovc;
36
+ this.NumAuto = new NumAuto();
37
+
38
+ // @ts-ignore
39
+ this.references = new ReferencesParser(model).getReferences();
40
+
41
+ // Initiating ConditionsRunner
42
+ this.conditions = new ConditionsRunner(this.references, this.ovc);
43
+
44
+ // Rendering documents
45
+ this.documentRender = new DocumentRender(
46
+ this.references,
47
+ this.conditions,
48
+ this.ovc,
49
+ this.NumAuto
50
+ );
51
+
52
+ this.generateDocumentNamesHash();
53
+ this.generateAllDocuments();
54
+ }
55
+
56
+ public getDocumentsIndex() {
57
+ return this.documentsIndex;
58
+ }
59
+
60
+ private generateDocumentNamesHash() {
61
+ Object.keys(this.model.documents).forEach(documentName => {
62
+ const conditionObject = this.references.conditions.documents[
63
+ documentName
64
+ ];
65
+ const condition =
66
+ conditionObject === undefined
67
+ ? true
68
+ : this.conditions.executeCondition(
69
+ conditionObject,
70
+ 0,
71
+ 0,
72
+ "documents"
73
+ );
74
+
75
+ // Rendering documents sections
76
+ if (condition === true) {
77
+ const hash = crypto
78
+ .createHash("sha1")
79
+ .update(documentName)
80
+ .digest("hex");
81
+
82
+ // Referencing in index
83
+ this.documentsIndex[hash] = {
84
+ name: documentName,
85
+ pdf: true,
86
+ docx: true
87
+ };
88
+ }
89
+ });
90
+ }
91
+
92
+ private generateAllDocuments() {
93
+ Object.keys(this.documentsIndex).forEach(documentNameHash => {
94
+ this.renderedDocuments[
95
+ documentNameHash
96
+ ] = this.documentRender.renderDocument(
97
+ this.documentsIndex[documentNameHash].name
98
+ );
99
+ });
100
+ }
101
+
102
+ public getDocument(documentNameHash: string) {
103
+ return this.renderedDocuments[documentNameHash];
104
+ }
105
+ }
106
+
107
+ export default Prerender;
@@ -0,0 +1,96 @@
1
+ import { Types } from "@legalplace/referencesparser";
2
+ import ConditionsRunner from "./ConditionsRunner";
3
+ import OptionRender from "./OptionRender";
4
+ import OVC_TYPE from "./ovc.type";
5
+ import NumAuto from "./NumAuto";
6
+
7
+ class SectionRender {
8
+ outputs: string[] = [];
9
+
10
+ references: Types.ReferencesType;
11
+
12
+ currentSection: number;
13
+
14
+ documentName: string;
15
+
16
+ conditions: ConditionsRunner;
17
+
18
+ ovc: OVC_TYPE;
19
+
20
+ private NumAuto: NumAuto;
21
+
22
+ constructor(options: {
23
+ references: Types.ReferencesType;
24
+ conditions: ConditionsRunner;
25
+ ovc: OVC_TYPE;
26
+ documentName: string;
27
+ currentSection: number;
28
+ numauto: NumAuto;
29
+ }) {
30
+ this.references = options.references;
31
+ this.conditions = options.conditions;
32
+ this.documentName = options.documentName;
33
+ this.currentSection = options.currentSection;
34
+ this.ovc = options.ovc;
35
+ this.NumAuto = options.numauto;
36
+
37
+ this.renderSection();
38
+ }
39
+
40
+ getOutputs() {
41
+ return this.outputs;
42
+ }
43
+
44
+ private renderSection() {
45
+ const section = this.references.sections[this.documentName][
46
+ this.currentSection
47
+ ];
48
+ const conditionObject = this.references.conditions.sections[
49
+ this.documentName
50
+ ][this.currentSection];
51
+ const condition =
52
+ conditionObject === undefined
53
+ ? true
54
+ : this.conditions.executeCondition(conditionObject, 0, 0, "sections");
55
+
56
+ // Rendering documents sections
57
+ if (condition === true) {
58
+ section.options.forEach(optionId => {
59
+ const option = this.references.options[optionId];
60
+ let repeatOption = optionId;
61
+ if (option.meta.type === "repeated") {
62
+ if (option.meta.repeatOption === undefined) return;
63
+ repeatOption =
64
+ typeof option.meta.repeatOption === "number"
65
+ ? option.meta.repeatOption
66
+ : parseInt(option.meta.repeatOption, 10);
67
+ }
68
+
69
+ // Option inputs
70
+ const inputs = this.ovc.options[repeatOption] || [
71
+ !["radio", "checkbox"].includes(option.meta.type)
72
+ ]; // Falling back on a single value array if option doesn't exist in ovc
73
+
74
+ // Looping through inputs
75
+ inputs.forEach((value, index) => {
76
+ // If value is false we stop here
77
+ if (value !== true) return;
78
+
79
+ this.outputs = [
80
+ ...this.outputs,
81
+ ...new OptionRender({
82
+ references: this.references,
83
+ id: optionId,
84
+ ovc: this.ovc,
85
+ index,
86
+ conditions: this.conditions,
87
+ numauto: this.NumAuto
88
+ }).getOutputs()
89
+ ];
90
+ });
91
+ });
92
+ }
93
+ }
94
+ }
95
+
96
+ export default SectionRender;
@@ -0,0 +1,10 @@
1
+ type OVC_TYPE = {
2
+ options: {
3
+ [key: string]: boolean[];
4
+ };
5
+ variables: {
6
+ [key: string]: (number | string)[];
7
+ };
8
+ };
9
+
10
+ export default OVC_TYPE;
@@ -0,0 +1,12 @@
1
+ {
2
+ // extend your base config so you don't have to redefine your compilerOptions
3
+ "extends": "./tsconfig.json",
4
+ "include": [
5
+ "src/**/*.ts",
6
+ "*.ts",
7
+ // etc
8
+
9
+ // if you have a mixed JS/TS codebase, don't forget to include your JS files
10
+ "src/**/*.js"
11
+ ]
12
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compileOnSave": true,
3
+ "compilerOptions": {
4
+ "target": "es5",
5
+ "module": "commonjs",
6
+ "lib": ["es2018"],
7
+ "outDir": "./dist/",
8
+ "strict": true,
9
+ "typeRoots": ["node_modules/@types"],
10
+ "esModuleInterop": true,
11
+ "removeComments": true,
12
+ "declaration": true
13
+ },
14
+ "include": ["src"],
15
+ "exclude": ["node_modules"]
16
+ }