timonel 2.2.0 → 2.4.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 (77) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -1
  3. package/SECURITY.md +15 -8
  4. package/dist/cli.js +29 -31
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.d.ts +7 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +7 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/helm.d.ts +200 -12
  11. package/dist/lib/helm.d.ts.map +1 -1
  12. package/dist/lib/helm.js +234 -13
  13. package/dist/lib/helm.js.map +1 -1
  14. package/dist/lib/helmChartWriter.d.ts +238 -0
  15. package/dist/lib/helmChartWriter.d.ts.map +1 -0
  16. package/dist/lib/helmChartWriter.js +318 -0
  17. package/dist/lib/helmChartWriter.js.map +1 -0
  18. package/dist/lib/resources/autoscaling/autoscalingResources.d.ts +26 -0
  19. package/dist/lib/resources/autoscaling/autoscalingResources.d.ts.map +1 -0
  20. package/dist/lib/resources/autoscaling/autoscalingResources.js +35 -0
  21. package/dist/lib/resources/autoscaling/autoscalingResources.js.map +1 -0
  22. package/dist/lib/resources/baseResourceProvider.d.ts +47 -0
  23. package/dist/lib/resources/baseResourceProvider.d.ts.map +1 -0
  24. package/dist/lib/resources/baseResourceProvider.js +83 -0
  25. package/dist/lib/resources/baseResourceProvider.js.map +1 -0
  26. package/dist/lib/resources/cloud/aws/awsResources.d.ts +165 -0
  27. package/dist/lib/resources/cloud/aws/awsResources.d.ts.map +1 -0
  28. package/dist/lib/resources/cloud/aws/awsResources.js +187 -0
  29. package/dist/lib/resources/cloud/aws/awsResources.js.map +1 -0
  30. package/dist/lib/resources/cloud/azure/azureResources.d.ts +169 -0
  31. package/dist/lib/resources/cloud/azure/azureResources.d.ts.map +1 -0
  32. package/dist/lib/resources/cloud/azure/azureResources.js +218 -0
  33. package/dist/lib/resources/cloud/azure/azureResources.js.map +1 -0
  34. package/dist/lib/resources/cloud/gcp/gcpResources.d.ts +133 -0
  35. package/dist/lib/resources/cloud/gcp/gcpResources.d.ts.map +1 -0
  36. package/dist/lib/resources/cloud/gcp/gcpResources.js +162 -0
  37. package/dist/lib/resources/cloud/gcp/gcpResources.js.map +1 -0
  38. package/dist/lib/resources/core/coreResources.d.ts +584 -0
  39. package/dist/lib/resources/core/coreResources.d.ts.map +1 -0
  40. package/dist/lib/resources/core/coreResources.js +796 -0
  41. package/dist/lib/resources/core/coreResources.js.map +1 -0
  42. package/dist/lib/resources/core/storageResources.d.ts +133 -0
  43. package/dist/lib/resources/core/storageResources.d.ts.map +1 -0
  44. package/dist/lib/resources/core/storageResources.js +120 -0
  45. package/dist/lib/resources/core/storageResources.js.map +1 -0
  46. package/dist/lib/resources/validation/validationResources.d.ts +26 -0
  47. package/dist/lib/resources/validation/validationResources.d.ts.map +1 -0
  48. package/dist/lib/resources/validation/validationResources.js +33 -0
  49. package/dist/lib/resources/validation/validationResources.js.map +1 -0
  50. package/dist/lib/rutter.d.ts +554 -0
  51. package/dist/lib/rutter.d.ts.map +1 -0
  52. package/dist/lib/rutter.js +665 -0
  53. package/dist/lib/rutter.js.map +1 -0
  54. package/dist/lib/security.d.ts +73 -0
  55. package/dist/lib/security.d.ts.map +1 -0
  56. package/dist/lib/security.js +138 -0
  57. package/dist/lib/security.js.map +1 -0
  58. package/dist/lib/umbrella.d.ts +22 -2
  59. package/dist/lib/umbrella.d.ts.map +1 -1
  60. package/dist/lib/umbrella.js +21 -1
  61. package/dist/lib/umbrella.js.map +1 -1
  62. package/dist/lib/umbrellaRutter.d.ts +97 -0
  63. package/dist/lib/umbrellaRutter.d.ts.map +1 -0
  64. package/dist/lib/{UmbrellaRutter.js → umbrellaRutter.js} +72 -23
  65. package/dist/lib/umbrellaRutter.js.map +1 -0
  66. package/package.json +2 -1
  67. package/dist/lib/HelmChartWriter.d.ts +0 -69
  68. package/dist/lib/HelmChartWriter.d.ts.map +0 -1
  69. package/dist/lib/HelmChartWriter.js +0 -124
  70. package/dist/lib/HelmChartWriter.js.map +0 -1
  71. package/dist/lib/Rutter.d.ts +0 -1334
  72. package/dist/lib/Rutter.d.ts.map +0 -1
  73. package/dist/lib/Rutter.js +0 -2138
  74. package/dist/lib/Rutter.js.map +0 -1
  75. package/dist/lib/UmbrellaRutter.d.ts +0 -34
  76. package/dist/lib/UmbrellaRutter.d.ts.map +0 -1
  77. package/dist/lib/UmbrellaRutter.js.map +0 -1
