@fincity/kirun-js 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.
Files changed (217) hide show
  1. package/.prettierrc +9 -0
  2. package/__tests__/engine/function/system/array/AddFirstTest.ts +235 -0
  3. package/__tests__/engine/function/system/array/AddTest.ts +126 -0
  4. package/__tests__/engine/function/system/array/BinarySearchTest.ts +135 -0
  5. package/__tests__/engine/function/system/array/CompareTest.ts +48 -0
  6. package/__tests__/engine/function/system/array/CopyTest.ts +86 -0
  7. package/__tests__/engine/function/system/array/DeleteFirstTest.ts +103 -0
  8. package/__tests__/engine/function/system/array/DeleteFromTest.ts +232 -0
  9. package/__tests__/engine/function/system/array/DeleteLastTest.ts +103 -0
  10. package/__tests__/engine/function/system/array/DeleteTest.ts +110 -0
  11. package/__tests__/engine/function/system/array/DisjointTest.ts +184 -0
  12. package/__tests__/engine/function/system/array/Equals.ts +67 -0
  13. package/__tests__/engine/function/system/array/FillTest.ts +36 -0
  14. package/__tests__/engine/function/system/array/FrequencyTest.ts +97 -0
  15. package/__tests__/engine/function/system/array/IndexOfArrayTest.ts +347 -0
  16. package/__tests__/engine/function/system/array/IndexOfTest.ts +267 -0
  17. package/__tests__/engine/function/system/array/InsertTest.ts +229 -0
  18. package/__tests__/engine/function/system/array/LastIndexOfArrayTest.ts +213 -0
  19. package/__tests__/engine/function/system/array/LastIndexOfTest.ts +253 -0
  20. package/__tests__/engine/function/system/array/MaxTest.ts +98 -0
  21. package/__tests__/engine/function/system/array/MinTest.ts +99 -0
  22. package/__tests__/engine/function/system/array/MisMatchTest.ts +215 -0
  23. package/__tests__/engine/function/system/array/ReverseTest.ts +235 -0
  24. package/__tests__/engine/function/system/array/RotateTest.ts +137 -0
  25. package/__tests__/engine/function/system/array/ShuffleTest.ts +154 -0
  26. package/__tests__/engine/function/system/array/SortTest.ts +130 -0
  27. package/__tests__/engine/function/system/array/SubArrayTest.ts +236 -0
  28. package/__tests__/engine/function/system/math/AddTest.ts +12 -0
  29. package/__tests__/engine/function/system/string/ConcatenateTest.ts +46 -0
  30. package/__tests__/engine/function/system/string/DeleteForGivenLengthTest.ts +38 -0
  31. package/__tests__/engine/function/system/string/InsertAtGivenPositionTest.ts +53 -0
  32. package/__tests__/engine/function/system/string/PostPadTest.ts +54 -0
  33. package/__tests__/engine/function/system/string/PrePadTest.ts +54 -0
  34. package/__tests__/engine/function/system/string/RegionMatchesTest.ts +78 -0
  35. package/__tests__/engine/function/system/string/ReverseTest.ts +36 -0
  36. package/__tests__/engine/function/system/string/SplitTest.ts +61 -0
  37. package/__tests__/engine/function/system/string/StringFunctionRepoTest2.ts +126 -0
  38. package/__tests__/engine/function/system/string/StringFunctionRepoTest3.ts +54 -0
  39. package/__tests__/engine/function/system/string/StringFunctionRepositoryTest.ts +146 -0
  40. package/__tests__/engine/function/system/string/ToStringTest.ts +43 -0
  41. package/__tests__/engine/function/system/string/TrimToTest.ts +28 -0
  42. package/__tests__/engine/json/schema/validator/SchemaValidatorTest.ts +26 -0
  43. package/__tests__/engine/runtime/KIRuntimeTest.ts +351 -0
  44. package/__tests__/engine/runtime/expression/ExpressionEvaluationTest.ts +128 -0
  45. package/__tests__/engine/runtime/expression/ExpressionTest.ts +33 -0
  46. package/__tests__/engine/runtime/expression/tokenextractor/OutputMapTokenValueExtractorTest.ts +44 -0
  47. package/__tests__/engine/runtime/expression/tokenextractor/TokenValueExtractorTest.ts +72 -0
  48. package/__tests__/engine/util/LinkedListTest.ts +29 -0
  49. package/__tests__/engine/util/string/StringFormatterTest.ts +17 -0
  50. package/__tests__/indexTest.ts +33 -0
  51. package/dist/index.js +2 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/module.js +2 -0
  54. package/dist/module.js.map +1 -0
  55. package/dist/types.d.ts +430 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/package.json +54 -0
  58. package/src/engine/HybridRepository.ts +18 -0
  59. package/src/engine/Repository.ts +3 -0
  60. package/src/engine/constant/KIRunConstants.ts +7 -0
  61. package/src/engine/exception/ExecutionException.ts +12 -0
  62. package/src/engine/exception/KIRuntimeException.ts +12 -0
  63. package/src/engine/function/AbstractFunction.ts +76 -0
  64. package/src/engine/function/Function.ts +13 -0
  65. package/src/engine/function/system/GenerateEvent.ts +76 -0
  66. package/src/engine/function/system/If.ts +40 -0
  67. package/src/engine/function/system/array/AbstractArrayFunction.ts +158 -0
  68. package/src/engine/function/system/array/Add.ts +31 -0
  69. package/src/engine/function/system/array/AddFirst.ts +44 -0
  70. package/src/engine/function/system/array/BinarySearch.ts +66 -0
  71. package/src/engine/function/system/array/Compare.ts +150 -0
  72. package/src/engine/function/system/array/Copy.ts +56 -0
  73. package/src/engine/function/system/array/Delete.ts +63 -0
  74. package/src/engine/function/system/array/DeleteFirst.ts +22 -0
  75. package/src/engine/function/system/array/DeleteFrom.ts +51 -0
  76. package/src/engine/function/system/array/DeleteLast.ts +23 -0
  77. package/src/engine/function/system/array/Disjoint.ts +85 -0
  78. package/src/engine/function/system/array/Equals.ts +36 -0
  79. package/src/engine/function/system/array/Fill.ts +51 -0
  80. package/src/engine/function/system/array/Frequency.ts +68 -0
  81. package/src/engine/function/system/array/IndexOf.ts +56 -0
  82. package/src/engine/function/system/array/IndexOfArray.ts +67 -0
  83. package/src/engine/function/system/array/Insert.ts +48 -0
  84. package/src/engine/function/system/array/LastIndexOf.ts +62 -0
  85. package/src/engine/function/system/array/LastIndexOfArray.ts +70 -0
  86. package/src/engine/function/system/array/Max.ts +31 -0
  87. package/src/engine/function/system/array/Min.ts +32 -0
  88. package/src/engine/function/system/array/MisMatch.ts +66 -0
  89. package/src/engine/function/system/array/Reverse.ts +50 -0
  90. package/src/engine/function/system/array/Rotate.ts +43 -0
  91. package/src/engine/function/system/array/Shuffle.ts +31 -0
  92. package/src/engine/function/system/array/Sort.ts +70 -0
  93. package/src/engine/function/system/array/SubArray.ts +48 -0
  94. package/src/engine/function/system/context/Create.ts +73 -0
  95. package/src/engine/function/system/context/Get.ts +55 -0
  96. package/src/engine/function/system/context/SetFunction.ts +244 -0
  97. package/src/engine/function/system/loop/CountLoop.ts +55 -0
  98. package/src/engine/function/system/loop/RangeLoop.ts +120 -0
  99. package/src/engine/function/system/math/Add.ts +34 -0
  100. package/src/engine/function/system/math/GenericMathFunction.ts +80 -0
  101. package/src/engine/function/system/math/Hypotenuse.ts +57 -0
  102. package/src/engine/function/system/math/MathFunctionRepository.ts +63 -0
  103. package/src/engine/function/system/math/Maximum.ts +38 -0
  104. package/src/engine/function/system/math/Minimum.ts +38 -0
  105. package/src/engine/function/system/math/Random.ts +27 -0
  106. package/src/engine/function/system/string/AbstractStringFunction.ts +409 -0
  107. package/src/engine/function/system/string/Concatenate.ts +57 -0
  108. package/src/engine/function/system/string/DeleteForGivenLength.ts +82 -0
  109. package/src/engine/function/system/string/InsertAtGivenPosition.ts +72 -0
  110. package/src/engine/function/system/string/PostPad.ts +83 -0
  111. package/src/engine/function/system/string/PrePad.ts +73 -0
  112. package/src/engine/function/system/string/RegionMatches.ts +119 -0
  113. package/src/engine/function/system/string/ReplaceAtGivenPosition.ts +101 -0
  114. package/src/engine/function/system/string/Reverse.ts +62 -0
  115. package/src/engine/function/system/string/Split.ts +53 -0
  116. package/src/engine/function/system/string/StringFunctionRepository.ts +60 -0
  117. package/src/engine/function/system/string/ToString.ts +45 -0
  118. package/src/engine/function/system/string/TrimTo.ts +55 -0
  119. package/src/engine/json/JsonExpression.ts +11 -0
  120. package/src/engine/json/schema/Schema.ts +670 -0
  121. package/src/engine/json/schema/SchemaUtil.ts +145 -0
  122. package/src/engine/json/schema/array/ArraySchemaType.ts +44 -0
  123. package/src/engine/json/schema/object/AdditionalPropertiesType.ts +32 -0
  124. package/src/engine/json/schema/string/StringFormat.ts +7 -0
  125. package/src/engine/json/schema/type/MultipleType.ts +28 -0
  126. package/src/engine/json/schema/type/SchemaType.ts +11 -0
  127. package/src/engine/json/schema/type/SingleType.ts +23 -0
  128. package/src/engine/json/schema/type/Type.ts +6 -0
  129. package/src/engine/json/schema/type/TypeUtil.ts +25 -0
  130. package/src/engine/json/schema/validator/AnyOfAllOfOneOfValidator.ts +108 -0
  131. package/src/engine/json/schema/validator/ArrayValidator.ts +145 -0
  132. package/src/engine/json/schema/validator/BooleanValidator.ts +24 -0
  133. package/src/engine/json/schema/validator/NullValidator.ts +17 -0
  134. package/src/engine/json/schema/validator/NumberValidator.ts +115 -0
  135. package/src/engine/json/schema/validator/ObjectValidator.ts +184 -0
  136. package/src/engine/json/schema/validator/SchemaValidator.ts +141 -0
  137. package/src/engine/json/schema/validator/StringValidator.ts +97 -0
  138. package/src/engine/json/schema/validator/TypeValidator.ts +49 -0
  139. package/src/engine/json/schema/validator/exception/SchemaReferenceException.ts +19 -0
  140. package/src/engine/json/schema/validator/exception/SchemaValidationException.ts +22 -0
  141. package/src/engine/model/AbstractStatement.ts +29 -0
  142. package/src/engine/model/Argument.ts +36 -0
  143. package/src/engine/model/Event.ts +62 -0
  144. package/src/engine/model/EventResult.ts +34 -0
  145. package/src/engine/model/FunctionDefinition.ts +69 -0
  146. package/src/engine/model/FunctionOutput.ts +37 -0
  147. package/src/engine/model/FunctionOutputGenerator.ts +5 -0
  148. package/src/engine/model/FunctionSignature.ts +67 -0
  149. package/src/engine/model/Parameter.ts +97 -0
  150. package/src/engine/model/ParameterReference.ts +57 -0
  151. package/src/engine/model/ParameterReferenceType.ts +4 -0
  152. package/src/engine/model/ParameterType.ts +4 -0
  153. package/src/engine/model/Position.ts +40 -0
  154. package/src/engine/model/Statement.ts +101 -0
  155. package/src/engine/model/StatementGroup.ts +37 -0
  156. package/src/engine/namespaces/Namespaces.ts +11 -0
  157. package/src/engine/repository/KIRunFunctionRepository.ts +37 -0
  158. package/src/engine/repository/KIRunSchemaRepository.ts +24 -0
  159. package/src/engine/runtime/ContextElement.ts +28 -0
  160. package/src/engine/runtime/FunctionExecutionParameters.ts +74 -0
  161. package/src/engine/runtime/KIRuntime.ts +653 -0
  162. package/src/engine/runtime/StatementExecution.ts +61 -0
  163. package/src/engine/runtime/StatementMessage.ts +30 -0
  164. package/src/engine/runtime/StatementMessageType.ts +5 -0
  165. package/src/engine/runtime/expression/Expression.ts +330 -0
  166. package/src/engine/runtime/expression/ExpressionEvaluator.ts +305 -0
  167. package/src/engine/runtime/expression/ExpressionToken.ts +15 -0
  168. package/src/engine/runtime/expression/ExpressionTokenValue.ts +23 -0
  169. package/src/engine/runtime/expression/Operation.ts +190 -0
  170. package/src/engine/runtime/expression/exception/ExpressionEvaluationException.ts +15 -0
  171. package/src/engine/runtime/expression/operators/binary/ArithmeticAdditionOperator.ts +9 -0
  172. package/src/engine/runtime/expression/operators/binary/ArithmeticDivisionOperator.ts +9 -0
  173. package/src/engine/runtime/expression/operators/binary/ArithmeticInetgerDivisionOperator.ts +9 -0
  174. package/src/engine/runtime/expression/operators/binary/ArithmeticModulusOperator.ts +9 -0
  175. package/src/engine/runtime/expression/operators/binary/ArithmeticMultiplicationOperator.ts +9 -0
  176. package/src/engine/runtime/expression/operators/binary/ArithmeticSubtractionOperator.ts +9 -0
  177. package/src/engine/runtime/expression/operators/binary/ArrayOperator.ts +31 -0
  178. package/src/engine/runtime/expression/operators/binary/BinaryOperator.ts +15 -0
  179. package/src/engine/runtime/expression/operators/binary/BitwiseAndOperator.ts +9 -0
  180. package/src/engine/runtime/expression/operators/binary/BitwiseLeftShiftOperator.ts +9 -0
  181. package/src/engine/runtime/expression/operators/binary/BitwiseOrOperator.ts +9 -0
  182. package/src/engine/runtime/expression/operators/binary/BitwiseRightShiftOperator.ts +9 -0
  183. package/src/engine/runtime/expression/operators/binary/BitwiseUnsignedRightShiftOperator.ts +9 -0
  184. package/src/engine/runtime/expression/operators/binary/BitwiseXorOperator.ts +9 -0
  185. package/src/engine/runtime/expression/operators/binary/LogicalAndOperator.ts +25 -0
  186. package/src/engine/runtime/expression/operators/binary/LogicalEqualOperator.ts +13 -0
  187. package/src/engine/runtime/expression/operators/binary/LogicalGreaterThanEqualOperator.ts +24 -0
  188. package/src/engine/runtime/expression/operators/binary/LogicalGreaterThanOperator.ts +24 -0
  189. package/src/engine/runtime/expression/operators/binary/LogicalLessThanEqualOperator.ts +24 -0
  190. package/src/engine/runtime/expression/operators/binary/LogicalLessThanOperator.ts +24 -0
  191. package/src/engine/runtime/expression/operators/binary/LogicalNotEqualOperator.ts +13 -0
  192. package/src/engine/runtime/expression/operators/binary/LogicalOrOperator.ts +25 -0
  193. package/src/engine/runtime/expression/operators/binary/ObjectOperator.ts +24 -0
  194. package/src/engine/runtime/expression/operators/unary/ArithmeticUnaryMinusOperator.ts +13 -0
  195. package/src/engine/runtime/expression/operators/unary/ArithmeticUnaryPlusOperator.ts +13 -0
  196. package/src/engine/runtime/expression/operators/unary/BitwiseComplementOperator.ts +22 -0
  197. package/src/engine/runtime/expression/operators/unary/LogicalNotOperator.ts +22 -0
  198. package/src/engine/runtime/expression/operators/unary/UnaryOperator.ts +15 -0
  199. package/src/engine/runtime/expression/tokenextractor/LiteralTokenValueExtractor.ts +64 -0
  200. package/src/engine/runtime/expression/tokenextractor/TokenValueExtractor.ts +136 -0
  201. package/src/engine/runtime/graph/ExecutionGraph.ts +81 -0
  202. package/src/engine/runtime/graph/GraphVertex.ts +118 -0
  203. package/src/engine/runtime/graph/GraphVertexType.ts +4 -0
  204. package/src/engine/runtime/tokenextractor/ArgumentsTokenValueExtractor.ts +22 -0
  205. package/src/engine/runtime/tokenextractor/ContextTokenValueExtractor.ts +37 -0
  206. package/src/engine/runtime/tokenextractor/OutputMapTokenValueExtractor.ts +32 -0
  207. package/src/engine/util/ArrayUtil.ts +23 -0
  208. package/src/engine/util/LinkedList.ts +229 -0
  209. package/src/engine/util/MapUtil.ts +86 -0
  210. package/src/engine/util/NullCheck.ts +3 -0
  211. package/src/engine/util/Tuples.ts +43 -0
  212. package/src/engine/util/primitive/PrimitiveUtil.ts +143 -0
  213. package/src/engine/util/string/StringBuilder.ts +59 -0
  214. package/src/engine/util/string/StringFormatter.ts +25 -0
  215. package/src/engine/util/string/StringUtil.ts +48 -0
  216. package/src/index.ts +13 -0
  217. package/tsconfig.json +6 -0
