@ollie-shop/cli 0.2.0 → 0.3.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 (182) hide show
  1. package/.turbo/turbo-build.log +2 -11
  2. package/CHANGELOG.md +13 -7
  3. package/CLAUDE_CLI.md +265 -0
  4. package/README.md +704 -8
  5. package/__tests__/mocks/console.ts +22 -0
  6. package/__tests__/mocks/core.ts +137 -0
  7. package/__tests__/mocks/index.ts +4 -0
  8. package/__tests__/mocks/inquirer.ts +16 -0
  9. package/__tests__/mocks/progress.ts +19 -0
  10. package/dist/__tests__/helpers/cli-test-helper.d.ts +89 -0
  11. package/dist/__tests__/helpers/cli-test-helper.d.ts.map +1 -0
  12. package/dist/__tests__/helpers/cli-test-helper.js +220 -0
  13. package/dist/__tests__/mocks/index.d.ts +69 -0
  14. package/dist/__tests__/mocks/index.d.ts.map +1 -0
  15. package/dist/__tests__/mocks/index.js +77 -0
  16. package/dist/actions/component.actions.d.ts +14 -0
  17. package/dist/actions/component.actions.d.ts.map +1 -0
  18. package/dist/actions/component.actions.js +273 -0
  19. package/dist/actions/function.actions.d.ts +15 -0
  20. package/dist/actions/function.actions.d.ts.map +1 -0
  21. package/dist/actions/function.actions.js +254 -0
  22. package/dist/actions/project.actions.d.ts +17 -0
  23. package/dist/actions/project.actions.d.ts.map +1 -0
  24. package/dist/actions/project.actions.js +97 -0
  25. package/dist/actions/version.actions.d.ts +19 -0
  26. package/dist/actions/version.actions.d.ts.map +1 -0
  27. package/dist/actions/version.actions.js +216 -0
  28. package/dist/commands/component.d.ts +3 -0
  29. package/dist/commands/component.d.ts.map +1 -0
  30. package/dist/commands/component.js +192 -0
  31. package/dist/commands/docs.d.ts +3 -0
  32. package/dist/commands/docs.d.ts.map +1 -0
  33. package/dist/commands/docs.js +16 -0
  34. package/dist/commands/function.d.ts +3 -0
  35. package/dist/commands/function.d.ts.map +1 -0
  36. package/dist/commands/function.js +243 -0
  37. package/dist/commands/help.d.ts +3 -0
  38. package/dist/commands/help.d.ts.map +1 -0
  39. package/dist/commands/help.js +20 -0
  40. package/dist/commands/index.d.ts +3 -0
  41. package/dist/commands/index.d.ts.map +1 -0
  42. package/dist/commands/index.js +26 -0
  43. package/dist/commands/login.d.ts +3 -0
  44. package/dist/commands/login.d.ts.map +1 -0
  45. package/dist/commands/login.js +175 -0
  46. package/dist/commands/project.d.ts +3 -0
  47. package/dist/commands/project.d.ts.map +1 -0
  48. package/dist/commands/project.js +78 -0
  49. package/dist/commands/store-version.d.ts +3 -0
  50. package/dist/commands/store-version.d.ts.map +1 -0
  51. package/dist/commands/store-version.js +241 -0
  52. package/dist/commands/version.d.ts +3 -0
  53. package/dist/commands/version.d.ts.map +1 -0
  54. package/dist/commands/version.js +46 -0
  55. package/dist/commands/whoami.d.ts +3 -0
  56. package/dist/commands/whoami.d.ts.map +1 -0
  57. package/dist/commands/whoami.js +41 -0
  58. package/dist/index.d.ts +3 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +88 -478
  61. package/dist/prompts/component.prompts.d.ts +14 -0
  62. package/dist/prompts/component.prompts.d.ts.map +1 -0
  63. package/dist/prompts/component.prompts.js +75 -0
  64. package/dist/prompts/function.prompts.d.ts +21 -0
  65. package/dist/prompts/function.prompts.d.ts.map +1 -0
  66. package/dist/prompts/function.prompts.js +127 -0
  67. package/dist/schemas/command.schema.d.ts +516 -0
  68. package/dist/schemas/command.schema.d.ts.map +1 -0
  69. package/dist/schemas/command.schema.js +267 -0
  70. package/dist/types/index.d.ts +147 -0
  71. package/dist/types/index.d.ts.map +1 -0
  72. package/dist/types/index.js +18 -0
  73. package/dist/utils/auth.d.ts +4 -0
  74. package/dist/utils/auth.d.ts.map +1 -0
  75. package/dist/utils/auth.js +26 -0
  76. package/dist/utils/cli-progress-reporter.d.ts +12 -0
  77. package/dist/utils/cli-progress-reporter.d.ts.map +1 -0
  78. package/dist/utils/cli-progress-reporter.js +77 -0
  79. package/dist/utils/command-builder.d.ts +22 -0
  80. package/dist/utils/command-builder.d.ts.map +1 -0
  81. package/dist/utils/command-builder.js +268 -0
  82. package/dist/utils/command-helpers.d.ts +19 -0
  83. package/dist/utils/command-helpers.d.ts.map +1 -0
  84. package/dist/utils/command-helpers.js +79 -0
  85. package/dist/utils/command-parser.d.ts +146 -0
  86. package/dist/utils/command-parser.d.ts.map +1 -0
  87. package/dist/utils/command-parser.js +179 -0
  88. package/dist/utils/command-suggestions.d.ts +35 -0
  89. package/dist/utils/command-suggestions.d.ts.map +1 -0
  90. package/dist/utils/command-suggestions.js +152 -0
  91. package/dist/utils/console.d.ts +44 -0
  92. package/dist/utils/console.d.ts.map +1 -0
  93. package/dist/utils/console.js +233 -0
  94. package/dist/utils/constants.d.ts +8 -0
  95. package/dist/utils/constants.d.ts.map +1 -0
  96. package/dist/utils/constants.js +10 -0
  97. package/dist/utils/context-detector.d.ts +12 -0
  98. package/dist/utils/context-detector.d.ts.map +1 -0
  99. package/dist/utils/context-detector.js +155 -0
  100. package/dist/utils/enhanced-error-handler.d.ts +47 -0
  101. package/dist/utils/enhanced-error-handler.d.ts.map +1 -0
  102. package/dist/utils/enhanced-error-handler.js +221 -0
  103. package/dist/utils/error-handler.d.ts +3 -0
  104. package/dist/utils/error-handler.d.ts.map +1 -0
  105. package/dist/utils/error-handler.js +55 -0
  106. package/dist/utils/errors.d.ts +44 -0
  107. package/dist/utils/errors.d.ts.map +1 -0
  108. package/dist/utils/errors.js +76 -0
  109. package/dist/utils/interactive-builder.d.ts +22 -0
  110. package/dist/utils/interactive-builder.d.ts.map +1 -0
  111. package/dist/utils/interactive-builder.js +246 -0
  112. package/dist/utils/rich-progress.d.ts +59 -0
  113. package/dist/utils/rich-progress.d.ts.map +1 -0
  114. package/dist/utils/rich-progress.js +234 -0
  115. package/dist/utils/store.d.ts +11 -0
  116. package/dist/utils/store.d.ts.map +1 -0
  117. package/dist/utils/store.js +19 -0
  118. package/dist/utils/validation-error-formatter.d.ts +25 -0
  119. package/dist/utils/validation-error-formatter.d.ts.map +1 -0
  120. package/dist/utils/validation-error-formatter.js +258 -0
  121. package/dist/utils/validation-helpers.d.ts +60 -0
  122. package/dist/utils/validation-helpers.d.ts.map +1 -0
  123. package/dist/utils/validation-helpers.js +152 -0
  124. package/package.json +43 -11
  125. package/src/__tests__/helpers/cli-test-helper.ts +281 -0
  126. package/src/__tests__/mocks/index.ts +142 -0
  127. package/src/actions/component.actions.ts +334 -0
  128. package/src/actions/function.actions.ts +313 -0
  129. package/src/actions/project.actions.ts +126 -0
  130. package/src/actions/version.actions.ts +233 -0
  131. package/src/commands/__tests__/component-validation.test.ts +250 -0
  132. package/src/commands/__tests__/component.test.ts +321 -0
  133. package/src/commands/__tests__/function-validation.test.ts +220 -0
  134. package/src/commands/__tests__/function.test.ts +286 -0
  135. package/src/commands/__tests__/store-version-validation.test.ts +414 -0
  136. package/src/commands/__tests__/store-version.test.ts +405 -0
  137. package/src/commands/__tests__/version.test.ts +71 -0
  138. package/src/commands/component.ts +188 -0
  139. package/src/commands/docs.ts +11 -11
  140. package/src/commands/function.ts +252 -0
  141. package/src/commands/help.ts +8 -18
  142. package/src/commands/index.ts +14 -7
  143. package/src/commands/login.ts +19 -79
  144. package/src/commands/project.ts +107 -0
  145. package/src/commands/store-version.ts +242 -0
  146. package/src/commands/version.ts +45 -8
  147. package/src/commands/whoami.ts +8 -13
  148. package/src/index.ts +108 -34
  149. package/src/prompts/component.prompts.ts +94 -0
  150. package/src/prompts/function.prompts.ts +168 -0
  151. package/src/schemas/command.schema.ts +354 -0
  152. package/src/types/index.ts +183 -0
  153. package/src/utils/__tests__/command-parser.test.ts +159 -0
  154. package/src/utils/__tests__/command-suggestions.test.ts +185 -0
  155. package/src/utils/__tests__/console.test.ts +192 -0
  156. package/src/utils/__tests__/context-detector.test.ts +258 -0
  157. package/src/utils/__tests__/enhanced-error-handler.test.ts +137 -0
  158. package/src/utils/__tests__/error-handler.test.ts +107 -0
  159. package/src/utils/__tests__/rich-progress.test.ts +170 -0
  160. package/src/utils/__tests__/validation-error-formatter.test.ts +175 -0
  161. package/src/utils/__tests__/validation-helpers.test.ts +125 -0
  162. package/src/utils/auth.ts +0 -1
  163. package/src/utils/cli-progress-reporter.ts +84 -0
  164. package/src/utils/command-builder.ts +390 -0
  165. package/src/utils/command-helpers.ts +83 -0
  166. package/src/utils/command-parser.ts +250 -0
  167. package/src/utils/command-suggestions.ts +176 -0
  168. package/src/utils/console.ts +291 -0
  169. package/src/utils/context-detector.ts +177 -0
  170. package/src/utils/enhanced-error-handler.ts +264 -0
  171. package/src/utils/error-handler.ts +60 -0
  172. package/src/utils/errors.ts +125 -0
  173. package/src/utils/interactive-builder.ts +271 -0
  174. package/src/utils/rich-progress.ts +320 -0
  175. package/src/utils/validation-error-formatter.ts +337 -0
  176. package/src/utils/validation-helpers.ts +192 -0
  177. package/tsconfig.json +13 -7
  178. package/vitest.config.ts +28 -0
  179. package/vitest.setup.ts +29 -0
  180. package/src/commands/validate.ts +0 -62
  181. package/src/utils/core.ts +0 -105
  182. package/tsup.config.ts +0 -15
