@ollie-shop/cli 0.3.0 → 0.3.3

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 (139) hide show
  1. package/.turbo/turbo-build.log +14 -2
  2. package/CHANGELOG.md +48 -0
  3. package/__tests__/mocks/core.ts +1 -1
  4. package/dist/index.d.ts +0 -2
  5. package/dist/index.js +40631 -75
  6. package/package.json +7 -6
  7. package/src/actions/component.actions.ts +148 -204
  8. package/src/actions/function.actions.ts +78 -171
  9. package/src/actions/project.actions.ts +16 -11
  10. package/src/commands/__tests__/component.test.ts +4 -7
  11. package/src/commands/__tests__/function.test.ts +1 -1
  12. package/src/commands/__tests__/store-version.test.ts +1 -4
  13. package/src/commands/component.ts +0 -10
  14. package/src/commands/function.ts +5 -56
  15. package/src/schemas/command.schema.ts +296 -6
  16. package/src/utils/__tests__/rich-progress.test.ts +22 -11
  17. package/src/utils/cli-progress-reporter.ts +2 -2
  18. package/src/utils/command-parser.ts +0 -5
  19. package/src/utils/console.ts +33 -4
  20. package/src/utils/constants.ts +32 -0
  21. package/src/utils/deploy-helpers.ts +357 -0
  22. package/src/utils/errors.ts +133 -2
  23. package/src/utils/interactive-builder.ts +61 -7
  24. package/src/utils/rich-progress.ts +25 -14
  25. package/src/utils/validation-helpers.ts +145 -12
  26. package/tsup.config.ts +15 -0
  27. package/dist/__tests__/helpers/cli-test-helper.d.ts +0 -89
  28. package/dist/__tests__/helpers/cli-test-helper.d.ts.map +0 -1
  29. package/dist/__tests__/helpers/cli-test-helper.js +0 -220
  30. package/dist/__tests__/mocks/index.d.ts +0 -69
  31. package/dist/__tests__/mocks/index.d.ts.map +0 -1
  32. package/dist/__tests__/mocks/index.js +0 -77
  33. package/dist/actions/component.actions.d.ts +0 -14
  34. package/dist/actions/component.actions.d.ts.map +0 -1
  35. package/dist/actions/component.actions.js +0 -273
  36. package/dist/actions/function.actions.d.ts +0 -15
  37. package/dist/actions/function.actions.d.ts.map +0 -1
  38. package/dist/actions/function.actions.js +0 -254
  39. package/dist/actions/project.actions.d.ts +0 -17
  40. package/dist/actions/project.actions.d.ts.map +0 -1
  41. package/dist/actions/project.actions.js +0 -97
  42. package/dist/actions/version.actions.d.ts +0 -19
  43. package/dist/actions/version.actions.d.ts.map +0 -1
  44. package/dist/actions/version.actions.js +0 -216
  45. package/dist/commands/component.d.ts +0 -3
  46. package/dist/commands/component.d.ts.map +0 -1
  47. package/dist/commands/component.js +0 -192
  48. package/dist/commands/docs.d.ts +0 -3
  49. package/dist/commands/docs.d.ts.map +0 -1
  50. package/dist/commands/docs.js +0 -16
  51. package/dist/commands/function.d.ts +0 -3
  52. package/dist/commands/function.d.ts.map +0 -1
  53. package/dist/commands/function.js +0 -243
  54. package/dist/commands/help.d.ts +0 -3
  55. package/dist/commands/help.d.ts.map +0 -1
  56. package/dist/commands/help.js +0 -20
  57. package/dist/commands/index.d.ts +0 -3
  58. package/dist/commands/index.d.ts.map +0 -1
  59. package/dist/commands/index.js +0 -26
  60. package/dist/commands/login.d.ts +0 -3
  61. package/dist/commands/login.d.ts.map +0 -1
  62. package/dist/commands/login.js +0 -175
  63. package/dist/commands/project.d.ts +0 -3
  64. package/dist/commands/project.d.ts.map +0 -1
  65. package/dist/commands/project.js +0 -78
  66. package/dist/commands/store-version.d.ts +0 -3
  67. package/dist/commands/store-version.d.ts.map +0 -1
  68. package/dist/commands/store-version.js +0 -241
  69. package/dist/commands/version.d.ts +0 -3
  70. package/dist/commands/version.d.ts.map +0 -1
  71. package/dist/commands/version.js +0 -46
  72. package/dist/commands/whoami.d.ts +0 -3
  73. package/dist/commands/whoami.d.ts.map +0 -1
  74. package/dist/commands/whoami.js +0 -41
  75. package/dist/index.d.ts.map +0 -1
  76. package/dist/prompts/component.prompts.d.ts +0 -14
  77. package/dist/prompts/component.prompts.d.ts.map +0 -1
  78. package/dist/prompts/component.prompts.js +0 -75
  79. package/dist/prompts/function.prompts.d.ts +0 -21
  80. package/dist/prompts/function.prompts.d.ts.map +0 -1
  81. package/dist/prompts/function.prompts.js +0 -127
  82. package/dist/schemas/command.schema.d.ts +0 -516
  83. package/dist/schemas/command.schema.d.ts.map +0 -1
  84. package/dist/schemas/command.schema.js +0 -267
  85. package/dist/types/index.d.ts +0 -147
  86. package/dist/types/index.d.ts.map +0 -1
  87. package/dist/types/index.js +0 -18
  88. package/dist/utils/auth.d.ts +0 -4
  89. package/dist/utils/auth.d.ts.map +0 -1
  90. package/dist/utils/auth.js +0 -26
  91. package/dist/utils/cli-progress-reporter.d.ts +0 -12
  92. package/dist/utils/cli-progress-reporter.d.ts.map +0 -1
  93. package/dist/utils/cli-progress-reporter.js +0 -77
  94. package/dist/utils/command-builder.d.ts +0 -22
  95. package/dist/utils/command-builder.d.ts.map +0 -1
  96. package/dist/utils/command-builder.js +0 -268
  97. package/dist/utils/command-helpers.d.ts +0 -19
  98. package/dist/utils/command-helpers.d.ts.map +0 -1
  99. package/dist/utils/command-helpers.js +0 -79
  100. package/dist/utils/command-parser.d.ts +0 -146
  101. package/dist/utils/command-parser.d.ts.map +0 -1
  102. package/dist/utils/command-parser.js +0 -179
  103. package/dist/utils/command-suggestions.d.ts +0 -35
  104. package/dist/utils/command-suggestions.d.ts.map +0 -1
  105. package/dist/utils/command-suggestions.js +0 -152
  106. package/dist/utils/console.d.ts +0 -44
  107. package/dist/utils/console.d.ts.map +0 -1
  108. package/dist/utils/console.js +0 -233
  109. package/dist/utils/constants.d.ts +0 -8
  110. package/dist/utils/constants.d.ts.map +0 -1
  111. package/dist/utils/constants.js +0 -10
  112. package/dist/utils/context-detector.d.ts +0 -12
  113. package/dist/utils/context-detector.d.ts.map +0 -1
  114. package/dist/utils/context-detector.js +0 -155
  115. package/dist/utils/enhanced-error-handler.d.ts +0 -47
  116. package/dist/utils/enhanced-error-handler.d.ts.map +0 -1
  117. package/dist/utils/enhanced-error-handler.js +0 -221
  118. package/dist/utils/error-handler.d.ts +0 -3
  119. package/dist/utils/error-handler.d.ts.map +0 -1
  120. package/dist/utils/error-handler.js +0 -55
  121. package/dist/utils/errors.d.ts +0 -44
  122. package/dist/utils/errors.d.ts.map +0 -1
  123. package/dist/utils/errors.js +0 -76
  124. package/dist/utils/interactive-builder.d.ts +0 -22
  125. package/dist/utils/interactive-builder.d.ts.map +0 -1
  126. package/dist/utils/interactive-builder.js +0 -246
  127. package/dist/utils/rich-progress.d.ts +0 -59
  128. package/dist/utils/rich-progress.d.ts.map +0 -1
  129. package/dist/utils/rich-progress.js +0 -234
  130. package/dist/utils/store.d.ts +0 -11
  131. package/dist/utils/store.d.ts.map +0 -1
  132. package/dist/utils/store.js +0 -19
  133. package/dist/utils/validation-error-formatter.d.ts +0 -25
  134. package/dist/utils/validation-error-formatter.d.ts.map +0 -1
  135. package/dist/utils/validation-error-formatter.js +0 -258
  136. package/dist/utils/validation-helpers.d.ts +0 -60
  137. package/dist/utils/validation-helpers.d.ts.map +0 -1
  138. package/dist/utils/validation-helpers.js +0 -152
  139. package/src/commands/__tests__/version.test.ts +0 -71
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ollie-shop/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "Ollie Shop CLI for building custom checkouts",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,8 +20,7 @@
20
20
  "open": "^8.4.2",
