@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.
- package/.turbo/turbo-build.log +6 -9
- package/CHANGELOG.md +27 -0
- package/dist/index.js +993 -3956
- package/package.json +15 -37
- package/src/README.md +126 -0
- package/src/cli.tsx +45 -0
- package/src/commands/help.tsx +79 -0
- package/src/commands/login.tsx +92 -0
- package/src/commands/start.tsx +411 -0
- package/src/index.tsx +8 -0
- package/src/utils/auth.ts +218 -21
- package/src/utils/bundle.ts +177 -0
- package/src/utils/config.ts +123 -0
- package/src/utils/esbuild.ts +541 -0
- package/tsconfig.json +10 -15
- package/tsup.config.ts +7 -7
- package/CLAUDE_CLI.md +0 -265
- package/README.md +0 -711
- package/__tests__/mocks/console.ts +0 -22
- package/__tests__/mocks/core.ts +0 -137
- package/__tests__/mocks/index.ts +0 -4
- package/__tests__/mocks/inquirer.ts +0 -16
- package/__tests__/mocks/progress.ts +0 -19
- package/dist/index.d.ts +0 -1
- package/src/__tests__/helpers/cli-test-helper.ts +0 -281
- package/src/__tests__/mocks/index.ts +0 -142
- package/src/actions/component.actions.ts +0 -278
- package/src/actions/function.actions.ts +0 -220
- package/src/actions/project.actions.ts +0 -131
- package/src/actions/version.actions.ts +0 -233
- package/src/commands/__tests__/component-validation.test.ts +0 -250
- package/src/commands/__tests__/component.test.ts +0 -318
- package/src/commands/__tests__/function-validation.test.ts +0 -220
- package/src/commands/__tests__/function.test.ts +0 -286
- package/src/commands/__tests__/store-version-validation.test.ts +0 -414
- package/src/commands/__tests__/store-version.test.ts +0 -402
- package/src/commands/component.ts +0 -178
- package/src/commands/docs.ts +0 -24
- package/src/commands/function.ts +0 -201
- package/src/commands/help.ts +0 -18
- package/src/commands/index.ts +0 -27
- package/src/commands/login.ts +0 -267
- package/src/commands/project.ts +0 -107
- package/src/commands/store-version.ts +0 -242
- package/src/commands/version.ts +0 -51
- package/src/commands/whoami.ts +0 -46
- package/src/index.ts +0 -116
- package/src/prompts/component.prompts.ts +0 -94
- package/src/prompts/function.prompts.ts +0 -168
- package/src/schemas/command.schema.ts +0 -644
- package/src/types/index.ts +0 -183
- package/src/utils/__tests__/command-parser.test.ts +0 -159
- package/src/utils/__tests__/command-suggestions.test.ts +0 -185
- package/src/utils/__tests__/console.test.ts +0 -192
- package/src/utils/__tests__/context-detector.test.ts +0 -258
- package/src/utils/__tests__/enhanced-error-handler.test.ts +0 -137
- package/src/utils/__tests__/error-handler.test.ts +0 -107
- package/src/utils/__tests__/rich-progress.test.ts +0 -181
- package/src/utils/__tests__/validation-error-formatter.test.ts +0 -175
- package/src/utils/__tests__/validation-helpers.test.ts +0 -125
- package/src/utils/cli-progress-reporter.ts +0 -84
- package/src/utils/command-builder.ts +0 -390
- package/src/utils/command-helpers.ts +0 -83
- package/src/utils/command-parser.ts +0 -245
- package/src/utils/command-suggestions.ts +0 -176
- package/src/utils/console.ts +0 -320
- package/src/utils/constants.ts +0 -39
- package/src/utils/context-detector.ts +0 -177
- package/src/utils/deploy-helpers.ts +0 -357
- package/src/utils/enhanced-error-handler.ts +0 -264
- package/src/utils/error-handler.ts +0 -60
- package/src/utils/errors.ts +0 -256
- package/src/utils/interactive-builder.ts +0 -325
- package/src/utils/rich-progress.ts +0 -331
- package/src/utils/store.ts +0 -23
- package/src/utils/validation-error-formatter.ts +0 -337
- package/src/utils/validation-helpers.ts +0 -325
- package/vitest.config.ts +0 -35
- package/vitest.setup.ts +0 -29
package/src/utils/errors.ts
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import type { ZodError } from "zod";
|
|
2
|
-
import type { ErrorContext } from "../types";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Recovery action that can be suggested to users when an error occurs
|
|
6
|
-
* @interface RecoveryAction
|
|
7
|
-
* @property {string} description - Human-readable description of the recovery action
|
|
8
|
-
* @property {string} [command] - Optional CLI command that can help resolve the issue
|
|
9
|
-
*/
|
|
10
|
-
export interface RecoveryAction {
|
|
11
|
-
description: string;
|
|
12
|
-
command?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Base error class for all Ollie Shop CLI errors
|
|
17
|
-
* Provides context and recovery suggestions to help users resolve issues
|
|
18
|
-
*
|
|
19
|
-
* @class OllieShopCLIError
|
|
20
|
-
* @extends {Error}
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* throw new OllieShopCLIError(
|
|
24
|
-
* "Component build failed",
|
|
25
|
-
* { componentId: "123", path: "./src" },
|
|
26
|
-
* [
|
|
27
|
-
* { description: "Check your TypeScript configuration" },
|
|
28
|
-
* { description: "Run validation", command: "ollieshop component validate" }
|
|
29
|
-
* ]
|
|
30
|
-
* );
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export class OllieShopCLIError extends Error {
|
|
34
|
-
public readonly context: ErrorContext;
|
|
35
|
-
public readonly recoveryActions: RecoveryAction[];
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Creates a new OllieShopCLIError instance
|
|
39
|
-
* @param {string} message - The error message
|
|
40
|
-
* @param {ErrorContext} [context={}] - Additional context about the error
|
|
41
|
-
* @param {RecoveryAction[]} [recoveryActions=[]] - Suggested actions to resolve the error
|
|
42
|
-
*/
|
|
43
|
-
constructor(
|
|
44
|
-
message: string,
|
|
45
|
-
context: ErrorContext = {},
|
|
46
|
-
recoveryActions: RecoveryAction[] = [],
|
|
47
|
-
) {
|
|
48
|
-
super(message);
|
|
49
|
-
this.name = "OllieShopCLIError";
|
|
50
|
-
this.context = context;
|
|
51
|
-
this.recoveryActions = recoveryActions;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Get the error context details
|
|
56
|
-
* @returns {ErrorContext} The error context object
|
|
57
|
-
*/
|
|
58
|
-
get details(): ErrorContext {
|
|
59
|
-
return this.context;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get suggested recovery actions
|
|
64
|
-
* @returns {RecoveryAction[]} Array of recovery actions
|
|
65
|
-
*/
|
|
66
|
-
get suggestions(): RecoveryAction[] {
|
|
67
|
-
return this.recoveryActions;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Create an OllieShopCLIError from a Zod validation error
|
|
72
|
-
* Extracts the most relevant error message and provides validation-specific suggestions
|
|
73
|
-
*
|
|
74
|
-
* @static
|
|
75
|
-
* @param {ZodError} error - The Zod validation error
|
|
76
|
-
* @param {ErrorContext} [context={}] - Additional context to include
|
|
77
|
-
* @returns {OllieShopCLIError} A new OllieShopCLIError instance
|
|
78
|
-
* @example
|
|
79
|
-
* ```typescript
|
|
80
|
-
* try {
|
|
81
|
-
* ComponentNameSchema.parse("Invalid Name!");
|
|
82
|
-
* } catch (error) {
|
|
83
|
-
* if (error instanceof ZodError) {
|
|
84
|
-
* throw OllieShopCLIError.fromZodError(error, { field: "name" });
|
|
85
|
-
* }
|
|
86
|
-
* }
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
static fromZodError(
|
|
90
|
-
error: ZodError,
|
|
91
|
-
context: ErrorContext = {},
|
|
92
|
-
): OllieShopCLIError {
|
|
93
|
-
const firstIssue = error.issues[0];
|
|
94
|
-
if (!firstIssue) {
|
|
95
|
-
return new OllieShopCLIError("Validation failed", context);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const message =
|
|
99
|
-
error.issues.length > 1
|
|
100
|
-
? `${firstIssue.message} (and ${error.issues.length - 1} more error${error.issues.length === 2 ? "" : "s"})`
|
|
101
|
-
: firstIssue.message;
|
|
102
|
-
|
|
103
|
-
return new OllieShopCLIError(message, context, [
|
|
104
|
-
{ description: "Check the command documentation for valid formats" },
|
|
105
|
-
]);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Create an OllieShopCLIError from an unknown error type
|
|
110
|
-
* Safely handles any error type and converts it to OllieShopCLIError
|
|
111
|
-
*
|
|
112
|
-
* @static
|
|
113
|
-
* @param {unknown} error - Any error or value
|
|
114
|
-
* @param {ErrorContext} [context={}] - Additional context to include
|
|
115
|
-
* @returns {OllieShopCLIError} A new OllieShopCLIError instance
|
|
116
|
-
* @example
|
|
117
|
-
* ```typescript
|
|
118
|
-
* try {
|
|
119
|
-
* // some operation
|
|
120
|
-
* } catch (error) {
|
|
121
|
-
* throw OllieShopCLIError.fromUnknown(error, { operation: "deploy" });
|
|
122
|
-
* }
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
static fromUnknown(
|
|
126
|
-
error: unknown,
|
|
127
|
-
context: ErrorContext = {},
|
|
128
|
-
): OllieShopCLIError {
|
|
129
|
-
if (error instanceof OllieShopCLIError) {
|
|
130
|
-
return error;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (error instanceof Error) {
|
|
134
|
-
return new OllieShopCLIError(error.message, context, [
|
|
135
|
-
{ description: "Check the command syntax and try again" },
|
|
136
|
-
]);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return new OllieShopCLIError(
|
|
140
|
-
String(error) || "Unknown error occurred",
|
|
141
|
-
context,
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Create a file not found error with helpful suggestions
|
|
147
|
-
*
|
|
148
|
-
* @static
|
|
149
|
-
* @param {string} path - The file path that was not found
|
|
150
|
-
* @param {ErrorContext} [context={}] - Additional context to include
|
|
151
|
-
* @returns {OllieShopCLIError} A new OllieShopCLIError instance with file-specific suggestions
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* if (!fs.existsSync(configPath)) {
|
|
155
|
-
* throw OllieShopCLIError.fileNotFound(configPath, { operation: "load-config" });
|
|
156
|
-
* }
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
|
-
static fileNotFound(
|
|
160
|
-
path: string,
|
|
161
|
-
context: ErrorContext = {},
|
|
162
|
-
): OllieShopCLIError {
|
|
163
|
-
return new OllieShopCLIError(
|
|
164
|
-
`File not found: ${path}`,
|
|
165
|
-
{ ...context, file: path },
|
|
166
|
-
[
|
|
167
|
-
{ description: "Check if the file path is correct" },
|
|
168
|
-
{ description: "Ensure the file exists in the specified location" },
|
|
169
|
-
],
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export const CLIError = OllieShopCLIError;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Error thrown when a CLI command execution fails
|
|
178
|
-
* Includes an error code for programmatic error handling
|
|
179
|
-
*
|
|
180
|
-
* @class CommandError
|
|
181
|
-
* @extends {OllieShopCLIError}
|
|
182
|
-
* @example
|
|
183
|
-
* ```typescript
|
|
184
|
-
* throw new CommandError(
|
|
185
|
-
* "Failed to connect to builder service",
|
|
186
|
-
* "BUILDER_CONNECTION_ERROR",
|
|
187
|
-
* { url: builderUrl, timeout: 5000 }
|
|
188
|
-
* );
|
|
189
|
-
* ```
|
|
190
|
-
*/
|
|
191
|
-
export class CommandError extends OllieShopCLIError {
|
|
192
|
-
public readonly code: string;
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Creates a new CommandError instance
|
|
196
|
-
* @param {string} message - The error message
|
|
197
|
-
* @param {string} code - A unique error code for this type of error
|
|
198
|
-
* @param {ErrorContext} [context={}] - Additional context about the error
|
|
199
|
-
*/
|
|
200
|
-
constructor(message: string, code: string, context: ErrorContext = {}) {
|
|
201
|
-
super(message, context);
|
|
202
|
-
this.name = "CommandError";
|
|
203
|
-
this.code = code;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Error thrown when validation fails with detailed field-level information
|
|
209
|
-
* Useful for form validation and input checking scenarios
|
|
210
|
-
*
|
|
211
|
-
* @class ValidationError
|
|
212
|
-
* @extends {OllieShopCLIError}
|
|
213
|
-
* @example
|
|
214
|
-
* ```typescript
|
|
215
|
-
* throw new ValidationError(
|
|
216
|
-
* "Component configuration is invalid",
|
|
217
|
-
* [
|
|
218
|
-
* { field: "name", message: "Must be lowercase with hyphens" },
|
|
219
|
-
* { field: "slot", message: "Invalid slot type" }
|
|
220
|
-
* ],
|
|
221
|
-
* { componentPath: "./src/components/header" }
|
|
222
|
-
* );
|
|
223
|
-
* ```
|
|
224
|
-
*/
|
|
225
|
-
export class ValidationError extends OllieShopCLIError {
|
|
226
|
-
public readonly fields: Array<{ field: string; message: string }>;
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Creates a new ValidationError instance
|
|
230
|
-
* @param {string} message - The overall error message
|
|
231
|
-
* @param {Array<{field: string; message: string}>} [fields=[]] - Field-specific validation errors
|
|
232
|
-
* @param {ErrorContext} [context={}] - Additional context about the error
|
|
233
|
-
*/
|
|
234
|
-
constructor(
|
|
235
|
-
message: string,
|
|
236
|
-
fields: Array<{ field: string; message: string }> = [],
|
|
237
|
-
context: ErrorContext = {},
|
|
238
|
-
) {
|
|
239
|
-
super(message, context);
|
|
240
|
-
this.name = "ValidationError";
|
|
241
|
-
this.fields = fields;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Get error details including field-level errors
|
|
246
|
-
* @returns {ErrorContext & {fields: Array<{field: string; message: string}>}} Combined context and field errors
|
|
247
|
-
*/
|
|
248
|
-
get details(): ErrorContext & {
|
|
249
|
-
fields: Array<{ field: string; message: string }>;
|
|
250
|
-
} {
|
|
251
|
-
return {
|
|
252
|
-
...this.context,
|
|
253
|
-
fields: this.fields,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
}
|
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import { ComponentSlot } from "@ollie-shop/core";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import inquirer from "inquirer";
|
|
4
|
-
import type { ComponentDeployOptions } from "../schemas/command.schema";
|
|
5
|
-
import type { InteractiveChoice, MockComponent } from "../types";
|
|
6
|
-
import type { CliConsole } from "./console.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Interactive command builder for creating CLI commands through prompts
|
|
10
|
-
* Provides a wizard-like interface for complex commands
|
|
11
|
-
*
|
|
12
|
-
* @class InteractiveCommandBuilder
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* const builder = new InteractiveCommandBuilder(console);
|
|
16
|
-
* await builder.buildDeployComponentCommand();
|
|
17
|
-
* // User is guided through deployment options
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export class InteractiveCommandBuilder {
|
|
21
|
-
/**
|
|
22
|
-
* Creates a new InteractiveCommandBuilder instance
|
|
23
|
-
* @param {CliConsole} console - Console instance for I/O operations
|
|
24
|
-
*/
|
|
25
|
-
constructor(private console: CliConsole) {}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Build component deploy command interactively
|
|
29
|
-
* Guides user through selecting a component and deployment options
|
|
30
|
-
*
|
|
31
|
-
* @async
|
|
32
|
-
* @throws {Error} If user cancels the wizard
|
|
33
|
-
* @example
|
|
34
|
-
* ```typescript
|
|
35
|
-
* await builder.buildDeployComponentCommand();
|
|
36
|
-
* // Shows:
|
|
37
|
-
* // - List of available components
|
|
38
|
-
* // - Deployment options checkboxes
|
|
39
|
-
* // - Command preview
|
|
40
|
-
* // - Execution confirmation
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
async buildDeployComponentCommand(): Promise<void> {
|
|
44
|
-
this.console.log(chalk.blue.bold("\n🚀 Component Deployment Wizard\n"));
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
// Get available components (mock data for now)
|
|
48
|
-
const components = await this.getAvailableComponents();
|
|
49
|
-
|
|
50
|
-
const answers = await inquirer.prompt([
|
|
51
|
-
{
|
|
52
|
-
type: "list",
|
|
53
|
-
name: "component",
|
|
54
|
-
message: "Select component to deploy:",
|
|
55
|
-
choices: components.map(
|
|
56
|
-
(c): InteractiveChoice => ({
|
|
57
|
-
name: `${c.name} (${c.slot}) - v${c.version || "1.0.0"} - ${chalk.dim(
|
|
58
|
-
`Created ${new Date(c.createdAt).toLocaleDateString()}`,
|
|
59
|
-
)}`,
|
|
60
|
-
value: c.id,
|
|
61
|
-
}),
|
|
62
|
-
),
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
type: "checkbox",
|
|
66
|
-
name: "options",
|
|
67
|
-
message: "Deployment options:",
|
|
68
|
-
choices: [
|
|
69
|
-
{ name: "Run tests before deploy", value: "test", checked: true },
|
|
70
|
-
{
|
|
71
|
-
name: "Enable verbose logging",
|
|
72
|
-
value: "verbose",
|
|
73
|
-
checked: false,
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
]);
|
|
78
|
-
|
|
79
|
-
// Build the command
|
|
80
|
-
let command = `ollieshop component deploy --id ${answers.component}`;
|
|
81
|
-
|
|
82
|
-
if (answers.options.includes("verbose")) {
|
|
83
|
-
command += " --verbose";
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Show preview
|
|
87
|
-
this.console.log(`\n${chalk.dim("[Preview] This will run:")}`);
|
|
88
|
-
this.console.log(chalk.cyan(` ${command}\n`));
|
|
89
|
-
|
|
90
|
-
// Confirm execution
|
|
91
|
-
const { proceed } = await inquirer.prompt({
|
|
92
|
-
type: "confirm",
|
|
93
|
-
name: "proceed",
|
|
94
|
-
message: "Execute this command?",
|
|
95
|
-
default: true,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
if (proceed) {
|
|
99
|
-
// Execute the command
|
|
100
|
-
this.console.log(chalk.dim("\nExecuting command...\n"));
|
|
101
|
-
|
|
102
|
-
// Import and execute the action directly
|
|
103
|
-
const { deployComponent } = await import(
|
|
104
|
-
"../actions/component.actions.js"
|
|
105
|
-
);
|
|
106
|
-
const deployOptions: ComponentDeployOptions = {
|
|
107
|
-
componentId: answers.component,
|
|
108
|
-
path: process.cwd(),
|
|
109
|
-
};
|
|
110
|
-
await deployComponent(deployOptions, this.console);
|
|
111
|
-
} else {
|
|
112
|
-
this.console.log(chalk.yellow("\n⚠️ Deployment cancelled"));
|
|
113
|
-
}
|
|
114
|
-
} catch (error) {
|
|
115
|
-
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
116
|
-
this.console.log(chalk.yellow("\n⚠️ Wizard cancelled"));
|
|
117
|
-
} else {
|
|
118
|
-
throw error;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Build component create command interactively
|
|
125
|
-
* Guides user through component creation options with live validation
|
|
126
|
-
*
|
|
127
|
-
* @async
|
|
128
|
-
* @throws {Error} If user cancels the wizard
|
|
129
|
-
* @example
|
|
130
|
-
* ```typescript
|
|
131
|
-
* await builder.buildCreateComponentCommand();
|
|
132
|
-
* // Prompts for:
|
|
133
|
-
* // - Component name (with live validation)
|
|
134
|
-
* // - Component slot selection
|
|
135
|
-
* // - Language preference (TypeScript/JavaScript)
|
|
136
|
-
* // - Test file inclusion
|
|
137
|
-
* ```
|
|
138
|
-
*/
|
|
139
|
-
async buildCreateComponentCommand(): Promise<void> {
|
|
140
|
-
this.console.log(chalk.blue.bold("\n🎨 Component Creation Wizard\n"));
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const answers = await inquirer.prompt([
|
|
144
|
-
{
|
|
145
|
-
type: "input",
|
|
146
|
-
name: "name",
|
|
147
|
-
message: "Component name:",
|
|
148
|
-
validate: (input: string) => {
|
|
149
|
-
if (!input) return "Component name is required";
|
|
150
|
-
if (!/^[a-z0-9-]+$/.test(input)) {
|
|
151
|
-
return "Must be lowercase with hyphens only (e.g., header-nav)";
|
|
152
|
-
}
|
|
153
|
-
return true;
|
|
154
|
-
},
|
|
155
|
-
transformer: (input: string) => {
|
|
156
|
-
// Show live validation
|
|
157
|
-
if (!/^[a-z0-9-]+$/.test(input) && input) {
|
|
158
|
-
return chalk.red(input);
|
|
159
|
-
}
|
|
160
|
-
return input;
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
type: "list",
|
|
165
|
-
name: "slot",
|
|
166
|
-
message: "Component slot:",
|
|
167
|
-
choices: ComponentSlot.options.map((slot) => ({
|
|
168
|
-
name:
|
|
169
|
-
slot.charAt(0).toUpperCase() + slot.slice(1).replace(/-/g, " "),
|
|
170
|
-
value: slot,
|
|
171
|
-
})),
|
|
172
|
-
default: "main",
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
type: "list",
|
|
176
|
-
name: "language",
|
|
177
|
-
message: "Language:",
|
|
178
|
-
choices: [
|
|
179
|
-
{ name: "TypeScript (recommended)", value: "typescript" },
|
|
180
|
-
{ name: "JavaScript", value: "javascript" },
|
|
181
|
-
],
|
|
182
|
-
default: "typescript",
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
type: "confirm",
|
|
186
|
-
name: "tests",
|
|
187
|
-
message: "Include test files?",
|
|
188
|
-
default: true,
|
|
189
|
-
},
|
|
190
|
-
]);
|
|
191
|
-
|
|
192
|
-
// Build the command
|
|
193
|
-
let command = `ollieshop component create --name ${answers.name}`;
|
|
194
|
-
|
|
195
|
-
if (answers.slot !== "main") {
|
|
196
|
-
command += ` --slot ${answers.slot}`;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (answers.language === "javascript") {
|
|
200
|
-
command += " --no-typescript";
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (!answers.tests) {
|
|
204
|
-
command += " --no-tests";
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Show preview
|
|
208
|
-
this.console.log(`\n${chalk.dim("[Preview] This will run:")}`);
|
|
209
|
-
this.console.log(chalk.cyan(` ${command}\n`));
|
|
210
|
-
|
|
211
|
-
// Confirm execution
|
|
212
|
-
const { proceed } = await inquirer.prompt({
|
|
213
|
-
type: "confirm",
|
|
214
|
-
name: "proceed",
|
|
215
|
-
message: "Create this component?",
|
|
216
|
-
default: true,
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
if (proceed) {
|
|
220
|
-
// Execute the command
|
|
221
|
-
this.console.log(chalk.dim("\nCreating component...\n"));
|
|
222
|
-
|
|
223
|
-
const { createComponent } = await import(
|
|
224
|
-
"../actions/component.actions.js"
|
|
225
|
-
);
|
|
226
|
-
await createComponent(
|
|
227
|
-
{
|
|
228
|
-
name: answers.name,
|
|
229
|
-
slot: answers.slot,
|
|
230
|
-
tests: answers.tests,
|
|
231
|
-
},
|
|
232
|
-
this.console,
|
|
233
|
-
);
|
|
234
|
-
} else {
|
|
235
|
-
this.console.log(chalk.yellow("\n⚠️ Component creation cancelled"));
|
|
236
|
-
}
|
|
237
|
-
} catch (error) {
|
|
238
|
-
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
239
|
-
this.console.log(chalk.yellow("\n⚠️ Wizard cancelled"));
|
|
240
|
-
} else {
|
|
241
|
-
throw error;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Get available components (mock for now)
|
|
248
|
-
* TODO: Replace with actual API call to list components
|
|
249
|
-
*
|
|
250
|
-
* @private
|
|
251
|
-
* @async
|
|
252
|
-
* @returns {Promise<MockComponent[]>} Array of mock component data
|
|
253
|
-
*/
|
|
254
|
-
private async getAvailableComponents(): Promise<MockComponent[]> {
|
|
255
|
-
// TODO: Replace with actual API call
|
|
256
|
-
return [
|
|
257
|
-
{
|
|
258
|
-
id: "comp_header_123",
|
|
259
|
-
name: "header-nav",
|
|
260
|
-
slot: "header",
|
|
261
|
-
version: "1.2.0",
|
|
262
|
-
enabled: true,
|
|
263
|
-
createdAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
|
|
264
|
-
type: "ui",
|
|
265
|
-
description: "Navigation header component",
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
id: "comp_cart_456",
|
|
269
|
-
name: "shopping-cart",
|
|
270
|
-
slot: "sidebar",
|
|
271
|
-
version: "1.0.0",
|
|
272
|
-
enabled: true,
|
|
273
|
-
createdAt: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
|
|
274
|
-
type: "ui",
|
|
275
|
-
description: "Shopping cart widget",
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
id: "comp_product_789",
|
|
279
|
-
name: "product-list",
|
|
280
|
-
slot: "main",
|
|
281
|
-
version: "2.1.0",
|
|
282
|
-
enabled: true,
|
|
283
|
-
createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
|
|
284
|
-
type: "ui",
|
|
285
|
-
description: "Product listing component",
|
|
286
|
-
},
|
|
287
|
-
];
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Run an interactive command builder for the specified command
|
|
293
|
-
* Creates a wizard-like interface based on the command type
|
|
294
|
-
*
|
|
295
|
-
* @async
|
|
296
|
-
* @param {string} command - The command type to run interactively
|
|
297
|
-
* @param {CliConsole} console - Console instance for I/O
|
|
298
|
-
* @example
|
|
299
|
-
* ```typescript
|
|
300
|
-
* // Run deployment wizard
|
|
301
|
-
* await runInteractiveCommand("deploy", console);
|
|
302
|
-
*
|
|
303
|
-
* // Run component creation wizard
|
|
304
|
-
* await runInteractiveCommand("create", console);
|
|
305
|
-
* ```
|
|
306
|
-
*/
|
|
307
|
-
export async function runInteractiveCommand(
|
|
308
|
-
command: string,
|
|
309
|
-
console: CliConsole,
|
|
310
|
-
): Promise<void> {
|
|
311
|
-
const builder = new InteractiveCommandBuilder(console);
|
|
312
|
-
|
|
313
|
-
switch (command) {
|
|
314
|
-
case "deploy":
|
|
315
|
-
case "component-deploy":
|
|
316
|
-
await builder.buildDeployComponentCommand();
|
|
317
|
-
break;
|
|
318
|
-
case "create":
|
|
319
|
-
case "component-create":
|
|
320
|
-
await builder.buildCreateComponentCommand();
|
|
321
|
-
break;
|
|
322
|
-
default:
|
|
323
|
-
console.warn(`Interactive mode not available for command: ${command}`);
|
|
324
|
-
}
|
|
325
|
-
}
|