@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,107 @@
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import {
3
+ buildProject,
4
+ initProject,
5
+ startDevServer,
6
+ validateProject,
7
+ } from "../actions/project.actions";
8
+ import { console as cliConsole } from "../utils/console";
9
+
10
+ export function registerProjectCommands(program: Command): void {
11
+ const projectCommand = program
12
+ .command("project")
13
+ .description("Project management commands");
14
+
15
+ projectCommand
16
+ .command("init")
17
+ .description("Initialize a new project")
18
+ .option("-n, --name <name>", "Project name")
19
+ .option("-t, --template <template>", "Project template")
20
+ .action(async (options) => {
21
+ try {
22
+ await initProject(
23
+ {
24
+ name: options.name,
25
+ template:
26
+ (options.template as
27
+ | "default"
28
+ | "grocery"
29
+ | "sales"
30
+ | undefined) || "default",
31
+ git: true,
32
+ install: true,
33
+ },
34
+ cliConsole,
35
+ );
36
+ } catch (error) {
37
+ cliConsole.error(
38
+ error instanceof Error ? error.message : "An error occurred",
39
+ );
40
+ process.exit(1);
41
+ }
42
+ });
43
+
44
+ projectCommand
45
+ .command("build")
46
+ .description("Build project")
47
+ .option("-p, --path <path>", "Project path")
48
+ .option("--watch", "Watch for changes")
49
+ .action(async (options) => {
50
+ try {
51
+ await buildProject(
52
+ {
53
+ path: options.path,
54
+ watch: options.watch ?? false,
55
+ },
56
+ cliConsole,
57
+ );
58
+ } catch (error) {
59
+ cliConsole.error(
60
+ error instanceof Error ? error.message : "An error occurred",
61
+ );
62
+ process.exit(1);
63
+ }
64
+ });
65
+
66
+ projectCommand
67
+ .command("dev")
68
+ .description("Start development server")
69
+ .option("-p, --port <port>", "Port number", Number.parseInt)
70
+ .option("--open", "Open browser")
71
+ .action(async (options) => {
72
+ try {
73
+ await startDevServer(
74
+ {
75
+ port: options.port ?? 3000,
76
+ open: options.open ?? false,
77
+ },
78
+ cliConsole,
79
+ );
80
+ } catch (error) {
81
+ cliConsole.error(
82
+ error instanceof Error ? error.message : "An error occurred",
83
+ );
84
+ process.exit(1);
85
+ }
86
+ });
87
+
88
+ projectCommand
89
+ .command("validate")
90
+ .description("Validate project")
91
+ .option("-p, --path <path>", "Project path")
92
+ .action(async (options) => {
93
+ try {
94
+ await validateProject(
95
+ {
96
+ path: options.path,
97
+ },
98
+ cliConsole,
99
+ );
100
+ } catch (error) {
101
+ cliConsole.error(
102
+ error instanceof Error ? error.message : "An error occurred",
103
+ );
104
+ process.exit(1);
105
+ }
106
+ });
107
+ }
@@ -0,0 +1,242 @@
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import { z } from "zod";
3
+ import * as versionActions from "../actions/version.actions";
4
+ import { buildCommand, buildCommandGroup } from "../utils/command-builder";
5
+ import { COMMON_OPTIONS, parseUUID } from "../utils/command-parser";
6
+ import { console as cliConsole } from "../utils/console";
7
+
8
+ const StoreVersionCreateOptionsSchema = z.object({
9
+ store: z.string().uuid("Invalid store ID format"),
10
+ name: z.string().min(1, "Version name is required"),
11
+ template: z.string().optional(),
12
+ active: z.boolean().optional(),
13
+ });
14
+
15
+ const StoreVersionListOptionsSchema = z.object({
16
+ store: z.string().uuid("Invalid store ID format"),
17
+ });
18
+
19
+ export function registerStoreVersionCommands(program: Command): void {
20
+ const cmd = buildCommandGroup(
21
+ program,
22
+ "store-version",
23
+ "Manage store versions",
24
+ ["sv"],
25
+ );
26
+
27
+ // Create version command
28
+ buildCommand(cmd, {
29
+ name: "create",
30
+ description: "Create a new version for a store",
31
+ options: [
32
+ COMMON_OPTIONS.storeId,
33
+ COMMON_OPTIONS.versionName,
34
+ COMMON_OPTIONS.template,
35
+ COMMON_OPTIONS.active,
36
+ COMMON_OPTIONS.noActive,
37
+ ],
38
+ schema: StoreVersionCreateOptionsSchema,
39
+ examples: [
40
+ {
41
+ description: "Create an active version",
42
+ command:
43
+ "ollieshop store-version create --store 123e4567-e89b-12d3-a456-426614174000 --name v2.0.0",
44
+ },
45
+ {
46
+ description: "Create version with grocery template",
47
+ command:
48
+ "ollieshop store-version create --store 123e4567-e89b-12d3-a456-426614174000 --name grocery-v1 --template grocery",
49
+ },
50
+ {
51
+ description: "Create inactive version for testing",
52
+ command:
53
+ "ollieshop store-version create --store 123e4567-e89b-12d3-a456-426614174000 --name test-version --no-active",
54
+ },
55
+ ],
56
+ handler: async (options) => {
57
+ await versionActions.create(options);
58
+ },
59
+ });
60
+
61
+ // List versions command
62
+ buildCommand(cmd, {
63
+ name: "list",
64
+ description: "List all versions for a store",
65
+ options: [COMMON_OPTIONS.storeId],
66
+ schema: StoreVersionListOptionsSchema,
67
+ examples: [
68
+ {
69
+ description: "List all versions for a store",
70
+ command:
71
+ "ollieshop store-version list --store 123e4567-e89b-12d3-a456-426614174000",
72
+ },
73
+ ],
74
+ handler: async (options) => {
75
+ await versionActions.list(options);
76
+ },
77
+ });
78
+
79
+ // Get version command with argument parser
80
+ const _getCmd = cmd
81
+ .command("get <versionId>")
82
+ .description("Get version details")
83
+ .addHelpText("after", "\nExamples:")
84
+ .addHelpText("after", " Get version details:")
85
+ .addHelpText(
86
+ "after",
87
+ " $ ollieshop store-version get 987fcdeb-51a2-43b7-9abc-123456789012",
88
+ )
89
+ .action(async (versionId) => {
90
+ try {
91
+ const validated = parseUUID(versionId);
92
+ await versionActions.get(validated);
93
+ } catch (error) {
94
+ if (error instanceof Error) {
95
+ cliConsole.error(`❌ ${error.message}`);
96
+ if (error.message.includes("UUID")) {
97
+ cliConsole.info("💡 Version IDs must be in UUID format");
98
+ cliConsole.log(" Example: 123e4567-e89b-12d3-a456-426614174000");
99
+ }
100
+ } else {
101
+ cliConsole.error(`Error: ${String(error)}`);
102
+ }
103
+ process.exit(1);
104
+ }
105
+ });
106
+
107
+ // Set default version command
108
+ const _setDefaultCmd = cmd
109
+ .command("set-default <versionId>")
110
+ .description("Set a version as the default for the store")
111
+ .addHelpText("after", "\nExamples:")
112
+ .addHelpText("after", " Set version as default:")
113
+ .addHelpText(
114
+ "after",
115
+ " $ ollieshop store-version set-default 987fcdeb-51a2-43b7-9abc-123456789012",
116
+ )
117
+ .action(async (versionId) => {
118
+ try {
119
+ const validated = parseUUID(versionId);
120
+ await versionActions.setDefault(validated);
121
+ } catch (error) {
122
+ if (error instanceof Error) {
123
+ cliConsole.error(`❌ ${error.message}`);
124
+ } else {
125
+ cliConsole.error(`Error: ${String(error)}`);
126
+ }
127
+ process.exit(1);
128
+ }
129
+ });
130
+
131
+ // Activate version command
132
+ const _activateCmd = cmd
133
+ .command("activate <versionId>")
134
+ .description("Activate a version")
135
+ .addHelpText("after", "\nExamples:")
136
+ .addHelpText("after", " Activate a version:")
137
+ .addHelpText(
138
+ "after",
139
+ " $ ollieshop store-version activate 987fcdeb-51a2-43b7-9abc-123456789012",
140
+ )
141
+ .action(async (versionId) => {
142
+ try {
143
+ const validated = parseUUID(versionId);
144
+ await versionActions.activate(validated);
145
+ } catch (error) {
146
+ if (error instanceof Error) {
147
+ cliConsole.error(`❌ ${error.message}`);
148
+ } else {
149
+ cliConsole.error(`Error: ${String(error)}`);
150
+ }
151
+ process.exit(1);
152
+ }
153
+ });
154
+
155
+ // Deactivate version command
156
+ const _deactivateCmd = cmd
157
+ .command("deactivate <versionId>")
158
+ .description("Deactivate a version")
159
+ .addHelpText("after", "\nExamples:")
160
+ .addHelpText("after", " Deactivate a version:")
161
+ .addHelpText(
162
+ "after",
163
+ " $ ollieshop store-version deactivate 987fcdeb-51a2-43b7-9abc-123456789012",
164
+ )
165
+ .action(async (versionId) => {
166
+ try {
167
+ const validated = parseUUID(versionId);
168
+ await versionActions.deactivate(validated);
169
+ } catch (error) {
170
+ if (error instanceof Error) {
171
+ cliConsole.error(`❌ ${error.message}`);
172
+ } else {
173
+ cliConsole.error(`Error: ${String(error)}`);
174
+ }
175
+ process.exit(1);
176
+ }
177
+ });
178
+
179
+ // Clone version command
180
+ const _cloneCmd = cmd
181
+ .command("clone <versionId>")
182
+ .description("Clone an existing version")
183
+ .requiredOption(
184
+ "-n, --name <name>",
185
+ "Name for the cloned version",
186
+ COMMON_OPTIONS.versionName.parser,
187
+ )
188
+ .addHelpText("after", "\nExamples:")
189
+ .addHelpText("after", " Clone a version:")
190
+ .addHelpText(
191
+ "after",
192
+ " $ ollieshop store-version clone 987fcdeb-51a2-43b7-9abc-123456789012 --name v2.1.0",
193
+ )
194
+ .addHelpText("after", "\n Clone for A/B testing:")
195
+ .addHelpText(
196
+ "after",
197
+ " $ ollieshop store-version clone 987fcdeb-51a2-43b7-9abc-123456789012 --name experiment-checkout",
198
+ )
199
+ .action(async (versionId, options) => {
200
+ try {
201
+ const validatedId = parseUUID(versionId);
202
+ await versionActions.clone(validatedId, options.name);
203
+ } catch (error) {
204
+ if (error instanceof Error) {
205
+ cliConsole.error(`❌ ${error.message}`);
206
+ } else {
207
+ cliConsole.error(`Error: ${String(error)}`);
208
+ }
209
+ process.exit(1);
210
+ }
211
+ });
212
+
213
+ // Delete version command
214
+ const _deleteCmd = cmd
215
+ .command("delete <versionId>")
216
+ .description("Delete a version")
217
+ .option("-f, --force", "Skip confirmation")
218
+ .addHelpText("after", "\nExamples:")
219
+ .addHelpText("after", " Delete with confirmation:")
220
+ .addHelpText(
221
+ "after",
222
+ " $ ollieshop store-version delete 987fcdeb-51a2-43b7-9abc-123456789012",
223
+ )
224
+ .addHelpText("after", "\n Delete without confirmation:")
225
+ .addHelpText(
226
+ "after",
227
+ " $ ollieshop store-version delete 987fcdeb-51a2-43b7-9abc-123456789012 --force",
228
+ )
229
+ .action(async (versionId, options) => {
230
+ try {
231
+ const validated = parseUUID(versionId);
232
+ await versionActions.deleteVersion(validated, options.force);
233
+ } catch (error) {
234
+ if (error instanceof Error) {
235
+ cliConsole.error(`❌ ${error.message}`);
236
+ } else {
237
+ cliConsole.error(`Error: ${String(error)}`);
238
+ }
239
+ process.exit(1);
240
+ }
241
+ });
242
+ }
@@ -1,14 +1,51 @@
1
- import chalk from "chalk";
2
- import type { Command } from "commander";
3
- import { pkg } from "../utils/core";
1
+ import type { Command } from "@commander-js/extra-typings";
2
+ import { console as cliConsole } from "../utils/console";
3
+
4
+ const pkg = require("../../package.json");
4
5
 