21
21
  "ora": "^5.4.1",
22
22
  "semver": "^7.5.4",
23
- "zod": "^3.22.4",
24
- "@ollie-shop/core": "1.0.0"
23
+ "zod": "^3.22.4"
25
24
  },
26
25
  "devDependencies": {
27
26
  "@anatine/zod-mock": "^3.14.0",
@@ -33,18 +32,20 @@
33
32
  "@vitest/coverage-v8": "3.0.4",
34
33
  "fishery": "^2.3.1",
35
34
  "msw": "^2.10.3",
35
+ "tsup": "^8.0.1",
36
36
  "typescript": "^5.7.3",
37
37
  "vitest": "^3.0.4",
38
38
  "vitest-mock-extended": "^3.1.0",
39
- "wait-for-expect": "^3.0.2"
39
+ "wait-for-expect": "^3.0.2",
40
+ "@ollie-shop/core": "1.0.2"
40
41
  },
41
42
  "publishConfig": {
42
43
  "access": "public",
43
44
  "registry": "https://registry.npmjs.org/"
44
45
  },
45
46
  "scripts": {
46
- "build": "tsc",
47
- "dev": "tsc --watch",
47
+ "build": "tsup",
48
+ "dev": "tsup --watch",
48
49
  "test": "vitest",
49
50
  "test:coverage": "vitest run --coverage",
50
51
  "lint": "eslint src/**/*.ts",
@@ -1,21 +1,47 @@
1
+ import {
2
+ buildAndDeployComponentFromDirectory,
3
+ buildComponent as buildComponentService,
4
+ createComponent as createComponentService,
5
+ validateComponent as validateComponentService,
6
+ } from "@ollie-shop/core";
1
7
  import type {
2
8
  ComponentCreateOptions,
3
9
  ComponentDeployOptions,
4
- ComponentListItem,
5
10
  ComponentValidateOptions,
6
11
  } from "../schemas/command.schema";
7
- import { ComponentListItemSchema } from "../schemas/command.schema";
8
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";
9
22
  import { handleValidationResult } from "../utils/validation-helpers";
10
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
+ */
11
41
  export async function createComponent(
12
42
  options: ComponentCreateOptions,
13
43
  cliConsole: CliConsole,
14
44
  ): Promise<void> {
15
- const { createComponent: createComponentService } = await import(
16
- "@ollie-shop/core"
17
- );
18
-
19
45
  const spinner = cliConsole.spinner({
20
46
  text: "Creating component...",
21
47
  });
@@ -54,19 +80,37 @@ export async function createComponent(
54
80
  ]);
55
81
  } catch (error) {
56
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
+ }
57
91
  throw error;
