@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.
- package/README.md +9 -46
- package/dist/integrity.json +5 -5
- package/dist/manifest.json +1 -1
- package/dist/meta.json +5 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +2 -2
- package/src/codegen/docs.ts +30 -438
- package/src/codegen/generate-lexicon.ts +1 -1
- package/src/codegen/parse.test.ts +5 -4
- package/src/codegen/parse.ts +8 -10
- package/src/codegen/snapshot.test.ts +3 -3
- package/src/generated/index.d.ts +13 -0
- package/src/generated/index.ts +1 -0
- package/src/generated/lexicon-gitlab.json +5 -0
- package/src/plugin.test.ts +1 -2
- package/src/plugin.ts +13 -40
- package/src/testdata/ci-schema-fixture.json +105 -229
- package/src/validate.test.ts +13 -22
- package/src/validate.ts +17 -108
package/src/validate.test.ts
CHANGED
|
@@ -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("
|
|
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
|
|
14
|
+
test("checks lexicon JSON exists and parses", async () => {
|
|
16
15
|
const result = await validate({ basePath });
|
|
17
|
-
const
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
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
|
|
21
|
+
test("checks types exist", async () => {
|
|
27
22
|
const result = await validate({ basePath });
|
|
28
|
-
const
|
|
29
|
-
expect(
|
|
30
|
-
|
|
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
|
|
28
|
+
test("checks required names are present", async () => {
|
|
36
29
|
const result = await validate({ basePath });
|
|
37
|
-
const
|
|
38
|
-
expect(
|
|
39
|
-
|
|
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
|
-
*
|
|
2
|
+
* Validate generated lexicon-gitlab artifacts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Thin wrapper around the core validation framework
|
|
5
|
+
* with GitLab-specific configuration.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
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
|
|
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
|
|
24
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
29
|
+
return validateLexiconArtifacts({
|
|
30
|
+
lexiconJsonFilename: "lexicon-gitlab.json",
|
|
31
|
+
requiredNames: REQUIRED_NAMES,
|
|
32
|
+
basePath,
|
|
33
|
+
});
|
|
125
34
|
}
|