timonel 2.10.2 → 2.12.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +8 -54
  3. package/dist/cli.js +65 -52
  4. package/dist/index.d.ts +1 -2
  5. package/dist/index.js +1 -2
  6. package/dist/lib/helmChartWriter.js +17 -2
  7. package/dist/lib/rutter.d.ts +1 -0
  8. package/dist/lib/rutter.js +64 -11
  9. package/dist/lib/templates/flexible-subchart.d.ts +1 -0
  10. package/dist/lib/templates/flexible-subchart.js +101 -0
  11. package/dist/lib/templates/umbrella-chart.d.ts +13 -2
  12. package/dist/lib/templates/umbrella-chart.js +128 -42
  13. package/dist/lib/utils/helmHelpers/envHelpers.d.ts +2 -0
  14. package/dist/lib/utils/helmHelpers/envHelpers.js +97 -0
  15. package/dist/lib/utils/helmHelpers/gitopsHelpers.d.ts +2 -0
  16. package/dist/lib/utils/helmHelpers/gitopsHelpers.js +132 -0
  17. package/dist/lib/utils/helmHelpers/index.d.ts +23 -0
  18. package/dist/lib/utils/helmHelpers/index.js +132 -0
  19. package/dist/lib/utils/helmHelpers/observabilityHelpers.d.ts +2 -0
  20. package/dist/lib/utils/helmHelpers/observabilityHelpers.js +221 -0
  21. package/dist/lib/utils/helmHelpers/types.d.ts +16 -0
  22. package/dist/lib/utils/helmHelpers/types.js +1 -0
  23. package/dist/lib/utils/helmHelpers/validationHelpers.d.ts +2 -0
  24. package/dist/lib/utils/helmHelpers/validationHelpers.js +201 -0
  25. package/dist/lib/utils/helmHelpers.d.ts +11 -1
  26. package/dist/lib/utils/helmHelpers.js +20 -7
  27. package/dist/lib/utils/helmYamlSerializer.d.ts +53 -1
  28. package/dist/lib/utils/helmYamlSerializer.js +325 -29
  29. package/dist/lib/utils/logger.d.ts +49 -0
  30. package/dist/lib/utils/logger.js +418 -0
  31. package/package.json +21 -11
  32. package/dist/lib/templates/basic-chart.d.ts +0 -19
  33. package/dist/lib/templates/basic-chart.js +0 -210
  34. package/dist/lib/templates/subchart.d.ts +0 -27
  35. package/dist/lib/templates/subchart.js +0 -219
@@ -1,5 +1,4 @@
1
- import type { App } from 'cdk8s';
2
- import { Chart } from 'cdk8s';
1
+ import { App, Chart } from 'cdk8s';
3
2
  import type { ChartProps } from '../types.js';
4
3
  export declare function generateUmbrellaChart(name: string): string;
