@accordproject/template-engine 2.7.1 → 2.9.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/dist/index.mjs CHANGED
@@ -101,6 +101,16 @@ function integerDrafter(value, format) {
101
101
  }
102
102
  }
103
103
 
104
+ function isDuration(value) {
105
+ return value != null && typeof value === "object" && "amount" in value && "unit" in value && typeof value.amount === "number" && typeof value.unit === "string";
106
+ }
107
+ function durationDrafter(value) {
108
+ if (!isDuration(value)) {
109
+ return "0 unknown";
110
+ }
111
+ return `${value.amount} ${value.unit}`;
112
+ }
113
+
104
114
  function longDrafter(value, format) {
105
115
  if (format) {
106
116
  return draftIntegerFormat(value, format);
@@ -189,6 +199,10 @@ function getDrafter(typeName) {
189
199
  return longDrafter;
190
200
  case "org.accordproject.money@0.3.0.MonetaryAmount":
191
201
  return monetaryAmountDrafter;
202
+ case "org.accordproject.time@0.3.0.Duration":
203
+ return durationDrafter;
204
+ case "org.accordproject.time@0.3.0.Period":
205
+ return durationDrafter;
192
206
  case "String":
193
207
  return stringDrafter;
194
208
  default:
@@ -889,7 +903,12 @@ async function generateAgreement(modelManager, clauseLibrary, templateMark, data
889
903
  delete context.dependencies;
890
904
  delete context.functionName;
891
905
  } else if (CLAUSE_DEFINITION_RE.test(nodeClass)) {
892
- if (context.condition) {
906
+ const path = getJsonPath(templateMark, context, this.path);
907
+ const variableValues = jp.query(data, path, 1);
908
+ if (context.name !== "top" && (variableValues.length === 0 || variableValues[0] === void 0 || variableValues[0] === null)) {
909
+ delete context.nodes;
910
+ stopHere = true;
911
+ } else if (context.condition) {
893
912
  checkCode(context.condition);
894
913
  const result = !!userCodeResults[this.path.join("/")];
895
914
  if (!result) {
@@ -952,10 +971,45 @@ class TemplateMarkInterpreter {
952
971
  const serializer = new Serializer(factory, modelManager);
953
972
  try {
954
973
  serializer.fromJSON(templateMark);
955
- return templateMark;
956
974
  } catch (err) {
957
975
  throw new Error(`Generated invalid agreement: ${err}: ${JSON.stringify(templateMark, null, 2)}`);
958
976
  }
977
+ const errors = [];
978
+ const templateClass = this.templateClass;
979
+ const guardBlockPaths = /* @__PURE__ */ new Map();
980
+ traverse(templateMark).forEach(function(node) {
981
+ if (!node || typeof node !== "object" || !node.$class) return;
982
+ const currentPath = this.path.join("/");
983
+ if (OPTIONAL_DEFINITION_RE.test(node.$class) || CONDITIONAL_DEFINITION_RE.test(node.$class) || WITH_DEFINITION_RE.test(node.$class)) {
984
+ guardBlockPaths.set(node.name, currentPath);
985
+ }
986
+ if (VARIABLE_DEFINITION_RE.test(node.$class) || ENUM_VARIABLE_DEFINITION_RE.test(node.$class) || FORMATTED_VARIABLE_DEFINITION_RE.test(node.$class)) {
987
+ const propName = node.name;
988
+ if (propName && propName !== "this") {
989
+ try {
990
+ const property = templateClass.getProperty(propName);
991
+ if (property && property.isOptional()) {
992
+ const guardPath = guardBlockPaths.get(propName);
993
+ const isGuarded = guardPath !== void 0 && (currentPath === guardPath || currentPath.startsWith(guardPath + "/"));
994
+ if (!isGuarded) {
995
+ errors.push({
996
+ propertyName: propName,
997
+ message: `Optional property '${propName}' is used without a guard. Wrap it in {{#optional ${propName}}}...{{/optional}} or {{#if ${propName}}}...{{/if}}.`
998
+ });
999
+ }
1000
+ }
1001
+ } catch {
1002
+ }
1003
+ }
1004
+ }
1005
+ });
1006
+ if (errors.length > 0) {
1007
+ const errorMessage = `Optional properties used without guards: ${errors.map((e) => e.propertyName).join(", ")}`;
1008
+ const error = new Error(errorMessage);
1009
+ error.errors = errors;
1010
+ throw error;
1011
+ }
1012
+ return templateMark;
959
1013
  }
960
1014
  /**
961
1015
  * Compiles the code nodes containing TS to code nodes containing JS.