@extrahorizon/exh-cli 1.12.0-dev-152-fc8569c → 1.12.0-dev-154-7343f7f
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.
|
@@ -17,10 +17,14 @@ async function buildTemplate(name, templateFilesByName, callChain = []) {
|
|
|
17
17
|
if (callChain.includes(name)) {
|
|
18
18
|
throw new Error(`Circular extension detected. ${renderCallChain(newCallChain)}`);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
if (!templateFile) {
|
|
20
|
+
if (!templateFilesByName[name]) {
|
|
22
21
|
throw new Error(`Template file dependency ${name} not found!`);
|
|
23
22
|
}
|
|
23
|
+
const { variables, ...templateFile } = templateFilesByName[name];
|
|
24
|
+
if (variables && templateFile.outputs) {
|
|
25
|
+
templateFile.outputs = replaceVariables(templateFile.outputs, variables);
|
|
26
|
+
templateFilesByName[name] = templateFile;
|
|
27
|
+
}
|
|
24
28
|
let templateConfig;
|
|
25
29
|
if (templateFile.extends_template) {
|
|
26
30
|
templateConfig = await extendV1Template(name, templateFilesByName, newCallChain);
|
|
@@ -31,8 +35,8 @@ async function buildTemplate(name, templateFilesByName, callChain = []) {
|
|
|
31
35
|
else {
|
|
32
36
|
templateConfig = { ...templateFile, name };
|
|
33
37
|
}
|
|
34
|
-
if (!(0, utils_1.isV1Template)(templateConfig)
|
|
35
|
-
|
|
38
|
+
if (!(0, utils_1.isV1Template)(templateConfig)) {
|
|
39
|
+
validateV2Template(templateConfig);
|
|
36
40
|
}
|
|
37
41
|
return templateConfig;
|
|
38
42
|
}
|
|
@@ -94,8 +98,55 @@ async function extendV2Template(name, templateFilesByName, callChain) {
|
|
|
94
98
|
outputs: newOutputs,
|
|
95
99
|
};
|
|
96
100
|
}
|
|
101
|
+
function replaceVariables(outputs, variables) {
|
|
102
|
+
const replaced = {};
|
|
103
|
+
const resolvedVariables = {};
|
|
104
|
+
for (const [varName, varValue] of Object.entries(variables)) {
|
|
105
|
+
resolvedVariables[varName] = resolveVariableValue(varValue);
|
|
106
|
+
}
|
|
107
|
+
for (const [key, value] of Object.entries(outputs)) {
|
|
108
|
+
let replacedValue = value;
|
|
109
|
+
for (const [varName, varValue] of Object.entries(resolvedVariables)) {
|
|
110
|
+
replacedValue = replacedValue
|
|
111
|
+
.replaceAll(`\${${varName}}`, varValue)
|
|
112
|
+
.replaceAll(`$${varName}`, varValue);
|
|
113
|
+
}
|
|
114
|
+
replaced[key] = replacedValue;
|
|
115
|
+
}
|
|
116
|
+
return replaced;
|
|
117
|
+
}
|
|
118
|
+
function resolveVariableValue(value) {
|
|
119
|
+
if (!value.startsWith('$')) {
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
const envVar = value.startsWith('${') && value.endsWith('}') ?
|
|
123
|
+
value.slice(2, -1) :
|
|
124
|
+
value.slice(1);
|
|
125
|
+
const validEnvPattern = /^[A-Z][A-Z0-9_]*$/;
|
|
126
|
+
if (!validEnvPattern.test(envVar)) {
|
|
127
|
+
throw new Error(`Invalid environment variable name ${envVar}. Environment variable names must contain only uppercase letters, numbers, and underscores and must start with a letter.`);
|
|
128
|
+
}
|
|
129
|
+
const resolved = process.env[envVar];
|
|
130
|
+
if (resolved === undefined) {
|
|
131
|
+
throw new Error(`Variable ${envVar} not found in environment`);
|
|
132
|
+
}
|
|
133
|
+
return resolved;
|
|
134
|
+
}
|
|
135
|
+
function validateV2Template(template) {
|
|
136
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]{0,49}$/.test(template.name)) {
|
|
137
|
+
throw new Error(`Template name '${template.name}' is invalid. Template names must start with a letter and can only contain letters, numbers, underscores and hyphens, and be at most 50 characters long.`);
|
|
138
|
+
}
|
|
139
|
+
if (Object.keys(template.outputs || {}).length < 1) {
|
|
140
|
+
throw new Error(`Template '${template.name}' must have at least one output defined.`);
|
|
141
|
+
}
|
|
142
|
+
for (const outputName of Object.keys(template.outputs)) {
|
|
143
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]{0,49}$/.test(outputName)) {
|
|
144
|
+
throw new Error(`Output name '${outputName}' is invalid. Output names must start with a letter and can only contain letters, numbers, underscores and hyphens, and be at most 50 characters long.`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
97
148
|
function v1ExtendingV2Error(extendsTemplate, callChain) {
|
|
98
|
-
return new Error(`You cannot extend a v2 template ('${extendsTemplate}') in a v1 template
|
|
149
|
+
return new Error(`You cannot extend a v2 template ('${extendsTemplate}') in a v1 template.` +
|
|
99
150
|
`In ${renderCallChain(callChain)}`);
|
|
100
151
|
}
|
|
101
152
|
function v1VariableNotFoundError(variableName, extendsTemplate, callChain) {
|
|
@@ -104,7 +155,7 @@ function v1VariableNotFoundError(variableName, extendsTemplate, callChain) {
|
|
|
104
155
|
`in ${renderCallChain(callChain)}`);
|
|
105
156
|
}
|
|
106
157
|
function v2ExtendingV1Error(extendsTemplate, callChain) {
|
|
107
|
-
return new Error(`You cannot extend a v1 template ('${extendsTemplate}') in a v2 template
|
|
158
|
+
return new Error(`You cannot extend a v1 template ('${extendsTemplate}') in a v2 template.` +
|
|
108
159
|
`In ${renderCallChain(callChain)}`);
|
|
109
160
|
}
|
|
110
161
|
function v2VariableNotFoundError(variableName, extendsTemplate, callChain) {
|