@intentius/chant-lexicon-helm 0.1.4 → 0.1.8
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/dist/integrity.json +34 -34
- package/dist/manifest.json +1 -1
- package/package.json +8 -8
- package/src/codegen/docs-cli.ts +1 -1
- package/src/codegen/docs.test.ts +2 -2
- package/src/codegen/generate-cli.ts +1 -1
- package/src/codegen/generate.test.ts +3 -3
- package/src/codegen/package.test.ts +2 -2
- package/src/codegen/package.ts +1 -3
- package/src/composites/composites.test.ts +1 -1
- package/src/coverage.test.ts +1 -1
- package/src/helpers.test.ts +1 -1
- package/src/import/import.test.ts +1 -1
- package/src/import/roundtrip.test.ts +1 -1
- package/src/intrinsics.test.ts +1 -1
- package/src/lint/post-synth/post-synth.test.ts +1 -1
- package/src/lint/post-synth/whm101.test.ts +1 -1
- package/src/lint/post-synth/whm102.test.ts +1 -1
- package/src/lint/post-synth/whm103.test.ts +1 -1
- package/src/lint/post-synth/whm104.test.ts +1 -1
- package/src/lint/post-synth/whm105.test.ts +1 -1
- package/src/lint/post-synth/whm201.test.ts +1 -1
- package/src/lint/post-synth/whm202.test.ts +1 -1
- package/src/lint/post-synth/whm203.test.ts +1 -1
- package/src/lint/post-synth/whm204.test.ts +1 -1
- package/src/lint/post-synth/whm301.test.ts +1 -1
- package/src/lint/post-synth/whm302.test.ts +1 -1
- package/src/lint/post-synth/whm401.test.ts +1 -1
- package/src/lint/post-synth/whm402.test.ts +1 -1
- package/src/lint/post-synth/whm403.test.ts +1 -1
- package/src/lint/post-synth/whm404.test.ts +1 -1
- package/src/lint/post-synth/whm405.test.ts +1 -1
- package/src/lint/post-synth/whm406.test.ts +1 -1
- package/src/lint/post-synth/whm407.test.ts +1 -1
- package/src/lint/post-synth/whm501.test.ts +1 -1
- package/src/lint/post-synth/whm502.test.ts +1 -1
- package/src/lint/rules/chart-metadata.test.ts +1 -1
- package/src/lint/rules/lint-rules.test.ts +1 -1
- package/src/lint/rules/no-hardcoded-image.test.ts +1 -1
- package/src/lint/rules/values-no-secrets.test.ts +1 -1
- package/src/list-artifacts.test.ts +94 -0
- package/src/list-artifacts.ts +79 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/hover.test.ts +1 -1
- package/src/package-cli.ts +1 -1
- package/src/plugin.test.ts +1 -1
- package/src/plugin.ts +7 -2
- package/src/serializer.test.ts +4 -5
- package/src/validate-cli.ts +1 -1
- package/src/validate.test.ts +1 -1
package/dist/integrity.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
"algorithm": "
|
|
2
|
+
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
5
|
-
"meta.json": "
|
|
6
|
-
"types/index.d.ts": "
|
|
7
|
-
"rules/
|
|
8
|
-
"rules/
|
|
9
|
-
"rules/values-no-
|
|
10
|
-
"rules/no-
|
|
11
|
-
"rules/
|
|
12
|
-
"rules/
|
|
13
|
-
"rules/
|
|
14
|
-
"rules/
|
|
15
|
-
"rules/
|
|
16
|
-
"rules/
|
|
17
|
-
"rules/whm105.ts": "
|
|
18
|
-
"rules/
|
|
19
|
-
"rules/
|
|
20
|
-
"rules/
|
|
21
|
-
"rules/
|
|
22
|
-
"rules/
|
|
23
|
-
"rules/
|
|
24
|
-
"rules/
|
|
25
|
-
"rules/
|
|
26
|
-
"rules/
|
|
27
|
-
"rules/
|
|
28
|
-
"rules/
|
|
29
|
-
"rules/
|
|
30
|
-
"rules/
|
|
31
|
-
"rules/
|
|
32
|
-
"rules/
|
|
33
|
-
"skills/chant-helm.md": "
|
|
34
|
-
"skills/chant-helm-patterns.md": "
|
|
35
|
-
"skills/chant-helm-security.md": "
|
|
4
|
+
"manifest.json": "d4a9a8168563da87916d1ff56334f061b9e7f573dd37a4b34714863a8570df1e",
|
|
5
|
+
"meta.json": "14243c5730a07c6a6edc35ddd351438547d58df5cf345f2233a355b0c7611ccc",
|
|
6
|
+
"types/index.d.ts": "5377696ca8698cd2999e4680feb8e8e4b54a7b49fb603a87b2f27356114d1794",
|
|
7
|
+
"rules/chart-metadata.ts": "8f3377e893d5e2828460b7fe5924fca098334245a9a2fdb90f6b67e490eaf091",
|
|
8
|
+
"rules/no-hardcoded-image.ts": "b00433bd5f4e963ffd56d8a623c00fbfaa40dc37b6d72609d26c91a309d75a90",
|
|
9
|
+
"rules/values-no-helm-tpl.ts": "bd30478da004bafaed6ed6231636f1e2867f5255deb6313c8f6e3505c5c91b11",
|
|
10
|
+
"rules/values-no-secrets.ts": "ec9193fb39764e65e44022e39fda124147350e4d2b4e2e34deaa5db82116f76c",
|
|
11
|
+
"rules/helm-helpers.ts": "c2631bbf261573c553e475cfc2f1b007fc5feb4b1f986b5ba660f3290f4d3eaf",
|
|
12
|
+
"rules/whm005-no-empty-wrapper.ts": "bfecf05449106c639b317eecdcd969ad2a851c4be9ee029380f99278e2a19630",
|
|
13
|
+
"rules/whm101.ts": "6fb49f184cec898640118a3ce14edc5d62c05c694491b0eab4e53dbc10921e8d",
|
|
14
|
+
"rules/whm102.ts": "99ea2a695b49fe39e20b8dccdec5bcf5b189e08ac026318ce633fbf9a226132d",
|
|
15
|
+
"rules/whm103.ts": "80f533af6d9bae924a3cc3ceedf158f13d4138d6ef3115a0e3093f5a0464592d",
|
|
16
|
+
"rules/whm104.ts": "1752338ade55c87dafee23dc09e0150c4ae55ac90eb8b8e9010c89b7ad73503d",
|
|
17
|
+
"rules/whm105.ts": "d710b04267c558839ec99001e0b4604017ef6484e7083585fe160192a5920d69",
|
|
18
|
+
"rules/whm201.ts": "0de1a8cad242feadbb4e9c4e0eebfb94df1f2c2bf535802ebf535067f7859619",
|
|
19
|
+
"rules/whm202.ts": "6a2fc424d8b753113cd13de565ce93dfd1cdf0e606c56977b9e17e92147abf54",
|
|
20
|
+
"rules/whm203.ts": "d98176fd2a2c0d6ddc2d3b37180c5e7be618b47b6c12821df9b51cfe7950d938",
|
|
21
|
+
"rules/whm204.ts": "b5e37aea05662e16e02843e20e4642de82b666026d58e1ebf18c337768fdaff8",
|
|
22
|
+
"rules/whm301.ts": "0ed09a07a8f3d59fb3c2bc330e7b92f7c2eb31655b6a301b06b10b485fe12edc",
|
|
23
|
+
"rules/whm302.ts": "d4cb8cdf776e4bdf0551fc8ab28c584f66efbe6648aef0b325acb07e415da73b",
|
|
24
|
+
"rules/whm401.ts": "a49b41ff9837f2c9ada011d4ee31fffe8e68b278d50badbab32459ea05bc4a01",
|
|
25
|
+
"rules/whm402.ts": "917f85fbc4d31c9b7eec5eda684aa24b847d33bd6f0507bdc435c1796bd66476",
|
|
26
|
+
"rules/whm403.ts": "716cc86eb1a4ba345ef875ac50cef033d017edf50964695ec9399b593d3bcce2",
|
|
27
|
+
"rules/whm404.ts": "e4c7d6877fb3f658ce3a109722fa65b508d7160e186fdf5a63d8ddfc6262e218",
|
|
28
|
+
"rules/whm405.ts": "6d7d230b94e694c3b94dd8fbfe719856c1fbf171ef6dd0552843f56f6c512c03",
|
|
29
|
+
"rules/whm406.ts": "79ce3b318ce53ee74bbf814ae31e0873fe882096dcb5c5369495bed022dbf57d",
|
|
30
|
+
"rules/whm407.ts": "200190f5de2d86d2bcc5aee0b5ce4807919ec727b1fc14576ea17b9b3073838b",
|
|
31
|
+
"rules/whm501.ts": "e6afa7c0eface9820380bf189fe8be58f4a6997dd5b74f76335022650616d080",
|
|
32
|
+
"rules/whm502.ts": "c3ed7b4b5215d96e46eba758aca2171928d8f8fb1eb20452ea6b4393672755b0",
|
|
33
|
+
"skills/chant-helm.md": "94528606c7a972f478d3c716eb7fe5fd79a6520532ccc4f9a3c99e9b0d691025",
|
|
34
|
+
"skills/chant-helm-patterns.md": "9e79e6a46391da46709d8aa57e2825a7cd9eb981cd923f02ad60836c49b2561e",
|
|
35
|
+
"skills/chant-helm-security.md": "bfc367eabceed2e84f1cf94501b407df78aeed963cec104f24a321d0962063c9"
|
|
36
36
|
},
|
|
37
|
-
"composite": "
|
|
37
|
+
"composite": "ca5dd2d974996391ad2e74466d0b3e8d2c879212cbf72b56ebe1499d6bb7d897"
|
|
38
38
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-helm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Helm chart lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"./types": "./dist/types/index.d.ts"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"generate": "
|
|
40
|
-
"bundle": "
|
|
41
|
-
"validate": "
|
|
42
|
-
"docs": "
|
|
43
|
-
"prepack": "
|
|
39
|
+
"generate": "tsx src/codegen/generate-cli.ts",
|
|
40
|
+
"bundle": "tsx src/package-cli.ts",
|
|
41
|
+
"validate": "tsx src/validate-cli.ts",
|
|
42
|
+
"docs": "tsx src/codegen/docs-cli.ts",
|
|
43
|
+
"prepack": "npm run generate && npm run bundle && npm run validate"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@intentius/chant-lexicon-k8s": "
|
|
46
|
+
"@intentius/chant-lexicon-k8s": "*"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@intentius/chant": "
|
|
49
|
+
"@intentius/chant": "*",
|
|
50
50
|
"typescript": "^5.9.3"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
package/src/codegen/docs-cli.ts
CHANGED
package/src/codegen/docs.test.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
|
|
3
3
|
describe("Helm docs generation", () => {
|
|
4
4
|
test("docs module is importable", async () => {
|
|
5
5
|
const mod = await import("./docs");
|
|
6
|
-
expect(mod.generateDocs).
|
|
6
|
+
expect(typeof mod.generateDocs).toBe("function");
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
test("generateDocs function signature accepts options", async () => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { generate } from "./generate";
|
|
3
3
|
|
|
4
4
|
describe("Helm generate pipeline", () => {
|
|
5
5
|
test("generate module is importable", async () => {
|
|
6
6
|
const mod = await import("./generate");
|
|
7
|
-
expect(mod.generate).
|
|
8
|
-
expect(mod.writeGeneratedFiles).
|
|
7
|
+
expect(typeof mod.generate).toBe("function");
|
|
8
|
+
expect(typeof mod.writeGeneratedFiles).toBe("function");
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
test("generates lexicon JSON, types, and index", async () => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { packageLexicon } from "./package";
|
|
3
3
|
|
|
4
4
|
describe("Helm package pipeline", () => {
|
|
5
5
|
test("packageLexicon is importable", async () => {
|
|
6
6
|
const mod = await import("./package");
|
|
7
|
-
expect(mod.packageLexicon).
|
|
7
|
+
expect(typeof mod.packageLexicon).toBe("function");
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
test("packageLexicon returns a valid result", async () => {
|
package/src/codegen/package.ts
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
* with Helm-specific manifest building and skill collection.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { createRequire } from "module";
|
|
7
6
|
import { readFileSync } from "fs";
|
|
8
|
-
const require = createRequire(import.meta.url);
|
|
9
7
|
import { join, dirname } from "path";
|
|
10
8
|
import { fileURLToPath } from "url";
|
|
9
|
+
import { helmPlugin } from "../plugin";
|
|
11
10
|
import {
|
|
12
11
|
packagePipeline,
|
|
13
12
|
collectSkills,
|
|
@@ -52,7 +51,6 @@ export async function packageLexicon(opts: PackageOptions = {}): Promise<Package
|
|
|
52
51
|
srcDir: pkgDir,
|
|
53
52
|
|
|
54
53
|
collectSkills: () => {
|
|
55
|
-
const { helmPlugin } = require("../plugin");
|
|
56
54
|
const skillDefs = helmPlugin.skills?.() ?? [];
|
|
57
55
|
return collectSkills(skillDefs);
|
|
58
56
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { INTRINSIC_MARKER } from "@intentius/chant/intrinsic";
|
|
3
3
|
import { HelmWebApp } from "./helm-web-app";
|
|
4
4
|
import { HelmStatefulService } from "./helm-stateful-service";
|
package/src/coverage.test.ts
CHANGED
package/src/helpers.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { stripTemplateExpressions, classifyExpression } from "./template-stripper";
|
|
3
3
|
import { HelmParser } from "./parser";
|
|
4
4
|
import { HelmGenerator } from "./generator";
|
package/src/intrinsics.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm101 } from "./whm101";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm101 } from "./whm101";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm102 } from "./whm102";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm103 } from "./whm103";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm104 } from "./whm104";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm105 } from "./whm105";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm201 } from "./whm201";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm202 } from "./whm202";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm203 } from "./whm203";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm204 } from "./whm204";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm301 } from "./whm301";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm302 } from "./whm302";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm401 } from "./whm401";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm402 } from "./whm402";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm403 } from "./whm403";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm404 } from "./whm404";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm405 } from "./whm405";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm406 } from "./whm406";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm407 } from "./whm407";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm501 } from "./whm501";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
3
3
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
4
4
|
import { whm502 } from "./whm502";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
|
|
3
|
+
const execMock = vi.fn();
|
|
4
|
+
vi.mock("node:child_process", async () => {
|
|
5
|
+
const actual = await vi.importActual<typeof import("node:child_process")>("node:child_process");
|
|
6
|
+
return { ...actual, exec: (cmd: string, cb: (err: Error | null, out: { stdout: string; stderr: string }) => void) => {
|
|
7
|
+
Promise.resolve(execMock(cmd)).then(
|
|
8
|
+
(out) => cb(null, out),
|
|
9
|
+
(err) => cb(err as Error, { stdout: "", stderr: "" }),
|
|
10
|
+
);
|
|
11
|
+
} };
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const { listArtifacts } = await import("./list-artifacts");
|
|
15
|
+
|
|
16
|
+
describe("helm listArtifacts", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
execMock.mockReset();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("queries `helm list -A -o json` and maps releases to artifacts", async () => {
|
|
22
|
+
let receivedCmd = "";
|
|
23
|
+
execMock.mockImplementation((cmd: string) => {
|
|
24
|
+
receivedCmd = cmd;
|
|
25
|
+
return {
|
|
26
|
+
stdout: JSON.stringify([
|
|
27
|
+
{
|
|
28
|
+
name: "web", namespace: "default", revision: "1",
|
|
29
|
+
updated: "2026-05-09 10:00:00.000000 +0000 UTC",
|
|
30
|
+
status: "deployed", chart: "web-1.0.0", app_version: "1.0",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "redis", namespace: "infra", revision: "3",
|
|
34
|
+
updated: "2026-05-09 09:00:00.000000 +0000 UTC",
|
|
35
|
+
status: "deployed", chart: "redis-7.4.0", app_version: "7.4",
|
|
36
|
+
},
|
|
37
|
+
]),
|
|
38
|
+
stderr: "",
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
43
|
+
|
|
44
|
+
expect(receivedCmd).toBe("helm list -A -o json");
|
|
45
|
+
expect(Object.keys(result).sort()).toEqual(["release/default/web", "release/infra/redis"]);
|
|
46
|
+
expect(result["release/default/web"]).toEqual({
|
|
47
|
+
type: "Helm::Release",
|
|
48
|
+
physicalId: "default/web",
|
|
49
|
+
status: "deployed",
|
|
50
|
+
lastUpdated: "2026-05-09 10:00:00.000000 +0000 UTC",
|
|
51
|
+
attributes: { chart: "web-1.0.0", revision: "1", appVersion: "1.0", namespace: "default" },
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("helm binary not installed → returns {} cleanly", async () => {
|
|
56
|
+
execMock.mockImplementation(() => { throw new Error("helm: command not found"); });
|
|
57
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
58
|
+
expect(result).toEqual({});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("empty cluster (no releases) → returns {}", async () => {
|
|
62
|
+
execMock.mockResolvedValue({ stdout: "[]", stderr: "" });
|
|
63
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
64
|
+
expect(result).toEqual({});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("status mapping for non-deployed states surfaces correctly", async () => {
|
|
68
|
+
execMock.mockResolvedValue({
|
|
69
|
+
stdout: JSON.stringify([
|
|
70
|
+
{ name: "broken", namespace: "default", revision: "2", status: "failed", chart: "x-1.0", app_version: "1" },
|
|
71
|
+
]),
|
|
72
|
+
stderr: "",
|
|
73
|
+
});
|
|
74
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
75
|
+
expect(result["release/default/broken"].status).toBe("failed");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("revision attribute changes between releases (drift signal)", async () => {
|
|
79
|
+
execMock.mockResolvedValue({
|
|
80
|
+
stdout: JSON.stringify([
|
|
81
|
+
{ name: "web", namespace: "default", revision: "5", status: "deployed", chart: "web-2.0.0", app_version: "2.0" },
|
|
82
|
+
]),
|
|
83
|
+
stderr: "",
|
|
84
|
+
});
|
|
85
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
86
|
+
expect(result["release/default/web"].attributes).toMatchObject({ revision: "5", chart: "web-2.0.0" });
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("malformed JSON output → returns {} (don't fail the snapshot)", async () => {
|
|
90
|
+
execMock.mockResolvedValue({ stdout: "not json", stderr: "" });
|
|
91
|
+
const result = await listArtifacts({ environment: "prod", entities: new Map() });
|
|
92
|
+
expect(result).toEqual({});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live introspection of Helm releases via `helm list -A -o json`.
|
|
3
|
+
*
|
|
4
|
+
* The Helm lexicon's chant entities describe chart-authoring primitives
|
|
5
|
+
* (Chart.yaml, templates/, values.yaml). The runtime concept — a Helm
|
|
6
|
+
* release installed in a kubeconfig context — is created by `helm install`
|
|
7
|
+
* outside chant's entity model. This implementation reports those releases
|
|
8
|
+
* as artifacts so `state diff --live` / `WatchOp` can detect manual
|
|
9
|
+
* installs/upgrades/rollbacks that slip past CI.
|
|
10
|
+
*
|
|
11
|
+
* Helm-not-installed (binary missing) → returns `{}` cleanly so other
|
|
12
|
+
* lexicons' snapshots aren't blocked.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { exec } from "node:child_process";
|
|
16
|
+
import { promisify } from "node:util";
|
|
17
|
+
import type { ArtifactMetadata } from "@intentius/chant/lexicon";
|
|
18
|
+
|
|
19
|
+
const execAsync = promisify(exec);
|
|
20
|
+
|
|
21
|
+
interface HelmListEntry {
|
|
22
|
+
name?: string;
|
|
23
|
+
namespace?: string;
|
|
24
|
+
revision?: string;
|
|
25
|
+
updated?: string;
|
|
26
|
+
status?: string;
|
|
27
|
+
chart?: string;
|
|
28
|
+
app_version?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function pruneUndefined<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {
|
|
32
|
+
const out: Record<string, unknown> = {};
|
|
33
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
34
|
+
if (v !== undefined) out[k] = v;
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function listArtifacts(_options: {
|
|
40
|
+
environment: string;
|
|
41
|
+
entities: Map<string, { entityType: string; props: Record<string, unknown> }>;
|
|
42
|
+
}): Promise<Record<string, ArtifactMetadata>> {
|
|
43
|
+
const result: Record<string, ArtifactMetadata> = {};
|
|
44
|
+
|
|
45
|
+
let stdout: string;
|
|
46
|
+
try {
|
|
47
|
+
({ stdout } = await execAsync("helm list -A -o json"));
|
|
48
|
+
} catch {
|
|
49
|
+
// Binary not installed, no kubeconfig, or some other error — return
|
|
50
|
+
// empty rather than blocking the whole snapshot.
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let entries: HelmListEntry[];
|
|
55
|
+
try {
|
|
56
|
+
entries = JSON.parse(stdout);
|
|
57
|
+
} catch {
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
if (!entry.name || !entry.namespace) continue;
|
|
63
|
+
const key = `release/${entry.namespace}/${entry.name}`;
|
|
64
|
+
result[key] = {
|
|
65
|
+
type: "Helm::Release",
|
|
66
|
+
physicalId: `${entry.namespace}/${entry.name}`,
|
|
67
|
+
status: entry.status ?? "unknown",
|
|
68
|
+
lastUpdated: entry.updated,
|
|
69
|
+
attributes: pruneUndefined({
|
|
70
|
+
chart: entry.chart,
|
|
71
|
+
revision: entry.revision,
|
|
72
|
+
appVersion: entry.app_version,
|
|
73
|
+
namespace: entry.namespace,
|
|
74
|
+
}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return result;
|
|
79
|
+
}
|
package/src/lsp/hover.test.ts
CHANGED
package/src/package-cli.ts
CHANGED
package/src/plugin.test.ts
CHANGED
package/src/plugin.ts
CHANGED
|
@@ -65,13 +65,13 @@ export const helmPlugin: LexiconPlugin = {
|
|
|
65
65
|
},
|
|
66
66
|
|
|
67
67
|
mcpTools() {
|
|
68
|
-
return [createDiffTool(helmSerializer, "Compare current Helm chart build output against previous output")];
|
|
68
|
+
return [createDiffTool(helmSerializer, "Compare current Helm chart build output against previous output", "helm")];
|
|
69
69
|
},
|
|
70
70
|
|
|
71
71
|
mcpResources() {
|
|
72
72
|
return [
|
|
73
73
|
{
|
|
74
|
-
uri: "resource-catalog",
|
|
74
|
+
uri: "helm:resource-catalog",
|
|
75
75
|
name: "Helm Chart Resource Catalog",
|
|
76
76
|
description: "JSON list of all supported Helm chart resource types",
|
|
77
77
|
mimeType: "application/json",
|
|
@@ -374,4 +374,9 @@ export const service = new Service({
|
|
|
374
374
|
|
|
375
375
|
console.error(`Packaged ${stats.resources} resources, ${stats.ruleCount} rules, ${stats.skillCount} skills`);
|
|
376
376
|
},
|
|
377
|
+
|
|
378
|
+
async listArtifacts(options) {
|
|
379
|
+
const { listArtifacts } = await import("./list-artifacts");
|
|
380
|
+
return listArtifacts(options);
|
|
381
|
+
},
|
|
377
382
|
};
|
package/src/serializer.test.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { createResource, createProperty } from "@intentius/chant/runtime";
|
|
3
3
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
4
4
|
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
5
5
|
import { helmSerializer } from "./serializer";
|
|
6
|
+
import { generateHelpers } from "./helpers";
|
|
6
7
|
import { Chart, Values, ValuesOverride, HelmNotes, HelmTest, HelmHook, HelmDependency, HelmMaintainer, HelmCRD } from "./resources";
|
|
7
8
|
import { values, include, printf, toYaml, quote, helmDefault, required, If, ElseIf, Range, With, Release, ChartRef, Capabilities, runtimeSlot } from "./intrinsics";
|
|
8
9
|
|
|
@@ -318,12 +319,12 @@ describe("resource-level If", () => {
|
|
|
318
319
|
const template = result.files!["templates/ingress.yaml"];
|
|
319
320
|
|
|
320
321
|
expect(template).toBeDefined();
|
|
321
|
-
expect(template
|
|
322
|
+
expect(template.startsWith("{{- if .Values.ingress.enabled }}\n")).toBe(true);
|
|
322
323
|
expect(template).toContain("apiVersion: networking.k8s.io/v1");
|
|
323
324
|
expect(template).toContain("kind: Ingress");
|
|
324
325
|
expect(template).toContain('{{ include "test.fullname" . }}');
|
|
325
326
|
expect(template).toContain("{{ .Values.ingress.host }}");
|
|
326
|
-
expect(template.trimEnd()
|
|
327
|
+
expect(template.trimEnd().endsWith("{{- end }}")).toBe(true);
|
|
327
328
|
});
|
|
328
329
|
|
|
329
330
|
test("does not wrap non-conditional resources", () => {
|
|
@@ -905,7 +906,6 @@ describe("ValuesOverride serialization", () => {
|
|
|
905
906
|
|
|
906
907
|
describe("helpers", () => {
|
|
907
908
|
test("generateHelpers includes all standard templates", () => {
|
|
908
|
-
const { generateHelpers } = require("./helpers");
|
|
909
909
|
const content = generateHelpers({ chartName: "my-chart" });
|
|
910
910
|
|
|
911
911
|
expect(content).toContain('define "my-chart.name"');
|
|
@@ -917,7 +917,6 @@ describe("helpers", () => {
|
|
|
917
917
|
});
|
|
918
918
|
|
|
919
919
|
test("generateHelpers respects includeServiceAccount=false", () => {
|
|
920
|
-
const { generateHelpers } = require("./helpers");
|
|
921
920
|
const content = generateHelpers({ chartName: "test", includeServiceAccount: false });
|
|
922
921
|
|
|
923
922
|
expect(content).toContain('define "test.name"');
|
package/src/validate-cli.ts
CHANGED
package/src/validate.test.ts
CHANGED