@@ -0,0 +1,653 @@
1
+ import { KIRuntimeException } from '../exception/KIRuntimeException';
2
+ import { AbstractFunction } from '../function/AbstractFunction';
3
+ import { Function } from '../function/Function';
4
+ import { Repository } from '../Repository';
5
+ import { JsonExpression } from '../json/JsonExpression';
6
+ import { Schema } from '../json/schema/Schema';
7
+ import { SchemaUtil } from '../json/schema/SchemaUtil';
8
+ import { Event } from '../model/Event';
9
+ import { EventResult } from '../model/EventResult';
10
+ import { FunctionDefinition } from '../model/FunctionDefinition';
11
+ import { FunctionOutput } from '../model/FunctionOutput';
12
+ import { FunctionSignature } from '../model/FunctionSignature';
13
+ import { Parameter } from '../model/Parameter';
14
+ import { ParameterReference } from '../model/ParameterReference';
15
+ import { ParameterReferenceType } from '../model/ParameterReferenceType';
16
+ import { Statement } from '../model/Statement';
17
+ import { LinkedList } from '../util/LinkedList';
18
+ import { StringFormatter } from '../util/string/StringFormatter';
19
+ import { StringUtil } from '../util/string/StringUtil';
20
+ import { Tuple4, Tuple2 } from '../util/Tuples';
21
+ import { ContextElement } from './ContextElement';
22
+ import { ExpressionEvaluator } from './expression/ExpressionEvaluator';
23
+ import { FunctionExecutionParameters } from './FunctionExecutionParameters';
24
+ import { ExecutionGraph } from './graph/ExecutionGraph';
25
+ import { GraphVertex } from './graph/GraphVertex';
26
+ import { StatementExecution } from './StatementExecution';
27
+ import { StatementMessageType } from './StatementMessageType';
28
+ import { isNullValue } from '../util/NullCheck';
29
+ import { SchemaType } from '../json/schema/type/SchemaType';
30
+ import { ArraySchemaType } from '../json/schema/array/ArraySchemaType';
31
+
32
+ export class KIRuntime extends AbstractFunction {
33
+ private static readonly PARAMETER_NEEDS_A_VALUE: string = 'Parameter "$" needs a value';
34
+
35
+ private static readonly STEP_REGEX_PATTERN: RegExp = new RegExp(
36
+ 'Steps\\.([a-zA-Z0-9\\\\-]{1,})\\.([a-zA-Z0-9\\\\-]{1,})',
37
+ 'g',
38
+ );
39
+
40
+ private static readonly VERSION: number = 1;
41
+
42
+ private static readonly MAX_EXECUTION_ITERATIONS: number = 10000000;
43
+
44
+ private fd: FunctionDefinition;
45
+
46
+ private fRepo: Repository<Function>;
47
+
48
+ private sRepo: Repository<Schema>;
49
+
50
+ public constructor(
51
+ fd: FunctionDefinition,
52
+ functionRepository: Repository<Function>,
53
+ schemaRepository: Repository<Schema>,
54
+ ) {
55
+ super();
56
+ this.fd = fd;
57
+ if (this.fd.getVersion() > KIRuntime.VERSION) {
58
+ throw new KIRuntimeException(
59
+ 'Runtime is at a lower version ' +
60
+ KIRuntime.VERSION +
61
+ ' and trying to run code from version ' +
62
+ this.fd.getVersion() +
63
+ '.',
64
+ );
65
+ }
66
+
67
+ this.fRepo = functionRepository;
68
+ this.sRepo = schemaRepository;
69
+ }
70
+
71
+ public getSignature(): FunctionSignature {
72
+ return this.fd;
73
+ }
74
+
75
+ private getExecutionPlan(
76
+ context: Map<string, ContextElement>,
77
+ ): ExecutionGraph<string, StatementExecution> {
78
+ let g: ExecutionGraph<string, StatementExecution> = new ExecutionGraph();
79
+ for (let s of Array.from(this.fd.getSteps().values()))
80
+ g.addVertex(this.prepareStatementExecution(context, s));
81
+
82
+ let unresolvedList: Tuple2<string, string>[] = this.makeEdges(g);
83
+
84
+ if (unresolvedList.length) {
85
+ throw new KIRuntimeException(
86
+ StringFormatter.format(
87
+ 'Found these unresolved dependencies : $ ',
88
+ unresolvedList.map((e) =>
89
+ StringFormatter.format('Steps.$.$', e.getT1(), e.getT2()),
90
+ ),
91
+ ),
92
+ );
93
+ }
94
+
95
+ return g;
96
+ }
97
+
98
+ protected internalExecute(inContext: FunctionExecutionParameters): FunctionOutput {
99
+ if (!inContext.getContext()) inContext.setContext(new Map());
100
+
101
+ if (!inContext.getEvents()) inContext.setEvents(new Map());
102
+
103
+ if (!inContext.getSteps()) inContext.setSteps(new Map());
104
+
105
+ let eGraph: ExecutionGraph<string, StatementExecution> = this.getExecutionPlan(
106
+ inContext.getContext()!,
107
+ );
108
+
109
+ // if (logger.isDebugEnabled()) {
110
+ // logger.debug(StringFormatter.format("Executing : $.$", this.fd.getNamespace(), this.fd.getName()));
111
+ // logger.debug(eGraph.toString());
112
+ // }
113
+
114
+ let messages: string[] = eGraph
115
+ .getVerticesData()
116
+ .filter((e) => e.getMessages().length)
117
+ .map((e) => e.getStatement().getStatementName() + ': \n' + e.getMessages().join(','));
118
+
119
+ if (messages?.length) {
120
+ throw new KIRuntimeException(
121
+ 'Please fix the errors in the function definition before execution : \n' +
122
+ messages.join(',\n'),
123
+ );
124
+ }
125
+
126
+ return this.executeGraph(eGraph, inContext);
127
+ }
128
+
129
+ private executeGraph(
130
+ eGraph: ExecutionGraph<string, StatementExecution>,
131
+ inContext: FunctionExecutionParameters,
132
+ ): FunctionOutput {
133
+ let executionQue: LinkedList<GraphVertex<string, StatementExecution>> = new LinkedList();
134
+ executionQue.addAll(eGraph.getVerticesWithNoIncomingEdges());
135
+
136
+ let branchQue: LinkedList<
137
+ Tuple4<
138
+ ExecutionGraph<string, StatementExecution>,
139
+ Tuple2<string, string>[],
140
+ FunctionOutput,
141
+ GraphVertex<string, StatementExecution>
142
+ >
143
+ > = new LinkedList();
144
+
145
+ while (
146
+ (!executionQue.isEmpty() || !branchQue.isEmpty()) &&
147
+ !inContext.getEvents()?.has(Event.OUTPUT)
148
+ ) {
149
+ this.processBranchQue(inContext, executionQue, branchQue);
150
+ this.processExecutionQue(inContext, executionQue, branchQue);
151
+
152
+ inContext.setCount(inContext.getCount() + 1);
153
+
154
+ if (inContext.getCount() == KIRuntime.MAX_EXECUTION_ITERATIONS)
155
+ throw new KIRuntimeException('Execution locked in an infinite loop');
156
+ }
157
+
158
+ if (!eGraph.isSubGraph() && !inContext.getEvents()?.size) {
159
+ throw new KIRuntimeException('No events raised');
160
+ }
161
+
162
+ return new FunctionOutput(
163
+ Array.from(inContext.getEvents()?.entries() ?? []).flatMap((e) =>
164
+ e[1].map((v) => EventResult.of(e[0], v)),
165
+ ),
166
+ );
167
+ }
168
+
169
+ private processExecutionQue(
170
+ inContext: FunctionExecutionParameters,
171
+ executionQue: LinkedList<GraphVertex<string, StatementExecution>>,
172
+ branchQue: LinkedList<
173
+ Tuple4<
174
+ ExecutionGraph<string, StatementExecution>,
175
+ Tuple2<string, string>[],
176
+ FunctionOutput,
177
+ GraphVertex<string, StatementExecution>
178
+ >
179
+ >,
180
+ ): void {
181
+ if (!executionQue.isEmpty()) {
182
+ let vertex: GraphVertex<string, StatementExecution> = executionQue.pop();
183
+
184
+ if (!this.allDependenciesResolvedVertex(vertex, inContext.getSteps()!))
185
+ executionQue.add(vertex);
186
+ else this.executeVertex(vertex, inContext, branchQue, executionQue);
187
+ }
188
+ }
189
+
190
+ private processBranchQue(
191
+ inContext: FunctionExecutionParameters,
192
+ executionQue: LinkedList<GraphVertex<string, StatementExecution>>,
193
+ branchQue: LinkedList<
194
+ Tuple4<
195
+ ExecutionGraph<string, StatementExecution>,
196
+ Tuple2<string, string>[],
197
+ FunctionOutput,
198
+ GraphVertex<string, StatementExecution>
199
+ >
200
+ >,
201
+ ): void {
202
+ if (branchQue.length) {
203
+ let branch: Tuple4<
204
+ ExecutionGraph<string, StatementExecution>,
205
+ Tuple2<string, string>[],
206
+ FunctionOutput,
207
+ GraphVertex<string, StatementExecution>
208
+ > = branchQue.pop();
209
+
210
+ if (!this.allDependenciesResolvedTuples(branch.getT2(), inContext.getSteps()!))
211
+ branchQue.add(branch);
212
+ else this.executeBranch(inContext, executionQue, branch);
213
+ }
214
+ }
215
+
216
+ private executeBranch(
217
+ inContext: FunctionExecutionParameters,
218
+ executionQue: LinkedList<GraphVertex<string, StatementExecution>>,
219
+ branch: Tuple4<
220
+ ExecutionGraph<string, StatementExecution>,
221
+ Tuple2<string, string>[],
222
+ FunctionOutput,
223
+ GraphVertex<string, StatementExecution>
224
+ >,
225
+ ): void {
226
+ let vertex: GraphVertex<string, StatementExecution> = branch.getT4();
227
+ let nextOutput: EventResult | undefined = undefined;
228
+
229
+ do {
230
+ this.executeGraph(branch.getT1(), inContext);
231
+ nextOutput = branch.getT3().next();
232
+
233
+ if (nextOutput) {
234
+ if (!inContext.getSteps()?.has(vertex.getData().getStatement().getStatementName()))
235
+ inContext
236
+ .getSteps()
237
+ ?.set(vertex.getData().getStatement().getStatementName(), new Map());
238
+
239
+ inContext
240
+ .getSteps()
241
+ ?.get(vertex.getData().getStatement().getStatementName())
242
+ ?.set(
243
+ nextOutput.getName(),
244
+ this.resolveInternalExpressions(nextOutput.getResult(), inContext),
245
+ );
246
+ }
247
+ } while (nextOutput && nextOutput.getName() != Event.OUTPUT);
248
+
249
+ if (nextOutput?.getName() == Event.OUTPUT && vertex.getOutVertices().has(Event.OUTPUT)) {
250
+ (vertex?.getOutVertices()?.get(Event.OUTPUT) ?? []).forEach((e) => executionQue.add(e));
251
+ }
252
+ }
253
+
254
+ private executeVertex(
255
+ vertex: GraphVertex<string, StatementExecution>,
256
+ inContext: FunctionExecutionParameters,
257
+ branchQue: LinkedList<
258
+ Tuple4<
259
+ ExecutionGraph<string, StatementExecution>,
260
+ Tuple2<string, string>[],
261
+ FunctionOutput,
262
+ GraphVertex<string, StatementExecution>
263
+ >
264
+ >,
265
+ executionQue: LinkedList<GraphVertex<string, StatementExecution>>,
266
+ ): void {
267
+ let s: Statement = vertex.getData().getStatement();
268
+
269
+ let fun: Function | undefined = this.fRepo.find(s.getNamespace(), s.getName());
270
+
271
+ if (!fun) {
272
+ throw new KIRuntimeException(
273
+ StringFormatter.format('$.$ function is not found.', s.getNamespace(), s.getName()),
274
+ );
275
+ }
276
+
277
+ let paramSet: Map<string, Parameter> | undefined = fun?.getSignature().getParameters();
278
+
279
+ let args: Map<string, any> = this.getArgumentsFromParametersMap(
280
+ inContext,
281
+ s,
282
+ paramSet ?? new Map(),
283
+ );
284
+
285
+ let context: Map<string, ContextElement> = inContext.getContext()!;
286
+
287
+ let result: FunctionOutput = fun.execute(
288
+ new FunctionExecutionParameters()
289
+ .setContext(context)
290
+ .setArguments(args)
291
+ .setEvents(inContext.getEvents()!)
292
+ .setSteps(inContext.getSteps()!)
293
+ .setStatementExecution(vertex.getData())
294
+ .setCount(inContext.getCount()),
295
+ );
296
+
297
+ let er: EventResult | undefined = result.next();
298
+
299
+ if (!er)
300
+ throw new KIRuntimeException(
301
+ StringFormatter.format('Executing $ returned no events', s.getStatementName()),
302
+ );
303
+
304
+ let isOutput: boolean = er.getName() == Event.OUTPUT;
305
+
306
+ if (!inContext.getSteps()?.has(s.getStatementName())) {
307
+ inContext.getSteps()!.set(s.getStatementName(), new Map());
308
+ }
309
+ inContext
310
+ .getSteps()!
311
+ .get(s.getStatementName())!
312
+ .set(er.getName(), this.resolveInternalExpressions(er.getResult(), inContext));
313
+
314
+ if (!isOutput) {
315
+ let subGraph = vertex.getSubGraphOfType(er.getName());
316
+ let unResolvedDependencies: Tuple2<string, string>[] = this.makeEdges(subGraph);
317
+ branchQue.push(new Tuple4(subGraph, unResolvedDependencies, result, vertex));
318
+ } else {
319
+ let out: Set<GraphVertex<string, StatementExecution>> | undefined = vertex
320
+ .getOutVertices()
321
+ .get(Event.OUTPUT);
322
+ if (out) out.forEach((e) => executionQue.add(e));
323
+ }
324
+ }
325
+
326
+ private resolveInternalExpressions(
327
+ result: Map<string, any>,
328
+ inContext: FunctionExecutionParameters,
329
+ ): Map<string, any> {
330
+ if (!result) return result;
331
+
332
+ return Array.from(result.entries())
333
+ .map((e) => new Tuple2(e[0], this.resolveInternalExpression(e[1], inContext)))
334
+ .reduce((a, c) => {
335
+ a.set(c.getT1(), c.getT2());
336
+ return a;
337
+ }, new Map());
338
+ }
339
+
340
+ private resolveInternalExpression(value: any, inContext: FunctionExecutionParameters): any {
341
+ if (isNullValue(value) || typeof value != 'object') return value;
342
+
343
+ if (value instanceof JsonExpression) {
344
+ let exp: ExpressionEvaluator = new ExpressionEvaluator(
345
+ (value as JsonExpression).getExpression(),
346
+ );
347
+ return exp.evaluate(inContext.getValuesMap());
348
+ }
349
+
350
+ if (Array.isArray(value)) {
351
+ let retArray: any[] = [];
352
+
353
+ for (let obj of value) {
354
+ retArray.push(this.resolveInternalExpression(obj, inContext));
355
+ }
356
+
357
+ return retArray;
358
+ }
359
+
360
+ if (typeof value === 'object') {
361
+ let retObject: any = {};
362
+
363
+ for (let entry of Object.entries(value)) {
364
+ retObject[entry[0]] = this.resolveInternalExpression(entry[1], inContext);
365
+ }
366
+
367
+ return retObject;
368
+ }
369
+
370
+ return undefined;
371
+ }
372
+
373
+ private allDependenciesResolvedTuples(
374
+ unResolvedDependencies: Tuple2<string, string>[],
375
+ output: Map<string, Map<string, Map<string, any>>>,
376
+ ): boolean {
377
+ for (let tup of unResolvedDependencies) {
378
+ if (!output.has(tup.getT1())) return false;
379
+ if (!output.get(tup.getT1())?.get(tup.getT2())) return false;
380
+ }
381
+
382
+ return true;
383
+ }
384
+
385
+ private allDependenciesResolvedVertex(
386
+ vertex: GraphVertex<string, StatementExecution>,
387
+ output: Map<string, Map<string, Map<string, any>>>,
388
+ ): boolean {
389
+ if (!vertex.getInVertices().size) return true;
390
+
391
+ return (
392
+ Array.from(vertex.getInVertices()).filter((e) => {
393
+ let stepName: string = e.getT1().getData().getStatement().getStatementName();
394
+ let type: string = e.getT2();
395
+
396
+ return !(output.has(stepName) && output.get(stepName)?.has(type));
397
+ }).length == 0
398
+ );
399
+ }
400
+
401
+ private getArgumentsFromParametersMap(
402
+ inContext: FunctionExecutionParameters,
403
+ s: Statement,
404
+ paramSet: Map<string, Parameter>,
405
+ ): Map<string, any> {
406
+ return Array.from(s.getParameterMap().entries())
407
+ .map((e) => {
408
+ let prList: ParameterReference[] = e[1];
409
+
410
+ let ret: any = undefined;
411
+
412
+ if (!prList?.length) return new Tuple2(e[0], ret);
413
+
414
+ let pDef: Parameter | undefined = paramSet.get(e[0]);
415
+
416
+ if (!pDef) return new Tuple2(e[0], undefined);
417
+
418
+ if (pDef.isVariableArgument()) {
419
+ ret = prList
420
+ .map((r) => this.parameterReferenceEvaluation(inContext, r))
421
+ .flatMap((r) => (Array.isArray(r) ? r : [r]));
422
+ } else {
423
+ ret = this.parameterReferenceEvaluation(inContext, prList[0]);
424
+ }
425
+
426
+ return new Tuple2(e[0], ret);
427
+ })
428
+ .filter((e) => !isNullValue(e.getT2()))
429
+ .reduce((a, c) => {
430
+ a.set(c.getT1(), c.getT2());
431
+ return a;
432
+ }, new Map());
433
+ }
434
+
435
+ private parameterReferenceEvaluation(
436
+ inContext: FunctionExecutionParameters,
437
+ ref: ParameterReference,
438
+ ): any {
439
+ let ret: any = undefined;
440
+
441
+ if (ref.getType() == ParameterReferenceType.VALUE) {
442
+ ret = this.resolveInternalExpression(ref.getValue(), inContext);
443
+ } else if (
444
+ ref.getType() == ParameterReferenceType.EXPRESSION &&
445
+ !StringUtil.isNullOrBlank(ref.getExpression())
446
+ ) {
447
+ let exp: ExpressionEvaluator = new ExpressionEvaluator(ref.getExpression() ?? '');
448
+ ret = exp.evaluate(inContext.getValuesMap());
449
+ }
450
+ return ret;
451
+ }
452
+
453
+ private prepareStatementExecution(
454
+ context: Map<string, ContextElement>,
455
+ s: Statement,
456
+ ): StatementExecution {
457
+ let se: StatementExecution = new StatementExecution(s);
458
+
459
+ let fun: Function | undefined = this.fRepo.find(s.getNamespace(), s.getName());
460
+
461
+ if (!fun) {
462
+ throw new KIRuntimeException(
463
+ StringFormatter.format('$.$ was not available', s.getNamespace(), s.getName()),
464
+ );
465
+ }
466
+
467
+ let paramSet: Map<string, Parameter> = new Map(fun.getSignature().getParameters());
468
+
469
+ for (let param of Array.from(s.getParameterMap().entries())) {
470
+ let p: Parameter | undefined = paramSet.get(param[0]);
471
+ if (!p) continue;
472
+
473
+ let refList: ParameterReference[] = param[1];
474
+
475
+ if (!refList.length) {
476
+ if (isNullValue(SchemaUtil.getDefaultValue(p.getSchema(), this.sRepo)))
477
+ se.addMessage(
478
+ StatementMessageType.ERROR,
479
+ StringFormatter.format(
480
+ KIRuntime.PARAMETER_NEEDS_A_VALUE,
481
+ p.getParameterName(),
482
+ ),
483
+ );
484
+ continue;
485
+ }
486
+
487
+ if (p.isVariableArgument()) {
488
+ for (let ref of refList) this.parameterReferenceValidation(context, se, p, ref);
489
+ } else {
490
+ let ref: ParameterReference = refList[0];
491
+ this.parameterReferenceValidation(context, se, p, ref);
492
+ }
493
+
494
+ paramSet.delete(p.getParameterName());
495
+ }
496
+
497
+ if (!isNullValue(se.getStatement().getDependentStatements())) {
498
+ for (let statement of se.getStatement().getDependentStatements())
499
+ se.addDependency(statement);
500
+ }
501
+
502
+ if (paramSet.size) {
503
+ for (let param of Array.from(paramSet.values())) {
504
+ if (isNullValue(SchemaUtil.getDefaultValue(param.getSchema(), this.sRepo)))
505
+ se.addMessage(
506
+ StatementMessageType.ERROR,
507
+ StringFormatter.format(
508
+ KIRuntime.PARAMETER_NEEDS_A_VALUE,
509
+ param.getParameterName(),
510
+ ),
511
+ );
512
+ }
513
+ }
514
+
515
+ return se;
516
+ }
517
+
518
+ private parameterReferenceValidation(
519
+ context: Map<string, ContextElement>,
520
+ se: StatementExecution,
521
+ p: Parameter,
522
+ ref: ParameterReference,
523
+ ): void {
524
+ // Breaking this execution doesn't make sense.
525
+
526
+ if (!ref) {
527
+ if (isNullValue(SchemaUtil.getDefaultValue(p.getSchema(), this.sRepo)))
528
+ se.addMessage(
529
+ StatementMessageType.ERROR,
530
+ StringFormatter.format(KIRuntime.PARAMETER_NEEDS_A_VALUE, p.getParameterName()),
531
+ );
532
+ } else if (ref.getType() == ParameterReferenceType.VALUE) {
533
+ if (
534
+ isNullValue(ref.getValue()) &&
535
+ isNullValue(SchemaUtil.getDefaultValue(p.getSchema(), this.sRepo))
536
+ )
537
+ se.addMessage(
538
+ StatementMessageType.ERROR,
539
+ StringFormatter.format(KIRuntime.PARAMETER_NEEDS_A_VALUE, p.getParameterName()),
540
+ );
541
+ let paramElements: LinkedList<Tuple2<Schema, any>> = new LinkedList();
542
+ paramElements.push(new Tuple2(p.getSchema(), ref.getValue()));
543
+
544
+ while (!paramElements.isEmpty()) {
545
+ let e: Tuple2<Schema, any> = paramElements.pop();
546
+
547
+ if (e.getT2() instanceof JsonExpression) {
548
+ this.addDependencies(se, (e.getT2() as JsonExpression).getExpression());
549
+ } else {
550
+ if (isNullValue(e.getT1()) || isNullValue(e.getT1().getType())) continue;
551
+
552
+ if (
553
+ e.getT1().getType()?.contains(SchemaType.ARRAY) &&
554
+ Array.isArray(e.getT2())
555
+ ) {
556
+ let ast: ArraySchemaType | undefined = e.getT1().getItems();
557
+ if (!ast) {
558
+ continue;
559
+ }
560
+ if (ast.isSingleType()) {
561
+ for (let je of e.getT2())
562
+ paramElements.push(new Tuple2(ast.getSingleSchema()!, je));
563
+ } else {
564
+ let array: any[] = e.getT2() as any[];
565
+ for (let i = 0; i < array.length; i++) {
566
+ paramElements.push(new Tuple2(ast.getTupleSchema()![i], array[i]));
567
+ }
568
+ }
569
+ } else if (
570
+ e.getT1().getType()?.contains(SchemaType.OBJECT) &&
571
+ typeof e.getT2() == 'object'
572
+ ) {
573
+ let sch: Schema = e.getT1();
574
+
575
+ if (
576
+ sch.getName() === Parameter.EXPRESSION.getName() &&
577
+ sch.getNamespace() === Parameter.EXPRESSION.getNamespace()
578
+ ) {
579
+ let obj = e.getT2();
580
+ let isExpression: boolean = obj['isExpression'];
581
+ if (isExpression) {
582
+ this.addDependencies(se, obj['value']);
583
+ }
584
+ } else {
585
+ if (sch.getProperties()) {
586
+ for (let entry of Object.entries(e.getT2())) {
587
+ if (!sch.getProperties()!.has(entry[0])) continue;
588
+ paramElements.push(
589
+ new Tuple2(sch.getProperties()!.get(entry[0])!, entry[1]),
590
+ );
591
+ }
592
+ }
593
+ }
594
+ }
595
+ }
596
+ }
597
+ } else if (ref.getType() == ParameterReferenceType.EXPRESSION) {
598
+ if (StringUtil.isNullOrBlank(ref.getExpression())) {
599
+ if (isNullValue(SchemaUtil.getDefaultValue(p.getSchema(), this.sRepo)))
600
+ se.addMessage(
601
+ StatementMessageType.ERROR,
602
+ StringFormatter.format(
603
+ KIRuntime.PARAMETER_NEEDS_A_VALUE,
604
+ p.getParameterName(),
605
+ ),
606
+ );
607
+ } else {
608
+ try {
609
+ // TODO: Type check for the resulting expression has to be done here...
610
+ this.addDependencies(se, ref.getExpression());
611
+ } catch (err) {
612
+ se.addMessage(
613
+ StatementMessageType.ERROR,
614
+ StringFormatter.format('Error evaluating $ : $', ref.getExpression(), err),
615
+ );
616
+ }
617
+ }
618
+ }
619
+ }
620
+
621
+ private addDependencies(se: StatementExecution, expression: string | undefined): void {
622
+ if (!expression) return;
623
+
624
+ Array.from(expression.match(KIRuntime.STEP_REGEX_PATTERN) ?? []).forEach((e) =>
625
+ se.addDependency(e),
626
+ );
627
+ }
628
+
629
+ public makeEdges(graph: ExecutionGraph<string, StatementExecution>): Tuple2<string, string>[] {
630
+ let values = graph.getNodeMap().values();
631
+
632
+ let retValue: Tuple2<string, string>[] = [];
633
+
634
+ for (let e of Array.from(values)) {
635
+ for (let d of e.getData().getDependencies()) {
636
+ let secondDot: number = d.indexOf('.', 6);
637
+ let step: string = d.substring(6, secondDot);
638
+ let eventDot: number = d.indexOf('.', secondDot + 1);
639
+ let event: string =
640
+ eventDot == -1
641
+ ? d.substring(secondDot + 1)
642
+ : d.substring(secondDot + 1, eventDot);
643
+
644
+ if (!graph.getNodeMap().has(step)) retValue.push(new Tuple2(step, event));
645
+
646
+ let st = graph.getNodeMap()!.get(step);
647
+ if (st) e.addInEdgeTo(st, event);
648
+ }
649
+ }
650
+
651
+ return retValue;
652
+ }
653
+ }