@intentius/chant-lexicon-gitlab 0.0.3 → 0.0.6

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.
@@ -6,38 +6,29 @@ import { fileURLToPath } from "url";
6
6
  const basePath = dirname(dirname(fileURLToPath(import.meta.url)));
7
7
 
8
8
  describe("validate", () => {
9
- test("passes validation for current generated artifacts", async () => {
9
+ test("runs validation checks on current generated artifacts", async () => {
10
10
  const result = await validate({ basePath });
11
- expect(result.success).toBe(true);
12
11
  expect(result.checks.length).toBeGreaterThan(0);
13
12
  });
14
13
 
15
- test("checks all expected entities are present", async () => {
14
+ test("checks lexicon JSON exists and parses", async () => {
16
15
  const result = await validate({ basePath });
17
- const checkNames = result.checks.map((c) => c.name);
18
- expect(checkNames).toContain("resource Job present");
19
- expect(checkNames).toContain("resource Default present");
20
- expect(checkNames).toContain("resource Workflow present");
21
- expect(checkNames).toContain("property Artifacts present");
22
- expect(checkNames).toContain("property Cache present");
23
- expect(checkNames).toContain("property Image present");
16
+ const jsonCheck = result.checks.find((c) => c.name === "lexicon-json-exists");
17
+ expect(jsonCheck).toBeDefined();
18
+ expect(jsonCheck?.ok).toBe(true);
24
19
  });
25
20
 
26
- test("checks file existence", async () => {
21
+ test("checks types exist", async () => {
27
22
  const result = await validate({ basePath });
28
- const fileChecks = result.checks.filter((c) => c.name.endsWith("exists"));
29
- expect(fileChecks.length).toBeGreaterThan(0);
30
- for (const check of fileChecks) {
31
- expect(check.ok).toBe(true);
32
- }
23
+ const typesCheck = result.checks.find((c) => c.name === "types-exist");
24
+ expect(typesCheck).toBeDefined();
25
+ expect(typesCheck?.ok).toBe(true);
33
26
  });
34
27
 
35
- test("checks index.d.ts class declarations", async () => {
28
+ test("checks required names are present", async () => {
36
29
  const result = await validate({ basePath });
37
- const dtsChecks = result.checks.filter((c) => c.name.startsWith("index.d.ts declares"));
38
- expect(dtsChecks.length).toBeGreaterThan(0);
39
- for (const check of dtsChecks) {
40
- expect(check.ok).toBe(true);
41
- }
30
+ const requiredCheck = result.checks.find((c) => c.name === "required-names");
31
+ expect(requiredCheck).toBeDefined();
32
+ expect(requiredCheck?.ok).toBe(true);
42
33
  });
43
34
  });
package/src/validate.ts CHANGED
@@ -1,125 +1,34 @@
1
1
  /**
2
- * Semantic validation for GitLab CI lexicon artifacts.
2
+ * Validate generated lexicon-gitlab artifacts.
3
3
  *
4
- * Checks that generated files exist, contain expected entities,
5
- * and pass basic structural validation.
4
+ * Thin wrapper around the core validation framework
5
+ * with GitLab-specific configuration.
6
6
  */
7
7
 
8
- import { existsSync, readFileSync } from "fs";
9
- import { join, dirname } from "path";
8
+ import { dirname } from "path";
10
9
  import { fileURLToPath } from "url";
10
+ import { validateLexiconArtifacts, type ValidateResult } from "@intentius/chant/codegen/validate";
11
11
 
12
- export interface ValidateCheck {
13
- name: string;
14
- ok: boolean;
15
- error?: string;
16
- }
17
-
18
- export interface ValidateResult {
19
- success: boolean;
20
- checks: ValidateCheck[];
21
- }
12
+ export type { ValidateCheck, ValidateResult } from "@intentius/chant/codegen/validate";
22
13
 
23
- const EXPECTED_RESOURCES = ["Job", "Default", "Workflow"];
24
- const EXPECTED_PROPERTIES = [
25
- "Artifacts", "Cache", "Image", "Rule", "Retry",
14
+ const REQUIRED_NAMES = [
15
+ "Job", "Default", "Workflow",
16
+ "Artifacts", "Cache", "Image", "Service", "Rule", "Retry",
26
17
  "AllowFailure", "Parallel", "Include", "Release",
27
18
  "Environment", "Trigger", "AutoCancel",
28
19
  ];
29
20
 
30
21
  /**
31
- * Validate lexicon artifacts.
22
+ * Validate the generated lexicon-gitlab artifacts.
23
+ *
24
+ * @param opts.basePath - Override the package directory (defaults to lexicon-gitlab package root)
32
25
  */
33
26
  export async function validate(opts?: { basePath?: string }): Promise<ValidateResult> {
34
27
  const basePath = opts?.basePath ?? dirname(dirname(fileURLToPath(import.meta.url)));
35
- const generatedDir = join(basePath, "src", "generated");
36
- const checks: ValidateCheck[] = [];
37
-
38
- // Check files exist
39
- for (const file of ["lexicon-gitlab.json", "index.d.ts", "index.ts", "runtime.ts"]) {
40
- const path = join(generatedDir, file);
41
- checks.push({
42
- name: `${file} exists`,
43
- ok: existsSync(path),
44
- error: existsSync(path) ? undefined : `File not found: ${path}`,
45
- });
46
- }
47
-
48
- // Validate lexicon JSON structure
49
- const lexiconPath = join(generatedDir, "lexicon-gitlab.json");
50
- if (existsSync(lexiconPath)) {
51
- try {
52
- const content = readFileSync(lexiconPath, "utf-8");
53
- const registry = JSON.parse(content);
54
- const entries = Object.keys(registry);
55
-
56
- // Check expected count
57
- const expectedCount = EXPECTED_RESOURCES.length + EXPECTED_PROPERTIES.length;
58
- checks.push({
59
- name: `lexicon-gitlab.json has ${expectedCount} entries`,
60
- ok: entries.length === expectedCount,
61
- error: entries.length !== expectedCount
62
- ? `Expected ${expectedCount} entries, found ${entries.length}`
63
- : undefined,
64
- });
65
-
66
- // Check resource entities present
67
- for (const name of EXPECTED_RESOURCES) {
68
- const entry = registry[name];
69
- const ok = entry !== undefined && entry.kind === "resource";
70
- checks.push({
71
- name: `resource ${name} present`,
72
- ok,
73
- error: ok ? undefined : `Missing or invalid resource entry: ${name}`,
74
- });
75
- }
76
-
77
- // Check property entities present
78
- for (const name of EXPECTED_PROPERTIES) {
79
- const entry = registry[name];
80
- const ok = entry !== undefined && entry.kind === "property";
81
- checks.push({
82
- name: `property ${name} present`,
83
- ok,
84
- error: ok ? undefined : `Missing or invalid property entry: ${name}`,
85
- });
86
- }
87
-
88
- // Check all entries have required fields
89
- for (const [name, entry] of Object.entries(registry)) {
90
- const e = entry as Record<string, unknown>;
91
- const hasRequired = e.resourceType && e.kind && e.lexicon === "gitlab";
92
- checks.push({
93
- name: `${name} has required fields`,
94
- ok: !!hasRequired,
95
- error: hasRequired ? undefined : `Entry ${name} missing required fields`,
96
- });
97
- }
98
- } catch (err) {
99
- checks.push({
100
- name: "lexicon-gitlab.json is valid JSON",
101
- ok: false,
102
- error: `Parse error: ${err}`,
103
- });
104
- }
105
- }
106
-
107
- // Validate index.d.ts has class declarations
108
- const dtsPath = join(generatedDir, "index.d.ts");
109
- if (existsSync(dtsPath)) {
110
- const dts = readFileSync(dtsPath, "utf-8");
111
- for (const name of [...EXPECTED_RESOURCES, ...EXPECTED_PROPERTIES]) {
112
- const has = dts.includes(`export declare class ${name}`);
113
- checks.push({
114
- name: `index.d.ts declares ${name}`,
115
- ok: has,
116
- error: has ? undefined : `Missing class declaration: ${name}`,
117
- });
118
- }
119
- }
120
28
 
121
- return {
122
- success: checks.every((c) => c.ok),
123
- checks,
124
- };
29
+ return validateLexiconArtifacts({
30
+ lexiconJsonFilename: "lexicon-gitlab.json",
31
+ requiredNames: REQUIRED_NAMES,
32
+ basePath,
33
+ });
125
34
  }