timonel 2.14.0-beta.1 → 3.0.0-beta.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/CHANGELOG.md +185 -0
- package/README.md +133 -9
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/lib/helmChartWriter.js +5 -3
- package/dist/lib/rutter.js +10 -8
- package/dist/lib/utils/envVarsLoader.d.ts +19 -0
- package/dist/lib/utils/envVarsLoader.js +57 -0
- package/dist/lib/utils/helmControlStructures.d.ts +4 -5
- package/dist/lib/utils/helmControlStructures.js +12 -0
- package/dist/lib/utils/helmYamlSerializer.d.ts +2 -0
- package/dist/lib/utils/helmYamlSerializer.js +491 -15
- package/dist/lib/utils/valuesRef.d.ts +102 -0
- package/dist/lib/utils/valuesRef.js +264 -0
- package/package.json +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { createHelmExpression } from './helmControlStructures.js';
|
|
2
|
+
const HELM_VALUE_SYMBOL = Symbol('HelmValue');
|
|
3
|
+
function serializeValue(value) {
|
|
4
|
+
if (typeof value === 'object' && value !== null && HELM_VALUE_SYMBOL in value) {
|
|
5
|
+
return value.__path;
|
|
6
|
+
}
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
return `"${value}"`;
|
|
9
|
+
}
|
|
10
|
+
return String(value);
|
|
11
|
+
}
|
|
12
|
+
function createCondition(condition) {
|
|
13
|
+
return {
|
|
14
|
+
[HELM_VALUE_SYMBOL]: true,
|
|
15
|
+
__condition: condition,
|
|
16
|
+
not() {
|
|
17
|
+
return createCondition(`not (${this.__condition})`);
|
|
18
|
+
},
|
|
19
|
+
and(other) {
|
|
20
|
+
return createCondition(`and (${this.__condition}) (${other.__condition})`);
|
|
21
|
+
},
|
|
22
|
+
or(other) {
|
|
23
|
+
return createCondition(`or (${this.__condition}) (${other.__condition})`);
|
|
24
|
+
},
|
|
25
|
+
toString() {
|
|
26
|
+
return this.__condition;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function createValueProxy(path) {
|
|
31
|
+
const baseObject = Object.create(null);
|
|
32
|
+
baseObject.__helmExpression = true;
|
|
33
|
+
baseObject.value = `{{ ${path} }}`;
|
|
34
|
+
const handler = {
|
|
35
|
+
ownKeys() {
|
|
36
|
+
return ['__helmExpression', 'value'];
|
|
37
|
+
},
|
|
38
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
39
|
+
if (prop === '__helmExpression') {
|
|
40
|
+
return { value: true, writable: false, enumerable: true, configurable: true };
|
|
41
|
+
}
|
|
42
|
+
if (prop === 'value') {
|
|
43
|
+
return { value: `{{ ${path} }}`, writable: false, enumerable: true, configurable: true };
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
},
|
|
47
|
+
has(target, prop) {
|
|
48
|
+
if (prop === HELM_VALUE_SYMBOL)
|
|
49
|
+
return true;
|
|
50
|
+
if (prop === '__helmExpression')
|
|
51
|
+
return true;
|
|
52
|
+
if (prop === 'value')
|
|
53
|
+
return true;
|
|
54
|
+
return false;
|
|
55
|
+
},
|
|
56
|
+
get(target, prop) {
|
|
57
|
+
if (prop === HELM_VALUE_SYMBOL)
|
|
58
|
+
return true;
|
|
59
|
+
if (prop === '__path')
|
|
60
|
+
return path;
|
|
61
|
+
if (prop === '__type')
|
|
62
|
+
return undefined;
|
|
63
|
+
if (prop === '__helmExpression')
|
|
64
|
+
return true;
|
|
65
|
+
if (prop === 'value')
|
|
66
|
+
return `{{ ${path} }}`;
|
|
67
|
+
if (prop === 'toJSON') {
|
|
68
|
+
return () => ({ __helmExpression: true, value: `{{ ${path} }}` });
|
|
69
|
+
}
|
|
70
|
+
if (typeof prop === 'string') {
|
|
71
|
+
switch (prop) {
|
|
72
|
+
case 'eq':
|
|
73
|
+
return (value) => createCondition(`eq ${path} ${serializeValue(value)}`);
|
|
74
|
+
case 'ne':
|
|
75
|
+
return (value) => createCondition(`ne ${path} ${serializeValue(value)}`);
|
|
76
|
+
case 'gt':
|
|
77
|
+
return (value) => createCondition(`gt ${path} ${serializeValue(value)}`);
|
|
78
|
+
case 'ge':
|
|
79
|
+
return (value) => createCondition(`ge ${path} ${serializeValue(value)}`);
|
|
80
|
+
case 'lt':
|
|
81
|
+
return (value) => createCondition(`lt ${path} ${serializeValue(value)}`);
|
|
82
|
+
case 'le':
|
|
83
|
+
return (value) => createCondition(`le ${path} ${serializeValue(value)}`);
|
|
84
|
+
case 'not':
|
|
85
|
+
return () => createCondition(`not ${path}`);
|
|
86
|
+
case 'and':
|
|
87
|
+
return (other) => createCondition(`and ${path} (${other.__condition})`);
|
|
88
|
+
case 'or':
|
|
89
|
+
return (other) => createCondition(`or ${path} (${other.__condition})`);
|
|
90
|
+
case 'default':
|
|
91
|
+
return (defaultValue) => createValueProxy(`${path} | default ${serializeValue(defaultValue)}`);
|
|
92
|
+
case 'quote':
|
|
93
|
+
return () => createValueProxy(`(${path} | quote)`);
|
|
94
|
+
case 'upper':
|
|
95
|
+
return () => createValueProxy(`(${path} | upper)`);
|
|
96
|
+
case 'lower':
|
|
97
|
+
return () => createValueProxy(`(${path} | lower)`);
|
|
98
|
+
case 'title':
|
|
99
|
+
return () => createValueProxy(`(${path} | title)`);
|
|
100
|
+
case 'trim':
|
|
101
|
+
return () => createValueProxy(`(${path} | trim)`);
|
|
102
|
+
case 'trimPrefix':
|
|
103
|
+
return (prefix) => createValueProxy(`(${path} | trimPrefix "${prefix}")`);
|
|
104
|
+
case 'trimSuffix':
|
|
105
|
+
return (suffix) => createValueProxy(`(${path} | trimSuffix "${suffix}")`);
|
|
106
|
+
case 'replace':
|
|
107
|
+
return (old, newStr) => createValueProxy(`(${path} | replace "${old}" "${newStr}")`);
|
|
108
|
+
case 'contains':
|
|
109
|
+
return (substr) => createCondition(`contains "${substr}" ${path}`);
|
|
110
|
+
case 'hasPrefix':
|
|
111
|
+
return (prefix) => createCondition(`hasPrefix ${path} "${prefix}"`);
|
|
112
|
+
case 'hasSuffix':
|
|
113
|
+
return (suffix) => createCondition(`hasSuffix ${path} "${suffix}"`);
|
|
114
|
+
case 'trunc':
|
|
115
|
+
return (length) => createValueProxy(`(${path} | trunc ${length})`);
|
|
116
|
+
case 'kindIs':
|
|
117
|
+
return (kind) => createCondition(`kindIs "${kind}" ${path}`);
|
|
118
|
+
case 'hasKey':
|
|
119
|
+
return (key) => createCondition(`hasKey ${path} "${key}"`);
|
|
120
|
+
case 'toYaml':
|
|
121
|
+
return () => createValueProxy(`${path} | toYaml`);
|
|
122
|
+
case 'toJson':
|
|
123
|
+
return () => createValueProxy(`${path} | toJson`);
|
|
124
|
+
case 'nindent':
|
|
125
|
+
return (spaces) => createValueProxy(`${path} | nindent ${spaces}`);
|
|
126
|
+
case 'indent':
|
|
127
|
+
return (spaces) => createValueProxy(`${path} | indent ${spaces}`);
|
|
128
|
+
case 'toExpression':
|
|
129
|
+
return () => createHelmExpression(`{{ ${path} }}`);
|
|
130
|
+
case 'if':
|
|
131
|
+
return (condition, thenValue) => {
|
|
132
|
+
let helmCondition;
|
|
133
|
+
if (isHelmCondition(condition)) {
|
|
134
|
+
helmCondition = condition;
|
|
135
|
+
}
|
|
136
|
+
else if (isHelmValue(condition)) {
|
|
137
|
+
helmCondition = createCondition(condition.__path);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error('v.if() requires a HelmCondition or HelmValue as the first argument');
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
__helmFieldConditional: true,
|
|
144
|
+
condition: helmCondition,
|
|
145
|
+
thenValue,
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
case 'ifElse':
|
|
149
|
+
return (condition, thenValue, elseValue) => {
|
|
150
|
+
const condStr = condition.__condition;
|
|
151
|
+
return createValueProxy(`(ternary ${serializeValue(thenValue)} ${serializeValue(elseValue)} (${condStr}))`);
|
|
152
|
+
};
|
|
153
|
+
case 'range':
|
|
154
|
+
return (callback) => ({
|
|
155
|
+
__helmRange: true,
|
|
156
|
+
source: createValueProxy(path),
|
|
157
|
+
callback,
|
|
158
|
+
});
|
|
159
|
+
case 'with':
|
|
160
|
+
return (callback) => {
|
|
161
|
+
const ctxProxy = { __path: '.', [HELM_VALUE_SYMBOL]: true };
|
|
162
|
+
const content = callback(ctxProxy);
|
|
163
|
+
let contentStr;
|
|
164
|
+
if (typeof content === 'object' &&
|
|
165
|
+
content !== null &&
|
|
166
|
+
'__helmExpression' in content) {
|
|
167
|
+
const helmExpr = content;
|
|
168
|
+
contentStr = helmExpr.value;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
contentStr = String(content);
|
|
172
|
+
}
|
|
173
|
+
const marker = `__FIELD_WITH_MARKER__:${path}:${contentStr}`;
|
|
174
|
+
return createHelmExpression(marker);
|
|
175
|
+
};
|
|
176
|
+
case 'toString':
|
|
177
|
+
return () => `{{ ${path} }}`;
|
|
178
|
+
case 'valueOf':
|
|
179
|
+
return () => path;
|
|
180
|
+
default:
|
|
181
|
+
return createValueProxy(`${path}.${prop}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return undefined;
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
return new Proxy(baseObject, handler);
|
|
188
|
+
}
|
|
189
|
+
export function valuesRef() {
|
|
190
|
+
const values = createValueProxy('.Values');
|
|
191
|
+
const helpers = {
|
|
192
|
+
include(templateName, context = '.') {
|
|
193
|
+
const ctx = context === '.' ? '.' : context.__path;
|
|
194
|
+
return createValueProxy(`(include "${templateName}" ${ctx})`);
|
|
195
|
+
},
|
|
196
|
+
printf(format, ...args) {
|
|
197
|
+
const argsStr = args
|
|
198
|
+
.map((arg) => serializeValue(arg))
|
|
199
|
+
.join(' ');
|
|
200
|
+
return createValueProxy(`(printf "${format}" ${argsStr})`);
|
|
201
|
+
},
|
|
202
|
+
release: {
|
|
203
|
+
name: createValueProxy('.Release.Name'),
|
|
204
|
+
namespace: createValueProxy('.Release.Namespace'),
|
|
205
|
+
service: createValueProxy('.Release.Service'),
|
|
206
|
+
isUpgrade: createValueProxy('.Release.IsUpgrade'),
|
|
207
|
+
isInstall: createValueProxy('.Release.IsInstall'),
|
|
208
|
+
revision: createValueProxy('.Release.Revision'),
|
|
209
|
+
},
|
|
210
|
+
chart: {
|
|
211
|
+
name: createValueProxy('.Chart.Name'),
|
|
212
|
+
version: createValueProxy('.Chart.Version'),
|
|
213
|
+
appVersion: createValueProxy('.Chart.AppVersion'),
|
|
214
|
+
type: createValueProxy('.Chart.Type'),
|
|
215
|
+
},
|
|
216
|
+
capabilities: {
|
|
217
|
+
kubeVersion: {
|
|
218
|
+
version: createValueProxy('.Capabilities.KubeVersion.Version'),
|
|
219
|
+
major: createValueProxy('.Capabilities.KubeVersion.Major'),
|
|
220
|
+
minor: createValueProxy('.Capabilities.KubeVersion.Minor'),
|
|
221
|
+
},
|
|
222
|
+
apiVersions: {
|
|
223
|
+
has(apiVersion) {
|
|
224
|
+
return createCondition(`.Capabilities.APIVersions.Has "${apiVersion}"`);
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
rawCondition(condition) {
|
|
229
|
+
return createCondition(condition);
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
return new Proxy(values, {
|
|
233
|
+
get(target, prop) {
|
|
234
|
+
if (prop in helpers) {
|
|
235
|
+
return helpers[prop];
|
|
236
|
+
}
|
|
237
|
+
return target[prop];
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
export function isHelmValue(value) {
|
|
242
|
+
return typeof value === 'object' && value !== null && HELM_VALUE_SYMBOL in value;
|
|
243
|
+
}
|
|
244
|
+
export function isHelmCondition(value) {
|
|
245
|
+
return (typeof value === 'object' &&
|
|
246
|
+
value !== null &&
|
|
247
|
+
HELM_VALUE_SYMBOL in value &&
|
|
248
|
+
'__condition' in value);
|
|
249
|
+
}
|
|
250
|
+
export function isHelmFieldConditional(value) {
|
|
251
|
+
return typeof value === 'object' && value !== null && '__helmFieldConditional' in value;
|
|
252
|
+
}
|
|
253
|
+
export function isHelmRange(value) {
|
|
254
|
+
return typeof value === 'object' && value !== null && '__helmRange' in value;
|
|
255
|
+
}
|
|
256
|
+
export function isHelmWith(value) {
|
|
257
|
+
return typeof value === 'object' && value !== null && '__helmWith' in value;
|
|
258
|
+
}
|
|
259
|
+
export function serializeHelmValue(value) {
|
|
260
|
+
return `{{ ${value.__path} }}`;
|
|
261
|
+
}
|
|
262
|
+
export function serializeHelmCondition(condition) {
|
|
263
|
+
return condition.__condition;
|
|
264
|
+
}
|