timonel 2.13.0 → 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.
@@ -0,0 +1,102 @@
1
+ import { type HelmExpression } from './helmControlStructures.js';
2
+ declare const HELM_VALUE_SYMBOL: unique symbol;
3
+ export interface HelmValue<T = unknown> {
4
+ [HELM_VALUE_SYMBOL]: true;
5
+ __path: string;
6
+ __type?: T;
7
+ eq(value: HelmValue | string | number | boolean): HelmCondition;
8
+ ne(value: HelmValue | string | number | boolean): HelmCondition;
9
+ gt(value: HelmValue | number): HelmCondition;
10
+ ge(value: HelmValue | number): HelmCondition;
11
+ lt(value: HelmValue | number): HelmCondition;
12
+ le(value: HelmValue | number): HelmCondition;
13
+ not(): HelmCondition;
14
+ and(other: HelmCondition): HelmCondition;
15
+ or(other: HelmCondition): HelmCondition;
16
+ default(defaultValue: HelmValue | string | number | boolean): HelmValue<T>;
17
+ quote(): HelmValue<string>;
18
+ upper(): HelmValue<string>;
19
+ lower(): HelmValue<string>;
20
+ title(): HelmValue<string>;
21
+ trim(): HelmValue<string>;
22
+ trimPrefix(prefix: string): HelmValue<string>;
23
+ trimSuffix(suffix: string): HelmValue<string>;
24
+ replace(old: string, newStr: string): HelmValue<string>;
25
+ contains(substr: string): HelmCondition;
26
+ hasPrefix(prefix: string): HelmCondition;
27
+ hasSuffix(suffix: string): HelmCondition;
28
+ trunc(length: number): HelmValue<string>;
29
+ kindIs(kind: 'string' | 'slice' | 'map' | 'bool' | 'int' | 'float'): HelmCondition;
30
+ hasKey(key: string): HelmCondition;
31
+ toYaml(): HelmValue<string>;
32
+ toJson(): HelmValue<string>;
33
+ nindent(spaces: number): HelmValue<string>;
34
+ indent(spaces: number): HelmValue<string>;
35
+ toExpression(): HelmExpression;
36
+ if<V>(condition: HelmCondition, thenValue: V): HelmFieldConditional<V>;
37
+ ifElse<V>(condition: HelmCondition, thenValue: V, elseValue: V): HelmValue<V>;
38
+ range<V>(callback: (item: HelmValue<T extends (infer U)[] ? U : unknown>, index: HelmValue<number>) => V): HelmRange<V>;
39
+ with<V>(callback: (ctx: HelmValue<T>) => V): HelmWith<V>;
40
+ }
41
+ export interface HelmCondition {
42
+ [HELM_VALUE_SYMBOL]: true;
43
+ __condition: string;
44
+ not(): HelmCondition;
45
+ and(other: HelmCondition): HelmCondition;
46
+ or(other: HelmCondition): HelmCondition;
47
+ toString(): string;
48
+ }
49
+ export interface HelmFieldConditional<T> {
50
+ __helmFieldConditional: true;
51
+ condition: HelmCondition;
52
+ thenValue: T;
53
+ elseValue?: T;
54
+ }
55
+ export interface HelmRange<T> {
56
+ __helmRange: true;
57
+ source: HelmValue;
58
+ callback: (item: HelmValue, index: HelmValue<number>) => T;
59
+ }
60
+ export interface HelmWith<T> {
61
+ __helmWith: true;
62
+ source: HelmValue;
63
+ callback: (ctx: HelmValue) => T;
64
+ }
65
+ export interface HelmHelpers {
66
+ include(templateName: string, context?: '.' | HelmValue): HelmValue<string>;
67
+ printf(format: string, ...args: (HelmValue | string | number)[]): HelmValue<string>;
68
+ release: {
69
+ name: HelmValue<string>;
70
+ namespace: HelmValue<string>;
71
+ service: HelmValue<string>;
72
+ isUpgrade: HelmValue<boolean>;
73
+ isInstall: HelmValue<boolean>;
74
+ revision: HelmValue<number>;
75
+ };
76
+ chart: {
77
+ name: HelmValue<string>;
78
+ version: HelmValue<string>;
79
+ appVersion: HelmValue<string>;
80
+ type: HelmValue<string>;
81
+ };
82
+ capabilities: {
83
+ kubeVersion: {
84
+ version: HelmValue<string>;
85
+ major: HelmValue<string>;
86
+ minor: HelmValue<string>;
87
+ };
88
+ apiVersions: {
89
+ has(apiVersion: string): HelmCondition;
90
+ };
91
+ };
92
+ rawCondition(condition: string): HelmCondition;
93
+ }
94
+ export declare function valuesRef<T extends Record<string, unknown>>(): HelmValue<T> & HelmHelpers;
95
+ export declare function isHelmValue(value: unknown): value is HelmValue;
96
+ export declare function isHelmCondition(value: unknown): value is HelmCondition;
97
+ export declare function isHelmFieldConditional(value: unknown): value is HelmFieldConditional<unknown>;
98
+ export declare function isHelmRange(value: unknown): value is HelmRange<unknown>;
99
+ export declare function isHelmWith(value: unknown): value is HelmWith<unknown>;
100
+ export declare function serializeHelmValue(value: HelmValue): string;
101
+ export declare function serializeHelmCondition(condition: HelmCondition): string;
102
+ export {};
@@ -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
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "timonel",
3
3
  "type": "module",
