@accordproject/template-engine 2.9.0 → 3.0.1

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/dist/index.d.ts CHANGED
@@ -152,15 +152,15 @@ declare class TemplateArchiveProcessor {
152
152
  * @param {object} request - the request to send to the template logic
153
153
  * @param {object} state - the current state of the template
154
154
  * @param {[string]} currentTime - the current time, defaults to now
155
- * @param {[number]} utcOffset - the UTC offer, defaults to zero
155
+ * @param {[number]} utcOffset - the UTC offset, defaults to zero
156
156
  * @returns {Promise} the response and any events
157
157
  */
158
158
  trigger(data: any, request: any, state?: any, currentTime?: string, utcOffset?: number): Promise<TriggerResponse>;
159
159
  /**
160
160
  * Init the logic of a template
161
161
  * @param {[string]} currentTime - the current time, defaults to now
162
- * @param {[number]} utcOffset - the UTC offer, defaults to zero
163
- * @returns {Promise} the response and any events
162
+ * @param {[number]} utcOffset - the UTC offset, defaults to zero
163
+ * @returns {Promise<InitResponse>} the new state
164
164
  */
165
165
  init(data: any, currentTime?: string, utcOffset?: number): Promise<InitResponse>;
166
166
  }
package/dist/index.js CHANGED
@@ -714,7 +714,7 @@ function getJsonPath(rootData, currentNode, paths) {
714
714
  }
715
715
  }
716
716
  }