@@ -0,0 +1,318 @@
1
+ /**
2
+ * @fileoverview Helm chart writer for generating complete Helm chart structures
3
+ * @since 1.0.0
4
+ */
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import YAML from 'yaml';
8
+ import { SecurityUtils } from './security.js';
9
+ /**
10
+ * Helm chart writer for generating complete chart structures
11
+ *
12
+ * This class provides static methods to generate a complete Helm chart
13
+ * including Chart.yaml, values.yaml, templates, and auxiliary files.
14
+ *
15
+ * @class HelmChartWriter
16
+ * @since 1.0.0
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * HelmChartWriter.write({
21
+ * outDir: './dist/my-chart',
22
+ * meta: { name: 'my-app', version: '1.0.0' },
23
+ * assets: []
24
+ * });
25
+ * ```
26
+ */
27
+ export class HelmChartWriter {
28
+ /**
29
+ * Writes a complete Helm chart to the specified directory
30
+ *
31
+ * Creates the full directory structure and writes all necessary files
32
+ * for a valid Helm chart including Chart.yaml, values files, templates,
33
+ * and auxiliary files.
34
+ *
35
+ * @param {HelmChartWriteOptions} opts - Chart configuration options
36
+ * @throws {Error} If output directory path is invalid
37
+ * @throws {Error} If chart metadata is invalid
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * HelmChartWriter.write({
42
+ * outDir: './charts/my-app',
43
+ * meta: {
44
+ * name: 'my-app',
45
+ * version: '1.0.0',
46
+ * description: 'My application'
47
+ * },
48
+ * defaultValues: { replicas: 3 },
49
+ * assets: []
50
+ * });
51
+ * ```
52
+ *
53
+ * @since 1.0.0
54
+ */
55
+ static write(opts) {
56
+ const { outDir, meta, defaultValues = {}, envValues = {}, assets, helpersTpl, notesTpl, valuesSchema, } = opts;
57
+ // Validate output directory path
58
+ const validatedOutDir = SecurityUtils.validatePath(outDir, process.cwd());
59
+ // Create directory structure
60
+ this.createDirectories(validatedOutDir);
61
+ // Write chart files
62
+ this.writeChartYaml(validatedOutDir, meta);
63
+ this.writeValuesFiles(validatedOutDir, defaultValues, envValues);
64
+ this.writeAssets(validatedOutDir, assets);
65
+ this.writeHelpers(validatedOutDir, helpersTpl);
66
+ this.writeNotes(validatedOutDir, notesTpl);
67
+ this.writeSchema(validatedOutDir, valuesSchema);
68
+ this.writeHelmIgnore(validatedOutDir);
69
+ }
70
+ /**
71
+ * Creates the necessary directory structure for the chart
72
+ *
73
+ * @private
74
+ * @param {string} outDir - Output directory path
75
+ * @throws {Error} If directories cannot be created
76
+ * @since 1.0.0
77
+ */
78
+ static createDirectories(outDir) {
79
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
80
+ fs.mkdirSync(path.join(outDir, 'templates'), { recursive: true });
81
+ // Create crds directory only if needed later
82
+ }
83
+ /**
84
+ * Writes the Chart.yaml file with chart metadata
85
+ *
86
+ * @private
87
+ * @param {string} outDir - Output directory path
88
+ * @param {HelmChartMeta} meta - Chart metadata
89
+ * @throws {Error} If Chart.yaml cannot be written
90
+ * @since 1.0.0
91
+ */
92
+ static writeChartYaml(outDir, meta) {
93
+ const chartYaml = YAML.stringify({
94
+ apiVersion: 'v2',
95
+ name: meta.name,
96
+ version: meta.version,
97
+ description: meta.description,
98
+ type: meta.type ?? 'application',
99
+ appVersion: meta.appVersion,
100
+ kubeVersion: meta.kubeVersion,
101
+ keywords: meta.keywords,
102
+ home: meta.home,
103
+ sources: meta.sources,
104
+ maintainers: meta.maintainers,
105
+ icon: meta.icon,
106
+ dependencies: meta.dependencies,
107
+ });
108
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
109
+ fs.writeFileSync(path.join(outDir, 'Chart.yaml'), chartYaml);
110
+ }
111
+ /**
112
+ * Writes values.yaml and environment-specific values files
113
+ *
114
+ * @private
115
+ * @param {string} outDir - Output directory path
116
+ * @param {Record<string, unknown>} defaultValues - Default values
117
+ * @param {EnvValuesMap} envValues - Environment-specific values
118
+ * @throws {Error} If values files cannot be written
119
+ * @since 1.0.0
120
+ */
121
+ static writeValuesFiles(outDir, defaultValues, envValues) {
122
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
123
+ fs.writeFileSync(path.join(outDir, 'values.yaml'), YAML.stringify(defaultValues));
124
+ for (const [env, values] of Object.entries(envValues)) {
125
+ // Use centralized environment name sanitization
126
+ const sanitizedEnv = SecurityUtils.sanitizeEnvironmentName(env);
127
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
128
+ fs.writeFileSync(path.join(outDir, `values-${sanitizedEnv}.yaml`), YAML.stringify(values));
129
+ }
130
+ }
131
+ /**
132
+ * Writes Kubernetes manifest assets to templates directory
133
+ *
134
+ * @private
135
+ * @param {string} outDir - Output directory path
136
+ * @param {SynthAsset[]} assets - Kubernetes manifests to write
137
+ * @since 1.0.0
138
+ */
139
+ static writeAssets(outDir, assets) {
140
+ writeAssets(outDir, assets);
141
+ }
142
+ /**
143
+ * Writes Helm template helpers to _helpers.tpl file
144
+ *
145
+ * @private
146
+ * @param {string} outDir - Output directory path
147
+ * @param {string | HelperDefinition[]} [helpersTpl] - Helpers content
148
+ * @since 1.0.0
149
+ */
150
+ static writeHelpers(outDir, helpersTpl) {
151
+ if (!helpersTpl)
152
+ return;
153
+ let content = '';
154
+ if (typeof helpersTpl === 'string') {
155
+ content = helpersTpl.endsWith('\n') ? helpersTpl : helpersTpl + '\n';
156
+ }
157
+ else if (Array.isArray(helpersTpl)) {
158
+ content = helpersTpl
159
+ .map((h) => [`{{- define "${h.name}" -}}`, h.body.trimEnd(), '{{- end }}', ''].join('\n'))
160
+ .join('\n');
161
+ }
162
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
163
+ fs.writeFileSync(path.join(outDir, 'templates', '_helpers.tpl'), content);
164
+ }
165
+ /**
166
+ * Writes NOTES.txt file for post-install instructions
167
+ *
168
+ * @private
169
+ * @param {string} outDir - Output directory path
170
+ * @param {string} [notesTpl] - Notes content
171
+ * @since 1.0.0
172
+ */
173
+ static writeNotes(outDir, notesTpl) {
174
+ if (!notesTpl)
175
+ return;
176
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
177
+ fs.writeFileSync(path.join(outDir, 'templates', 'NOTES.txt'), notesTpl.endsWith('\n') ? notesTpl : notesTpl + '\n');
178
+ }
179
+ /**
180
+ * Writes values.schema.json for values validation
181
+ *
182
+ * @private
183
+ * @param {string} outDir - Output directory path
184
+ * @param {Record<string, unknown>} [valuesSchema] - JSON schema
185
+ * @since 1.0.0
186
+ */
187
+ static writeSchema(outDir, valuesSchema) {
188
+ if (!valuesSchema)
189
+ return;
190
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
191
+ fs.writeFileSync(path.join(outDir, 'values.schema.json'), JSON.stringify(valuesSchema, null, 2) + '\n');
192
+ }
193
+ /**
194
+ * Writes .helmignore file with common ignore patterns
195
+ *
196
+ * @private
197
+ * @param {string} outDir - Output directory path
198
+ * @since 1.0.0
199
+ */
200
+ static writeHelmIgnore(outDir) {
201
+ const helmIgnorePath = path.join(outDir, '.helmignore');
202
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
203
+ if (!fs.existsSync(helmIgnorePath)) {
204
+ const helmIgnore = [
205
+ '# VCS',
206
+ '.git/',
207
+ '.hg/',
208
+ '.svn/',
209
+ '',
210
+ '# OS/editor',
211
+ '.DS_Store',
212
+ '.idea/',
213
+ '.vscode/',
214
+ '',
215
+ '# Backups',
216
+ '*.swp',
217
+ '*.bak',
218
+ '*.tmp',
219
+ '*.orig',
220
+ '',
221
+ '# Chart dependencies and packages',
222
+ 'charts/',
223
+ '*.tgz',
224
+ '',
225
+ ].join('\n');
226
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
227
+ fs.writeFileSync(helmIgnorePath, helmIgnore);
228
+ }
229
+ }
230
+ }
231
+ /**
232
+ * Splits YAML string into individual documents
233
+ *
234
+ * @private
235
+ * @param {string} yamlStr - YAML string with potential document separators
236
+ * @returns {string[]} Array of individual YAML documents
237
+ * @since 1.0.0
238
+ */
239
+ function splitDocs(yamlStr) {
240
+ return yamlStr
241
+ .split(/^---\s*$/m)
242
+ .map((p) => p.trim())
243
+ .filter((p) => p.length);
244
+ }
245
+ /**
246
+ * Writes all synthesized assets to the chart directory
247
+ *
248
+ * @private
249
+ * @param {string} outDir - Output directory path
250
+ * @param {SynthAsset[]} assets - Assets to write
251
+ * @throws {Error} If asset ID contains invalid characters
252
+ * @since 1.0.0
253
+ */
254
+ function writeAssets(outDir, assets) {
255
+ for (const asset of assets) {
256
+ // Sanitize asset ID to prevent path traversal
257
+ const sanitizedId = asset.id.replace(/[^a-zA-Z0-9-_]/g, '');
258
+ if (sanitizedId !== asset.id) {
259
+ throw new Error(`Invalid asset ID: ${SecurityUtils.sanitizeLogMessage(asset.id)}`);
260
+ }
261
+ const targetDir = getTargetDirectory(asset.target);
262
+ if (asset.singleFile) {
263
+ writeSingleAssetFile(outDir, targetDir, sanitizedId, asset.yaml);
264
+ }
265
+ else {
266
+ writeMultipleAssetFiles(outDir, targetDir, sanitizedId, asset.yaml);
267
+ }
268
+ }
269
+ }
270
+ /**
271
+ * Gets the target directory for an asset
272
+ *
273
+ * @private
274
+ * @param {('templates' | 'crds')} [target] - Target directory type
275
+ * @returns {string} Directory name
276
+ * @since 1.0.0
277
+ */
278
+ function getTargetDirectory(target) {
279
+ return target === 'crds' ? 'crds' : 'templates';
280
+ }
281
+ /**
282
+ * Writes a single asset file without document splitting
283
+ *
284
+ * @private
285
+ * @param {string} outDir - Output directory path
286
+ * @param {string} targetDir - Target subdirectory
287
+ * @param {string} assetId - Asset identifier
288
+ * @param {string} yaml - YAML content
289
+ * @since 1.0.0
290
+ */
291
+ function writeSingleAssetFile(outDir, targetDir, assetId, yaml) {
292
+ const filename = `${assetId}.yaml`;
293
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
294
+ fs.mkdirSync(path.join(outDir, targetDir), { recursive: true });
295
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
296
+ fs.writeFileSync(path.join(outDir, targetDir, filename), yaml + '\n');
297
+ }
298
+ /**
299
+ * Writes multiple asset files by splitting YAML documents
300
+ *
301
+ * @private
302
+ * @param {string} outDir - Output directory path
303
+ * @param {string} targetDir - Target subdirectory
304
+ * @param {string} assetId - Asset identifier
305
+ * @param {string} yaml - YAML content with potential multiple documents
306
+ * @since 1.0.0
307
+ */
308
+ function writeMultipleAssetFiles(outDir, targetDir, assetId, yaml) {
309
+ const parts = splitDocs(yaml);
310
+ parts.forEach((doc, index) => {
311
+ const filename = `${assetId}${parts.length > 1 ? `-${index + 1}` : ''}.yaml`;
312
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
313
+ fs.mkdirSync(path.join(outDir, targetDir), { recursive: true });
314
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Chart writer needs dynamic paths
315
+ fs.writeFileSync(path.join(outDir, targetDir, filename), doc + '\n');
316
+ });
317
+ }
318
+ //# sourceMappingURL=helmChartWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helmChartWriter.js","sourceRoot":"","sources":["../../src/lib/helmChartWriter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Autoscaling resources for Kubernetes workloads
3
+ * @since 2.3.0
4
+ */
5
+ import { BaseResourceProvider } from '../baseResourceProvider.js';
6
+ /**
7
+ * Autoscaling resources provider for HPA, VPA, and PodDisruptionBudget
8
+ *
9
+ * @extends BaseResourceProvider
10
+ * @since 2.3.0
11
+ */
12
+ export declare class AutoscalingResources extends BaseResourceProvider {
13
+ /**
14
+ * Add Horizontal Pod Autoscaler (HPA)
15
+ */
16
+ addHPA(_spec: unknown): void;
17
+ /**
18
+ * Add Vertical Pod Autoscaler (VPA)
19
+ */
20
+ addVPA(_spec: unknown): void;
21
+ /**
22
+ * Add Pod Disruption Budget (PDB)
23
+ */
24
+ addPodDisruptionBudget(_spec: unknown): void;
25
+ }
26
+ //# sourceMappingURL=autoscalingResources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoscalingResources.d.ts","sourceRoot":"","sources":["../../../../src/lib/resources/autoscaling/autoscalingResources.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,oBAAoB;IAC5D;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO;IAKrB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO;IAKrB;;OAEG;IACH,sBAAsB,CAAC,KAAK,EAAE,OAAO;CAItC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview Autoscaling resources for Kubernetes workloads
3
+ * @since 2.3.0
4
+ */
5
+ import { BaseResourceProvider } from '../baseResourceProvider.js';
6
+ /**
7
+ * Autoscaling resources provider for HPA, VPA, and PodDisruptionBudget
8
+ *
9
+ * @extends BaseResourceProvider
10
+ * @since 2.3.0
11
+ */
12
+ export class AutoscalingResources extends BaseResourceProvider {
13
+ /**
14
+ * Add Horizontal Pod Autoscaler (HPA)
15
+ */
16
+ addHPA(_spec) {
17
+ // Implementation moved from CoreResources
18
+ // TODO: Move HPA implementation here
19
+ }
20
+ /**
21
+ * Add Vertical Pod Autoscaler (VPA)
22
+ */
23
+ addVPA(_spec) {
24
+ // Implementation moved from CoreResources
25
+ // TODO: Move VPA implementation here
26
+ }
27
+ /**
28
+ * Add Pod Disruption Budget (PDB)
29
+ */
30
+ addPodDisruptionBudget(_spec) {
31
+ // Implementation moved from CoreResources
32
+ // TODO: Move PDB implementation here
33
+ }
34
+ }
35
+ //# sourceMappingURL=autoscalingResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoscalingResources.js","sourceRoot":"","sources":["../../../../src/lib/resources/autoscaling/autoscalingResources.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,oBAAoB;IAC5D;;OAEG;IACH,MAAM,CAAC,KAAc;QACnB,0CAA0C;QAC1C,qCAAqC;IACvC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAc;QACnB,0CAA0C;QAC1C,qCAAqC;IACvC,CAAC;IAED;;OAEG;IACH,sBAAsB,CAAC,KAAc;QACnC,0CAA0C;QAC1C,qCAAqC;IACvC,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ import type { Chart } from 'cdk8s';
2
+ import { ApiObject } from 'cdk8s';
3
+ /**
4
+ * Base interface for all resource providers
5
+ * Provides common functionality and ensures consistent patterns across providers
6
+ *
7
+ * @since 2.4.0
8
+ */
9
+ export interface IResourceProvider {
10
+ /** Reference to the CDK8s chart */
11
+ readonly chart: Chart;
12
+ }
13
+ /**
14
+ * Abstract base class for resource providers
15
+ * Implements common functionality and validation patterns
16
+ *
17
+ * @since 2.4.0
18
+ */
19
+ export declare abstract class BaseResourceProvider implements IResourceProvider {
20
+ readonly chart: Chart;
21
+ constructor(chart: Chart);
22
+ /**
23
+ * Validates that a name follows Kubernetes naming conventions
24
+ * @param name - Resource name to validate
25
+ * @param resourceType - Type of resource for error messages
26
+ * @throws Error if name is invalid
27
+ */
28
+ protected validateKubernetesName(name: string, resourceType: string): void;
29
+ /**
30
+ * Validates that labels follow Kubernetes conventions
31
+ * @param labels - Labels to validate
32
+ * @param resourceType - Type of resource for error messages
33
+ */
34
+ protected validateLabels(labels: Record<string, string> | undefined, resourceType: string): void;
35
+ /**
36
+ * Creates a standardized ApiObject with common metadata
37
+ * @param name - Resource name
38
+ * @param apiVersion - Kubernetes API version
39
+ * @param kind - Kubernetes resource kind
40
+ * @param spec - Resource specification
41
+ * @param labels - Optional labels
42
+ * @param annotations - Optional annotations
43
+ * @returns Created ApiObject
44
+ */
45
+ protected createApiObject(name: string, apiVersion: string, kind: string, spec: Record<string, unknown>, labels?: Record<string, string>, annotations?: Record<string, string>): ApiObject;
46
+ }
47
+ //# sourceMappingURL=baseResourceProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseResourceProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/baseResourceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;GAKG;AACH,8BAAsB,oBAAqB,YAAW,iBAAiB;aACzC,KAAK,EAAE,KAAK;gBAAZ,KAAK,EAAE,KAAK;IAExC;;;;;OAKG;IACH,SAAS,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAe1E;;;;OAIG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IA4BhG;;;;;;;;;OASG;IACH,SAAS,CAAC,eAAe,CACvB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,SAAS;CAeb"}
@@ -0,0 +1,83 @@
1
+ import { ApiObject } from 'cdk8s';
2
+ /**
3
+ * Abstract base class for resource providers
4
+ * Implements common functionality and validation patterns
5
+ *
6
+ * @since 2.4.0
7
+ */
8
+ export class BaseResourceProvider {
9
+ constructor(chart) {
10
+ this.chart = chart;
11
+ }
12
+ /**
13
+ * Validates that a name follows Kubernetes naming conventions
14
+ * @param name - Resource name to validate
15
+ * @param resourceType - Type of resource for error messages
16
+ * @throws Error if name is invalid
17
+ */
18
+ validateKubernetesName(name, resourceType) {
19
+ if (!name || typeof name !== 'string') {
20
+ throw new Error(`${resourceType} name must be a non-empty string`);
21
+ }
22
+ // Kubernetes name validation (RFC 1123 subdomain)
23
+ // eslint-disable-next-line security/detect-unsafe-regex -- Simple character class regex is safe
24
+ const nameRegex = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/;
25
+ if (!nameRegex.test(name) || name.length > 63) {
26
+ throw new Error(`${resourceType} name '${name}' must be a valid Kubernetes name (lowercase alphanumeric and hyphens, max 63 chars)`);
27
+ }
28
+ }
29
+ /**
30
+ * Validates that labels follow Kubernetes conventions
31
+ * @param labels - Labels to validate
32
+ * @param resourceType - Type of resource for error messages
33
+ */
34
+ validateLabels(labels, resourceType) {
35
+ if (!labels)
36
+ return;
37
+ Object.entries(labels).forEach(([key, value]) => {
38
+ // Validate label key
39
+ if (key.length > 253) {
40
+ throw new Error(`${resourceType} label key '${key}' exceeds 253 characters`);
41
+ }
42
+ // Validate label value
43
+ if (value.length > 63) {
44
+ throw new Error(`${resourceType} label value '${value}' exceeds 63 characters`);
45
+ }
46
+ // Skip validation for Helm template values
47
+ if (value.includes('{{') && value.includes('}}')) {
48
+ return;
49
+ }
50
+ // Basic character validation
51
+ // eslint-disable-next-line security/detect-unsafe-regex -- Simple character class regex is safe
52
+ const labelRegex = /^[a-zA-Z0-9]([-a-zA-Z0-9_.]*[a-zA-Z0-9])?$/;
53
+ if (!labelRegex.test(value)) {
54
+ throw new Error(`${resourceType} label value '${value}' contains invalid characters`);
55
+ }
56
+ });
57
+ }
58
+ /**
59
+ * Creates a standardized ApiObject with common metadata
60
+ * @param name - Resource name
61
+ * @param apiVersion - Kubernetes API version
62
+ * @param kind - Kubernetes resource kind
63
+ * @param spec - Resource specification
64
+ * @param labels - Optional labels
65
+ * @param annotations - Optional annotations
66
+ * @returns Created ApiObject
67
+ */
68
+ createApiObject(name, apiVersion, kind, spec, labels, annotations) {
69
+ this.validateKubernetesName(name, kind);
70
+ this.validateLabels(labels, kind);
71
+ return new ApiObject(this.chart, name, {
72
+ apiVersion,
73
+ kind,
74
+ metadata: {
75
+ name,
76
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
77
+ ...(annotations && Object.keys(annotations).length > 0 ? { annotations } : {}),
78
+ },
79
+ spec,
80
+ });
81
+ }
82
+ }
83
+ //# sourceMappingURL=baseResourceProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseResourceProvider.js","sourceRoot":"","sources":["../../../src/lib/resources/baseResourceProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAalC;;;;;GAKG;AACH,MAAM,OAAgB,oBAAoB;IACxC,YAA4B,KAAY;QAAZ,UAAK,GAAL,KAAK,CAAO;IAAG,CAAC;IAE5C;;;;;OAKG;IACO,sBAAsB,CAAC,IAAY,EAAE,YAAoB;QACjE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,kCAAkC,CAAC,CAAC;QACrE,CAAC;QAED,kDAAkD;QAClD,gGAAgG;QAChG,MAAM,SAAS,GAAG,iCAAiC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,GAAG,YAAY,UAAU,IAAI,sFAAsF,CACpH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACO,cAAc,CAAC,MAA0C,EAAE,YAAoB;QACvF,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAC9C,qBAAqB;YACrB,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,eAAe,GAAG,0BAA0B,CAAC,CAAC;YAC/E,CAAC;YAED,uBAAuB;YACvB,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,iBAAiB,KAAK,yBAAyB,CAAC,CAAC;YAClF,CAAC;YAED,2CAA2C;YAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,6BAA6B;YAC7B,gGAAgG;YAChG,MAAM,UAAU,GAAG,4CAA4C,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,iBAAiB,KAAK,+BAA+B,CAAC,CAAC;YACxF,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACO,eAAe,CACvB,IAAY,EACZ,UAAkB,EAClB,IAAY,EACZ,IAA6B,EAC7B,MAA+B,EAC/B,WAAoC;QAEpC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAElC,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;YACrC,UAAU;YACV,IAAI;YACJ,QAAQ,EAAE;gBACR,IAAI;gBACJ,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/D,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/E;YACD,IAAI;SACL,CAAC,CAAC;IACL,CAAC;CACF"}