@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/README.md +28 -3
- package/dist/index.js +56 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -2
- package/dist/index.mjs.map +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +17 -10
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
|
-
|
|
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.
|