@ollie-shop/cli 0.3.4 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.turbo/turbo-build.log +6 -9
  2. package/CHANGELOG.md +27 -0
  3. package/dist/index.js +993 -3956
  4. package/package.json +15 -37
  5. package/src/README.md +126 -0
  6. package/src/cli.tsx +45 -0
  7. package/src/commands/help.tsx +79 -0
  8. package/src/commands/login.tsx +92 -0
  9. package/src/commands/start.tsx +411 -0
  10. package/src/index.tsx +8 -0
  11. package/src/utils/auth.ts +218 -21
  12. package/src/utils/bundle.ts +177 -0
  13. package/src/utils/config.ts +123 -0
  14. package/src/utils/esbuild.ts +541 -0
  15. package/tsconfig.json +10 -15
  16. package/tsup.config.ts +7 -7
  17. package/CLAUDE_CLI.md +0 -265
  18. package/README.md +0 -711
  19. package/__tests__/mocks/console.ts +0 -22
  20. package/__tests__/mocks/core.ts +0 -137
  21. package/__tests__/mocks/index.ts +0 -4
  22. package/__tests__/mocks/inquirer.ts +0 -16
  23. package/__tests__/mocks/progress.ts +0 -19
  24. package/dist/index.d.ts +0 -1
  25. package/src/__tests__/helpers/cli-test-helper.ts +0 -281
  26. package/src/__tests__/mocks/index.ts +0 -142
  27. package/src/actions/component.actions.ts +0 -278
  28. package/src/actions/function.actions.ts +0 -220
  29. package/src/actions/project.actions.ts +0 -131
  30. package/src/actions/version.actions.ts +0 -233
  31. package/src/commands/__tests__/component-validation.test.ts +0 -250
  32. package/src/commands/__tests__/component.test.ts +0 -318
  33. package/src/commands/__tests__/function-validation.test.ts +0 -220
  34. package/src/commands/__tests__/function.test.ts +0 -286
  35. package/src/commands/__tests__/store-version-validation.test.ts +0 -414
  36. package/src/commands/__tests__/store-version.test.ts +0 -402
  37. package/src/commands/component.ts +0 -178
  38. package/src/commands/docs.ts +0 -24
  39. package/src/commands/function.ts +0 -201
  40. package/src/commands/help.ts +0 -18
  41. package/src/commands/index.ts +0 -27
  42. package/src/commands/login.ts +0 -267
  43. package/src/commands/project.ts +0 -107
  44. package/src/commands/store-version.ts +0 -242
  45. package/src/commands/version.ts +0 -51
  46. package/src/commands/whoami.ts +0 -46
  47. package/src/index.ts +0 -116
  48. package/src/prompts/component.prompts.ts +0 -94
  49. package/src/prompts/function.prompts.ts +0 -168
  50. package/src/schemas/command.schema.ts +0 -644
  51. package/src/types/index.ts +0 -183
  52. package/src/utils/__tests__/command-parser.test.ts +0 -159
  53. package/src/utils/__tests__/command-suggestions.test.ts +0 -185
  54. package/src/utils/__tests__/console.test.ts +0 -192
  55. package/src/utils/__tests__/context-detector.test.ts +0 -258
  56. package/src/utils/__tests__/enhanced-error-handler.test.ts +0 -137
  57. package/src/utils/__tests__/error-handler.test.ts +0 -107
  58. package/src/utils/__tests__/rich-progress.test.ts +0 -181
  59. package/src/utils/__tests__/validation-error-formatter.test.ts +0 -175
  60. package/src/utils/__tests__/validation-helpers.test.ts +0 -125
  61. package/src/utils/cli-progress-reporter.ts +0 -84
  62. package/src/utils/command-builder.ts +0 -390
  63. package/src/utils/command-helpers.ts +0 -83
  64. package/src/utils/command-parser.ts +0 -245
  65. package/src/utils/command-suggestions.ts +0 -176
  66. package/src/utils/console.ts +0 -320
  67. package/src/utils/constants.ts +0 -39
  68. package/src/utils/context-detector.ts +0 -177
  69. package/src/utils/deploy-helpers.ts +0 -357
  70. package/src/utils/enhanced-error-handler.ts +0 -264
  71. package/src/utils/error-handler.ts +0 -60
  72. package/src/utils/errors.ts +0 -256
  73. package/src/utils/interactive-builder.ts +0 -325
  74. package/src/utils/rich-progress.ts +0 -331
  75. package/src/utils/store.ts +0 -23
  76. package/src/utils/validation-error-formatter.ts +0 -337
  77. package/src/utils/validation-helpers.ts +0 -325
  78. package/vitest.config.ts +0 -35
  79. package/vitest.setup.ts +0 -29