4
- "version": "2.13.0",
4
+ "version": "3.0.0-beta.1",
5
5
  "description": "Timonel: programmatic Helm chart generator using cdk8s (TypeScript)",
6
6
  "bin": {
7
7
  "timonel": "dist/cli.js",
@@ -12,18 +12,27 @@
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
15
16
  "default": "./dist/index.js"
16
17
  },
17
18
  "./lib/helm": {
18
19
  "types": "./dist/lib/helm.d.ts",
20
+ "import": "./dist/lib/helm.js",
19
21
  "default": "./dist/lib/helm.js"
20
22
  },
23
+ "./lib/utils/helmControlStructures": {
24
+ "types": "./dist/lib/utils/helmControlStructures.d.ts",
25
+ "import": "./dist/lib/utils/helmControlStructures.js",
26
+ "default": "./dist/lib/utils/helmControlStructures.js"
27
+ },
21
28
  "./lib/utils/logger": {
22
29
  "types": "./dist/lib/utils/logger.d.ts",
30
+ "import": "./dist/lib/utils/logger.js",
23
31
  "default": "./dist/lib/utils/logger.js"
24
32
  },
25
33
  "./lib/utils/helmYamlSerializer": {
26
34
  "types": "./dist/lib/utils/helmYamlSerializer.d.ts",
35
+ "import": "./dist/lib/utils/helmYamlSerializer.js",
27
36
  "default": "./dist/lib/utils/helmYamlSerializer.js"
28
37
  }
29
38
  },
@@ -95,7 +104,6 @@
95
104
  "cdk8s-plus-33": "^2.4.6",
96
105
  "constructs": "^10.4.3",
97
106
  "handlebars": "^4.7.8",
98
- "js-yaml": "^4.1.1",
99
107
  "pino": "^10.1.0",
100
108
  "pino-pretty": "^13.1.2",
101
109
  "ts-node": "^10.9.2",
@@ -108,7 +116,6 @@
108
116
  "@semantic-release/changelog": "^6.0.3",
109
117
  "@semantic-release/exec": "^7.1.0",
110
118
  "@semantic-release/git": "^10.0.1",
111
- "@types/js-yaml": "^4.0.9",
112
119
  "@types/node": "^24.10.1",
113
120
  "@typescript-eslint/eslint-plugin": "^8.47.0",
114
121
  "@typescript-eslint/parser": "^8.47.0",