@@ -0,0 +1,405 @@
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import {
3
+ storeFactory,
4
+ versionFactory,
5
+ } from "@ollie-shop/core/__tests__/factories";
6
+ import {
7
+ createTestProgram,
8
+ executeCLI,
9
+ resetCLIMocks,
10
+ } from "@tests/helpers/cli-test-helper";
11
+ import { createMockCore } from "@tests/mocks";
12
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
13
+ import { registerStoreVersionCommands } from "../store-version";
14
+
15
+ // Mock the version actions module
16
+ vi.mock("../../actions/version.actions", () => ({
17
+ create: vi.fn(),
18
+ list: vi.fn(),
19
+ get: vi.fn(),
20
+ setDefault: vi.fn(),
21
+ activate: vi.fn(),
22
+ deactivate: vi.fn(),
23
+ clone: vi.fn(),
24
+ deleteVersion: vi.fn(),
25
+ }));
26
+
27
+ // Import mocked actions
28
+ import * as versionActions from "../../actions/version.actions";
29
+
30
+ describe("Store Version Command", () => {
31
+ let program: Command;
32
+ let _mockCore: ReturnType<typeof createMockCore>;
33
+
34
+ beforeEach(() => {
35
+ const testSetup = createTestProgram();
36
+ program = testSetup.program;
37
+ _mockCore = createMockCore();
38
+
39
+ // Register the store-version commands
40
+ registerStoreVersionCommands(program);
41
+
42
+ // Reset all mocks
43
+ vi.clearAllMocks();
44
+ });
45
+
46
+ afterEach(() => {
47
+ resetCLIMocks();
48
+ });
49
+
50
+ describe("create subcommand", () => {
51
+ it("should create a version with required options", async () => {
52
+ // Arrange
53
+ const newVersion = versionFactory.build({
54
+ name: "test-version",
55
+ template: "default",
56
+ active: true,
57
+ });
58
+
59
+ vi.mocked(versionActions.create).mockResolvedValue(newVersion);
60
+
61
+ // Act
62
+ const result = await executeCLI(program, [
63
+ "store-version",
64
+ "create",
65
+ "--store",
66
+ "123e4567-e89b-12d3-a456-426614174000",
67
+ "--name",
68
+ "test-version",
69
+ ]);
70
+
71
+ // Assert
72
+ expect(result.exitCode).toBe(0);
73
+ expect(versionActions.create).toHaveBeenCalledWith({
74
+ store: "123e4567-e89b-12d3-a456-426614174000",
75
+ name: "test-version",
76
+ template: "default",
77
+ active: true,
78
+ });
79
+ });
80
+
81
+ it("should create an inactive version when --no-active is specified", async () => {
82
+ // Arrange
83
+ const newVersion = versionFactory.build({
84
+ name: "test-version",
85
+ active: false,
86
+ });
87
+
88
+ vi.mocked(versionActions.create).mockResolvedValue(newVersion);
89
+
90
+ // Act
91
+ const result = await executeCLI(program, [
92
+ "store-version",
93
+ "create",
94
+ "--store",
95
+ "123e4567-e89b-12d3-a456-426614174000",
96
+ "--name",
97
+ "test-version",
98
+ "--no-active",
99
+ ]);
100
+
101
+ // Assert
102
+ expect(result.exitCode).toBe(0);
103
+ expect(versionActions.create).toHaveBeenCalledWith({
104
+ store: "123e4567-e89b-12d3-a456-426614174000",
105
+ name: "test-version",
106
+ template: "default",
107
+ active: false,
108
+ });
109
+ });
110
+
111
+ it("should handle validation errors for invalid store ID", async () => {
112
+ // Act
113
+ const result = await executeCLI(program, [
114
+ "store-version",
115
+ "create",
116
+ "--store",
117
+ "invalid-uuid",
118
+ "--name",
119
+ "test-version",
120
+ ]);
121
+
122
+ // Assert
123
+ expect(result.exitCode).toBe(1);
124
+ expect(versionActions.create).not.toHaveBeenCalled();
125
+ });
126
+
127
+ it("should handle missing required options", async () => {
128
+ // Act
129
+ const result = await executeCLI(program, ["store-version", "create"]);
130
+
131
+ // Assert
132
+ expect(result.exitCode).toBe(1);
133
+ expect(versionActions.create).not.toHaveBeenCalled();
134
+ });
135
+ });
136
+
137
+ describe("list subcommand", () => {
138
+ it("should list versions for a store", async () => {
139
+ // Arrange
140
+ const store = storeFactory.build();
141
+ const versions = [
142
+ versionFactory.build({
143
+ storeId: store.id,
144
+ name: "Production",
145
+ default: true,
146
+ }),
147
+ versionFactory.build({
148
+ storeId: store.id,
149
+ name: "Staging",
150
+ default: false,
151
+ }),
152
+ ];
153
+
154
+ vi.mocked(versionActions.list).mockResolvedValue(versions);
155
+
156
+ // Act
157
+ const result = await executeCLI(program, [
158
+ "store-version",
159
+ "list",
160
+ "--store",
161
+ store.id,
162
+ ]);
163
+
164
+ // Assert
165
+ expect(result.exitCode).toBe(0);
166
+ expect(versionActions.list).toHaveBeenCalledWith({
167
+ store: store.id,
168
+ });
169
+ });
170
+
171
+ it("should handle validation errors for invalid store ID", async () => {
172
+ // Act
173
+ const result = await executeCLI(program, [
174
+ "store-version",
175
+ "list",
176
+ "--store",
177
+ "invalid-uuid",
178
+ ]);
179
+
180
+ // Assert
181
+ expect(result.exitCode).toBe(1);
182
+ expect(versionActions.list).not.toHaveBeenCalled();
183
+ });
184
+ });
185
+
186
+ describe("get subcommand", () => {
187
+ it("should get version details by ID", async () => {
188
+ // Arrange
189
+ const version = versionFactory.build();
190
+ vi.mocked(versionActions.get).mockResolvedValue(version);
191
+
192
+ // Act
193
+ const result = await executeCLI(program, [
194
+ "store-version",
195
+ "get",
196
+ version.id,
197
+ ]);
198
+
199
+ // Assert
200
+ expect(result.exitCode).toBe(0);
201
+ expect(versionActions.get).toHaveBeenCalledWith(version.id);
202
+ });
203
+
204
+ it("should handle validation errors for invalid version ID", async () => {
205
+ // Act
206
+ const result = await executeCLI(program, [
207
+ "store-version",
208
+ "get",
209
+ "invalid-uuid",
210
+ ]);
211
+
212
+ // Assert
213
+ expect(result.exitCode).toBe(1);
214
+ expect(versionActions.get).not.toHaveBeenCalled();
215
+ });
216
+ });
217
+
218
+ describe("set-default subcommand", () => {
219
+ it("should set a version as default", async () => {
220
+ // Arrange
221
+ const version = versionFactory.build();
222
+ const defaultVersion = { ...version, default: true };
223
+ vi.mocked(versionActions.setDefault).mockResolvedValue(defaultVersion);
224
+
225
+ // Act
226
+ const result = await executeCLI(program, [
227
+ "store-version",
228
+ "set-default",
229
+ version.id,
230
+ ]);
231
+
232
+ // Assert
233
+ expect(result.exitCode).toBe(0);
234
+ expect(versionActions.setDefault).toHaveBeenCalledWith(version.id);
235
+ });
236
+ });
237
+
238
+ describe("activate subcommand", () => {
239
+ it("should activate a version", async () => {
240
+ // Arrange
241
+ const version = versionFactory.build({ active: false });
242
+ const activeVersion = { ...version, active: true };
243
+ vi.mocked(versionActions.activate).mockResolvedValue(activeVersion);
244
+
245
+ // Act
246
+ const result = await executeCLI(program, [
247
+ "store-version",
248
+ "activate",
249
+ version.id,
250
+ ]);
251
+
252
+ // Assert
253
+ expect(result.exitCode).toBe(0);
254
+ expect(versionActions.activate).toHaveBeenCalledWith(version.id);
255
+ });
256
+ });
257
+
258
+ describe("deactivate subcommand", () => {
259
+ it("should deactivate a version", async () => {
260
+ // Arrange
261
+ const version = versionFactory.build({ active: true });
262
+ const inactiveVersion = { ...version, active: false };
263
+ vi.mocked(versionActions.deactivate).mockResolvedValue(inactiveVersion);
264
+
265
+ // Act
266
+ const result = await executeCLI(program, [
267
+ "store-version",
268
+ "deactivate",
269
+ version.id,
270
+ ]);
271
+
272
+ // Assert
273
+ expect(result.exitCode).toBe(0);
274
+ expect(versionActions.deactivate).toHaveBeenCalledWith(version.id);
275
+ });
276
+ });
277
+
278
+ describe("clone subcommand", () => {
279
+ it("should clone a version with a new name", async () => {
280
+ // Arrange
281
+ const originalVersion = versionFactory.build();
282
+ const clonedVersion = versionFactory.build({ name: "Cloned Version" });
283
+ vi.mocked(versionActions.clone).mockResolvedValue(clonedVersion);
284
+
285
+ // Act
286
+ const result = await executeCLI(program, [
287
+ "store-version",
288
+ "clone",
289
+ originalVersion.id,
290
+ "--name",
291
+ "Cloned Version",
292
+ ]);
293
+
294
+ // Assert
295
+ expect(result.exitCode).toBe(0);
296
+ expect(versionActions.clone).toHaveBeenCalledWith(
297
+ originalVersion.id,
298
+ "Cloned Version",
299
+ );
300
+ });
301
+
302
+ it("should handle missing name option", async () => {
303
+ // Arrange
304
+ const version = versionFactory.build();
305
+
306
+ // Act
307
+ const result = await executeCLI(program, [
308
+ "store-version",
309
+ "clone",
310
+ version.id,
311
+ ]);
312
+
313
+ // Assert
314
+ expect(result.exitCode).toBe(1);
315
+ expect(versionActions.clone).not.toHaveBeenCalled();
316
+ });
317
+ });
318
+
319
+ describe("delete subcommand", () => {
320
+ it("should delete a version", async () => {
321
+ // Arrange
322
+ const version = versionFactory.build();
323
+ vi.mocked(versionActions.deleteVersion).mockResolvedValue(undefined);
324
+
325
+ // Act
326
+ const result = await executeCLI(program, [
327
+ "store-version",
328
+ "delete",
329
+ version.id,
330
+ ]);
331
+
332
+ // Assert
333
+ expect(result.exitCode).toBe(0);
334
+ expect(versionActions.deleteVersion).toHaveBeenCalledWith(
335
+ version.id,
336
+ undefined,
337
+ );
338
+ });
339
+
340
+ it("should delete a version with force flag", async () => {
341
+ // Arrange
342
+ const version = versionFactory.build();
343
+ vi.mocked(versionActions.deleteVersion).mockResolvedValue(undefined);
344
+
345
+ // Act
346
+ const result = await executeCLI(program, [
347
+ "store-version",
348
+ "delete",
349
+ version.id,
350
+ "--force",
351
+ ]);
352
+
353
+ // Assert
354
+ expect(result.exitCode).toBe(0);
355
+ expect(versionActions.deleteVersion).toHaveBeenCalledWith(
356
+ version.id,
357
+ true,
358
+ );
359
+ });
360
+ });
361
+
362
+ describe("error handling", () => {
363
+ it("should handle action errors gracefully", async () => {
364
+ // Arrange
365
+ const error = new Error("Version creation failed");
366
+ vi.mocked(versionActions.create).mockRejectedValue(error);
367
+
368
+ // Act
369
+ const result = await executeCLI(program, [
370
+ "store-version",
371
+ "create",
372
+ "--store",
373
+ "123e4567-e89b-12d3-a456-426614174000",
374
+ "--name",
375
+ "test-version",
376
+ ]);
377
+
378
+ // Assert
379
+ expect(result.exitCode).toBe(1);
380
+ });
381
+ });
382
+
383
+ describe("alias support", () => {
384
+ it("should work with sv alias", async () => {
385
+ // Arrange
386
+ const store = storeFactory.build();
387
+ const versions = [versionFactory.build({ storeId: store.id })];
388
+ vi.mocked(versionActions.list).mockResolvedValue(versions);
389
+
390
+ // Act
391
+ const result = await executeCLI(program, [
392
+ "sv",
393
+ "list",
394
+ "--store",
395
+ store.id,
396
+ ]);
397
+
398
+ // Assert
399
+ expect(result.exitCode).toBe(0);
400
+ expect(versionActions.list).toHaveBeenCalledWith({
401
+ store: store.id,
402
+ });
403
+ });
404
+ });
405
+ });
@@ -0,0 +1,71 @@
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import {
3
+ createTestProgram,
4
+ executeCLI,
5
+ resetCLIMocks,
6
+ } from "@tests/helpers/cli-test-helper";
7
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
8
+ import { configureVersionCommand } from "../version";
9
+
10
+ // Mock the package.json to provide a test version
11
+ vi.mock("../../package.json", () => ({
12
+ default: { version: "0.2.0" },
13
+ }));
14
+
15
+ // Mock the console utility
16
+ vi.mock("../../utils/console", () => ({
17
+ console: {
18
+ info: vi.fn(),
19
+ error: vi.fn(),
20
+ success: vi.fn(),
21
+ warn: vi.fn(),
22
+ log: vi.fn(),
23
+ },
24
+ }));
25
+
26
+ // Import the mocked console
27
+ import { console as mockConsole } from "../../utils/console";
28
+
29
+ describe("Version Command", () => {
30
+ let program: Command;
31
+
32
+ beforeEach(() => {
33
+ const testSetup = createTestProgram();
34
+ program = testSetup.program;
35
+
36
+ // Configure the version command
37
+ configureVersionCommand(program);
38
+
39
+ // Reset all mocks
40
+ vi.clearAllMocks();
41
+ });
42
+
43
+ afterEach(() => {
44
+ resetCLIMocks();
45
+ });
46
+
47
+ describe("version command", () => {
48
+ it("should display the CLI version", async () => {
49
+ // Act
50
+ const result = await executeCLI(program, ["version"]);
51
+
52
+ // Assert
53
+ expect(result.exitCode).toBe(0);
54
+ expect(mockConsole.info).toHaveBeenCalledWith(
55
+ "Ollie Shop CLI version: 0.2.0",
56
+ );
57
+ });
58
+
59
+ it("should call the version command action", async () => {
60
+ // Act
61
+ const result = await executeCLI(program, ["version"]);
62
+
63
+ // Assert
64
+ expect(result.exitCode).toBe(0);
65
+ expect(mockConsole.info).toHaveBeenCalledTimes(1);
66
+ expect(mockConsole.info).toHaveBeenCalledWith(
67
+ expect.stringContaining("Ollie Shop CLI version:"),
68
+ );
69
+ });
70
+ });
71
+ });
@@ -0,0 +1,188 @@
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import * as componentActions from "../actions/component.actions";
3
+ import {
4
+ ComponentBuildOptionsSchema,
5
+ type ComponentCreateOptions,
6
+ ComponentCreateOptionsSchema,
7
+ type ComponentDeployOptions,
8
+ ComponentDeployOptionsSchema,
9
+ ComponentValidateOptionsSchema,
10
+ } from "../schemas/command.schema";
11
+ import { buildCommand, buildCommandGroup } from "../utils/command-builder";
12
+ import { COMMON_OPTIONS } from "../utils/command-parser";
13
+
14
+ export function registerComponentCommands(program: Command): void {
15
+ const cmd = buildCommandGroup(
16
+ program,
17
+ "component",
18
+ "Manage Ollie Shop components",
19
+ ["comp"],
20
+ );
21
+
22
+ // Create component command
23
+ buildCommand(cmd, {
24
+ name: "create",
25
+ description: "Create a new component",
26
+ options: [
27
+ COMMON_OPTIONS.componentName,
28
+ COMMON_OPTIONS.componentSlot,
29
+ COMMON_OPTIONS.tests,
30
+ COMMON_OPTIONS.noTests,
31
+ {
32
+ flags: "-i, --interactive",
33
+ description: "Use interactive mode",
34
+ defaultValue: false,
35
+ },
36
+ ],
37
+ schema: ComponentCreateOptionsSchema,
38
+ examples: [
39
+ {
40
+ description: "Create a header component",
41
+ command: "ollieshop component create --name header --slot header",
42
+ },
43
+ {
44
+ description: "Create a component with TypeScript",
45
+ command: "ollieshop component create --name product-list --typescript",
46
+ },
47
+ {
48
+ description: "Interactive mode",
49
+ command: "ollieshop component create --interactive",
50
+ },
51
+ {
52
+ description: "Create with tests",
53
+ command: "ollieshop component create --name product-list",
54
+ },
55
+ ],
56
+ handler: async (options, console) => {
57
+ // Use interactive mode if requested
58
+ if ("interactive" in options && options.interactive) {
59
+ const { runInteractiveCommand } = await import(
60
+ "../utils/interactive-builder.js"
61
+ );
62
+ await runInteractiveCommand("component-create", console);
63
+ return;
64
+ }
65
+
66
+ await componentActions.createComponent(
67
+ options as ComponentCreateOptions,
68
+ console,
69
+ );
70
+ },
71
+ });
72
+
73
+ // Validate component command
74
+ buildCommand(cmd, {
75
+ name: "validate",
76
+ description: "Validate a component",
77
+ options: [COMMON_OPTIONS.path],
78
+ schema: ComponentValidateOptionsSchema,
79
+ examples: [
80
+ {
81
+ description: "Validate current directory",
82
+ command: "ollieshop component validate",
83
+ },
84
+ {
85
+ description: "Validate specific component",
86
+ command: "ollieshop component validate --path ./components/header",
87
+ },
88
+ ],
89
+ handler: async (options, console) => {
90
+ await componentActions.validateComponent(
91
+ {
92
+ path: options.path || process.cwd(),
93
+ strict: options.strict ?? false,
94
+ fix: options.fix ?? false,
95
+ },
96
+ console,
97
+ );
98
+ },
99
+ });
100
+
101
+ // Build component command
102
+ buildCommand(cmd, {
103
+ name: "build",
104
+ description: "Build a component",
105
+ options: [COMMON_OPTIONS.path, COMMON_OPTIONS.watch],
106
+ schema: ComponentBuildOptionsSchema,
107
+ examples: [
108
+ {
109
+ description: "Build current directory",
110
+ command: "ollieshop component build",
111
+ },
112
+ {
113
+ description: "Build specific component",
114
+ command: "ollieshop component build --path ./components/header",
115
+ },
116
+ {
117
+ description: "Build with watch mode",
118
+ command: "ollieshop component build --watch",
119
+ },
120
+ ],
121
+ handler: async (options, console) => {
122
+ await componentActions.buildComponent(
123
+ {
124
+ path: options.path || process.cwd(),
125
+ watch: options.watch ?? false,
126
+ },
127
+ console,
128
+ );
129
+ },
130
+ });
131
+
132
+ // Deploy component command
133
+ buildCommand(cmd, {
134
+ name: "deploy",
135
+ description: "Deploy a component",
136
+ options: [
137
+ {
138
+ flags: "--id <id>",
139
+ description: "Component ID",
140
+ required: true,
141
+ },
142
+ COMMON_OPTIONS.path,
143
+ {
144
+ flags: "--wait",
145
+ description: "Wait for deployment to complete",
146
+ defaultValue: false,
147
+ },
148
+ ],
149
+ schema: ComponentDeployOptionsSchema,
150
+ examples: [
151
+ {
152
+ description: "Deploy a component",
153
+ command: "ollieshop component deploy --id comp-123",
154
+ },
155
+ {
156
+ description: "Deploy and wait for completion",
157
+ command: "ollieshop component deploy --id comp-123 --wait",
158
+ },
159
+ ],
160
+ handler: async (options: ComponentDeployOptions, console) => {
161
+ // Map id to componentId if provided
162
+ const deployOptions = {
163
+ path: options.path,
164
+ componentId: options.id || options.componentId,
165
+ wait: options.wait,
166
+ };
167
+ await componentActions.deployComponent(deployOptions, console);
168
+ },
169
+ });
170
+
171
+ // List components command
172
+ buildCommand(cmd, {
173
+ name: "list",
174
+ description: "List all components",
175
+ aliases: ["ls"],
176
+ examples: [
177
+ {
178
+ description: "List all components",
179
+ command: "ollieshop component list",
180
+ },
181
+ ],
182
+ handler: async (_, console) => {
183
+ await componentActions.listComponents(console);
184
+ },
185
+ });
186
+
187
+ // Add more commands as needed
188
+ }
@@ -1,24 +1,24 @@
1
- import chalk from "chalk";
2
- import type { Command } from "commander";
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import { console as cliConsole } from "../utils/console";
3
3
 