@@ -1,278 +0,0 @@
1
- import {
2
- buildAndDeployComponentFromDirectory,
3
- buildComponent as buildComponentService,
4
- createComponent as createComponentService,
5
- validateComponent as validateComponentService,
6
- } from "@ollie-shop/core";
7
- import type {
8
- ComponentCreateOptions,
9
- ComponentDeployOptions,
10
- ComponentValidateOptions,
11
- } from "../schemas/command.schema";
12
- import type { CliConsole } from "../utils/console";
13
- import { ERROR_MESSAGES } from "../utils/constants";
14
- import { getContextualPath } from "../utils/context-detector.js";
15
- import {
16
- configureBuilderUrl,
17
- handleDeploymentError,
18
- handleDeploymentResult,
19
- showDeploymentSuccess,
20
- waitForDeploymentWithProgress,
21
- } from "../utils/deploy-helpers";
22
- import { handleValidationResult } from "../utils/validation-helpers";
23
-
24
- /**
25
- * Create a new component from a template
26
- * Generates component files with TypeScript setup and optional tests
27
- *
28
- * @async
29
- * @param {ComponentCreateOptions} options - Component creation options
30
- * @param {CliConsole} cliConsole - Console instance for output
31
- * @throws {Error} If component name is not provided or creation fails
32
- * @example
33
- * ```typescript
34
- * await createComponent({
35
- * name: "shopping-cart",
36
- * slot: "sidebar",
37
- * tests: true
38
- * }, console);
39
- * ```
40
- */
41
- export async function createComponent(
42
- options: ComponentCreateOptions,
43
- cliConsole: CliConsole,
44
- ): Promise<void> {
45
- const spinner = cliConsole.spinner({
46
- text: "Creating component...",
47
- });
48
-
49
- try {
50
- if (!options.name) {
51
- throw new Error("Component name is required");
52
- }
53
-
54
- const result = await createComponentService({
55
- name: options.name,
56
- slot: options.slot || "main",
57
- typescript: true, // Always use TypeScript
58
- includeTests: options.tests ?? true,
59
- });
60
-
61
- spinner.succeed(`Component created successfully at ${result}`);
62
-
63
- cliConsole.nextSteps("Next steps", [
64
- {
65
- description: "Navigate to component directory",
66
- command: `cd ${result}`,
67
- },
68
- {
69
- description: "Install dependencies",
70
- command: "npm install",
71
- },
72
- {
73
- description: "Start development",
74
- command: "npm run dev",
75
- },
76
- {
77
- description: "Deploy component",
78
- command: "ollieshop component deploy --id <id>",
79
- },
80
- ]);
81
- } catch (error) {
82
- spinner.fail("Failed to create component");
83
- const { message, stack } =
84
- error instanceof Error
85
- ? error
86
- : { message: "Unexpected error", stack: undefined };
87
- cliConsole.error(`Error details: ${message}`);
88
- if (stack) {
89
- cliConsole.debug(`Stack trace: ${stack}`);
90
- }
91
- throw error;
92
- }
93
- }
94
-
95
- /**
96
- * Validate a component's structure and configuration
97
- * Checks for required files, proper exports, and valid metadata
98
- *
99
- * @async
100
- * @param {ComponentValidateOptions} options - Validation options including path
101
- * @param {CliConsole} cliConsole - Console instance for output
102
- * @throws {Error} If validation fails or path is invalid
103
- * @example
104
- * ```typescript
105
- * await validateComponent({
106
- * path: "./components/shopping-cart"
107
- * }, console);
108
- * ```
109
- */
110
- export async function validateComponent(
111
- options: ComponentValidateOptions,
112
- cliConsole: CliConsole,
113
- ): Promise<void> {
114
- const targetPath = getContextualPath(options.path, "component");
115
- const spinner = cliConsole.spinner({ text: "Validating component..." });
116
-
117
- try {
118
- const result = await validateComponentService(targetPath);
119
- handleValidationResult(result, spinner, cliConsole, "Component");
120
- } catch (error) {
121
- spinner.fail("Validation failed");
122
- const { message, stack } =
123
- error instanceof Error
124
- ? error
125
- : { message: "Unexpected error", stack: undefined };
126
- cliConsole.error(`Error details: ${message}`);
127
- if (stack) {
128
- cliConsole.debug(`Stack trace: ${stack}`);
129
- }
130
- throw error;
131
- }
132
- }
133
-
134
- /**
135
- * Build a component for production deployment
136
- * Bundles the component with optimizations and outputs build metrics
137
- *
138
- * @async
139
- * @param {Object} options - Build options
140
- * @param {string} [options.path] - Component path (defaults to current directory)
141
- * @param {boolean} [options.watch] - Enable watch mode for development
142
- * @param {CliConsole} cliConsole - Console instance for output
143
- * @throws {Error} If build fails
144
- * @example
145
- * ```typescript
146
- * await buildComponent({
147
- * path: "./components/shopping-cart",
148
- * watch: false
149
- * }, console);
150
- * ```
151
- */
152
- export async function buildComponent(
153
- options: { path?: string; watch?: boolean },
154
- cliConsole: CliConsole,
155
- ): Promise<void> {
156
- const targetPath = getContextualPath(options.path, "component");
157
- const spinner = cliConsole.spinner({ text: "Building component..." });
158
-
159
- try {
160
- if (options.watch) {
161
- cliConsole.info("Watching for changes...");
162
- }
163
-
164
- const result = await buildComponentService(targetPath);
165
-
166
- spinner.succeed("Component built successfully!");
167
- if (result.outputPath) {
168
- cliConsole.info(`Output: ${result.outputPath}`);
169
- }
170
- if (result.size) {
171
- cliConsole.info(`Size: ${(result.size / 1024).toFixed(2)} KB`);
172
- }
173
- if (result.duration) {
174
- cliConsole.info(`Duration: ${(result.duration / 1000).toFixed(2)}s`);
175
- }
176
-
177
- if (result.warnings && result.warnings.length > 0) {
178
- cliConsole.warn("Build warnings:");
179
- for (const warning of result.warnings) {
180
- cliConsole.warn(` - ${warning}`);
181
- }
182
- }
183
- } catch (error) {
184
- spinner.fail("Build failed");
185
- throw error;
186
- }
187
- }
188
-
189
- /**
190
- * Deploy a component to the Ollie Shop infrastructure
191
- * Builds and uploads the component to CloudFront CDN with real-time progress
192
- *
193
- * @async
194
- * @param {ComponentDeployOptions} options - Deployment options
195
- * @param {CliConsole} cliConsole - Console instance for output
196
- * @throws {Error} If component ID is not provided or deployment fails
197
- * @example
198
- * ```typescript
199
- * await deployComponent({
200
- * componentId: "123e4567-e89b-12d3-a456-426614174000",
201
- * path: "./components/shopping-cart"
202
- * }, console);
203
- * ```
204
- */
205
- export async function deployComponent(
206
- options: ComponentDeployOptions,
207
- cliConsole: CliConsole,
208
- ): Promise<void> {
209
- if (!options.componentId) {
210
- throw new Error(ERROR_MESSAGES.COMPONENT_ID_REQUIRED);
211
- }
212
-
213
- configureBuilderUrl();
214
-
215
- const spinner = cliConsole.spinner({
216
- text: "Preparing component for deployment...",
217
- });
218
-
219
- try {
220
- const componentPath = options.path || process.cwd();
221
- const result = await buildAndDeployComponentFromDirectory(
222
- options.componentId,
223
- componentPath,
224
- );
225
-
226
- handleDeploymentResult(result, "component", cliConsole, spinner);
227
- spinner.stop();
228
-
229
- try {
230
- const { completedBuild, duration } = await waitForDeploymentWithProgress(
231
- result.buildId,
232
- "component",
233
- cliConsole,
234
- );
235
-
236
- showDeploymentSuccess(
237
- completedBuild,
238
- duration,
239
- options.componentId,
240
- "component",
241
- cliConsole,
242
- );
243
- } catch (error) {
244
- handleDeploymentError(error, result.buildId, "component", cliConsole);
245
- throw error;
246
- }
247
- } catch (error) {
248
- if (spinner.isSpinning) {
249
- spinner.fail("Deployment failed");
250
- }
251
- throw error;
252
- }
253
- }
254
-
255
- // checkDeployStatus function removed - no longer needed since deployments always wait for completion
256
-
257
- /**
258
- * List all components for the current store
259
- * Currently displays information about accessing components via admin dashboard
260
- *
261
- * @async
262
- * @param {CliConsole} cliConsole - Console instance for output
263
- * @example
264
- * ```typescript
265
- * await listComponents(console);
266
- * // Shows suggestions for creating and managing components
267
- * ```
268
- */
269
- export async function listComponents(cliConsole: CliConsole): Promise<void> {
270
- cliConsole.info(
271
- "Component listing is currently only available through the admin dashboard.",
272
- );
273
- cliConsole.suggestions([
274
- "Create your first component with: ollieshop component create",
275
- "Deploy components with: ollieshop component deploy --id <component-id>",
276
- "Visit the admin dashboard to view existing components",
277
- ]);
278
- }
@@ -1,220 +0,0 @@
1
- import {
2
- buildAndDeployFunctionFromDirectory,
3
- buildFunction as buildFunctionService,
4
- createFunction as createFunctionService,
5
- testFunction as testFunctionService,
6
- validateFunction as validateFunctionService,
7
- } from "@ollie-shop/core";
8
- import type {
9
- FunctionBuildOptions,
10
- FunctionCreateOptions,
11
- FunctionDeployOptions,
12
- FunctionTestOptions,
13
- } from "../schemas/command.schema";
14
- import type { CliConsole } from "../utils/console";
15
- import { ERROR_MESSAGES } from "../utils/constants";
16
- import { getContextualPath } from "../utils/context-detector.js";
17
- import {
18
- configureBuilderUrl,
19
- handleDeploymentError,
20
- handleDeploymentResult,
21
- showDeploymentSuccess,
22
- waitForDeploymentWithProgress,
23
- } from "../utils/deploy-helpers";
24
- import { handleValidationResult } from "../utils/validation-helpers";
25
-
26
- export async function createFunction(
27
- options: FunctionCreateOptions,
28
- cliConsole: CliConsole,
29
- ): Promise<void> {
30
- const spinner = cliConsole.spinner({
31
- text: "Creating function...",
32
- });
33
-
34
- try {
35
- const result = await createFunctionService({
36
- name: options.name || "my-function",
37
- invocation: options.invocation || "request",
38
- priority: options.priority || 50,
39
- onError: options.onError || "throw",
40
- typescript: true, // Always use TypeScript
41
- includeTests: options.tests ?? true,
42
- description: options.description,
43
- });
44
-
45
- spinner.succeed(`Function created successfully at ${result}`);
46
-
47
- cliConsole.nextSteps("Next steps", [
48
- {
49
- description: "Navigate to function directory",
50
- command: `cd ${result}`,
51
- },
52
- {
53
- description: "Install dependencies",
54
- command: "npm install",
55
- },
56
- {
57
- description: "Test function",
58
- command: "npm test",
59
- },
60
- {
61
- description: "Deploy function",
62
- command: "ollieshop function deploy",
63
- },
64
- ]);
65
- } catch (error) {
66
- spinner.fail("Failed to create function");
67
- const { message, stack } =
68
- error instanceof Error
69
- ? error
70
- : { message: "Unexpected error", stack: undefined };
71
- cliConsole.error(`Error details: ${message}`);
72
- if (stack) {
73
- cliConsole.debug(`Stack trace: ${stack}`);
74
- }
75
- throw error;
76
- }
77
- }
78
-
79
- export async function buildFunction(
80
- options: FunctionBuildOptions,
81
- cliConsole: CliConsole,
82
- ): Promise<void> {
83
- const targetPath = getContextualPath(options.path, "function");
84
- const spinner = cliConsole.spinner({ text: "Building function..." });
85
-
86
- try {
87
- if (options.watch) {
88
- cliConsole.info("Watching for changes...");
89
- }
90
-
91
- const result = await buildFunctionService(targetPath);
92
-
93
- spinner.succeed("Function built successfully!");
94
- if (typeof result === "object" && "outputPath" in result) {
95
- cliConsole.info(`Output: ${result.outputPath || targetPath}`);
96
- }
97
- } catch (error) {
98
- spinner.fail("Build failed");
99
- throw error;
100
- }
101
- }
102
-
103
- export async function testFunction(
104
- options: FunctionTestOptions,
105
- cliConsole: CliConsole,
106
- ): Promise<void> {
107
- const targetPath = getContextualPath(options.path, "function");
108
- const spinner = cliConsole.spinner({ text: "Testing function..." });
109
-
110
- try {
111
- if (options.watch) {
112
- cliConsole.info("Running tests in watch mode...");
113
- }
114
-
115
- const result = await testFunctionService(targetPath, {
116
- watch: options.watch,
117
- });
118
-
119
- spinner.succeed("Function tests completed!");
120
- if (typeof result === "object" && "summary" in result) {
121
- cliConsole.info(`Test summary: ${result.summary}`);
122
- }
123
- } catch (error) {
124
- spinner.fail("Tests failed");
125
- const { message, stack } =
126
- error instanceof Error
127
- ? error
128
- : { message: "Unexpected error", stack: undefined };
129
- cliConsole.error(`Error details: ${message}`);
130
- if (stack) {
131
- cliConsole.debug(`Stack trace: ${stack}`);
132
- }
133
- throw error;
134
- }
135
- }
136
-
137
- export async function validateFunction(
138
- options: { path?: string; strict?: boolean; fix?: boolean },
139
- cliConsole: CliConsole,
140
- ): Promise<void> {
141
- const targetPath = getContextualPath(options.path, "function");
142
- const spinner = cliConsole.spinner({ text: "Validating function..." });
143
-
144
- try {
145
- const result = await validateFunctionService(targetPath);
146
- handleValidationResult(result, spinner, cliConsole, "Function");
147
- } catch (error) {
148
- spinner.fail("Validation failed");
149
- const { message, stack } =
150
- error instanceof Error
151
- ? error
152
- : { message: "Unexpected error", stack: undefined };
153
- cliConsole.error(`Error details: ${message}`);
154
- if (stack) {
155
- cliConsole.debug(`Stack trace: ${stack}`);
156
- }
157
- throw error;
158
- }
159
- }
160
-
161
- export async function deployFunction(
162
- options: FunctionDeployOptions,
163
- cliConsole: CliConsole,
164
- ): Promise<void> {
165
- if (!options.functionId) {
166
- throw new Error(ERROR_MESSAGES.FUNCTION_ID_REQUIRED);
167
- }
168
-
169
- configureBuilderUrl();
170
-
171
- const spinner = cliConsole.spinner({
172
- text: "Preparing function for deployment...",
173
- });
174
-
175
- try {
176
- const functionPath = options.path || process.cwd();
177
- const result = await buildAndDeployFunctionFromDirectory(
178
- options.functionId,
179
- functionPath,
180
- );
181
-
182
- handleDeploymentResult(result, "function", cliConsole, spinner);
183
- spinner.stop();
184
-
185
- try {
186
- const { completedBuild, duration } = await waitForDeploymentWithProgress(
187
- result.buildId,
188
- "function",
189
- cliConsole,
190
- );
191
-
192
- showDeploymentSuccess(
193
- completedBuild,
194
- duration,
195
- options.functionId,
196
- "function",
197
- cliConsole,
198
- );
199
- } catch (error) {
200
- handleDeploymentError(error, result.buildId, "function", cliConsole);
201
- throw error;
202
- }
203
- } catch (error) {
204
- if (spinner.isSpinning) {
205
- spinner.fail("Deployment failed");
206
- }
207
- throw error;
208
- }
209
- }
210
-
211
- export async function listFunctions(cliConsole: CliConsole): Promise<void> {
212
- cliConsole.info(
213
- "Function listing is currently only available through the admin dashboard.",
214
- );
215
- cliConsole.suggestions([
216
- "Create your first function with: ollieshop function create",
217
- "Deploy functions with: ollieshop function deploy --id <function-id>",
218
- "Visit the admin dashboard to view existing functions",
219
- ]);
220
- }
@@ -1,131 +0,0 @@
1
- import type { InitOptions } from "../schemas/command.schema";
2
- import type { CliConsole } from "../utils/console";
3
- import { handleValidationResult } from "../utils/validation-helpers";
4
-
5
- export async function initProject(
6
- options: InitOptions,
7
- cliConsole: CliConsole,
8
- ): Promise<void> {
9
- // Lazy import - only loaded when this function is called
10
- const { initProject: initProjectService } = await import("@ollie-shop/core");
11
-
12
- const spinner = cliConsole.spinner({
13
- text: "Initializing project...",
14
- });
15
-
16
- try {
17
- // Map our template names to core service expected names
18
- const templateMap = {
19
- default: "default",
20
- grocery: "grocery",
21
- sales: "sales",
22
- } as const;
23
-
24
- const coreTemplate =
25
- templateMap[options.template as keyof typeof templateMap] || "default";
26
-
27
- const result = await initProjectService({
28
- name: options.name || "my-ollie-shop",
29
- template: coreTemplate,
30
- typescript: true, // Always use TypeScript
31
- git: options.git ?? true,
32
- installDeps: options.install ?? true,
33
- components: [],
34
- platformStoreId: "local",
35
- platform: "custom",
36
- });
37
-
38
- spinner.succeed("Project initialized successfully!");
39
- cliConsole.success(`Project created at: ${result.projectPath}`);
40
-
41
- if (options.git) {
42
- cliConsole.info("Git repository initialized");
43
- }
44
-
45
- cliConsole.nextSteps("Next steps", [
46
- {
47
- description: "Navigate to project directory",
48
- command: `cd ${result.projectPath}`,
49
- },
50
- {
51
- description: "Install dependencies",
52
- command: "npm install",
53
- },
54
- {
55
- description: "Start development server",
56
- command: "npm run dev",
57
- },
58
- ]);
59
- } catch (error) {
60
- spinner.fail("Failed to initialize project");
61
- throw error;
62
- }
63
- }
64
-
65
- export async function validateProject(
66
- options: { path?: string; strict?: boolean; fix?: boolean },
67
- cliConsole: CliConsole,
68
- ): Promise<void> {
69
- // Lazy import - only loaded when this function is called
70
- const { validateProject: validateProjectService } = await import(
71
- "@ollie-shop/core"
72
- );
73
-
74
- const targetPath = options.path || process.cwd();
75
- const spinner = cliConsole.spinner({ text: "Validating project..." });
76
-
77
- try {
78
- const result = await validateProjectService(targetPath);
79
- handleValidationResult(result, spinner, cliConsole, "Project");
80
- } catch (error) {
81
- spinner.fail("Validation failed");
82
- throw error;
83
- }
84
- }
85
-
86
- export async function buildProject(
87
- options: { path?: string; watch?: boolean },
88
- cliConsole: CliConsole,
89
- ): Promise<void> {
90
- const targetPath = options.path || process.cwd();
91
-
92
- cliConsole.info(
93
- "Project building is available through individual component and function builds.",
94
- );
95
- cliConsole.info(`Target path: ${targetPath}`);
96
-
97
- if (options.watch) {
98
- cliConsole.info(
99
- "Use watch mode on individual components and functions for development.",
100
- );
101
- }
102
-
103
- cliConsole.suggestions([
104
- "Build components individually with: ollieshop component build",
105
- "Build functions individually with: ollieshop function build",
106
- "Use watch mode: ollieshop component build --watch",
107
- ]);
108
- }
109
-
110
- export async function startDevServer(
111
- options: { port?: number; open?: boolean },
112
- cliConsole: CliConsole,
113
- ): Promise<void> {
114
- cliConsole.info(
115
- "Development server functionality is available through individual component and function development.",
116
- );
117
- cliConsole.info(`Target port: ${options.port || 3000}`);
118
-
119
- if (options.open) {
120
- cliConsole.info(
121
- "Use --open flag with individual component development servers.",
122
- );
123
- }
124
-
125
- cliConsole.suggestions([
126
- "Start component development with: cd components/[name] && npm run dev",
127
- "Start function development with: cd functions/[name] && npm run dev",
128
- "Create components with: ollieshop component create",
129
- "Create functions with: ollieshop function create",
130
- ]);
131
- }