58
92
  }
59
93
  }
60
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
+ */
61
110
  export async function validateComponent(
62
111
  options: ComponentValidateOptions,
63
112
  cliConsole: CliConsole,
64
113
  ): Promise<void> {
65
- const { validateComponent: validateComponentService } = await import(
66
- "@ollie-shop/core"
67
- );
68
- const { getContextualPath } = await import("../utils/context-detector.js");
69
-
70
114
  const targetPath = getContextualPath(options.path, "component");
71
115
  const spinner = cliConsole.spinner({ text: "Validating component..." });
72
116
 
@@ -75,19 +119,40 @@ export async function validateComponent(
75
119
  handleValidationResult(result, spinner, cliConsole, "Component");
76
120
  } catch (error) {
77
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
+ }
78
130
  throw error;
79
131
  }
80
132
  }
81
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
+ */
82
152
  export async function buildComponent(
83
153
  options: { path?: string; watch?: boolean },
84
154
  cliConsole: CliConsole,
85
155
  ): Promise<void> {
86
- const { buildComponent: buildComponentService } = await import(
87
- "@ollie-shop/core"
88
- );
89
- const { getContextualPath } = await import("../utils/context-detector.js");
90
-
91
156
  const targetPath = getContextualPath(options.path, "component");
92
157
  const spinner = cliConsole.spinner({ text: "Building component..." });
93
158
 
@@ -121,214 +186,93 @@ export async function buildComponent(
121
186
  }
122
187
  }
