@intentius/chant-lexicon-helm 0.0.16

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 (110) hide show
  1. package/README.md +22 -0
  2. package/dist/integrity.json +36 -0
  3. package/dist/manifest.json +37 -0
  4. package/dist/meta.json +208 -0
  5. package/dist/rules/chart-metadata.ts +64 -0
  6. package/dist/rules/helm-helpers.ts +64 -0
  7. package/dist/rules/no-hardcoded-image.ts +62 -0
  8. package/dist/rules/values-no-secrets.ts +82 -0
  9. package/dist/rules/whm101.ts +46 -0
  10. package/dist/rules/whm102.ts +33 -0
  11. package/dist/rules/whm103.ts +59 -0
  12. package/dist/rules/whm104.ts +35 -0
  13. package/dist/rules/whm105.ts +30 -0
  14. package/dist/rules/whm201.ts +36 -0
  15. package/dist/rules/whm202.ts +50 -0
  16. package/dist/rules/whm203.ts +39 -0
  17. package/dist/rules/whm204.ts +60 -0
  18. package/dist/rules/whm301.ts +41 -0
  19. package/dist/rules/whm302.ts +40 -0
  20. package/dist/rules/whm401.ts +57 -0
  21. package/dist/rules/whm402.ts +45 -0
  22. package/dist/rules/whm403.ts +45 -0
  23. package/dist/rules/whm404.ts +36 -0
  24. package/dist/rules/whm405.ts +53 -0
  25. package/dist/rules/whm406.ts +34 -0
  26. package/dist/rules/whm407.ts +83 -0
  27. package/dist/rules/whm501.ts +103 -0
  28. package/dist/rules/whm502.ts +94 -0
  29. package/dist/skills/chant-helm-chart-patterns.md +229 -0
  30. package/dist/skills/chant-helm-chart-security-patterns.md +192 -0
  31. package/dist/skills/chant-helm-create-chart.md +211 -0
  32. package/dist/types/index.d.ts +132 -0
  33. package/package.json +34 -0
  34. package/src/codegen/docs-cli.ts +4 -0
  35. package/src/codegen/docs.ts +483 -0
  36. package/src/codegen/generate-cli.ts +28 -0
  37. package/src/codegen/generate.ts +249 -0
  38. package/src/codegen/naming.ts +38 -0
  39. package/src/codegen/package.ts +64 -0
  40. package/src/composites/composites.test.ts +1050 -0
  41. package/src/composites/helm-batch-job.ts +209 -0
  42. package/src/composites/helm-crd-lifecycle.ts +184 -0
  43. package/src/composites/helm-cron-job.ts +177 -0
  44. package/src/composites/helm-daemon-set.ts +169 -0
  45. package/src/composites/helm-external-secret.ts +93 -0
  46. package/src/composites/helm-library.ts +51 -0
  47. package/src/composites/helm-microservice.ts +331 -0
  48. package/src/composites/helm-monitored-service.ts +252 -0
  49. package/src/composites/helm-namespace-env.ts +154 -0
  50. package/src/composites/helm-secure-ingress.ts +114 -0
  51. package/src/composites/helm-stateful-service.ts +213 -0
  52. package/src/composites/helm-web-app.ts +264 -0
  53. package/src/composites/helm-worker.ts +207 -0
  54. package/src/composites/index.ts +38 -0
  55. package/src/coverage.test.ts +21 -0
  56. package/src/coverage.ts +50 -0
  57. package/src/generated/index.d.ts +132 -0
  58. package/src/generated/index.ts +13 -0
  59. package/src/generated/lexicon-helm.json +208 -0
  60. package/src/helpers.test.ts +51 -0
  61. package/src/helpers.ts +100 -0
  62. package/src/import/generator.ts +285 -0
  63. package/src/import/import.test.ts +224 -0
  64. package/src/import/parser.ts +160 -0
  65. package/src/import/template-stripper.ts +123 -0
  66. package/src/index.ts +108 -0
  67. package/src/intrinsics.test.ts +380 -0
  68. package/src/intrinsics.ts +484 -0
  69. package/src/lint/post-synth/helm-helpers.ts +64 -0
  70. package/src/lint/post-synth/post-synth.test.ts +504 -0
  71. package/src/lint/post-synth/whm101.ts +46 -0
  72. package/src/lint/post-synth/whm102.ts +33 -0
  73. package/src/lint/post-synth/whm103.ts +59 -0
  74. package/src/lint/post-synth/whm104.ts +35 -0
  75. package/src/lint/post-synth/whm105.ts +30 -0
  76. package/src/lint/post-synth/whm201.ts +36 -0
  77. package/src/lint/post-synth/whm202.ts +50 -0
  78. package/src/lint/post-synth/whm203.ts +39 -0
  79. package/src/lint/post-synth/whm204.ts +60 -0
  80. package/src/lint/post-synth/whm301.ts +41 -0
  81. package/src/lint/post-synth/whm302.ts +40 -0
  82. package/src/lint/post-synth/whm401.ts +57 -0
  83. package/src/lint/post-synth/whm402.ts +45 -0
  84. package/src/lint/post-synth/whm403.ts +45 -0
  85. package/src/lint/post-synth/whm404.ts +36 -0
  86. package/src/lint/post-synth/whm405.ts +53 -0
  87. package/src/lint/post-synth/whm406.ts +34 -0
  88. package/src/lint/post-synth/whm407.ts +83 -0
  89. package/src/lint/post-synth/whm501.ts +103 -0
  90. package/src/lint/post-synth/whm502.ts +94 -0
  91. package/src/lint/rules/chart-metadata.ts +64 -0
  92. package/src/lint/rules/lint-rules.test.ts +97 -0
  93. package/src/lint/rules/no-hardcoded-image.ts +62 -0
  94. package/src/lint/rules/values-no-secrets.ts +82 -0
  95. package/src/lsp/completions.test.ts +72 -0
  96. package/src/lsp/completions.ts +20 -0
  97. package/src/lsp/hover.test.ts +46 -0
  98. package/src/lsp/hover.ts +46 -0
  99. package/src/package-cli.ts +28 -0
  100. package/src/plugin.test.ts +71 -0
  101. package/src/plugin.ts +206 -0
  102. package/src/resources.ts +77 -0
  103. package/src/serializer.test.ts +930 -0
  104. package/src/serializer.ts +835 -0
  105. package/src/skills/chart-patterns.md +229 -0
  106. package/src/skills/chart-security-patterns.md +192 -0
  107. package/src/skills/create-chart.md +211 -0
  108. package/src/validate-cli.ts +21 -0
  109. package/src/validate.test.ts +37 -0
  110. package/src/validate.ts +36 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Helm generation pipeline — static type generation.