717
- if (currentNode.name !== "this") {
717
+ if (currentNode.name !== "this" && currentNode.name !== "top") {
718
718
  withPath.push(`['${currentNode.name}']`);
719
719
  }
720
720
  return withPath.length > 0 ? `$${withPath.join("")}` : "$";
@@ -904,8 +904,17 @@ async function generateAgreement(modelManager, clauseLibrary, templateMark, data
904
904
  }
905
905
  } else if (CONDITIONAL_DEFINITION_RE.test(nodeClass)) {
906
906
  if (context.condition) {
907
- const result = userCodeResults[this.path.join("/")];
908
- context.isTrue = !!result;
907
+ const key = this.path.join("/");
908
+ const resultStr = userCodeResults[key];
909
+ if (resultStr === void 0 || resultStr === null) {
910
+ context.isTrue = false;
911
+ } else {
912
+ try {
913
+ context.isTrue = !!JSON.parse(resultStr);
914
+ } catch (err) {
915
+ throw new Error(`Invalid JSON boolean result for condition '${key}': ${String(err)}`);
916
+ }
917
+ }
909
918
  } else {
910
919
  const path = getJsonPath(templateMark, context, this.path);
911
920
  const variableValues = jp.query(data, path, 1);
@@ -926,16 +935,27 @@ async function generateAgreement(modelManager, clauseLibrary, templateMark, data
926
935
  } else if (CLAUSE_DEFINITION_RE.test(nodeClass)) {
927
936
  const path = getJsonPath(templateMark, context, this.path);
928
937
  const variableValues = jp.query(data, path, 1);
929
- if (context.name !== "top" && (variableValues.length === 0 || variableValues[0] === void 0 || variableValues[0] === null)) {
930
- delete context.nodes;
931
- stopHere = true;
932
- } else if (context.condition) {
938
+ if (context.condition) {
933
939
  checkCode(context.condition);
934
- const result = !!userCodeResults[this.path.join("/")];
940
+ const key = this.path.join("/");
941
+ const resultStr = userCodeResults[key];
942
+ let result = false;
943
+ if (resultStr === void 0 || resultStr === null) {
944
+ result = false;
945
+ } else {
946
+ try {
947
+ result = !!JSON.parse(resultStr);
948
+ } catch (err) {
949
+ throw new Error(`Invalid JSON boolean result for condition '${key}': ${String(err)}`);
950
+ }
951
+ }
935
952
  if (!result) {
936
953
  delete context.nodes;
937
954
  stopHere = true;
938
955
  }
956
+ } else if (context.name !== "top" && (variableValues.length === 0 || variableValues[0] === void 0 || variableValues[0] === null)) {
957
+ delete context.nodes;
958
+ stopHere = true;
939
959
  }
940
960
  delete context.condition;
941
961
  delete context.functionName;
@@ -984,14 +1004,14 @@ class TemplateMarkInterpreter {
984
1004
  * @throws {Error} if the templateMark document is invalid
985
1005
  */
986
1006
  checkTypes(templateMark) {
987
- const modelManager = new concertoCore.ModelManager({ strict: true });
1007
+ const modelManager = new concertoCore.ModelManager();
988
1008
  modelManager.addCTOModel(markdownCommon.ConcertoMetaModel.MODEL, "concertometamodel.cto");
989
1009
  modelManager.addCTOModel(markdownCommon.CommonMarkModel.MODEL, "commonmark.cto");
990
1010
  modelManager.addCTOModel(markdownCommon.TemplateMarkModel.MODEL, "templatemark.cto");
991
1011
  const factory = new concertoCore.Factory(modelManager);
992
- const serializer = new concertoCore.Serializer(factory, modelManager);
1012
+ const serializer = new concertoCore.Serializer(factory, modelManager, {});
993
1013
  try {
994
- serializer.fromJSON(templateMark);
1014
+ serializer.fromJSON(templateMark, {});
995
1015
  } catch (err) {
996
1016
  throw new Error(`Generated invalid agreement: ${err}: ${JSON.stringify(templateMark, null, 2)}`);
997
1017
  }
@@ -1063,22 +1083,22 @@ class TemplateMarkInterpreter {
1063
1083
  return compiler.compile(templateMark);
1064
1084
  }
1065
1085
  validateCiceroMark(ciceroMark) {
1066
- const modelManager = new concertoCore.ModelManager({ strict: true });
1086
+ const modelManager = new concertoCore.ModelManager();
1067
1087
  modelManager.addCTOModel(markdownCommon.ConcertoMetaModel.MODEL, "concertometamodel.cto");
1068
1088
  modelManager.addCTOModel(markdownCommon.CommonMarkModel.MODEL, "commonmark.cto");
1069
1089
  modelManager.addCTOModel(markdownCommon.CiceroMarkModel.MODEL, "ciceromark.cto");
1070
1090
  const factory = new concertoCore.Factory(modelManager);
1071
- const serializer = new concertoCore.Serializer(factory, modelManager);
1091
+ const serializer = new concertoCore.Serializer(factory, modelManager, {});
1072
1092
  try {
1073
- return serializer.fromJSON(ciceroMark);
1093
+ return serializer.fromJSON(ciceroMark, {});
1074
1094
  } catch (err) {
1075
1095
  throw new Error(`Generated invalid agreement: ${err}: ${JSON.stringify(ciceroMark, null, 2)}`);
1076
1096
  }
1077
1097
  }
1078
1098
  async generate(templateMark, data, options) {
1079
1099
  const factory = new concertoCore.Factory(this.modelManager);
1080
- const serializer = new concertoCore.Serializer(factory, this.modelManager);
1081
- const templateData = serializer.fromJSON(data);
1100
+ const serializer = new concertoCore.Serializer(factory, this.modelManager, {});
1101
+ const templateData = serializer.fromJSON(data, {});
1082
1102
  if (templateData.getFullyQualifiedType() !== this.templateClass.getFullyQualifiedName()) {
1083
1103
  throw new Error(`Template data must be of type '${this.templateClass.getFullyQualifiedName()}'.`);
1084
1104
  }
@@ -1127,7 +1147,7 @@ class TemplateArchiveProcessor {
1127
1147
  * @param {object} request - the request to send to the template logic
1128
1148
  * @param {object} state - the current state of the template
1129
1149
  * @param {[string]} currentTime - the current time, defaults to now
1130
- * @param {[number]} utcOffset - the UTC offer, defaults to zero
1150
+ * @param {[number]} utcOffset - the UTC offset, defaults to zero
1131
1151
  * @returns {Promise} the response and any events
1132
1152
  */
1133
1153
  async trigger(data, request, state, currentTime, utcOffset) {
@@ -1147,6 +1167,8 @@ class TemplateArchiveProcessor {
1147
1167
  const result = compiler.compile(code);
1148
1168
  compiledCode[tsFile.getIdentifier()] = result;
1149
1169
  }
1170
+ const resolvedTime = currentTime ?? (/* @__PURE__ */ new Date()).toISOString();
1171
+ const resolvedOffset = utcOffset ?? 0;
1150
1172
  const evaluator = new JavaScriptEvaluator();
1151
1173
  const evalResponse = await evaluator.evalDangerously({
1152
1174
  templateLogic: true,
@@ -1155,7 +1177,7 @@ class TemplateArchiveProcessor {
1155
1177
  code: compiledCode["logic/logic.ts"].code,
1156
1178
  // TODO DCS - how to find the code to run?
1157
1179
  argumentNames: ["data", "request", "state"],
1158
- arguments: [data, request, state, currentTime, utcOffset]
1180
+ arguments: [data, request, state, resolvedTime, resolvedOffset]
1159
1181
  });
1160
1182
  if (evalResponse.result) {
1161
1183
  return evalResponse.result;
@@ -1169,8 +1191,8 @@ class TemplateArchiveProcessor {
1169
1191
  /**
1170
1192
  * Init the logic of a template
1171
1193
  * @param {[string]} currentTime - the current time, defaults to now
1172
- * @param {[number]} utcOffset - the UTC offer, defaults to zero
1173
- * @returns {Promise} the response and any events
1194
+ * @param {[number]} utcOffset - the UTC offset, defaults to zero
1195
+ * @returns {Promise<InitResponse>} the new state
1174
1196
  */
1175
1197
  async init(data, currentTime, utcOffset) {
1176
1198
  const logicManager = this.template.getLogicManager();
@@ -1189,6 +1211,8 @@ class TemplateArchiveProcessor {
1189
1211
  const result = compiler.compile(code);
1190
1212
  compiledCode[tsFile.getIdentifier()] = result;
1191
1213
  }
1214
+ const resolvedTime = currentTime ?? (/* @__PURE__ */ new Date()).toISOString();
1215
+ const resolvedOffset = utcOffset ?? 0;
1192
1216
  const evaluator = new JavaScriptEvaluator();
1193
1217
  const evalResponse = await evaluator.evalDangerously({
1194
1218
  templateLogic: true,
@@ -1197,7 +1221,7 @@ class TemplateArchiveProcessor {
1197
1221
  code: compiledCode["logic/logic.ts"].code,
1198
1222
  // TODO DCS - how to find the code to run?
1199
1223
  argumentNames: ["data"],
1200
- arguments: [data, currentTime, utcOffset]
1224
+ arguments: [data, resolvedTime, resolvedOffset]
1201
1225
  });
1202
1226
  if (evalResponse.result) {
1203
1227
  return evalResponse.result;