123
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
+ */
124
205
  export async function deployComponent(
125
- options: ComponentDeployOptions & { wait?: boolean },
206
+ options: ComponentDeployOptions,
126
207
  cliConsole: CliConsole,
127
208
  ): Promise<void> {
128
209
  if (!options.componentId) {
129
- throw new Error("Component ID is required for deployment");
210
+ throw new Error(ERROR_MESSAGES.COMPONENT_ID_REQUIRED);
130
211
  }
131
212
 
213
+ configureBuilderUrl();
214
+
132
215
  const spinner = cliConsole.spinner({
133
- text: "Building and deploying component...",
216
+ text: "Preparing component for deployment...",
134
217
  });
135
218
 
136
219
  try {
137
- // For CLI demo purposes, simulate deployment without Supabase
138
- // In production, this would use the builder API directly
139
- const buildId = `build-${Date.now()}`;
140
- const result = {
141
- buildId,
142
- status: "IN_PROGRESS" as const,
143
- startTime: new Date().toISOString(),
144
- };
145
-
146
- spinner.succeed("Component deployment initiated!");
147
- cliConsole.success(`Build ID: ${result.buildId}`);
148
- cliConsole.info(`Initial Status: ${result.status}`);
220
+ const componentPath = options.path || process.cwd();
221
+ const result = await buildAndDeployComponentFromDirectory(
222
+ options.componentId,
223
+ componentPath,
224
+ );
149
225
 
150
- // If wait flag is set, simulate deployment progress
151
- if (options.wait) {
152
- // Stop spinner and use rich progress reporter
153
- spinner.stop();
226
+ handleDeploymentResult(result, "component", cliConsole, spinner);
227
+ spinner.stop();
154
228
 
155
- const { RichProgressReporter } = await import(
156
- "../utils/rich-progress.js"
229
+ try {
230
+ const { completedBuild, duration } = await waitForDeploymentWithProgress(
231
+ result.buildId,
232
+ "component",
233
+ cliConsole,
157
234
  );
158
- const progressReporter = new RichProgressReporter();
159
- progressReporter.start();
160
-
161
- try {
162
- // Simulate deployment progress for demo
163
- const phases = [
164
- {
165
- phase: "validate",
166
- message: "Validating component...",
167
- progress: 0.1,
168
- },
169
- { phase: "build", message: "Building component...", progress: 0.3 },
170
- {
171
- phase: "bundle",
172
- message: "Creating bundle...",
173
- progress: 0.5,
174
- metadata: { bundleSize: 125000, gzippedSize: 42000 },
175
- },
176
- { phase: "upload", message: "Uploading to CDN...", progress: 0.7 },
177
- { phase: "deploy", message: "Deploying component...", progress: 0.9 },
178
- { phase: "complete", message: "Deployment complete!", progress: 1.0 },
179
- ];
180
-
181
- // Simulate progress updates
182
- for (const update of phases) {
183
- await new Promise((resolve) => setTimeout(resolve, 1000));
184
- progressReporter.updateProgress(update);
185
- }
186
-
187
- const deploymentUrl = `https://cdn.ollie.shop/components/${options.componentId}/${buildId}`;
188
- const duration = 5.5; // simulated duration
189
235
 
190
- progressReporter.stop(true);
191
-
192
- cliConsole.success(`\nDeployment URL: ${deploymentUrl}`);
193
- cliConsole.info(`Duration: ${duration}s`);
194
- } catch (error) {
195
- progressReporter.stop(false);
196
- throw error;
197
- }
198
- } else {
199
- // Async mode - just show next steps
200
- cliConsole.nextSteps("Monitor deployment", [
201
- {
202
- description: "Check deployment status",
203
- command: `ollieshop component deploy-status ${result.buildId}`,
204
- },
205
- {
206
- description: "Or deploy with --wait flag to wait for completion",
207
- command: `ollieshop component deploy --id ${options.componentId} --wait`,
208
- },
209
- ]);
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;
210
246
  }
211
247
  } catch (error) {
212
- spinner.fail("Deployment failed");
213
- throw error;
214
- }
215
- }
216
-
217
- export async function checkDeployStatus(
218
- buildId: string,
219
- cliConsole: CliConsole,
220
- ): Promise<void> {
221
- const spinner = cliConsole.spinner({ text: "Checking deployment status..." });
222
-
223
- try {
224
- // For CLI demo purposes, return mock build status
225
- // In production, this would use the builder API directly
226
- const build = {
227
- id: buildId,
228
- status: "SUCCEEDED",
229
- startTime: new Date(Date.now() - 30000).toISOString(),
230
- endTime: new Date().toISOString(),
231
- };
232
-
233
- if (!build) {
234
- spinner.fail("Build not found");
235
- return;
248
+ if (spinner.isSpinning) {
249
+ spinner.fail("Deployment failed");
236
250
  }
237
-
238
- spinner.succeed("Status retrieved");
239
-
240
- cliConsole.info(`Build ID: ${build.id}`);
241
- cliConsole.info(`Status: ${build.status}`);
242
- cliConsole.info(
243
- `Start Time: ${new Date(build.startTime).toLocaleString()}`,
244
- );
245
-
246
- if (build.endTime) {
247
- cliConsole.info(`End Time: ${new Date(build.endTime).toLocaleString()}`);
248
- const duration =
249
- (new Date(build.endTime).getTime() -
250
- new Date(build.startTime).getTime()) /
251
- 1000;
252
- cliConsole.info(`Duration: ${duration}s`);
253
- }
254
-
255
- if (build.status === "SUCCEEDED") {
256
- cliConsole.success("✅ Deployment completed successfully!");
257
- } else if (build.status === "FAILED" || build.status === "FAULT") {
258
- cliConsole.error("❌ Deployment failed");
259
- } else if (build.status === "IN_PROGRESS") {
260
- cliConsole.info("🔄 Deployment in progress...");
261
- }
262
- } catch (error) {
263
- spinner.fail("Failed to check status");
264
251
  throw error;
265
252
  }
266
253
  }
267
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
+ */
268
269
  export async function listComponents(cliConsole: CliConsole): Promise<void> {
269
- const spinner = cliConsole.spinner({ text: "Loading components..." });
270
-
271
- try {
272
- // For CLI demo purposes, return mock components
273
- // In production, this would use the API directly
274
- const rawComponents = [
275
- {
276
- id: "comp-1",
277
- name: "custom-header",
278
- slot: "header",
279
- active: true,
280
- createdAt: new Date().toISOString(),
281
- },
282
- {
283
- id: "comp-2",
284
- name: "shipping-calculator",
285
- slot: "shipping",
286
- active: false,
287
- createdAt: new Date(Date.now() - 172800000).toISOString(),
288
- },
289
- ];
290
-
291
- // Map core component types to CLI display format
292
- const components: ComponentListItem[] = rawComponents.map((component) =>
293
- ComponentListItemSchema.parse({
294
- id: component.id,
295
- name: component.name,
296
- slot: component.slot,
297
- version: "1.0.0", // TODO: Get version from component metadata
298
- enabled: component.active,
299
- createdAt: component.createdAt,
300
- type: "ui", // TODO: Get type from component metadata
301
- description: "Component description", // TODO: Get from metadata
302
- }),
303
- );
304
-
305
- spinner.succeed();
306
-
307
- if (components.length === 0) {
308
- cliConsole.warn("No components found");
309
- cliConsole.suggestions([
310
- "Create your first component with: ollieshop component create",
311
- "Check our documentation at: https://docs.ollie.shop/components",
312
- ]);
313
- return;
314
- }
315
-
316
- cliConsole.info(
317
- `Found ${components.length} component${components.length === 1 ? "" : "s"}:\n`,
318
- );
319
-
320
- cliConsole.table(
321
- components.map((c) => ({
322
- ID: c.id,
323
- Name: c.name,
324
- Slot: c.slot,
325
- Version: c.version || "N/A",
326
- Enabled: c.enabled ? "✓" : "✗",
327
- Created: new Date(c.createdAt).toLocaleDateString(),
328
- })),
329
- );
330
- } catch (error) {
331
- spinner.fail("Failed to list components");
332
- throw error;
333
- }
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
+ ]);
334
278
  }