5
6
  export function configureVersionCommand(program: Command): void {
7
+ // Simple version command
6
8
  program
7
9
  .command("version")
8
- .description("Display the current CLI version")
9
- .action(() => {
10
- console.log(
11
- `${chalk.bold("Ollie Shop CLI version:")} ${chalk.cyan(pkg.version)}\n`,
12
- );
10
+ .alias("v")
11
+ .description("Display CLI version and environment information")
12
+ .option("-d, --detailed", "Show detailed version information", false)
13
+ .option("-j, --json", "Output version information as JSON", false)
14
+ .action(async (options) => {
15
+ if (options.json) {
16
+ const versionInfo = {
17
+ cli: pkg.version,
18
+ node: process.version,
19
+ platform: process.platform,
20
+ arch: process.arch,
21
+ };
22
+ console.log(JSON.stringify(versionInfo, null, 2));
23
+ return;
24
+ }
25
+
26
+ cliConsole.info(`Ollie Shop CLI version: ${pkg.version}`);
27
+
28
+ if (options.detailed) {
29
+ cliConsole.log("");
30
+ cliConsole.log("Environment:");
31
+ cliConsole.log(` Node.js: ${process.version}`);
32
+ cliConsole.log(` Platform: ${process.platform}`);
33
+ cliConsole.log(` Architecture: ${process.arch}`);
34
+
35
+ // Check for core package version
36
+ try {
37
+ const corePkg = require("@ollie-shop/core/package.json");
38
+ cliConsole.log(` Core: v${corePkg.version}`);
39
+ } catch {
40
+ // Core package might not be available
41
+ }
42
+
43
+ cliConsole.log("");
44
+ cliConsole.log("For help, run: ollieshop --help");
45
+ cliConsole.log("Documentation: https://docs.ollie.shop");
46
+ cliConsole.log(
47
+ "Report issues: https://github.com/ollie-shop/cli/issues",
48
+ );
49
+ }
13
50
  });
14
51
  }
@@ -1,16 +1,15 @@
1
- import chalk from "chalk";
2
- import type { Command } from "commander";
1
+ import type { Command } from "@commander-js/extra-typings";
3
2
  import { getCurrentUser } from "../utils/auth";
3
+ import { console as cliConsole } from "../utils/console";
4
4
  import { type OllieConfig, getOllieConfig } from "../utils/store";
5
5
 
6
- // Reads credentials from ~/.ollie-shop/credentials.json
7
6
  async function getUserInfo(): Promise<{ email?: string; store?: OllieConfig }> {
8
7
  try {
9
8
  const user = await getCurrentUser();
10
9
  const store = await getOllieConfig();
11
10
 
12
11
  if (!user || !user.email) {
13
- console.log("No user authenticated");
12
+ cliConsole.error("No user authenticated");
14
13
  return {};
15
14
  }
16
15
 
@@ -31,21 +30,17 @@ export function configureWhoamiCommand(program: Command) {
31
30
  const { email, store } = await getUserInfo();
32
31
 
33
32
  if (!email) {
34
- console.log(chalk.red("You are not authenticated"));
33
+ cliConsole.error("You are not authenticated");
35
34
  return;
36
35
  }
37
36
 
38
- console.log();
39
- console.log(
40
- `${chalk.bold("You are logged in as:")} ${chalk.cyan(email)}`,
41
- );
37
+ cliConsole.newLine();
38
+ cliConsole.info(`You are logged in as: ${email}`);
42
39
 
43
40
  if (store) {
44
- console.log(
45
- `${chalk.bold("Current store:")} ${chalk.cyan(store.platformStoreId ?? "unknown")}`,
46
- );
41
+ cliConsole.info(`Current store: ${store.platformStoreId ?? "unknown"}`);
47
42
  }
48
43
 
49
- console.log();
44
+ cliConsole.newLine();
50
45
  });
51
46
  }
package/src/index.ts CHANGED
@@ -1,42 +1,116 @@
1
- import { Command } from "commander";
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from "@commander-js/extra-typings";
4
+ import packageJson from "../package.json";
2
5
  import { registerCommands } from "./commands";
3
6
  import {
4
- checkForUpdates,
5
- pkg,
6
- showWelcomeMessage,
7
- validateProjectLocation,
8
- } from "./utils/core";
9
-
10
- /**
11
- * Creates and configures the CLI program instance
12
- */
13
- export function createProgram() {
14
- const program = new Command();
15
-
16
- program
17
- .name("ollieshop")
18
- .description("Ollie Shop CLI tools")
19
- .version(pkg.version);
20
-
21
- // Register CLI commands from external modules
22
- registerCommands(program);
23
-
24
- return program;
25
- }
7
+ type GlobalOptions,
8
+ GlobalOptionsSchema,
9
+ } from "./schemas/command.schema";
10
+ import { console as cliConsole } from "./utils/console";
11
+
12
+ class OllieShopCLI {
13
+ private program = new Command();
14
+
15
+ constructor() {
16
+ this.setupProgram();
17
+ this.registerCommands();
18
+ }
19
+
20
+ private setupProgram(): void {
21
+ this.program
22
+ .name("ollieshop")
23
+ .description(
24
+ "Ollie Shop CLI - Build and manage your e-commerce components and functions",
25
+ )
26
+ .version(packageJson.version)
27
+ .option("-v, --verbose", "Enable verbose logging", false)
28
+ .option("-q, --quiet", "Suppress non-essential output", false)
29
+ .option("--no-color", "Disable colored output", false)
30
+ .option("-c, --config <path>", "Path to configuration file")
31
+ .option(
32
+ "--log-level <level>",
33
+ "Set log level (error|warn|info|debug)",
34
+ "info",
35
+ )
36
+ .hook("preAction", (thisCommand: Command) => {
37
+ this.setupGlobalOptions(thisCommand);
38
+ });
39
+ }
40
+
41
+ private setupGlobalOptions(thisCommand: Command): void {
42
+ try {
43
+ const options = thisCommand.opts();
44
+ const parsedOptions = this.validateGlobalOptions(options);
26
45
 
27
- // If this file is executed directly, initialize the CLI
28
- if (require.main === module) {
29
- (async () => {
30
- const program = createProgram();
46
+ cliConsole.setOptions({
47
+ quiet: parsedOptions.quiet,
48
+ verbose: parsedOptions.verbose,
49
+ noColor: !parsedOptions.color, // --no-color sets color to false
50
+ });
31
51
 
32
- if (process.argv.length <= 2) {
33
- await checkForUpdates();
34
- showWelcomeMessage();
35
- process.exit(0);
52
+ if (parsedOptions.verbose) {
53
+ process.env.DEBUG = "ollieshop:*";
54
+ }
55
+ } catch (error) {
56
+ cliConsole.error("Invalid global options:");
57
+ if (error instanceof Error) {
58
+ cliConsole.error(error.message);
59
+ }
60
+ process.exit(1);
36
61
  }
62
+ }
37
63
 
38
- validateProjectLocation();
64
+ private validateGlobalOptions(options: unknown): GlobalOptions {
65
+ const result = GlobalOptionsSchema.safeParse(options);
66
+ if (!result.success) {
67
+ const errors = result.error.issues.map(
68
+ (issue) => `${issue.path.join(".")}: ${issue.message}`,
69
+ );
70
+ throw new Error(errors.join("\n"));
71
+ }
72
+ return result.data;
73
+ }
74
+
75
+ private registerCommands(): void {
76
+ try {
77
+ registerCommands(this.program);
78
+ } catch (error) {
79
+ cliConsole.error("Failed to register commands:");
80
+ if (error instanceof Error) {
81
+ cliConsole.error(error.message);
82
+ }
83
+ process.exit(1);
84
+ }
85
+ }
39
86
 
40
- program.parse();
41
- })();
87
+ async run(): Promise<void> {
88
+ try {
89
+ // Show command suggestions if no args provided
90
+ if (process.argv.length <= 2) {
91
+ const { showCommandSuggestions } = await import(
92
+ "./utils/command-suggestions.js"
93
+ );
94
+ showCommandSuggestions(cliConsole);
95
+ return;
96
+ }
97
+
98
+ await this.program.parseAsync();
99
+ } catch (error) {
100
+ cliConsole.error("CLI execution failed:");
101
+ if (error instanceof Error) {
102
+ cliConsole.error(error.message);
103
+ if (process.env.DEBUG) {
104
+ cliConsole.info(`Stack trace: ${error.stack || ""}`);
105
+ }
106
+ }
107
+ process.exit(1);
108
+ }
109
+ }
42
110
  }
111
+
112
+ const cli = new OllieShopCLI();
113
+ cli.run().catch((error) => {
114
+ cliConsole.error(`Unexpected error: ${error}`);
115
+ process.exit(1);
116
+ });