5
4
  export declare class UmbrellaChartTemplate extends Chart {
@@ -9,6 +8,18 @@ export declare class UmbrellaChartTemplate extends Chart {
9
8
  private configure;
10
9
  private _addService;
11
10
  private _addSubchart;
11
+ private _createFlexibleSubchart;
12
+ private _createFallbackSubchart;
13
+ private _handleFunctionChart;
14
+ private _handleObjectChart;
15
+ private _isRutterInstance;
16
+ private _isChartInstance;
17
+ private _processRutterInstance;
18
+ private _processChartInstance;
19
+ private _copyTemplates;
20
+ private _ensureDirectoryExists;
21
+ private _processAssets;
22
+ private _cleanupTempDir;
12
23
  private _createBasicSubchart;
13
24
  writeHelmChart(outputDir: string): void;
14
25
  }
@@ -1,13 +1,20 @@
1
- import { writeFileSync, mkdirSync, existsSync } from 'fs';
1
+ import { writeFileSync, mkdirSync, existsSync, copyFileSync, readdirSync, rmSync } from 'fs';
2
2
  import { join } from 'path';
3
- import { Chart, ApiObject } from 'cdk8s';
3
+ import * as jsYaml from 'js-yaml';
4
+ import { App, Chart, ApiObject } from 'cdk8s';
4
5
  import { dumpHelmAwareYaml } from '../utils/helmYamlSerializer.js';
5
6
  import { generateHelpersTemplate } from '../utils/helmHelpers.js';
6
7
  import { createFlexibleSubchart } from './flexible-subchart.js';
7
8
  export function generateUmbrellaChart(name) {
8
9
  return `import { App } from 'cdk8s';
9
10
  import { UmbrellaChart } from 'timonel';
11
+ // Import subcharts - add your subchart imports here
10
12
 
13
+ /**
14
+ * Synthesizes the umbrella chart with all subcharts
15
+ * @param outDir Output directory for generated charts
16
+ * @since 2.11.0
17
+ */
11
18
  export function synth(outDir: string) {
12
19
  const app = new App({
13
20
  outdir: outDir,
@@ -20,7 +27,9 @@ export function synth(outDir: string) {
20
27
  version: '0.1.0',
21
28
  description: '${name} umbrella chart',
22
29
  services: [],
23
- subcharts: []
30
+ subcharts: [
31
+ // Add your subcharts here:
32
+ ]
24
33
  });
25
34
 
26
35
  // Generate Helm chart files
@@ -95,54 +104,131 @@ export class UmbrellaChartTemplate extends Chart {
95
104
  }
96
105
  _addSubchart(subchart, index) {
97
106
  try {
98
- let _subchartInstance;
99
- const { name: _name, version: _version, description: _description, ...subchartProps } = subchart;
100
- const flexibleSubchart = createFlexibleSubchart(this, `${subchart.name}-${index}`, {
101
- name: subchart.name,
102
- version: subchart.version || '1.0.0',
103
- description: subchart.description || `${subchart.name} subchart`,
104
- ...subchartProps,
105
- });
107
+ const flexibleSubchart = this._createFlexibleSubchart(subchart, index);
106
108
  if (typeof subchart.chart === 'function') {
107
- try {
108
- const subchartInstance = subchart.chart(this, `${subchart.name}-${index}`);
109
- if (subchartInstance.node.children) {
110
- subchartInstance.node.children.forEach((child) => {
111
- if (child instanceof Chart) {
112
- flexibleSubchart.addConstruct(child);
113
- }
114
- });
115
- }
116
- }
117
- catch {
118
- const subchartInstance = subchart.chart();
119
- if (subchartInstance.node.children) {
120
- subchartInstance.node.children.forEach((child) => {
121
- if (child instanceof Chart) {
122
- flexibleSubchart.addConstruct(child);
123
- }
124
- });
125
- }
126
- }
109
+ this._handleFunctionChart(subchart, index, flexibleSubchart);
127
110
  }
128
111
  else if (subchart.chart && typeof subchart.chart === 'object') {
129
- if (subchart.chart.constructor && subchart.chart.constructor.name !== 'Object') {
130
- flexibleSubchart.addConstruct(subchart.chart);
131
- }
132
- else {
133
- flexibleSubchart.addManifest(subchart.chart);
134
- }
112
+ this._handleObjectChart(subchart, flexibleSubchart);
135
113
  }
136
114
  console.log(`Added flexible subchart: ${subchart.name}`);
137
115
  }
138
116
  catch (_error) {
139
117
  console.warn(`Failed to add subchart ${subchart.name}:`, _error);
140
- const _fallbackSubchart = createFlexibleSubchart(this, `${subchart.name}-fallback-${index}`, {
141
- name: subchart.name,
142
- version: subchart.version || '1.0.0',
143
- description: `${subchart.name} subchart (fallback)`,
118
+ this._createFallbackSubchart(subchart, index);
119
+ }
120
+ }
121
+ _createFlexibleSubchart(subchart, index) {
122
+ const { name: _name, version: _version, description: _description, ...subchartProps } = subchart;
123
+ return createFlexibleSubchart(this, `${subchart.name}-${index}`, {
124
+ name: subchart.name,
125
+ version: subchart.version || '1.0.0',
126
+ description: subchart.description || `${subchart.name} subchart`,
127
+ ...subchartProps,
128
+ });
129
+ }
130
+ _createFallbackSubchart(subchart, index) {
131
+ const _fallbackSubchart = createFlexibleSubchart(this, `${subchart.name}-fallback-${index}`, {
132
+ name: subchart.name,
133
+ version: subchart.version || '1.0.0',
134
+ description: `${subchart.name} subchart (fallback)`,
135
+ });
136
+ console.log(`Created fallback subchart: ${subchart.name}`);
137
+ }
138
+ _handleFunctionChart(subchart, index, flexibleSubchart) {
139
+ try {
140
+ const tempApp = new App({ outdir: 'temp' });
141
+ const rutterInstance = subchart.chart(tempApp);
142
+ if (this._isRutterInstance(rutterInstance)) {
143
+ this._processRutterInstance(subchart, index, rutterInstance, flexibleSubchart);
144
+ }
145
+ else if (this._isChartInstance(rutterInstance)) {
146
+ this._processChartInstance(rutterInstance, flexibleSubchart);
147
+ }
148
+ }
149
+ catch (error) {
150
+ console.log(`Failed to process subchart ${subchart.name}:`, error);
151
+ }
152
+ }
153
+ _handleObjectChart(subchart, flexibleSubchart) {
154
+ const chartObj = subchart.chart;
155
+ if (chartObj.constructor && chartObj.constructor.name !== 'Object') {
156
+ flexibleSubchart.addConstruct(subchart.chart);
157
+ }
158
+ else {
159
+ flexibleSubchart.addManifest(subchart.chart);
160
+ }
161
+ }
162
+ _isRutterInstance(instance) {
163
+ return !!(instance && typeof instance.addManifest === 'function');
164
+ }
165
+ _isChartInstance(instance) {
166
+ const obj = instance;
167
+ const node = obj?.node;
168
+ return !!(node && node.children);
169
+ }
170
+ _processRutterInstance(subchart, index, rutterInstance, flexibleSubchart) {
171
+ const tempDir = `temp-${subchart.name}-${index}`;
172
+ const write = rutterInstance.write;
173
+ write?.(tempDir);
174
+ this._copyTemplates(subchart.name, tempDir);
175
+ this._processAssets(rutterInstance, flexibleSubchart);
176
+ this._cleanupTempDir(tempDir);
177
+ }
178
+ _processChartInstance(rutterInstance, flexibleSubchart) {
179
+ const obj = rutterInstance;
180
+ const node = obj?.node;
181
+ const children = node?.children;
182
+ children?.forEach((child) => {
183
+ if (child instanceof Chart) {
184
+ flexibleSubchart.addConstruct(child);
185
+ }
186
+ });
187
+ }
188
+ _copyTemplates(subchartName, tempDir) {
189
+ const tempTemplatesDir = join(tempDir, 'templates');
190
+ const subchartTemplatesDir = join('dist', 'charts', subchartName, 'templates');
191
+ if (existsSync(tempTemplatesDir)) {
192
+ this._ensureDirectoryExists(join('dist', 'charts', subchartName));
193
+ this._ensureDirectoryExists(subchartTemplatesDir);
194
+ const templateFiles = readdirSync(tempTemplatesDir);
195
+ templateFiles.forEach((file) => {
196
+ if (file.endsWith('.yaml') || file.endsWith('.yml') || file.endsWith('.tpl')) {
197
+ const sourceFile = join(tempTemplatesDir, file);
198
+ const targetFile = join(subchartTemplatesDir, file);
199
+ copyFileSync(sourceFile, targetFile);
200
+ }
144
201
  });
145
- console.log(`Created fallback subchart: ${subchart.name}`);
202
+ }
203
+ }
204
+ _ensureDirectoryExists(dirPath) {
205
+ if (!existsSync(dirPath)) {
206
+ mkdirSync(dirPath, { recursive: true });
207
+ }
208
+ }
209
+ _processAssets(rutterInstance, flexibleSubchart) {
210
+ const getAssets = rutterInstance.getAssets;
211
+ const assets = getAssets?.() || [];
212
+ assets.forEach((asset, assetIndex) => {
213
+ try {
214
+ const manifest = jsYaml.load(asset.yaml);
215
+ if (manifest?.apiVersion && manifest?.kind) {
216
+ new ApiObject(flexibleSubchart, `${String(manifest.kind).toLowerCase()}-${assetIndex}`, {
217
+ apiVersion: String(manifest.apiVersion),
218
+ kind: String(manifest.kind),
219
+ metadata: manifest.metadata || {},
220
+ spec: manifest.spec || {},
221
+ });
222
+ }
223
+ }
224
+ catch (error) {
225
+ console.log(`Failed to parse asset ${asset.id}:`, error);
226
+ }
227
+ });
228
+ }
229
+ _cleanupTempDir(tempDir) {
230
+ if (existsSync(tempDir)) {
231
+ rmSync(tempDir, { recursive: true, force: true });
146
232
  }
147
233
  }
148
234
  _createBasicSubchart(subchartName, subchartDir) {
@@ -0,0 +1,2 @@
1
+ import type { HelperDefinition } from './types.js';
2
+ export declare const ENV_HELPERS: HelperDefinition[];
@@ -0,0 +1,97 @@
1
+ export const ENV_HELPERS = [
2
+ {
3
+ name: 'env.required',
4
+ template: `{{- $key := . -}}
5
+ {{- $value := index .Values.env $key -}}
6
+ {{- required (printf "Environment variable %s is required" $key) $value }}`,
7
+ },
8
+ {
9
+ name: 'env.isDev',
10
+ template: `{{- $env := .Values.environment | default "production" -}}
11
+ {{- or (eq $env "dev") (eq $env "development") }}`,
12
+ },
13
+ {
14
+ name: 'env.isProd',
15
+ template: `{{- $env := .Values.environment | default "production" -}}
16
+ {{- or (eq $env "prod") (eq $env "production") }}`,
17
+ },
18
+ {
19
+ name: 'env.isStaging',
20
+ template: `{{- $env := .Values.environment | default "production" -}}
21
+ {{- or (eq $env "staging") (eq $env "stage") }}`,
22
+ },
23
+ {
24
+ name: 'env.isTest',
25
+ template: `{{- $env := .Values.environment | default "production" -}}
26
+ {{- or (eq $env "test") (eq $env "testing") }}`,
27
+ },
28
+ {
29
+ name: 'config.merge',
30
+ template: `{{- $base := .base | default dict -}}
31
+ {{- $env := .env | default dict -}}
32
+ {{- $override := .override | default dict -}}
33
+ {{- merge $override $env $base | toJson }}`,
34
+ },
35
+ {
36
+ name: 'config.secretRef',
37
+ template: `{{- if .fromSecret -}}
38
+ valueFrom:
39
+ secretKeyRef:
40
+ name: {{ .fromSecret.name }}
41
+ key: {{ .fromSecret.key }}
42
+ {{- if .fromSecret.optional }}
43
+ optional: true
44
+ {{- end }}
45
+ {{- else if .fromConfigMap -}}
46
+ valueFrom:
47
+ configMapKeyRef:
48
+ name: {{ .fromConfigMap.name }}
49
+ key: {{ .fromConfigMap.key }}
50
+ {{- if .fromConfigMap.optional }}
51
+ optional: true
52
+ {{- end }}
53
+ {{- else -}}
54
+ value: {{ .value | quote }}
55
+ {{- end }}`,
56
+ },
57
+ {
58
+ name: 'config.envFromSource',
59
+ template: `{{- if .configMapRef -}}
60
+ configMapRef:
61
+ name: {{ .configMapRef.name }}
62
+ {{- if .configMapRef.optional }}
63
+ optional: true
64
+ {{- end }}
65
+ {{- else if .secretRef -}}
66
+ secretRef:
67
+ name: {{ .secretRef.name }}
68
+ {{- if .secretRef.optional }}
69
+ optional: true
70
+ {{- end }}
71
+ {{- end }}`,
72
+ },
73
+ {
74
+ name: 'config.featureFlag',
75
+ template: `{{- $flag := .flag -}}
76
+ {{- $default := .default | default false -}}
77
+ {{- $envKey := printf "FEATURE_%s" ($flag | upper) -}}
78
+ {{- $envFlag := index .Values.env $envKey | default "" -}}
79
+ {{- $valueFlag := index .Values.features $flag | default "" -}}
80
+ {{- if $valueFlag }}
81
+ {{- $valueFlag }}
82
+ {{- else if $envFlag }}
83
+ {{- $envFlag }}
84
+ {{- else }}
85
+ {{- $default }}
86
+ {{- end }}`,
87
+ },
88
+ {
89
+ name: 'config.debugMode',
90
+ template: `{{- $debug := .Values.debug | default (index .Values.env "DEBUG") | default false -}}
91
+ {{- if or $debug (include "env.isDev" .) -}}
92
+ true
93
+ {{- else -}}
94
+ false
95
+ {{- end }}`,
96
+ },
97
+ ];
@@ -0,0 +1,2 @@
1
+ import type { HelperDefinition } from './types.js';
2
+ export declare const GITOPS_HELPERS: HelperDefinition[];
@@ -0,0 +1,132 @@
1
+ export const GITOPS_HELPERS = [
2
+ {
3
+ name: 'git.commitSha',
4
+ template: `{{- .Values.git.commitSha | default "unknown" }}`,
5
+ },
6
+ {
7
+ name: 'git.shortSha',
8
+ template: `{{- $sha := include "git.commitSha" . -}}
9
+ {{- if ne $sha "unknown" -}}
10
+ {{- $sha | trunc 8 -}}
11
+ {{- else -}}
12
+ unknown
13
+ {{- end }}`,
14
+ },
15
+ {
16
+ name: 'git.branch',
17
+ template: `{{- .Values.git.branch | default "main" }}`,
18
+ },
19
+ {
20
+ name: 'git.tag',
21
+ template: `{{- .Values.git.tag | default "" }}`,
22
+ },
23
+ {
24
+ name: 'git.repository',
25
+ template: `{{- .Values.git.repository | default "unknown/repository" }}`,
26
+ },
27
+ {
28
+ name: 'image.tagWithSha',
29
+ template: `{{- $repo := .Values.image.repository -}}
30
+ {{- $sha := include "git.shortSha" . -}}
31
+ {{- printf "%s:%s" $repo $sha }}`,
32
+ },
33
+ {
34
+ name: 'image.tagWithVersion',
35
+ template: `{{- $repo := .Values.image.repository -}}
36
+ {{- $tag := .Values.image.tag | default .Chart.AppVersion | default "latest" -}}
37
+ {{- printf "%s:%s" $repo $tag }}`,
38
+ },
39
+ {
40
+ name: 'image.tagWithBranch',
41
+ template: `{{- $repo := .Values.image.repository -}}
42
+ {{- $branch := include "git.branch" . | replace "/" "-" | lower -}}
43
+ {{- printf "%s:%s" $repo $branch }}`,
44
+ },
45
+ {
46
+ name: 'ci.buildId',
47
+ template: `{{- .Values.ci.buildId | default "unknown" }}`,
48
+ },
49
+ {
50
+ name: 'ci.buildUrl',
51
+ template: `{{- .Values.ci.buildUrl | default "" }}`,
52
+ },
53
+ {
54
+ name: 'ci.jobUrl',
55
+ template: `{{- .Values.ci.jobUrl | default "" }}`,
56
+ },
57
+ {
58
+ name: 'ci.runner',
59
+ template: `{{- .Values.ci.runner | default "unknown" }}`,
60
+ },
61
+ {
62
+ name: 'deploy.timestamp',
63
+ template: `{{- now | date "2006-01-02T15:04:05Z07:00" }}`,
64
+ },
65
+ {
66
+ name: 'deploy.user',
67
+ template: `{{- .Values.deploy.user | default "automated" }}`,
68
+ },
69
+ {
70
+ name: 'deploy.annotations',
71
+ template: `deployment.kubernetes.io/revision: "{{ .Release.Revision }}"
72
+ app.kubernetes.io/version: "{{ .Chart.AppVersion }}"
73
+ app.kubernetes.io/part-of: "{{ .Values.application.name | default .Chart.Name }}"
74
+ git.commit: "{{ include "git.commitSha" . }}"
75
+ git.branch: "{{ include "git.branch" . }}"
76
+ git.repository: "{{ include "git.repository" . }}"
77
+ ci.build-id: "{{ include "ci.buildId" . }}"
78
+ ci.build-url: "{{ include "ci.buildUrl" . }}"
79
+ deploy.timestamp: "{{ include "deploy.timestamp" . }}"
80
+ deploy.user: "{{ include "deploy.user" . }}"`,
81
+ },
82
+ {
83
+ name: 'deploy.labels',
84
+ template: `app.kubernetes.io/version: "{{ .Chart.AppVersion }}"
85
+ app.kubernetes.io/component: "{{ .Values.component | default "application" }}"
86
+ app.kubernetes.io/part-of: "{{ .Values.application.name | default .Chart.Name }}"
87
+ git.branch: "{{ include "git.branch" . | replace "/" "-" | lower }}"
88
+ environment: "{{ .Values.environment | default "development" }}"`,
89
+ },
90
+ {
91
+ name: 'semver.parse',
92
+ template: `{{- $version := . -}}
93
+ {{- $parts := regexSplit "\\\\." $version -1 -}}
94
+ {{- if eq (len $parts) 3 -}}
95
+ {{- printf "{\\"major\\": %s, \\"minor\\": %s, \\"patch\\": %s}" (index $parts 0) (index $parts 1) (index $parts 2) -}}
96
+ {{- else -}}
97
+ {{- printf "{\\"major\\": 0, \\"minor\\": 0, \\"patch\\": 0}" -}}
98
+ {{- end }}`,
99
+ },
100
+ {
101
+ name: 'semver.bump',
102
+ template: `{{- $version := .version -}}
103
+ {{- $type := .type | default "patch" -}}
104
+ {{- $parts := regexSplit "\\\\." $version -1 -}}
105
+ {{- if eq (len $parts) 3 -}}
106
+ {{- $major := index $parts 0 | int -}}
107
+ {{- $minor := index $parts 1 | int -}}
108
+ {{- $patch := index $parts 2 | int -}}
109
+ {{- if eq $type "major" -}}
110
+ {{- printf "%d.0.0" (add $major 1) -}}
111
+ {{- else if eq $type "minor" -}}
112
+ {{- printf "%d.%d.0" $major (add $minor 1) -}}
113
+ {{- else -}}
114
+ {{- printf "%d.%d.%d" $major $minor (add $patch 1) -}}
115
+ {{- end -}}
116
+ {{- else -}}
117
+ {{- fail (printf "Invalid semantic version: %s" $version) -}}
118
+ {{- end }}`,
119
+ },
120
+ {
121
+ name: 'rollout.canaryWeight',
122
+ template: `{{- $weight := .Values.rollout.canary.weight | default 10 -}}
123
+ {{- $env := .Values.environment | default "development" -}}
124
+ {{- if eq $env "production" -}}
125
+ {{- min $weight 5 -}}
126
+ {{- else if eq $env "staging" -}}
127
+ {{- min $weight 50 -}}
128
+ {{- else -}}
129
+ {{- $weight -}}
130
+ {{- end }}`,
131
+ },
132
+ ];
@@ -0,0 +1,23 @@
1
+ export type { HelperDefinition, HelperCategory, CloudProvider, HelperOptions } from './types.js';
2
+ export { ENV_HELPERS } from './envHelpers.js';
3
+ export { GITOPS_HELPERS } from './gitopsHelpers.js';
4
+ export { OBSERVABILITY_HELPERS } from './observabilityHelpers.js';
5
+ export { VALIDATION_HELPERS } from './validationHelpers.js';
6
+ import type { HelperDefinition, HelperCategory, HelperOptions } from './types.js';
7
+ export declare function getNewHelpersByCategory(category: HelperCategory): HelperDefinition[];
8
+ export declare function getAvailableHelperCategories(): HelperCategory[];
9
+ export declare function getHelpersByCategories(categories: HelperCategory[]): HelperDefinition[];
10
+ export declare function getHelpersByOptions(options: HelperOptions): HelperDefinition[];
11
+ export declare function formatNewHelpers(helpers: HelperDefinition[]): string;
12
+ export declare function generateNewHelpersTemplate(options?: HelperOptions, customHelpers?: HelperDefinition[]): string;
13
+ export declare function getCachedNewHelpersTemplate(options?: HelperOptions, customHelpers?: HelperDefinition[]): string;
14
+ export declare function createNewHelper(name: string, template: string): HelperDefinition;
15
+ export declare function validateHelperNames(helpers: HelperDefinition[]): void;
16
+ export declare function filterHelpersByPattern(helpers: HelperDefinition[], pattern: RegExp): HelperDefinition[];
17
+ export declare function getHelperStatistics(helpers: HelperDefinition[]): {
18
+ totalHelpers: number;
19
+ categoryCounts: Record<string, number>;
20
+ averageTemplateLength: number;
21
+ longestHelper: string;
22
+ shortestHelper: string;
23
+ };
@@ -0,0 +1,132 @@
1
+ export { ENV_HELPERS } from './envHelpers.js';
2
+ export { GITOPS_HELPERS } from './gitopsHelpers.js';
3
+ export { OBSERVABILITY_HELPERS } from './observabilityHelpers.js';
4
+ export { VALIDATION_HELPERS } from './validationHelpers.js';
5
+ import { ENV_HELPERS } from './envHelpers.js';
6
+ import { GITOPS_HELPERS } from './gitopsHelpers.js';
7
+ import { OBSERVABILITY_HELPERS } from './observabilityHelpers.js';
8
+ import { VALIDATION_HELPERS } from './validationHelpers.js';
9
+ const HELPER_CATEGORIES = new Map([
10
+ ['env', ENV_HELPERS],
11
+ ['gitops', GITOPS_HELPERS],
12
+ ['observability', OBSERVABILITY_HELPERS],
13
+ ['validation', VALIDATION_HELPERS],
14
+ ]);
15
+ const COMPILED_HELPERS_CACHE = new Map();
16
+ export function getNewHelpersByCategory(category) {
17
+ const helpers = HELPER_CATEGORIES.get(category);
18
+ if (!helpers) {
19
+ throw new Error(`Unknown helper category: ${category}`);
20
+ }
21
+ return [...helpers];
22
+ }
23
+ export function getAvailableHelperCategories() {
24
+ return Array.from(HELPER_CATEGORIES.keys());
25
+ }
26
+ export function getHelpersByCategories(categories) {
27
+ const helpers = [];
28
+ for (const category of categories) {
29
+ helpers.push(...getNewHelpersByCategory(category));
30
+ }
31
+ return helpers;
32
+ }
33
+ export function getHelpersByOptions(options) {
34
+ const helpers = [];
35
+ if (options.includeEnv) {
36
+ helpers.push(...ENV_HELPERS);
37
+ }
38
+ if (options.includeGitops) {
39
+ helpers.push(...GITOPS_HELPERS);
40
+ }
41
+ if (options.includeObservability) {
42
+ helpers.push(...OBSERVABILITY_HELPERS);
43
+ }
44
+ if (options.includeValidation) {
45
+ helpers.push(...VALIDATION_HELPERS);
46
+ }
47
+ return helpers;
48
+ }
49
+ export function formatNewHelpers(helpers) {
50
+ return helpers
51
+ .map((helper) => `{{/*
52
+ ${helper.name}
53
+ */}}
54
+ {{- define "${helper.name}" -}}
55
+ ${helper.template}
56
+ {{- end }}`)
57
+ .join('\n\n');
58
+ }
59
+ export function generateNewHelpersTemplate(options, customHelpers) {
60
+ const helpers = [];
61
+ if (options) {
62
+ helpers.push(...getHelpersByOptions(options));
63
+ }
64
+ if (customHelpers) {
65
+ helpers.push(...customHelpers);
66
+ }
67
+ return formatNewHelpers(helpers);
68
+ }
69
+ export function getCachedNewHelpersTemplate(options, customHelpers) {
70
+ const cacheKey = JSON.stringify({ options, customHelpers });
71
+ if (COMPILED_HELPERS_CACHE.has(cacheKey)) {
72
+ return COMPILED_HELPERS_CACHE.get(cacheKey);
73
+ }
74
+ const template = generateNewHelpersTemplate(options, customHelpers);
75
+ COMPILED_HELPERS_CACHE.set(cacheKey, template);
76
+ return template;
77
+ }
78
+ export function createNewHelper(name, template) {
79
+ return { name, template };
80
+ }
81
+ export function validateHelperNames(helpers) {
82
+ const namePattern = /^[a-zA-Z][a-zA-Z0-9._-]*$/;
83
+ const duplicates = new Set();
84
+ const seen = new Set();
85
+ for (const helper of helpers) {
86
+ if (!namePattern.test(helper.name)) {
87
+ throw new Error(`Invalid helper name: "${helper.name}". Names must start with a letter and contain only letters, numbers, dots, underscores, and hyphens.`);
88
+ }
89
+ if (seen.has(helper.name)) {
90
+ duplicates.add(helper.name);
91
+ }
92
+ else {
93
+ seen.add(helper.name);
94
+ }
95
+ }
96
+ if (duplicates.size > 0) {
97
+ throw new Error(`Duplicate helper names found: ${Array.from(duplicates).join(', ')}`);
98
+ }
99
+ }
100
+ export function filterHelpersByPattern(helpers, pattern) {
101
+ return helpers.filter((helper) => pattern.test(helper.name));
102
+ }
103
+ export function getHelperStatistics(helpers) {
104
+ const categoryMap = new Map();
105
+ let totalTemplateLength = 0;
106
+ let longestHelper = '';
107
+ let shortestHelper = '';
108
+ let longestLength = 0;
109
+ let shortestLength = Infinity;
110
+ for (const helper of helpers) {
111
+ const category = helper.name.split('.')[0] || 'unknown';
112
+ const currentCount = categoryMap.get(category) || 0;
113
+ categoryMap.set(category, currentCount + 1);
114
+ const templateLength = helper.template.length;
115
+ totalTemplateLength += templateLength;
116
+ if (templateLength > longestLength) {
117
+ longestLength = templateLength;
118
+ longestHelper = helper.name;
119
+ }
120
+ if (templateLength < shortestLength) {
121
+ shortestLength = templateLength;
122
+ shortestHelper = helper.name;
123
+ }
124
+ }
125
+ return {
126
+ totalHelpers: helpers.length,
127
+ categoryCounts: Object.fromEntries(categoryMap),
128
+ averageTemplateLength: helpers.length > 0 ? Math.round(totalTemplateLength / helpers.length) : 0,
129
+ longestHelper,
130
+ shortestHelper,
131
+ };
132
+ }
@@ -0,0 +1,2 @@
1
+ import type { HelperDefinition } from './types.js';
2
+ export declare const OBSERVABILITY_HELPERS: HelperDefinition[];