@intentius/chant-lexicon-gitlab 0.0.1

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 (56) hide show
  1. package/package.json +27 -0
  2. package/src/codegen/__snapshots__/snapshot.test.ts.snap +33 -0
  3. package/src/codegen/docs-cli.ts +3 -0
  4. package/src/codegen/docs.ts +962 -0
  5. package/src/codegen/fetch.ts +73 -0
  6. package/src/codegen/generate-cli.ts +41 -0
  7. package/src/codegen/generate-lexicon.ts +53 -0
  8. package/src/codegen/generate-typescript.ts +144 -0
  9. package/src/codegen/generate.ts +166 -0
  10. package/src/codegen/naming.ts +52 -0
  11. package/src/codegen/package.ts +64 -0
  12. package/src/codegen/parse.test.ts +195 -0
  13. package/src/codegen/parse.ts +531 -0
  14. package/src/codegen/patches.test.ts +99 -0
  15. package/src/codegen/patches.ts +100 -0
  16. package/src/codegen/rollback.ts +26 -0
  17. package/src/codegen/snapshot.test.ts +109 -0
  18. package/src/coverage.test.ts +39 -0
  19. package/src/coverage.ts +52 -0
  20. package/src/generated/index.d.ts +248 -0
  21. package/src/generated/index.ts +23 -0
  22. package/src/generated/lexicon-gitlab.json +77 -0
  23. package/src/generated/runtime.ts +4 -0
  24. package/src/import/generator.test.ts +151 -0
  25. package/src/import/generator.ts +173 -0
  26. package/src/import/parser.test.ts +160 -0
  27. package/src/import/parser.ts +282 -0
  28. package/src/import/roundtrip.test.ts +89 -0
  29. package/src/index.ts +25 -0
  30. package/src/intrinsics.test.ts +42 -0
  31. package/src/intrinsics.ts +40 -0
  32. package/src/lint/post-synth/post-synth.test.ts +155 -0
  33. package/src/lint/post-synth/wgl010.ts +41 -0
  34. package/src/lint/post-synth/wgl011.ts +54 -0
  35. package/src/lint/post-synth/yaml-helpers.ts +88 -0
  36. package/src/lint/rules/artifact-no-expiry.ts +62 -0
  37. package/src/lint/rules/deprecated-only-except.ts +53 -0
  38. package/src/lint/rules/index.ts +8 -0
  39. package/src/lint/rules/missing-script.ts +65 -0
  40. package/src/lint/rules/missing-stage.ts +62 -0
  41. package/src/lint/rules/rules.test.ts +146 -0
  42. package/src/lsp/completions.test.ts +85 -0
  43. package/src/lsp/completions.ts +18 -0
  44. package/src/lsp/hover.test.ts +60 -0
  45. package/src/lsp/hover.ts +36 -0
  46. package/src/plugin.test.ts +228 -0
  47. package/src/plugin.ts +380 -0
  48. package/src/serializer.test.ts +309 -0
  49. package/src/serializer.ts +226 -0
  50. package/src/testdata/ci-schema-fixture.json +2184 -0
  51. package/src/testdata/create-fixture.ts +46 -0
  52. package/src/testdata/load-fixtures.ts +23 -0
  53. package/src/validate-cli.ts +19 -0
  54. package/src/validate.test.ts +43 -0
  55. package/src/validate.ts +125 -0
  56. package/src/variables.ts +27 -0