3
+ *
4
+ * Unlike AWS/K8s, Helm types are defined statically (no upstream schema to
5
+ * fetch). This module generates lexicon-helm.json, index.d.ts, and index.ts
6
+ * directly from the known Helm resource/property type definitions.
7
+ */
8
+
9
+ import {
10
+ writeGeneratedArtifacts,
11
+ type GenerateResult,
12
+ } from "@intentius/chant/codegen/generate";
13
+
14
+ // ── Static type definitions ──────────────────────────────
15
+
16
+ interface HelmTypeEntry {
17
+ resourceType: string;
18
+ /** Export name matching resources.ts (e.g. "HelmTest" not "Test") */
19
+ exportName: string;
20
+ kind: "resource" | "property";
21
+ description: string;
22
+ props: Record<string, { type: string; description: string; required?: boolean }>;
23
+ }
24
+
25
+ const HELM_TYPES: HelmTypeEntry[] = [
26
+ {
27
+ resourceType: "Helm::Chart",
28
+ exportName: "Chart",
29
+ kind: "resource",
30
+ description: "Chart.yaml metadata — defines the chart identity, version, and type.",
31
+ props: {
32
+ apiVersion: { type: "string", description: "Chart API version (v2)", required: true },
33
+ name: { type: "string", description: "Chart name", required: true },
34
+ version: { type: "string", description: "Chart version (SemVer)", required: true },
35
+ appVersion: { type: "string", description: "Version of the app deployed by this chart" },
36
+ description: { type: "string", description: "A single-sentence description of this chart" },
37
+ type: { type: "string", description: "Chart type: application or library" },
38
+ keywords: { type: "string[]", description: "Keywords for chart search" },
39
+ home: { type: "string", description: "URL of the project home page" },
40
+ icon: { type: "string", description: "URL to an SVG or PNG image for the chart" },
41
+ deprecated: { type: "boolean", description: "Whether this chart is deprecated" },
42
+ sources: { type: "string[]", description: "URLs to source code for this chart" },
43
+ maintainers: { type: "HelmMaintainerProps[]", description: "List of chart maintainers" },
44
+ annotations: { type: "Record<string, string>", description: "Arbitrary key-value annotations" },
45
+ kubeVersion: { type: "string", description: "SemVer range of compatible Kubernetes versions" },
46
+ condition: { type: "string", description: "YAML path for chart enablement (subcharts)" },
47
+ tags: { type: "string", description: "Tags for grouping charts for enabling/disabling" },
48
+ },
49
+ },
50
+ {
51
+ resourceType: "Helm::Values",
52
+ exportName: "Values",
53
+ kind: "resource",
54
+ description: "Typed values definition — emits values.yaml and values.schema.json.",
55
+ props: {},
56
+ },
57
+ {
58
+ resourceType: "Helm::Test",
59
+ exportName: "HelmTest",
60
+ kind: "resource",
61
+ description: "Helm test pod — annotated with helm.sh/hook: test.",
62
+ props: {
63
+ resource: { type: "object", description: "K8s Pod resource to use as the test" },
64
+ },
65
+ },
66
+ {
67
+ resourceType: "Helm::Notes",
68
+ exportName: "HelmNotes",
69
+ kind: "resource",
70
+ description: "NOTES.txt template content — displayed after helm install.",
71
+ props: {
72
+ content: { type: "string", description: "NOTES.txt content (may contain Go template expressions)", required: true },
73
+ },
74
+ },
75
+ {
76
+ resourceType: "Helm::Hook",
77
+ exportName: "HelmHook",
78
+ kind: "property",
79
+ description: "Lifecycle hook annotation — wraps a K8s resource with helm.sh/hook annotations.",
80
+ props: {
81
+ hook: { type: "string", description: "Hook type: pre-install, post-install, pre-upgrade, post-upgrade, pre-delete, post-delete, pre-rollback, post-rollback, test", required: true },
82
+ weight: { type: "number", description: "Hook execution order weight" },
83
+ deletePolicy: { type: "string", description: "Hook delete policy: before-hook-creation, hook-succeeded, hook-failed" },
84
+ resource: { type: "object", description: "K8s resource to annotate with the hook", required: true },
85
+ },
86
+ },
87
+ {
88
+ resourceType: "Helm::Dependency",
89
+ exportName: "HelmDependency",
90
+ kind: "property",
91
+ description: "Chart dependency entry for Chart.yaml dependencies.",
92
+ props: {
93
+ name: { type: "string", description: "Dependency chart name", required: true },
94
+ version: { type: "string", description: "Dependency version range (SemVer)", required: true },
95
+ repository: { type: "string", description: "Repository URL", required: true },
96
+ condition: { type: "string", description: "YAML path that enables/disables this dependency" },
97
+ tags: { type: "string[]", description: "Tags for grouping dependencies" },
98
+ enabled: { type: "boolean", description: "Whether this dependency is enabled" },
99
+ importValues: { type: "unknown[]", description: "Values to import from dependency (import-values in Chart.yaml)" },
100
+ alias: { type: "string", description: "Alias for the dependency" },
101
+ },
102
+ },
103
+ {
104
+ resourceType: "Helm::Maintainer",
105
+ exportName: "HelmMaintainer",
106
+ kind: "property",
107
+ description: "Chart maintainer entry for Chart.yaml maintainers.",
108
+ props: {
109
+ name: { type: "string", description: "Maintainer name", required: true },
110
+ email: { type: "string", description: "Maintainer email" },
111
+ url: { type: "string", description: "Maintainer URL" },
112
+ },
113
+ },
114
+ {
115
+ resourceType: "Helm::CRD",
116
+ exportName: "HelmCRD",
117
+ kind: "resource",
118
+ description: "Custom Resource Definition — placed in the crds/ directory.",
119
+ props: {
120
+ content: { type: "string", description: "CRD YAML content", required: true },
121
+ filename: { type: "string", description: "CRD filename (e.g. mycrd.yaml)" },
122
+ },
123
+ },
124
+ ];
125
+
126
+ // ── Generate artifacts ──────────────────────────────────
127
+
128
+ function generateLexiconJSON(): string {
129
+ const registry: Record<string, Record<string, unknown>> = {};
130
+ for (const t of HELM_TYPES) {
131
+ registry[t.exportName] = {
132
+ resourceType: t.resourceType,
133
+ kind: t.kind,
134
+ description: t.description,
135
+ props: t.props,
136
+ };
137
+ }
138
+ return JSON.stringify(registry, null, 2);
139
+ }
140
+
141
+ function generateTypesDTS(): string {
142
+ const lines: string[] = [
143
+ '// Auto-generated Helm lexicon type declarations',
144
+ '// Do not edit manually',
145
+ '',
146
+ '/** Minimal Declarable interface for generated types. */',
147
+ 'interface Declarable { [key: string]: unknown; }',
148
+ '',
149
+ ];
150
+
151
+ for (const t of HELM_TYPES) {
152
+ const className = t.exportName;
153
+ const propsInterface = `${className}Props`;
154
+
155
+ // Generate props interface
156
+ lines.push(`/** ${t.description} */`);
157
+ lines.push(`export interface ${propsInterface} {`);
158
+ for (const [key, prop] of Object.entries(t.props)) {
159
+ const optional = prop.required ? "" : "?";
160
+ lines.push(` /** ${prop.description} */`);
161
+ lines.push(` ${key}${optional}: ${prop.type};`);
162
+ }
163
+ if (Object.keys(t.props).length === 0) {
164
+ lines.push(" [key: string]: unknown;");
165
+ }
166
+ lines.push("}");
167
+ lines.push("");
168
+
169
+ // Generate class declaration
170
+ lines.push(`/** ${t.description} */`);
171
+ lines.push(`export declare const ${className}: new (props: ${propsInterface}) => Declarable;`);
172
+ lines.push("");
173
+ }
174
+
175
+ return lines.join("\n");
176
+ }
177
+
178
+ function generateRuntimeIndex(): string {
179
+ const lines: string[] = [
180
+ '// Auto-generated Helm lexicon runtime index',
181
+ '// Do not edit manually',
182
+ '',
183
+ 'import { createResource, createProperty } from "@intentius/chant/runtime";',
184
+ '',
185
+ ];
186
+
187
+ for (const t of HELM_TYPES) {
188
+ if (t.kind === "resource") {
189
+ lines.push(`export const ${t.exportName} = createResource("${t.resourceType}", "helm", {});`);
190
+ } else {
191
+ lines.push(`export const ${t.exportName} = createProperty("${t.resourceType}", "helm");`);
192
+ }
193
+ }
194
+
195
+ lines.push("");
196
+ return lines.join("\n");
197
+ }
198
+
199
+ // ── Public API ──────────────────────────────────────────
200
+
201
+ export interface HelmGenerateOptions {
202
+ verbose?: boolean;
203
+ force?: boolean;
204
+ }
205
+
206
+ /**
207
+ * Run the Helm generation pipeline.
208
+ * Since Helm types are static, this doesn't fetch anything.
209
+ */
210
+ export async function generate(opts: HelmGenerateOptions = {}): Promise<GenerateResult> {
211
+ const log = opts.verbose
212
+ ? (msg: string) => console.error(msg)
213
+ : (_msg: string) => {};
214
+
215
+ log("Generating Helm lexicon (static types)...");
216
+
217
+ const lexiconJSON = generateLexiconJSON();
218
+ const typesDTS = generateTypesDTS();
219
+ const indexTS = generateRuntimeIndex();
220
+
221
+ const resourceCount = HELM_TYPES.filter((t) => t.kind === "resource").length;
222
+ const propertyCount = HELM_TYPES.filter((t) => t.kind === "property").length;
223
+
224
+ log(`Generated ${resourceCount} resources, ${propertyCount} property types`);
225
+
226
+ return {
227
+ lexiconJSON,
228
+ typesDTS,
229
+ indexTS,
230
+ resources: resourceCount,
231
+ properties: propertyCount,
232
+ enums: 0,
233
+ warnings: [],
234
+ };
235
+ }
236
+
237
+ /**
238
+ * Write generated artifacts to disk.
239
+ */
240
+ export function writeGeneratedFiles(result: GenerateResult, baseDir: string): void {
241
+ writeGeneratedArtifacts({
242
+ baseDir,
243
+ files: {
244
+ "lexicon-helm.json": result.lexiconJSON,
245
+ "index.d.ts": result.typesDTS,
246
+ "index.ts": result.indexTS,
247
+ },
248
+ });
249
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Helm naming strategy — trivial mapping since Helm types are few and static.
3
+ *
4
+ * Maps Helm::{TypeName} → TypeName (e.g. Helm::Chart → Chart).
5
+ */
6
+
7
+ import {
8
+ NamingStrategy as CoreNamingStrategy,
9
+ type NamingConfig,
10
+ type NamingInput,
11
+ } from "@intentius/chant/codegen/naming";
12
+
13
+ const helmNamingConfig: NamingConfig = {
14
+ priorityNames: {
15
+ "Helm::Chart": "Chart",
16
+ "Helm::Values": "Values",
17
+ "Helm::Test": "HelmTest",
18
+ "Helm::Notes": "HelmNotes",
19
+ "Helm::Hook": "HelmHook",
20
+ "Helm::Dependency": "HelmDependency",
21
+ },
22
+
23
+ priorityAliases: {},
24
+ priorityPropertyAliases: {},
25
+ serviceAbbreviations: {},
26
+
27
+ shortName: (typeName: string) => typeName.split("::").pop() ?? typeName,
28
+ serviceName: (_typeName: string) => "Helm",
29
+ };
30
+
31
+ /**
32
+ * Helm naming strategy.
33
+ */
34
+ export class NamingStrategy extends CoreNamingStrategy {
35
+ constructor(inputs: NamingInput[]) {
36
+ super(inputs, helmNamingConfig);
37
+ }
38
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Helm lexicon packaging — delegates to core packagePipeline
3
+ * with Helm-specific manifest building and skill collection.
4
+ */
5
+
6
+ import { createRequire } from "module";
7
+ import { readFileSync } from "fs";
8
+ const require = createRequire(import.meta.url);
9
+ import { join, dirname } from "path";
10
+ import { fileURLToPath } from "url";
11
+ import {
12
+ packagePipeline,
13
+ collectSkills,
14
+ type PackageOptions,
15
+ type PackageResult,
16
+ } from "@intentius/chant/codegen/package";
17
+ import { generate } from "./generate";
18
+
19
+ export type { PackageOptions, PackageResult };
20
+
21
+ const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
22
+
23
+ /**
24
+ * Package the Helm lexicon into a distributable BundleSpec.
25
+ */
26
+ export async function packageLexicon(opts: PackageOptions = {}): Promise<PackageResult> {
27
+ const pkgJson = JSON.parse(readFileSync(join(pkgDir, "..", "package.json"), "utf-8"));
28
+
29
+ return packagePipeline(
30
+ {
31
+ generate: (genOpts) => generate({ verbose: genOpts.verbose, force: genOpts.force }),
32
+
33
+ buildManifest: (_genResult) => {
34
+ return {
35
+ name: "helm",
36
+ version: pkgJson.version ?? "0.0.0",
37
+ chantVersion: ">=0.1.0",
38
+ namespace: "Helm",
39
+ intrinsics: [
40
+ { name: "values", description: "Proxy accessor for {{ .Values.x }} references" },
41
+ { name: "Release", description: "Built-in Release object" },
42
+ { name: "ChartRef", description: "Built-in Chart object" },
43
+ { name: "include", description: "Include a named template" },
44
+ { name: "If", description: "Conditional resource/value" },
45
+ { name: "Range", description: "Range loop" },
46
+ { name: "With", description: "With scope" },
47
+ ],
48
+ pseudoParameters: {},
49
+ };
50
+ },
51
+
52
+ srcDir: pkgDir,
53
+
54
+ collectSkills: () => {
55
+ const { helmPlugin } = require("../plugin");
56
+ const skillDefs = helmPlugin.skills?.() ?? [];
57
+ return collectSkills(skillDefs);
58
+ },
59
+
60
+ version: pkgJson.version ?? "0.0.0",
61
+ },
62
+ opts,
63
+ );
64
+ }