4
4
  export function configureDocsCommand(program: Command): void {
5
5
  program
6
6
  .command("docs")
7
7
  .description("Show documentation links for Ollie Shop")
8
8
  .action(() => {
9
- console.log(chalk.cyanBright("\nOllie Shop Documentation\n"));
9
+ cliConsole.info("Ollie Shop Documentation\n");
10
10
 
11
- console.log(
12
- `${chalk.green("Main Docs:".padEnd(20))} https://docs.ollie.shop/ollie-shop`,
11
+ cliConsole.info(
12
+ `${"Main Docs:".padEnd(20)} https://docs.ollie.shop/ollie-shop`,
13
13
  );
14
- console.log(
15
- `${chalk.green("Components:".padEnd(20))} https://docs.ollie.shop/ollie-shop/concepts/component`,
14
+ cliConsole.info(
15
+ `${"Components:".padEnd(20)} https://docs.ollie.shop/ollie-shop/concepts/component`,
16
16
  );
17
- console.log(
18
- `${chalk.green("Functions:".padEnd(20))} https://docs.ollie.shop/ollie-shop/concepts/function`,
17
+ cliConsole.info(
18
+ `${"Functions:".padEnd(20)} https://docs.ollie.shop/ollie-shop/concepts/function`,
19
19
  );
20
- console.log(
21
- `${chalk.green("Versions:".padEnd(20))} https://docs.ollie.shop/ollie-shop/concepts/version\n`,
20
+ cliConsole.info(
21
+ `${"Versions:".padEnd(20)} https://docs.ollie.shop/ollie-shop/concepts/version\n`,
22
22
  );
23
23
  });
24
24
  }