@@ -0,0 +1,195 @@
1
+ import { describe, test, expect } from "bun:test";
2
+ import { parseCISchema, gitlabShortName, gitlabServiceName } from "./parse";
3
+ import { loadSchemaFixture } from "../testdata/load-fixtures";
4
+
5
+ const fixture = loadSchemaFixture();
6
+
7
+ describe("parseCISchema", () => {
8
+ test("returns 15 entities", () => {
9
+ const results = parseCISchema(fixture);
10
+ expect(results).toHaveLength(15);
11
+ });
12
+
13
+ test("returns 3 resource entities", () => {
14
+ const results = parseCISchema(fixture);
15
+ const resources = results.filter((r) => !r.isProperty);
16
+ expect(resources).toHaveLength(3);
17
+ const names = resources.map((r) => r.resource.typeName);
18
+ expect(names).toContain("GitLab::CI::Job");
19
+ expect(names).toContain("GitLab::CI::Default");
20
+ expect(names).toContain("GitLab::CI::Workflow");
21
+ });
22
+
23
+ test("returns 12 property entities", () => {
24
+ const results = parseCISchema(fixture);
25
+ const properties = results.filter((r) => r.isProperty);
26
+ expect(properties).toHaveLength(12);
27
+ const names = properties.map((r) => r.resource.typeName);
28
+ expect(names).toContain("GitLab::CI::Artifacts");
29
+ expect(names).toContain("GitLab::CI::Cache");
30
+ expect(names).toContain("GitLab::CI::Image");
31
+ expect(names).toContain("GitLab::CI::Rule");
32
+ expect(names).toContain("GitLab::CI::Retry");
33
+ expect(names).toContain("GitLab::CI::AllowFailure");
34
+ expect(names).toContain("GitLab::CI::Parallel");
35
+ expect(names).toContain("GitLab::CI::Include");
36
+ expect(names).toContain("GitLab::CI::Release");
37
+ expect(names).toContain("GitLab::CI::Environment");
38
+ expect(names).toContain("GitLab::CI::Trigger");
39
+ expect(names).toContain("GitLab::CI::AutoCancel");
40
+ });
41
+
42
+ test("property entities have isProperty set to true", () => {
43
+ const results = parseCISchema(fixture);
44
+ const properties = results.filter((r) => r.isProperty);
45
+ for (const p of properties) {
46
+ expect(p.isProperty).toBe(true);
47
+ }
48
+ });
49
+
50
+ test("resource entities do not have isProperty set", () => {
51
+ const results = parseCISchema(fixture);
52
+ const resources = results.filter((r) => !r.isProperty);
53
+ for (const r of resources) {
54
+ expect(r.isProperty).toBeUndefined();
55
+ }
56
+ });
57
+ });
58
+
59
+ describe("Job entity", () => {
60
+ test("has expected properties", () => {
61
+ const results = parseCISchema(fixture);
62
+ const job = results.find((r) => r.resource.typeName === "GitLab::CI::Job");
63
+ expect(job).toBeDefined();
64
+ const propNames = job!.resource.properties.map((p) => p.name);
65
+ expect(propNames).toContain("script");
66
+ expect(propNames).toContain("stage");
67
+ expect(propNames).toContain("image");
68
+ expect(propNames).toContain("artifacts");
69
+ expect(propNames).toContain("cache");
70
+ expect(propNames).toContain("before_script");
71
+ expect(propNames).toContain("after_script");
72
+ expect(propNames).toContain("rules");
73
+ expect(propNames).toContain("when");
74
+ expect(propNames).toContain("environment");
75
+ expect(propNames).toContain("variables");
76
+ });
77
+
78
+ test("has no attributes (CI entities have no read-only attrs)", () => {
79
+ const results = parseCISchema(fixture);
80
+ const job = results.find((r) => r.resource.typeName === "GitLab::CI::Job");
81
+ expect(job!.resource.attributes).toEqual([]);
82
+ });
83
+
84
+ test("has a description", () => {
85
+ const results = parseCISchema(fixture);
86
+ const job = results.find((r) => r.resource.typeName === "GitLab::CI::Job");
87
+ expect(job!.resource.description).toBeDefined();
88
+ expect(typeof job!.resource.description).toBe("string");
89
+ });
90
+ });
91
+
92
+ describe("Image entity", () => {
93
+ test("has name property marked as required", () => {
94
+ const results = parseCISchema(fixture);
95
+ const image = results.find((r) => r.resource.typeName === "GitLab::CI::Image");
96
+ expect(image).toBeDefined();
97
+ const nameProp = image!.resource.properties.find((p) => p.name === "name");
98
+ expect(nameProp).toBeDefined();
99
+ expect(nameProp!.required).toBe(true);
100
+ expect(nameProp!.tsType).toBe("string");
101
+ });
102
+ });
103
+
104
+ describe("Artifacts entity", () => {
105
+ test("has paths and expire_in properties", () => {
106
+ const results = parseCISchema(fixture);
107
+ const artifacts = results.find((r) => r.resource.typeName === "GitLab::CI::Artifacts");
108
+ expect(artifacts).toBeDefined();
109
+ const propNames = artifacts!.resource.properties.map((p) => p.name);
110
+ expect(propNames).toContain("paths");
111
+ expect(propNames).toContain("expire_in");
112
+ });
113
+ });
114
+
115
+ describe("Cache entity", () => {
116
+ test("has key, paths, and policy properties", () => {
117
+ const results = parseCISchema(fixture);
118
+ const cache = results.find((r) => r.resource.typeName === "GitLab::CI::Cache");
119
+ expect(cache).toBeDefined();
120
+ const propNames = cache!.resource.properties.map((p) => p.name);
121
+ expect(propNames).toContain("key");
122
+ expect(propNames).toContain("paths");
123
+ expect(propNames).toContain("policy");
124
+ });
125
+ });
126
+
127
+ describe("property types and enums", () => {
128
+ test("entities have empty propertyTypes (nested types extracted as top-level)", () => {
129
+ const results = parseCISchema(fixture);
130
+ for (const r of results) {
131
+ expect(r.propertyTypes).toEqual([]);
132
+ }
133
+ });
134
+
135
+ test("entities have empty enums (enums extracted separately)", () => {
136
+ const results = parseCISchema(fixture);
137
+ for (const r of results) {
138
+ expect(r.enums).toEqual([]);
139
+ }
140
+ });
141
+ });
142
+
143
+ describe("edge cases", () => {
144
+ test("empty schema returns empty results", () => {
145
+ const emptySchema = JSON.stringify({ definitions: {} });
146
+ const results = parseCISchema(emptySchema);
147
+ expect(results).toHaveLength(0);
148
+ });
149
+
150
+ test("schema with missing definitions returns partial results", () => {
151
+ const partial = JSON.stringify({
152
+ definitions: {
153
+ job_template: {
154
+ properties: {
155
+ script: { type: "string" },
156
+ },
157
+ },
158
+ },
159
+ });
160
+ const results = parseCISchema(partial);
161
+ // Should get at least the Job entity
162
+ expect(results.length).toBeGreaterThan(0);
163
+ const job = results.find((r) => r.resource.typeName === "GitLab::CI::Job");
164
+ expect(job).toBeDefined();
165
+ });
166
+
167
+ test("accepts Buffer input", () => {
168
+ const results = parseCISchema(fixture);
169
+ expect(results.length).toBeGreaterThan(0);
170
+ });
171
+
172
+ test("accepts string input", () => {
173
+ const results = parseCISchema(fixture.toString("utf-8"));
174
+ expect(results.length).toBeGreaterThan(0);
175
+ });
176
+ });
177
+
178
+ describe("gitlabShortName", () => {
179
+ test("extracts short name from type", () => {
180
+ expect(gitlabShortName("GitLab::CI::Job")).toBe("Job");
181
+ expect(gitlabShortName("GitLab::CI::Artifacts")).toBe("Artifacts");
182
+ expect(gitlabShortName("GitLab::CI::AutoCancel")).toBe("AutoCancel");
183
+ });
184
+ });
185
+
186
+ describe("gitlabServiceName", () => {
187
+ test("extracts service name from type", () => {
188
+ expect(gitlabServiceName("GitLab::CI::Job")).toBe("CI");
189
+ expect(gitlabServiceName("GitLab::CI::Cache")).toBe("CI");
190
+ });
191
+
192
+ test("returns CI for short names", () => {
193
+ expect(gitlabServiceName("Job")).toBe("CI");
194
+ });
195
+ });