@gqlkit-ts/cli 0.1.0 → 0.2.0

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 (234) hide show
  1. package/dist/auto-type-generator/auto-type-generator.d.ts +19 -3
  2. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
  3. package/dist/auto-type-generator/auto-type-generator.js +236 -49
  4. package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
  5. package/dist/auto-type-generator/index.d.ts +1 -1
  6. package/dist/auto-type-generator/index.d.ts.map +1 -1
  7. package/dist/auto-type-generator/index.js.map +1 -1
  8. package/dist/auto-type-generator/inline-enum-collector.d.ts +31 -0
  9. package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -0
  10. package/dist/auto-type-generator/inline-enum-collector.js +157 -0
  11. package/dist/auto-type-generator/inline-enum-collector.js.map +1 -0
  12. package/dist/auto-type-generator/naming-convention.d.ts +4 -0
  13. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
  14. package/dist/auto-type-generator/naming-convention.js +8 -0
  15. package/dist/auto-type-generator/naming-convention.js.map +1 -1
  16. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
  17. package/dist/gen-orchestrator/orchestrator.js +106 -8
  18. package/dist/gen-orchestrator/orchestrator.js.map +1 -1
  19. package/dist/resolver-extractor/extract-resolvers.d.ts +10 -1
  20. package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -1
  21. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +11 -1
  22. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
  23. package/dist/resolver-extractor/extractor/define-api-extractor.js +88 -264
  24. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
  25. package/dist/schema-generator/emitter/code-emitter.d.ts +10 -2
  26. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
  27. package/dist/schema-generator/emitter/code-emitter.js +19 -4
  28. package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
  29. package/dist/schema-generator/generate-schema.d.ts.map +1 -1
  30. package/dist/schema-generator/generate-schema.js +18 -1
  31. package/dist/schema-generator/generate-schema.js.map +1 -1
  32. package/dist/schema-generator/integrator/result-integrator.d.ts +20 -0
  33. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
  34. package/dist/schema-generator/integrator/result-integrator.js +42 -0
  35. package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
  36. package/dist/shared/constants.d.ts +0 -16
  37. package/dist/shared/constants.d.ts.map +1 -1
  38. package/dist/shared/constants.js +0 -19
  39. package/dist/shared/constants.js.map +1 -1
  40. package/dist/shared/directive-detector.d.ts.map +1 -1
  41. package/dist/shared/directive-detector.js +8 -15
  42. package/dist/shared/directive-detector.js.map +1 -1
  43. package/dist/shared/file-scanner.d.ts.map +1 -1
  44. package/dist/shared/file-scanner.js +5 -3
  45. package/dist/shared/file-scanner.js.map +1 -1
  46. package/dist/shared/index.d.ts +1 -1
  47. package/dist/shared/index.d.ts.map +1 -1
  48. package/dist/shared/index.js +1 -3
  49. package/dist/shared/index.js.map +1 -1
  50. package/dist/shared/interface-detector.d.ts +3 -2
  51. package/dist/shared/interface-detector.d.ts.map +1 -1
  52. package/dist/shared/interface-detector.js +54 -11
  53. package/dist/shared/interface-detector.js.map +1 -1
  54. package/dist/shared/path-utils.d.ts +2 -0
  55. package/dist/shared/path-utils.d.ts.map +1 -0
  56. package/dist/shared/path-utils.js +4 -0
  57. package/dist/shared/path-utils.js.map +1 -0
  58. package/dist/shared/type-converter.d.ts.map +1 -1
  59. package/dist/shared/type-converter.js +11 -0
  60. package/dist/shared/type-converter.js.map +1 -1
  61. package/dist/shared/typescript-utils.d.ts +34 -7
  62. package/dist/shared/typescript-utils.d.ts.map +1 -1
  63. package/dist/shared/typescript-utils.js +72 -24
  64. package/dist/shared/typescript-utils.js.map +1 -1
  65. package/dist/type-extractor/collector/scalar-collector.d.ts.map +1 -1
  66. package/dist/type-extractor/collector/scalar-collector.js +4 -14
  67. package/dist/type-extractor/collector/scalar-collector.js.map +1 -1
  68. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
  69. package/dist/type-extractor/converter/graphql-converter.js +42 -3
  70. package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
  71. package/dist/type-extractor/extractor/field-type-resolver.d.ts +28 -0
  72. package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -0
  73. package/dist/type-extractor/extractor/field-type-resolver.js +394 -0
  74. package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -0
  75. package/dist/type-extractor/extractor/type-extractor.d.ts +12 -3
  76. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
  77. package/dist/type-extractor/extractor/type-extractor.js +176 -210
  78. package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
  79. package/dist/type-extractor/extractor/type-name-collector.d.ts +24 -0
  80. package/dist/type-extractor/extractor/type-name-collector.d.ts.map +1 -0
  81. package/dist/type-extractor/extractor/type-name-collector.js +102 -0
  82. package/dist/type-extractor/extractor/type-name-collector.js.map +1 -0
  83. package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts +89 -0
  84. package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts.map +1 -0
  85. package/dist/type-extractor/mapper/scalar-base-type-mapper.js +158 -0
  86. package/dist/type-extractor/mapper/scalar-base-type-mapper.js.map +1 -0
  87. package/dist/type-extractor/types/diagnostics.d.ts +1 -1
  88. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
  89. package/dist/type-extractor/types/graphql.d.ts +2 -0
  90. package/dist/type-extractor/types/graphql.d.ts.map +1 -1
  91. package/dist/type-extractor/types/index.d.ts +2 -1
  92. package/dist/type-extractor/types/index.d.ts.map +1 -1
  93. package/dist/type-extractor/types/index.js +1 -1
  94. package/dist/type-extractor/types/index.js.map +1 -1
  95. package/dist/type-extractor/types/ts-type-reference-factory.d.ts +39 -0
  96. package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -0
  97. package/dist/type-extractor/types/ts-type-reference-factory.js +69 -0
  98. package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -0
  99. package/dist/type-extractor/types/typescript.d.ts +21 -1
  100. package/dist/type-extractor/types/typescript.d.ts.map +1 -1
  101. package/dist/type-extractor/validator/type-validator.js +1 -1
  102. package/dist/type-extractor/validator/type-validator.js.map +1 -1
  103. package/docs/index.md +1 -0
  104. package/docs/integration/drizzle.md +191 -0
  105. package/docs/schema/enums.md +208 -0
  106. package/docs/schema/fields.md +2 -0
  107. package/docs/schema/inputs.md +2 -0
  108. package/docs/schema/objects.md +2 -0
  109. package/docs/schema/queries-mutations.md +2 -0
  110. package/package.json +10 -3
  111. package/src/auto-type-generator/auto-type-generator.ts +925 -0
  112. package/src/auto-type-generator/index.ts +21 -0
  113. package/src/auto-type-generator/inline-enum-collector.ts +290 -0
  114. package/src/auto-type-generator/name-collision-validator.ts +119 -0
  115. package/src/auto-type-generator/naming-convention.ts +126 -0
  116. package/src/cli.ts +11 -0
  117. package/src/commands/gen.ts +141 -0
  118. package/src/commands/main.ts +5 -0
  119. package/src/config/define-config.ts +28 -0
  120. package/src/config/index.ts +7 -0
  121. package/src/config/types.ts +144 -0
  122. package/src/config-loader/index.ts +14 -0
  123. package/src/config-loader/loader.ts +143 -0
  124. package/src/config-loader/validator.ts +672 -0
  125. package/src/gen-orchestrator/hook-executor/hook-executor.ts +117 -0
  126. package/src/gen-orchestrator/orchestrator.ts +784 -0
  127. package/src/gen-orchestrator/reporter/diagnostic-reporter.ts +44 -0
  128. package/src/gen-orchestrator/reporter/progress-reporter.ts +61 -0
  129. package/src/gen-orchestrator/writer/file-writer.ts +38 -0
  130. package/src/index.ts +2 -0
  131. package/src/resolver-extractor/extract-resolvers.ts +63 -0
  132. package/src/resolver-extractor/extractor/define-api-extractor.ts +806 -0
  133. package/src/resolver-extractor/index.ts +19 -0
  134. package/src/resolver-extractor/validator/abstract-resolver-validator.ts +251 -0
  135. package/src/resolver-extractor/validator/only-validator.ts +158 -0
  136. package/src/schema-generator/builder/ast-builder.ts +706 -0
  137. package/src/schema-generator/emitter/code-emitter.ts +351 -0
  138. package/src/schema-generator/emitter/sdl-emitter.ts +13 -0
  139. package/src/schema-generator/generate-schema.ts +170 -0
  140. package/src/schema-generator/index.ts +19 -0
  141. package/src/schema-generator/integrator/result-integrator.ts +690 -0
  142. package/src/schema-generator/pruner/schema-pruner.ts +112 -0
  143. package/src/schema-generator/resolver-collector/resolver-collector.ts +123 -0
  144. package/src/shared/constants.ts +122 -0
  145. package/src/shared/default-value-detector.ts +172 -0
  146. package/src/shared/diagnostics.ts +35 -0
  147. package/src/shared/directive-definition-extractor.ts +564 -0
  148. package/src/shared/directive-detector.ts +556 -0
  149. package/src/shared/file-scanner.ts +170 -0
  150. package/src/shared/index.ts +32 -0
  151. package/src/shared/inline-object-extractor.ts +102 -0
  152. package/src/shared/inline-object-utils.ts +23 -0
  153. package/src/shared/interface-detector.ts +176 -0
  154. package/src/shared/interface-validator.ts +211 -0
  155. package/src/shared/metadata-detector.ts +443 -0
  156. package/src/shared/path-utils.ts +3 -0
  157. package/src/shared/program-factory.ts +51 -0
  158. package/src/shared/source-location.ts +27 -0
  159. package/src/shared/tsconfig-loader.ts +126 -0
  160. package/src/shared/tsdoc-parser.ts +155 -0
  161. package/src/shared/type-converter.ts +99 -0
  162. package/src/shared/typescript-utils.ts +246 -0
  163. package/src/type-extractor/collector/result-collector.ts +57 -0
  164. package/src/type-extractor/collector/scalar-collector.ts +254 -0
  165. package/src/type-extractor/converter/field-eligibility.ts +112 -0
  166. package/src/type-extractor/converter/graphql-converter.ts +459 -0
  167. package/src/type-extractor/extract-types.ts +1 -0
  168. package/src/type-extractor/extractor/field-type-resolver.ts +569 -0
  169. package/src/type-extractor/extractor/type-extractor.ts +1567 -0
  170. package/src/type-extractor/extractor/type-name-collector.ts +130 -0
  171. package/src/type-extractor/index.ts +20 -0
  172. package/src/type-extractor/mapper/scalar-base-type-mapper.ts +265 -0
  173. package/src/type-extractor/types/diagnostics.ts +99 -0
  174. package/src/type-extractor/types/graphql.ts +55 -0
  175. package/src/type-extractor/types/index.ts +37 -0
  176. package/src/type-extractor/types/ts-type-reference-factory.ts +137 -0
  177. package/src/type-extractor/types/typescript.ts +133 -0
  178. package/src/type-extractor/validator/type-validator.ts +77 -0
  179. package/dist/auto-type-generator/auto-type-generator.test.d.ts +0 -2
  180. package/dist/auto-type-generator/auto-type-generator.test.d.ts.map +0 -1
  181. package/dist/auto-type-generator/auto-type-generator.test.js +0 -613
  182. package/dist/auto-type-generator/auto-type-generator.test.js.map +0 -1
  183. package/dist/auto-type-generator/name-collision-validator.test.d.ts +0 -2
  184. package/dist/auto-type-generator/name-collision-validator.test.d.ts.map +0 -1
  185. package/dist/auto-type-generator/name-collision-validator.test.js +0 -358
  186. package/dist/auto-type-generator/name-collision-validator.test.js.map +0 -1
  187. package/dist/auto-type-generator/naming-convention.test.d.ts +0 -2
  188. package/dist/auto-type-generator/naming-convention.test.d.ts.map +0 -1
  189. package/dist/auto-type-generator/naming-convention.test.js +0 -132
  190. package/dist/auto-type-generator/naming-convention.test.js.map +0 -1
  191. package/dist/commands/gen.test.d.ts +0 -2
  192. package/dist/commands/gen.test.d.ts.map +0 -1
  193. package/dist/commands/gen.test.js +0 -226
  194. package/dist/commands/gen.test.js.map +0 -1
  195. package/dist/config-loader/loader.test.d.ts +0 -2
  196. package/dist/config-loader/loader.test.d.ts.map +0 -1
  197. package/dist/config-loader/loader.test.js +0 -123
  198. package/dist/config-loader/loader.test.js.map +0 -1
  199. package/dist/config-loader/validator.test.d.ts +0 -2
  200. package/dist/config-loader/validator.test.d.ts.map +0 -1
  201. package/dist/config-loader/validator.test.js +0 -846
  202. package/dist/config-loader/validator.test.js.map +0 -1
  203. package/dist/gen-orchestrator/golden.test.d.ts +0 -2
  204. package/dist/gen-orchestrator/golden.test.d.ts.map +0 -1
  205. package/dist/gen-orchestrator/golden.test.js +0 -102
  206. package/dist/gen-orchestrator/golden.test.js.map +0 -1
  207. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts +0 -2
  208. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts.map +0 -1
  209. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js +0 -167
  210. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js.map +0 -1
  211. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts +0 -2
  212. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts.map +0 -1
  213. package/dist/gen-orchestrator/reporter/progress-reporter.test.js +0 -74
  214. package/dist/gen-orchestrator/reporter/progress-reporter.test.js.map +0 -1
  215. package/dist/resolver-extractor/validator/only-validator.test.d.ts +0 -8
  216. package/dist/resolver-extractor/validator/only-validator.test.d.ts.map +0 -1
  217. package/dist/resolver-extractor/validator/only-validator.test.js +0 -352
  218. package/dist/resolver-extractor/validator/only-validator.test.js.map +0 -1
  219. package/dist/schema-generator/builder/ast-builder.test.d.ts +0 -2
  220. package/dist/schema-generator/builder/ast-builder.test.d.ts.map +0 -1
  221. package/dist/schema-generator/builder/ast-builder.test.js +0 -469
  222. package/dist/schema-generator/builder/ast-builder.test.js.map +0 -1
  223. package/dist/shared/file-scanner.test.d.ts +0 -2
  224. package/dist/shared/file-scanner.test.d.ts.map +0 -1
  225. package/dist/shared/file-scanner.test.js +0 -138
  226. package/dist/shared/file-scanner.test.js.map +0 -1
  227. package/dist/shared/interface-validator.test.d.ts +0 -2
  228. package/dist/shared/interface-validator.test.d.ts.map +0 -1
  229. package/dist/shared/interface-validator.test.js +0 -145
  230. package/dist/shared/interface-validator.test.js.map +0 -1
  231. package/dist/type-extractor/types/typescript.test.d.ts +0 -2
  232. package/dist/type-extractor/types/typescript.test.d.ts.map +0 -1
  233. package/dist/type-extractor/types/typescript.test.js +0 -287
  234. package/dist/type-extractor/types/typescript.test.js.map +0 -1
@@ -1,846 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { validateConfig } from "./validator.js";
3
- describe("ConfigValidator", () => {
4
- const configPath = "/project/gqlkit.config.ts";
5
- describe("validateConfig", () => {
6
- it("should return valid for empty config", () => {
7
- const result = validateConfig({
8
- config: {},
9
- configPath,
10
- });
11
- expect(result.valid).toBe(true);
12
- expect(result.resolvedConfig).toBeTruthy();
13
- expect(result.resolvedConfig.scalars).toEqual([]);
14
- expect(result.diagnostics.length).toBe(0);
15
- });
16
- it("should return valid for config with scalars", () => {
17
- const result = validateConfig({
18
- config: {
19
- scalars: [
20
- {
21
- graphqlName: "DateTime",
22
- type: { from: "./src/scalars", name: "DateTime" },
23
- },
24
- ],
25
- },
26
- configPath,
27
- });
28
- expect(result.valid).toBe(true);
29
- expect(result.resolvedConfig).toBeTruthy();
30
- expect(result.resolvedConfig.scalars.length).toBe(1);
31
- });
32
- it("should return error for non-object config", () => {
33
- const result = validateConfig({
34
- config: "not an object",
35
- configPath,
36
- });
37
- expect(result.valid).toBe(false);
38
- expect(result.diagnostics.length).toBe(1);
39
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
40
- });
41
- it("should return error for null config", () => {
42
- const result = validateConfig({
43
- config: null,
44
- configPath,
45
- });
46
- expect(result.valid).toBe(false);
47
- expect(result.diagnostics.length).toBe(1);
48
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
49
- });
50
- it("should return error when scalars is not an array", () => {
51
- const result = validateConfig({
52
- config: {
53
- scalars: "not an array",
54
- },
55
- configPath,
56
- });
57
- expect(result.valid).toBe(false);
58
- expect(result.diagnostics.length).toBe(1);
59
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
60
- expect(result.diagnostics[0]?.message).toContain("scalars");
61
- });
62
- it("should return error when scalar mapping is missing graphqlName", () => {
63
- const result = validateConfig({
64
- config: {
65
- scalars: [
66
- {
67
- type: { from: "./src/scalars", name: "DateTime" },
68
- },
69
- ],
70
- },
71
- configPath,
72
- });
73
- expect(result.valid).toBe(false);
74
- expect(result.diagnostics.length).toBe(1);
75
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
76
- expect(result.diagnostics[0]?.message).toContain("graphqlName");
77
- });
78
- it("should return error when scalar mapping is missing type", () => {
79
- const result = validateConfig({
80
- config: {
81
- scalars: [
82
- {
83
- graphqlName: "DateTime",
84
- },
85
- ],
86
- },
87
- configPath,
88
- });
89
- expect(result.valid).toBe(false);
90
- expect(result.diagnostics.length).toBe(1);
91
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
92
- expect(result.diagnostics[0]?.message).toContain("type");
93
- });
94
- it("should return error when type.from is missing", () => {
95
- const result = validateConfig({
96
- config: {
97
- scalars: [
98
- {
99
- graphqlName: "DateTime",
100
- type: { name: "DateTime" },
101
- },
102
- ],
103
- },
104
- configPath,
105
- });
106
- expect(result.valid).toBe(false);
107
- expect(result.diagnostics.length).toBe(1);
108
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
109
- expect(result.diagnostics[0]?.message).toContain("type.from");
110
- });
111
- it("should return error when type.name is missing", () => {
112
- const result = validateConfig({
113
- config: {
114
- scalars: [
115
- {
116
- graphqlName: "DateTime",
117
- type: { from: "./src/scalars" },
118
- },
119
- ],
120
- },
121
- configPath,
122
- });
123
- expect(result.valid).toBe(false);
124
- expect(result.diagnostics.length).toBe(1);
125
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
126
- expect(result.diagnostics[0]?.message).toContain("type.name");
127
- });
128
- describe("built-in scalar override", () => {
129
- for (const builtinName of ["ID", "String", "Int", "Float", "Boolean"]) {
130
- it(`should return error when overriding built-in scalar ${builtinName}`, () => {
131
- const result = validateConfig({
132
- config: {
133
- scalars: [
134
- {
135
- graphqlName: builtinName,
136
- type: { from: "./src/scalars", name: "Custom" },
137
- },
138
- ],
139
- },
140
- configPath,
141
- });
142
- expect(result.valid).toBe(false);
143
- expect(result.diagnostics.length).toBe(1);
144
- expect(result.diagnostics[0]?.code).toBe("CONFIG_BUILTIN_OVERRIDE");
145
- expect(result.diagnostics[0]?.message).toContain(builtinName);
146
- });
147
- }
148
- });
149
- describe("duplicate detection", () => {
150
- it("should return error for duplicate graphqlName", () => {
151
- const result = validateConfig({
152
- config: {
153
- scalars: [
154
- {
155
- graphqlName: "DateTime",
156
- type: { from: "./src/scalars", name: "DateTime" },
157
- },
158
- {
159
- graphqlName: "DateTime",
160
- type: { from: "./src/other", name: "OtherDateTime" },
161
- },
162
- ],
163
- },
164
- configPath,
165
- });
166
- expect(result.valid).toBe(false);
167
- expect(result.diagnostics.length).toBe(1);
168
- expect(result.diagnostics[0]?.code).toBe("CONFIG_DUPLICATE_MAPPING");
169
- expect(result.diagnostics[0]?.message).toContain("DateTime");
170
- });
171
- it("should return error for duplicate type mapping", () => {
172
- const result = validateConfig({
173
- config: {
174
- scalars: [
175
- {
176
- graphqlName: "DateTime",
177
- type: { from: "./src/scalars", name: "DateTime" },
178
- },
179
- {
180
- graphqlName: "Timestamp",
181
- type: { from: "./src/scalars", name: "DateTime" },
182
- },
183
- ],
184
- },
185
- configPath,
186
- });
187
- expect(result.valid).toBe(false);
188
- expect(result.diagnostics.length).toBe(1);
189
- expect(result.diagnostics[0]?.code).toBe("CONFIG_DUPLICATE_TYPE");
190
- expect(result.diagnostics[0]?.message).toContain("DateTime");
191
- });
192
- it("should allow same type name from different paths", () => {
193
- const result = validateConfig({
194
- config: {
195
- scalars: [
196
- {
197
- graphqlName: "DateTime",
198
- type: { from: "./src/scalars", name: "DateTime" },
199
- },
200
- {
201
- graphqlName: "CustomDateTime",
202
- type: { from: "./src/custom", name: "DateTime" },
203
- },
204
- ],
205
- },
206
- configPath,
207
- });
208
- expect(result.valid).toBe(true);
209
- expect(result.diagnostics.length).toBe(0);
210
- });
211
- });
212
- describe("new scalar config format (name, tsType)", () => {
213
- it("should accept new format with name and tsType.name", () => {
214
- const result = validateConfig({
215
- config: {
216
- scalars: [
217
- {
218
- name: "DateTime",
219
- tsType: { name: "Date" },
220
- },
221
- ],
222
- },
223
- configPath,
224
- });
225
- expect(result.valid).toBe(true);
226
- expect(result.resolvedConfig).toBeTruthy();
227
- expect(result.resolvedConfig.scalars.length).toBe(1);
228
- expect(result.resolvedConfig.scalars[0]?.graphqlName).toBe("DateTime");
229
- expect(result.resolvedConfig.scalars[0]?.typeName).toBe("Date");
230
- expect(result.resolvedConfig.scalars[0]?.importPath).toBe(null);
231
- });
232
- it("should accept new format with tsType.from for module specification", () => {
233
- const result = validateConfig({
234
- config: {
235
- scalars: [
236
- {
237
- name: "DateTime",
238
- tsType: { name: "DateTimeString", from: "./src/types" },
239
- },
240
- ],
241
- },
242
- configPath,
243
- });
244
- expect(result.valid).toBe(true);
245
- expect(result.resolvedConfig).toBeTruthy();
246
- expect(result.resolvedConfig.scalars.length).toBe(1);
247
- expect(result.resolvedConfig.scalars[0]?.graphqlName).toBe("DateTime");
248
- expect(result.resolvedConfig.scalars[0]?.typeName).toBe("DateTimeString");
249
- expect(result.resolvedConfig.scalars[0]?.importPath).toBe("./src/types");
250
- });
251
- it("should accept only option for input-only scalar", () => {
252
- const result = validateConfig({
253
- config: {
254
- scalars: [
255
- {
256
- name: "DateTime",
257
- tsType: { name: "Date" },
258
- only: "input",
259
- },
260
- ],
261
- },
262
- configPath,
263
- });
264
- expect(result.valid).toBe(true);
265
- expect(result.resolvedConfig).toBeTruthy();
266
- expect(result.resolvedConfig.scalars[0]?.only).toBe("input");
267
- });
268
- it("should accept only option for output-only scalar", () => {
269
- const result = validateConfig({
270
- config: {
271
- scalars: [
272
- {
273
- name: "DateTime",
274
- tsType: { name: "Date" },
275
- only: "output",
276
- },
277
- ],
278
- },
279
- configPath,
280
- });
281
- expect(result.valid).toBe(true);
282
- expect(result.resolvedConfig).toBeTruthy();
283
- expect(result.resolvedConfig.scalars[0]?.only).toBe("output");
284
- });
285
- it("should default only to null when not specified", () => {
286
- const result = validateConfig({
287
- config: {
288
- scalars: [
289
- {
290
- name: "DateTime",
291
- tsType: { name: "Date" },
292
- },
293
- ],
294
- },
295
- configPath,
296
- });
297
- expect(result.valid).toBe(true);
298
- expect(result.resolvedConfig).toBeTruthy();
299
- expect(result.resolvedConfig.scalars[0]?.only).toBe(null);
300
- });
301
- it("should accept description option", () => {
302
- const result = validateConfig({
303
- config: {
304
- scalars: [
305
- {
306
- name: "DateTime",
307
- tsType: { name: "Date" },
308
- description: "ISO 8601 date-time format",
309
- },
310
- ],
311
- },
312
- configPath,
313
- });
314
- expect(result.valid).toBe(true);
315
- expect(result.resolvedConfig).toBeTruthy();
316
- expect(result.resolvedConfig.scalars[0]?.description).toBe("ISO 8601 date-time format");
317
- });
318
- it("should default description to null when not specified", () => {
319
- const result = validateConfig({
320
- config: {
321
- scalars: [
322
- {
323
- name: "DateTime",
324
- tsType: { name: "Date" },
325
- },
326
- ],
327
- },
328
- configPath,
329
- });
330
- expect(result.valid).toBe(true);
331
- expect(result.resolvedConfig).toBeTruthy();
332
- expect(result.resolvedConfig.scalars[0]?.description).toBe(null);
333
- });
334
- it("should return error for invalid only value", () => {
335
- const result = validateConfig({
336
- config: {
337
- scalars: [
338
- {
339
- name: "DateTime",
340
- tsType: { name: "Date" },
341
- only: "invalid",
342
- },
343
- ],
344
- },
345
- configPath,
346
- });
347
- expect(result.valid).toBe(false);
348
- expect(result.diagnostics.length).toBe(1);
349
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_ONLY_VALUE");
350
- expect(result.diagnostics[0]?.message).toContain("only");
351
- });
352
- it("should return error when name is missing in new format", () => {
353
- const result = validateConfig({
354
- config: {
355
- scalars: [
356
- {
357
- tsType: { name: "Date" },
358
- },
359
- ],
360
- },
361
- configPath,
362
- });
363
- expect(result.valid).toBe(false);
364
- expect(result.diagnostics.length).toBe(1);
365
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
366
- });
367
- it("should return error when tsType.name is missing", () => {
368
- const result = validateConfig({
369
- config: {
370
- scalars: [
371
- {
372
- name: "DateTime",
373
- tsType: {},
374
- },
375
- ],
376
- },
377
- configPath,
378
- });
379
- expect(result.valid).toBe(false);
380
- expect(result.diagnostics.length).toBe(1);
381
- expect(result.diagnostics[0]?.code).toBe("CONFIG_MISSING_PROPERTY");
382
- expect(result.diagnostics[0]?.message).toContain("tsType.name");
383
- });
384
- it("should allow multiple mappings for same scalar name with different only values", () => {
385
- const result = validateConfig({
386
- config: {
387
- scalars: [
388
- {
389
- name: "DateTime",
390
- tsType: { name: "Date" },
391
- only: "input",
392
- },
393
- {
394
- name: "DateTime",
395
- tsType: { name: "DateTimeOutput", from: "./src/types" },
396
- only: "output",
397
- },
398
- ],
399
- },
400
- configPath,
401
- });
402
- expect(result.valid).toBe(true);
403
- expect(result.resolvedConfig).toBeTruthy();
404
- expect(result.resolvedConfig.scalars.length).toBe(2);
405
- expect(result.resolvedConfig.scalars[0]?.graphqlName).toBe("DateTime");
406
- expect(result.resolvedConfig.scalars[0]?.only).toBe("input");
407
- expect(result.resolvedConfig.scalars[1]?.graphqlName).toBe("DateTime");
408
- expect(result.resolvedConfig.scalars[1]?.only).toBe("output");
409
- });
410
- it("should return error for built-in scalar override in new format", () => {
411
- const result = validateConfig({
412
- config: {
413
- scalars: [
414
- {
415
- name: "String",
416
- tsType: { name: "CustomString" },
417
- },
418
- ],
419
- },
420
- configPath,
421
- });
422
- expect(result.valid).toBe(false);
423
- expect(result.diagnostics.length).toBe(1);
424
- expect(result.diagnostics[0]?.code).toBe("CONFIG_BUILTIN_OVERRIDE");
425
- });
426
- });
427
- describe("output options (legacy tests - updated to new format)", () => {
428
- it("should return error for invalid output type (not object)", () => {
429
- const result = validateConfig({
430
- config: {
431
- output: "invalid",
432
- },
433
- configPath,
434
- });
435
- expect(result.valid).toBe(false);
436
- expect(result.diagnostics.length).toBe(1);
437
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
438
- expect(result.diagnostics[0]?.message).toContain("output");
439
- });
440
- });
441
- describe("tsconfigPath options", () => {
442
- it("should resolve tsconfigPath to null when not provided", () => {
443
- const result = validateConfig({
444
- config: {},
445
- configPath,
446
- });
447
- expect(result.valid).toBe(true);
448
- expect(result.resolvedConfig).toBeTruthy();
449
- expect(result.resolvedConfig.tsconfigPath).toBe(null);
450
- });
451
- it("should accept string tsconfigPath", () => {
452
- const result = validateConfig({
453
- config: {
454
- tsconfigPath: "./tsconfig.build.json",
455
- },
456
- configPath,
457
- });
458
- expect(result.valid).toBe(true);
459
- expect(result.resolvedConfig).toBeTruthy();
460
- expect(result.resolvedConfig.tsconfigPath).toBe("./tsconfig.build.json");
461
- });
462
- it("should return error for invalid tsconfigPath type", () => {
463
- const result = validateConfig({
464
- config: {
465
- tsconfigPath: 123,
466
- },
467
- configPath,
468
- });
469
- expect(result.valid).toBe(false);
470
- expect(result.diagnostics.length).toBe(1);
471
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
472
- expect(result.diagnostics[0]?.message).toContain("tsconfigPath");
473
- });
474
- it("should return error for empty tsconfigPath", () => {
475
- const result = validateConfig({
476
- config: {
477
- tsconfigPath: "",
478
- },
479
- configPath,
480
- });
481
- expect(result.valid).toBe(false);
482
- expect(result.diagnostics.length).toBe(1);
483
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_PATH");
484
- expect(result.diagnostics[0]?.message).toContain("empty");
485
- });
486
- });
487
- describe("sourceDir options", () => {
488
- it("should resolve default sourceDir when not provided", () => {
489
- const result = validateConfig({
490
- config: {},
491
- configPath,
492
- });
493
- expect(result.valid).toBe(true);
494
- expect(result.resolvedConfig).toBeTruthy();
495
- expect(result.resolvedConfig.sourceDir).toBe("src/gqlkit/schema");
496
- });
497
- it("should accept valid sourceDir string", () => {
498
- const result = validateConfig({
499
- config: {
500
- sourceDir: "src/graphql",
501
- },
502
- configPath,
503
- });
504
- expect(result.valid).toBe(true);
505
- expect(result.resolvedConfig).toBeTruthy();
506
- expect(result.resolvedConfig.sourceDir).toBe("src/graphql");
507
- });
508
- it("should return error for empty sourceDir", () => {
509
- const result = validateConfig({
510
- config: {
511
- sourceDir: "",
512
- },
513
- configPath,
514
- });
515
- expect(result.valid).toBe(false);
516
- expect(result.diagnostics.length).toBe(1);
517
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_SOURCE_DIR");
518
- expect(result.diagnostics[0]?.message).toContain("cannot be empty");
519
- });
520
- it("should return error for non-string sourceDir", () => {
521
- const result = validateConfig({
522
- config: {
523
- sourceDir: 123,
524
- },
525
- configPath,
526
- });
527
- expect(result.valid).toBe(false);
528
- expect(result.diagnostics.length).toBe(1);
529
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
530
- expect(result.diagnostics[0]?.message).toContain("sourceDir");
531
- });
532
- });
533
- describe("sourceIgnoreGlobs options", () => {
534
- it("should resolve default sourceIgnoreGlobs when not provided", () => {
535
- const result = validateConfig({
536
- config: {},
537
- configPath,
538
- });
539
- expect(result.valid).toBe(true);
540
- expect(result.resolvedConfig).toBeTruthy();
541
- expect(result.resolvedConfig.sourceIgnoreGlobs).toEqual([]);
542
- });
543
- it("should accept valid glob patterns array", () => {
544
- const result = validateConfig({
545
- config: {
546
- sourceIgnoreGlobs: ["**/*.test.ts", "**/__tests__/**"],
547
- },
548
- configPath,
549
- });
550
- expect(result.valid).toBe(true);
551
- expect(result.resolvedConfig).toBeTruthy();
552
- expect(result.resolvedConfig.sourceIgnoreGlobs).toEqual([
553
- "**/*.test.ts",
554
- "**/__tests__/**",
555
- ]);
556
- });
557
- it("should accept empty array", () => {
558
- const result = validateConfig({
559
- config: {
560
- sourceIgnoreGlobs: [],
561
- },
562
- configPath,
563
- });
564
- expect(result.valid).toBe(true);
565
- expect(result.resolvedConfig).toBeTruthy();
566
- expect(result.resolvedConfig.sourceIgnoreGlobs).toEqual([]);
567
- });
568
- it("should return error for non-array sourceIgnoreGlobs", () => {
569
- const result = validateConfig({
570
- config: {
571
- sourceIgnoreGlobs: "**/*.test.ts",
572
- },
573
- configPath,
574
- });
575
- expect(result.valid).toBe(false);
576
- expect(result.diagnostics.length).toBe(1);
577
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_IGNORE_GLOBS");
578
- expect(result.diagnostics[0]?.message).toContain("must be an array of strings");
579
- });
580
- it("should return error for array with non-string elements", () => {
581
- const result = validateConfig({
582
- config: {
583
- sourceIgnoreGlobs: ["valid", 123, "also-valid"],
584
- },
585
- configPath,
586
- });
587
- expect(result.valid).toBe(false);
588
- expect(result.diagnostics.length).toBe(1);
589
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_IGNORE_GLOBS");
590
- expect(result.diagnostics[0]?.message).toContain("must be an array of strings");
591
- });
592
- });
593
- describe("new output options (resolversPath, typeDefsPath, schemaPath)", () => {
594
- it("should resolve default output paths when output is undefined", () => {
595
- const result = validateConfig({
596
- config: {},
597
- configPath,
598
- });
599
- expect(result.valid).toBe(true);
600
- expect(result.resolvedConfig).toBeTruthy();
601
- expect(result.resolvedConfig.output.resolversPath).toBe("src/gqlkit/__generated__/resolvers.ts");
602
- expect(result.resolvedConfig.output.typeDefsPath).toBe("src/gqlkit/__generated__/typeDefs.ts");
603
- expect(result.resolvedConfig.output.schemaPath).toBe("src/gqlkit/__generated__/schema.graphql");
604
- });
605
- it("should resolve default paths when individual options are undefined", () => {
606
- const result = validateConfig({
607
- config: { output: {} },
608
- configPath,
609
- });
610
- expect(result.valid).toBe(true);
611
- expect(result.resolvedConfig).toBeTruthy();
612
- expect(result.resolvedConfig.output.resolversPath).toBe("src/gqlkit/__generated__/resolvers.ts");
613
- expect(result.resolvedConfig.output.typeDefsPath).toBe("src/gqlkit/__generated__/typeDefs.ts");
614
- expect(result.resolvedConfig.output.schemaPath).toBe("src/gqlkit/__generated__/schema.graphql");
615
- });
616
- it("should use custom paths when provided", () => {
617
- const result = validateConfig({
618
- config: {
619
- output: {
620
- resolversPath: "custom/resolvers.ts",
621
- typeDefsPath: "custom/typeDefs.ts",
622
- schemaPath: "custom/schema.graphql",
623
- },
624
- },
625
- configPath,
626
- });
627
- expect(result.valid).toBe(true);
628
- expect(result.resolvedConfig).toBeTruthy();
629
- expect(result.resolvedConfig.output.resolversPath).toBe("custom/resolvers.ts");
630
- expect(result.resolvedConfig.output.typeDefsPath).toBe("custom/typeDefs.ts");
631
- expect(result.resolvedConfig.output.schemaPath).toBe("custom/schema.graphql");
632
- });
633
- it("should allow null to suppress output for each path", () => {
634
- const result = validateConfig({
635
- config: {
636
- output: {
637
- resolversPath: null,
638
- typeDefsPath: null,
639
- schemaPath: null,
640
- },
641
- },
642
- configPath,
643
- });
644
- expect(result.valid).toBe(true);
645
- expect(result.resolvedConfig).toBeTruthy();
646
- expect(result.resolvedConfig.output.resolversPath).toBe(null);
647
- expect(result.resolvedConfig.output.typeDefsPath).toBe(null);
648
- expect(result.resolvedConfig.output.schemaPath).toBe(null);
649
- });
650
- it("should allow mixed null and string", () => {
651
- const result = validateConfig({
652
- config: {
653
- output: {
654
- resolversPath: "custom/resolvers.ts",
655
- typeDefsPath: null,
656
- schemaPath: "custom/schema.graphql",
657
- },
658
- },
659
- configPath,
660
- });
661
- expect(result.valid).toBe(true);
662
- expect(result.resolvedConfig).toBeTruthy();
663
- expect(result.resolvedConfig.output.resolversPath).toBe("custom/resolvers.ts");
664
- expect(result.resolvedConfig.output.typeDefsPath).toBe(null);
665
- expect(result.resolvedConfig.output.schemaPath).toBe("custom/schema.graphql");
666
- });
667
- it("should return error for invalid resolversPath type", () => {
668
- const result = validateConfig({
669
- config: {
670
- output: {
671
- resolversPath: 123,
672
- },
673
- },
674
- configPath,
675
- });
676
- expect(result.valid).toBe(false);
677
- expect(result.diagnostics.length).toBe(1);
678
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_OUTPUT_TYPE");
679
- expect(result.diagnostics[0]?.message).toContain("output.resolversPath");
680
- });
681
- it("should return error for invalid typeDefsPath type", () => {
682
- const result = validateConfig({
683
- config: {
684
- output: {
685
- typeDefsPath: true,
686
- },
687
- },
688
- configPath,
689
- });
690
- expect(result.valid).toBe(false);
691
- expect(result.diagnostics.length).toBe(1);
692
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_OUTPUT_TYPE");
693
- expect(result.diagnostics[0]?.message).toContain("output.typeDefsPath");
694
- });
695
- it("should return error for empty string resolversPath", () => {
696
- const result = validateConfig({
697
- config: {
698
- output: {
699
- resolversPath: "",
700
- },
701
- },
702
- configPath,
703
- });
704
- expect(result.valid).toBe(false);
705
- expect(result.diagnostics.length).toBe(1);
706
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_OUTPUT_PATH");
707
- expect(result.diagnostics[0]?.message).toContain("empty");
708
- });
709
- });
710
- describe("hooks options", () => {
711
- it("should resolve default empty hooks when not provided", () => {
712
- const result = validateConfig({
713
- config: {},
714
- configPath,
715
- });
716
- expect(result.valid).toBe(true);
717
- expect(result.resolvedConfig).toBeTruthy();
718
- expect(result.resolvedConfig.hooks.afterAllFileWrite).toEqual([]);
719
- });
720
- it("should accept single command string for afterAllFileWrite", () => {
721
- const result = validateConfig({
722
- config: {
723
- hooks: {
724
- afterAllFileWrite: "prettier --write",
725
- },
726
- },
727
- configPath,
728
- });
729
- expect(result.valid).toBe(true);
730
- expect(result.resolvedConfig).toBeTruthy();
731
- expect(result.resolvedConfig.hooks.afterAllFileWrite).toEqual([
732
- "prettier --write",
733
- ]);
734
- });
735
- it("should accept array of command strings for afterAllFileWrite", () => {
736
- const result = validateConfig({
737
- config: {
738
- hooks: {
739
- afterAllFileWrite: ["prettier --write", "eslint --fix"],
740
- },
741
- },
742
- configPath,
743
- });
744
- expect(result.valid).toBe(true);
745
- expect(result.resolvedConfig).toBeTruthy();
746
- expect(result.resolvedConfig.hooks.afterAllFileWrite).toEqual([
747
- "prettier --write",
748
- "eslint --fix",
749
- ]);
750
- });
751
- it("should accept empty array for afterAllFileWrite", () => {
752
- const result = validateConfig({
753
- config: {
754
- hooks: {
755
- afterAllFileWrite: [],
756
- },
757
- },
758
- configPath,
759
- });
760
- expect(result.valid).toBe(true);
761
- expect(result.resolvedConfig).toBeTruthy();
762
- expect(result.resolvedConfig.hooks.afterAllFileWrite).toEqual([]);
763
- });
764
- it("should accept hooks object without afterAllFileWrite", () => {
765
- const result = validateConfig({
766
- config: {
767
- hooks: {},
768
- },
769
- configPath,
770
- });
771
- expect(result.valid).toBe(true);
772
- expect(result.resolvedConfig).toBeTruthy();
773
- expect(result.resolvedConfig.hooks.afterAllFileWrite).toEqual([]);
774
- });
775
- it("should return error for non-object hooks", () => {
776
- const result = validateConfig({
777
- config: {
778
- hooks: "invalid",
779
- },
780
- configPath,
781
- });
782
- expect(result.valid).toBe(false);
783
- expect(result.diagnostics.length).toBe(1);
784
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_TYPE");
785
- expect(result.diagnostics[0]?.message).toContain("hooks");
786
- });
787
- it("should return error for invalid afterAllFileWrite type", () => {
788
- const result = validateConfig({
789
- config: {
790
- hooks: {
791
- afterAllFileWrite: 123,
792
- },
793
- },
794
- configPath,
795
- });
796
- expect(result.valid).toBe(false);
797
- expect(result.diagnostics.length).toBe(1);
798
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_HOOK_TYPE");
799
- expect(result.diagnostics[0]?.message).toContain("afterAllFileWrite");
800
- });
801
- it("should return error for array with non-string elements", () => {
802
- const result = validateConfig({
803
- config: {
804
- hooks: {
805
- afterAllFileWrite: ["valid", 123, "also-valid"],
806
- },
807
- },
808
- configPath,
809
- });
810
- expect(result.valid).toBe(false);
811
- expect(result.diagnostics.length).toBe(1);
812
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_HOOK_TYPE");
813
- expect(result.diagnostics[0]?.message).toContain("afterAllFileWrite");
814
- });
815
- it("should return error for empty command string", () => {
816
- const result = validateConfig({
817
- config: {
818
- hooks: {
819
- afterAllFileWrite: "",
820
- },
821
- },
822
- configPath,
823
- });
824
- expect(result.valid).toBe(false);
825
- expect(result.diagnostics.length).toBe(1);
826
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_HOOK_COMMAND");
827
- expect(result.diagnostics[0]?.message).toContain("empty");
828
- });
829
- it("should return error for array containing empty string", () => {
830
- const result = validateConfig({
831
- config: {
832
- hooks: {
833
- afterAllFileWrite: ["prettier --write", "", "eslint --fix"],
834
- },
835
- },
836
- configPath,
837
- });
838
- expect(result.valid).toBe(false);
839
- expect(result.diagnostics.length).toBe(1);
840
- expect(result.diagnostics[0]?.code).toBe("CONFIG_INVALID_HOOK_COMMAND");
841
- expect(result.diagnostics[0]?.message).toContain("empty");
842
- });
843
- });
844
- });
845
- });
846
- //# sourceMappingURL=validator.test.js.map