@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.
- package/.turbo/turbo-build.log +14 -2
- package/CHANGELOG.md +48 -0
- package/__tests__/mocks/core.ts +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +40631 -75
- package/package.json +7 -6
- package/src/actions/component.actions.ts +148 -204
- package/src/actions/function.actions.ts +78 -171
- package/src/actions/project.actions.ts +16 -11
- package/src/commands/__tests__/component.test.ts +4 -7
- package/src/commands/__tests__/function.test.ts +1 -1
- package/src/commands/__tests__/store-version.test.ts +1 -4
- package/src/commands/component.ts +0 -10
- package/src/commands/function.ts +5 -56
- package/src/schemas/command.schema.ts +296 -6
- package/src/utils/__tests__/rich-progress.test.ts +22 -11
- package/src/utils/cli-progress-reporter.ts +2 -2
- package/src/utils/command-parser.ts +0 -5
- package/src/utils/console.ts +33 -4
- package/src/utils/constants.ts +32 -0
- package/src/utils/deploy-helpers.ts +357 -0
- package/src/utils/errors.ts +133 -2
- package/src/utils/interactive-builder.ts +61 -7
- package/src/utils/rich-progress.ts +25 -14
- package/src/utils/validation-helpers.ts +145 -12
- package/tsup.config.ts +15 -0
- package/dist/__tests__/helpers/cli-test-helper.d.ts +0 -89
- package/dist/__tests__/helpers/cli-test-helper.d.ts.map +0 -1
- package/dist/__tests__/helpers/cli-test-helper.js +0 -220
- package/dist/__tests__/mocks/index.d.ts +0 -69
- package/dist/__tests__/mocks/index.d.ts.map +0 -1
- package/dist/__tests__/mocks/index.js +0 -77
- package/dist/actions/component.actions.d.ts +0 -14
- package/dist/actions/component.actions.d.ts.map +0 -1
- package/dist/actions/component.actions.js +0 -273
- package/dist/actions/function.actions.d.ts +0 -15
- package/dist/actions/function.actions.d.ts.map +0 -1
- package/dist/actions/function.actions.js +0 -254
- package/dist/actions/project.actions.d.ts +0 -17
- package/dist/actions/project.actions.d.ts.map +0 -1
- package/dist/actions/project.actions.js +0 -97
- package/dist/actions/version.actions.d.ts +0 -19
- package/dist/actions/version.actions.d.ts.map +0 -1
- package/dist/actions/version.actions.js +0 -216
- package/dist/commands/component.d.ts +0 -3
- package/dist/commands/component.d.ts.map +0 -1
- package/dist/commands/component.js +0 -192
- package/dist/commands/docs.d.ts +0 -3
- package/dist/commands/docs.d.ts.map +0 -1
- package/dist/commands/docs.js +0 -16
- package/dist/commands/function.d.ts +0 -3
- package/dist/commands/function.d.ts.map +0 -1
- package/dist/commands/function.js +0 -243
- package/dist/commands/help.d.ts +0 -3
- package/dist/commands/help.d.ts.map +0 -1
- package/dist/commands/help.js +0 -20
- package/dist/commands/index.d.ts +0 -3
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -26
- package/dist/commands/login.d.ts +0 -3
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -175
- package/dist/commands/project.d.ts +0 -3
- package/dist/commands/project.d.ts.map +0 -1
- package/dist/commands/project.js +0 -78
- package/dist/commands/store-version.d.ts +0 -3
- package/dist/commands/store-version.d.ts.map +0 -1
- package/dist/commands/store-version.js +0 -241
- package/dist/commands/version.d.ts +0 -3
- package/dist/commands/version.d.ts.map +0 -1
- package/dist/commands/version.js +0 -46
- package/dist/commands/whoami.d.ts +0 -3
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js +0 -41
- package/dist/index.d.ts.map +0 -1
- package/dist/prompts/component.prompts.d.ts +0 -14
- package/dist/prompts/component.prompts.d.ts.map +0 -1
- package/dist/prompts/component.prompts.js +0 -75
- package/dist/prompts/function.prompts.d.ts +0 -21
- package/dist/prompts/function.prompts.d.ts.map +0 -1
- package/dist/prompts/function.prompts.js +0 -127
- package/dist/schemas/command.schema.d.ts +0 -516
- package/dist/schemas/command.schema.d.ts.map +0 -1
- package/dist/schemas/command.schema.js +0 -267
- package/dist/types/index.d.ts +0 -147
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -18
- package/dist/utils/auth.d.ts +0 -4
- package/dist/utils/auth.d.ts.map +0 -1
- package/dist/utils/auth.js +0 -26
- package/dist/utils/cli-progress-reporter.d.ts +0 -12
- package/dist/utils/cli-progress-reporter.d.ts.map +0 -1
- package/dist/utils/cli-progress-reporter.js +0 -77
- package/dist/utils/command-builder.d.ts +0 -22
- package/dist/utils/command-builder.d.ts.map +0 -1
- package/dist/utils/command-builder.js +0 -268
- package/dist/utils/command-helpers.d.ts +0 -19
- package/dist/utils/command-helpers.d.ts.map +0 -1
- package/dist/utils/command-helpers.js +0 -79
- package/dist/utils/command-parser.d.ts +0 -146
- package/dist/utils/command-parser.d.ts.map +0 -1
- package/dist/utils/command-parser.js +0 -179
- package/dist/utils/command-suggestions.d.ts +0 -35
- package/dist/utils/command-suggestions.d.ts.map +0 -1
- package/dist/utils/command-suggestions.js +0 -152
- package/dist/utils/console.d.ts +0 -44
- package/dist/utils/console.d.ts.map +0 -1
- package/dist/utils/console.js +0 -233
- package/dist/utils/constants.d.ts +0 -8
- package/dist/utils/constants.d.ts.map +0 -1
- package/dist/utils/constants.js +0 -10
- package/dist/utils/context-detector.d.ts +0 -12
- package/dist/utils/context-detector.d.ts.map +0 -1
- package/dist/utils/context-detector.js +0 -155
- package/dist/utils/enhanced-error-handler.d.ts +0 -47
- package/dist/utils/enhanced-error-handler.d.ts.map +0 -1
- package/dist/utils/enhanced-error-handler.js +0 -221
- package/dist/utils/error-handler.d.ts +0 -3
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -55
- package/dist/utils/errors.d.ts +0 -44
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -76
- package/dist/utils/interactive-builder.d.ts +0 -22
- package/dist/utils/interactive-builder.d.ts.map +0 -1
- package/dist/utils/interactive-builder.js +0 -246
- package/dist/utils/rich-progress.d.ts +0 -59
- package/dist/utils/rich-progress.d.ts.map +0 -1
- package/dist/utils/rich-progress.js +0 -234
- package/dist/utils/store.d.ts +0 -11
- package/dist/utils/store.d.ts.map +0 -1
- package/dist/utils/store.js +0 -19
- package/dist/utils/validation-error-formatter.d.ts +0 -25
- package/dist/utils/validation-error-formatter.d.ts.map +0 -1
- package/dist/utils/validation-error-formatter.js +0 -258
- package/dist/utils/validation-helpers.d.ts +0 -60
- package/dist/utils/validation-helpers.d.ts.map +0 -1
- package/dist/utils/validation-helpers.js +0 -152
- package/src/commands/__tests__/version.test.ts +0 -71
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import cliProgress from "cli-progress";
|
|
3
3
|
import type { ProgressParams, ProgressPayload, Spinner } from "../types";
|
|
4
|
+
import type { CliConsole } from "./console";
|
|
4
5
|
|
|
5
6
|
// Enhanced build progress type for CLI display
|
|
6
7
|
interface CLIBuildProgress {
|
|
@@ -40,8 +41,10 @@ export class RichProgressReporter {
|
|
|
40
41
|
dependencies?: number;
|
|
41
42
|
removedExports?: number;
|
|
42
43
|
} = {};
|
|
44
|
+
private cliConsole: CliConsole;
|
|
43
45
|
|
|
44
|
-
constructor() {
|
|
46
|
+
constructor(cliConsole: CliConsole) {
|
|
47
|
+
this.cliConsole = cliConsole;
|
|
45
48
|
// Create a formatter function that matches cli-progress expectations
|
|
46
49
|
const formatter = (
|
|
47
50
|
options: Record<string, unknown>,
|
|
@@ -88,13 +91,17 @@ export class RichProgressReporter {
|
|
|
88
91
|
return this.formatBar(formatOptions, progressParams, progressPayload);
|
|
89
92
|
};
|
|
90
93
|
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
const formatFunction =
|
|
94
|
+
// Create a type-safe wrapper for the cli-progress formatter
|
|
95
|
+
// This ensures our formatter function matches the expected signature
|
|
96
|
+
const formatFunction: cliProgress.GenericFormatter = (
|
|
97
|
+
options: Record<string, unknown>,
|
|
98
|
+
params: Record<string, unknown>,
|
|
99
|
+
payload: Record<string, unknown>,
|
|
100
|
+
) => formatter(options, params, payload);
|
|
94
101
|
|
|
95
102
|
this.multibar = new cliProgress.MultiBar(
|
|
96
103
|
{
|
|
97
|
-
format: formatFunction
|
|
104
|
+
format: formatFunction,
|
|
98
105
|
barCompleteChar: "\u2588",
|
|
99
106
|
barIncompleteChar: "\u2591",
|
|
100
107
|
hideCursor: true,
|
|
@@ -149,7 +156,7 @@ export class RichProgressReporter {
|
|
|
149
156
|
* Start progress tracking
|
|
150
157
|
*/
|
|
151
158
|
start(): void {
|
|
152
|
-
|
|
159
|
+
this.cliConsole.info(chalk.blue.bold("\n🚀 Starting deployment...\n"));
|
|
153
160
|
|
|
154
161
|
// Create bars for each step
|
|
155
162
|
for (const step of this.steps) {
|
|
@@ -238,7 +245,7 @@ export class RichProgressReporter {
|
|
|
238
245
|
if (success) {
|
|
239
246
|
this.showSuccessSummary();
|
|
240
247
|
} else {
|
|
241
|
-
|
|
248
|
+
this.cliConsole.error(chalk.red("\n❌ Deployment failed\n"));
|
|
242
249
|
}
|
|
243
250
|
}
|
|
244
251
|
|
|
@@ -248,33 +255,37 @@ export class RichProgressReporter {
|
|
|
248
255
|
private showSuccessSummary(): void {
|
|
249
256
|
const duration = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
250
257
|
|
|
251
|
-
|
|
258
|
+
this.cliConsole.success(
|
|
259
|
+
chalk.green.bold("\n✅ Deployment completed successfully!\n"),
|
|
260
|
+
);
|
|
252
261
|
|
|
253
262
|
if (Object.keys(this.stats).length > 0) {
|
|
254
|
-
|
|
263
|
+
this.cliConsole.info(chalk.blue("📊 Build Stats:"));
|
|
255
264
|
|
|
256
265
|
if (this.stats.bundleSize) {
|
|
257
266
|
const sizeKB = (this.stats.bundleSize / 1024).toFixed(1);
|
|
258
267
|
const gzipKB = this.stats.gzippedSize
|
|
259
268
|
? (this.stats.gzippedSize / 1024).toFixed(1)
|
|
260
269
|
: "?";
|
|
261
|
-
|
|
270
|
+
this.cliConsole.info(
|
|
271
|
+
` • Bundle size: ${sizeKB}KB (gzipped: ${gzipKB}KB)`,
|
|
272
|
+
);
|
|
262
273
|
}
|
|
263
274
|
|
|
264
275
|
if (this.stats.removedExports) {
|
|
265
|
-
|
|
276
|
+
this.cliConsole.info(
|
|
266
277
|
` • Tree shaking: Removed ${this.stats.removedExports} unused exports`,
|
|
267
278
|
);
|
|
268
279
|
}
|
|
269
280
|
|
|
270
281
|
if (this.stats.dependencies) {
|
|
271
|
-
|
|
282
|
+
this.cliConsole.info(` • Dependencies: ${this.stats.dependencies}`);
|
|
272
283
|
}
|
|
273
284
|
|
|
274
|
-
|
|
285
|
+
this.cliConsole.info("");
|
|
275
286
|
}
|
|
276
287
|
|
|
277
|
-
|
|
288
|
+
this.cliConsole.info(chalk.dim(`Total time: ${duration}s`));
|
|
278
289
|
}
|
|
279
290
|
}
|
|
280
291
|
|
|
@@ -9,19 +9,42 @@ import {
|
|
|
9
9
|
} from "../schemas/command.schema";
|
|
10
10
|
import type { CliConsole } from "./console";
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Result of a validation operation
|
|
14
|
+
* @interface ValidationResult
|
|
15
|
+
* @property {boolean} valid - Whether the validation passed
|
|
16
|
+
* @property {Array<{message?: string} | string>} [errors] - List of validation errors
|
|
17
|
+
* @property {Array<{message?: string} | string>} [warnings] - List of validation warnings
|
|
18
|
+
*/
|
|
12
19
|
export interface ValidationResult {
|
|
13
20
|
valid: boolean;
|
|
14
21
|
errors?: Array<{ message?: string } | string>;
|
|
15
22
|
warnings?: Array<{ message?: string } | string>;
|
|
16
23
|
}
|
|
17
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Interface for managing spinner states
|
|
27
|
+
* @interface SpinnerManager
|
|
28
|
+
* @property {Function} succeed - Mark spinner as successful with message
|
|
29
|
+
* @property {Function} fail - Mark spinner as failed with message
|
|
30
|
+
*/
|
|
18
31
|
export interface SpinnerManager {
|
|
19
32
|
succeed: (text: string) => void;
|
|
20
33
|
fail: (text: string) => void;
|
|
21
34
|
}
|
|
22
35
|
|
|
23
36
|
/**
|
|
24
|
-
*
|
|
37
|
+
* Validates a component name against naming conventions
|
|
38
|
+
* Component names must be lowercase, use hyphens, and follow kebab-case
|
|
39
|
+
*
|
|
40
|
+
* @param {string} name - The component name to validate
|
|
41
|
+
* @returns {true | string} Returns true if valid, or an error message string if invalid
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* validateComponentName("my-header") // returns true
|
|
45
|
+
* validateComponentName("MyHeader") // returns "Component name must be lowercase"
|
|
46
|
+
* validateComponentName("my_header") // returns "Use hyphens instead of underscores"
|
|
47
|
+
* ```
|
|
25
48
|
*/
|
|
26
49
|
export function validateComponentName(name: string): true | string {
|
|
27
50
|
const result = ComponentNameSchema.safeParse(name);
|
|
@@ -31,7 +54,17 @@ export function validateComponentName(name: string): true | string {
|
|
|
31
54
|
}
|
|
32
55
|
|
|
33
56
|
/**
|
|
34
|
-
*
|
|
57
|
+
* Validates a function name against naming conventions
|
|
58
|
+
* Function names must be lowercase, use hyphens, and follow kebab-case
|
|
59
|
+
*
|
|
60
|
+
* @param {string} name - The function name to validate
|
|
61
|
+
* @returns {true | string} Returns true if valid, or an error message string if invalid
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* validateFunctionName("validate-cart") // returns true
|
|
65
|
+
* validateFunctionName("validateCart") // returns "Function name must be lowercase"
|
|
66
|
+
* validateFunctionName("validate cart") // returns "No spaces allowed in function names"
|
|
67
|
+
* ```
|
|
35
68
|
*/
|
|
36
69
|
export function validateFunctionName(name: string): true | string {
|
|
37
70
|
const result = FunctionNameSchema.safeParse(name);
|
|
@@ -41,7 +74,15 @@ export function validateFunctionName(name: string): true | string {
|
|
|
41
74
|
}
|
|
42
75
|
|
|
43
76
|
/**
|
|
44
|
-
*
|
|
77
|
+
* Validates a store ID is in proper UUID v4 format
|
|
78
|
+
*
|
|
79
|
+
* @param {string} storeId - The store ID to validate
|
|
80
|
+
* @returns {true | string} Returns true if valid UUID, or an error message if invalid
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* validateStoreId("123e4567-e89b-12d3-a456-426614174000") // returns true
|
|
84
|
+
* validateStoreId("invalid-id") // returns "Invalid store ID format"
|
|
85
|
+
* ```
|
|
45
86
|
*/
|
|
46
87
|
export function validateStoreId(storeId: string): true | string {
|
|
47
88
|
const result = StoreIdSchema.safeParse(storeId);
|
|
@@ -51,7 +92,17 @@ export function validateStoreId(storeId: string): true | string {
|
|
|
51
92
|
}
|
|
52
93
|
|
|
53
94
|
/**
|
|
54
|
-
*
|
|
95
|
+
* Validates a version name meets requirements
|
|
96
|
+
* Version names must be 1-100 characters long
|
|
97
|
+
*
|
|
98
|
+
* @param {string} name - The version name to validate
|
|
99
|
+
* @returns {true | string} Returns true if valid, or an error message if invalid
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* validateVersionName("Production v2.0") // returns true
|
|
103
|
+
* validateVersionName("") // returns "Version name is required"
|
|
104
|
+
* validateVersionName("a".repeat(101)) // returns "Version name is too long (max 100 characters)"
|
|
105
|
+
* ```
|
|
55
106
|
*/
|
|
56
107
|
export function validateVersionName(name: string): true | string {
|
|
57
108
|
const result = VersionNameSchema.safeParse(name);
|
|
@@ -61,7 +112,19 @@ export function validateVersionName(name: string): true | string {
|
|
|
61
112
|
}
|
|
62
113
|
|
|
63
114
|
/**
|
|
64
|
-
*
|
|
115
|
+
* Validates a priority value is within acceptable range
|
|
116
|
+
* Priority must be an integer between 0 and 100 (inclusive)
|
|
117
|
+
*
|
|
118
|
+
* @param {number} priority - The priority value to validate
|
|
119
|
+
* @returns {true | string} Returns true if valid, or an error message if invalid
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* validatePriority(50) // returns true
|
|
123
|
+
* validatePriority(0) // returns true (minimum)
|
|
124
|
+
* validatePriority(100) // returns true (maximum)
|
|
125
|
+
* validatePriority(150) // returns "Priority must be between 0 and 100"
|
|
126
|
+
* validatePriority(50.5) // returns "Priority must be a whole number"
|
|
127
|
+
* ```
|
|
65
128
|
*/
|
|
66
129
|
export function validatePriority(priority: number): true | string {
|
|
67
130
|
const result = PrioritySchema.safeParse(priority);
|
|
@@ -71,7 +134,19 @@ export function validatePriority(priority: number): true | string {
|
|
|
71
134
|
}
|
|
72
135
|
|
|
73
136
|
/**
|
|
74
|
-
*
|
|
137
|
+
* Validates a URL or URL pattern for functions
|
|
138
|
+
* Supports both full URLs (http/https) and path patterns (e.g., /api/*)
|
|
139
|
+
*
|
|
140
|
+
* @param {string} url - The URL or pattern to validate
|
|
141
|
+
* @returns {true | string} Returns true if valid, or an error message if invalid
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* validateUrl("https://api.example.com/webhook") // returns true
|
|
145
|
+
* validateUrl("/api/cart/*") // returns true (path pattern)
|
|
146
|
+
* validateUrl("/*") // returns true (wildcard pattern)
|
|
147
|
+
* validateUrl("ftp://example.com") // returns "URL must be a valid URL or path pattern"
|
|
148
|
+
* validateUrl("") // returns "URL is required"
|
|
149
|
+
* ```
|
|
75
150
|
*/
|
|
76
151
|
export function validateUrl(url: string): true | string {
|
|
77
152
|
const result = UrlSchema.safeParse(url);
|
|
@@ -81,7 +156,18 @@ export function validateUrl(url: string): true | string {
|
|
|
81
156
|
}
|
|
82
157
|
|
|
83
158
|
/**
|
|
84
|
-
*
|
|
159
|
+
* Validates a semantic version string
|
|
160
|
+
* Must follow semver format: MAJOR.MINOR.PATCH (e.g., 1.0.0)
|
|
161
|
+
*
|
|
162
|
+
* @param {string} version - The version string to validate
|
|
163
|
+
* @returns {true | string} Returns true if valid semver, or an error message if invalid
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* validateSemver("1.0.0") // returns true
|
|
167
|
+
* validateSemver("2.4.6") // returns true
|
|
168
|
+
* validateSemver("1.0") // returns "Version must follow semantic versioning format (e.g., 1.0.0)"
|
|
169
|
+
* validateSemver("v1.0.0") // returns "Version must follow semantic versioning format (e.g., 1.0.0)"
|
|
170
|
+
* ```
|
|
85
171
|
*/
|
|
86
172
|
export function validateSemver(version: string): true | string {
|
|
87
173
|
const result = SemverSchema.safeParse(version);
|
|
@@ -91,7 +177,19 @@ export function validateSemver(version: string): true | string {
|
|
|
91
177
|
}
|
|
92
178
|
|
|
93
179
|
/**
|
|
94
|
-
*
|
|
180
|
+
* Processes and displays validation errors to the user
|
|
181
|
+
* Formats errors into a readable list with bullet points
|
|
182
|
+
*
|
|
183
|
+
* @param {Array<{message?: string} | string>} errors - Array of error objects or strings
|
|
184
|
+
* @param {CliConsole} cliConsole - Console instance for output
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* processValidationErrors(["Invalid name", {message: "Path not found"}], console);
|
|
188
|
+
* // Output:
|
|
189
|
+
* // Errors:
|
|
190
|
+
* // • Invalid name
|
|
191
|
+
* // • Path not found
|
|
192
|
+
* ```
|
|
95
193
|
*/
|
|
96
194
|
export function processValidationErrors(
|
|
97
195
|
errors: Array<{ message?: string } | string>,
|
|
@@ -105,7 +203,18 @@ export function processValidationErrors(
|
|
|
105
203
|
}
|
|
106
204
|
|
|
107
205
|
/**
|
|
108
|
-
*
|
|
206
|
+
* Processes and displays validation warnings to the user
|
|
207
|
+
* Formats warnings into a readable list with bullet points
|
|
208
|
+
*
|
|
209
|
+
* @param {Array<{message?: string} | string>} warnings - Array of warning objects or strings
|
|
210
|
+
* @param {CliConsole} cliConsole - Console instance for output
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* processValidationWarnings(["Deprecated feature used"], console);
|
|
214
|
+
* // Output:
|
|
215
|
+
* // Warnings:
|
|
216
|
+
* // • Deprecated feature used
|
|
217
|
+
* ```
|
|
109
218
|
*/
|
|
110
219
|
export function processValidationWarnings(
|
|
111
220
|
warnings: Array<{ message?: string } | string>,
|
|
@@ -120,7 +229,19 @@ export function processValidationWarnings(
|
|
|
120
229
|
}
|
|
121
230
|
|
|
122
231
|
/**
|
|
123
|
-
*
|
|
232
|
+
* Handles validation results by updating spinner state and displaying errors/warnings
|
|
233
|
+
* Central function for processing validation outcomes in CLI commands
|
|
234
|
+
*
|
|
235
|
+
* @param {ValidationResult | unknown} result - Validation result object or unknown type
|
|
236
|
+
* @param {SpinnerManager} spinner - Spinner instance to update visual feedback
|
|
237
|
+
* @param {CliConsole} cliConsole - Console instance for output
|
|
238
|
+
* @param {string} entityType - Type of entity being validated (e.g., "Component", "Function")
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* const result = await validateComponent(path);
|
|
242
|
+
* handleValidationResult(result, spinner, console, "Component");
|
|
243
|
+
* // Updates spinner to success/fail and displays any errors or warnings
|
|
244
|
+
* ```
|
|
124
245
|
*/
|
|
125
246
|
export function handleValidationResult(
|
|
126
247
|
result: ValidationResult | unknown,
|
|
@@ -140,7 +261,14 @@ export function handleValidationResult(
|
|
|
140
261
|
}
|
|
141
262
|
|
|
142
263
|
/**
|
|
143
|
-
*
|
|
264
|
+
* Updates spinner state based on validation success/failure
|
|
265
|
+
* Internal helper for handleValidationResult
|
|
266
|
+
*
|
|
267
|
+
* @param {ValidationResult} result - Validation result with valid status
|
|
268
|
+
* @param {SpinnerManager} spinner - Spinner to update
|
|
269
|
+
* @param {CliConsole} cliConsole - Console for error output
|
|
270
|
+
* @param {string} entityType - Type of entity for messaging
|
|
271
|
+
* @private
|
|
144
272
|
*/
|
|
145
273
|
function handleValidResult(
|
|
146
274
|
result: ValidationResult,
|
|
@@ -159,7 +287,12 @@ function handleValidResult(
|
|
|
159
287
|
}
|
|
160
288
|
|
|
161
289
|
/**
|
|
162
|
-
*
|
|
290
|
+
* Displays validation warnings if present
|
|
291
|
+
* Internal helper for handleValidationResult
|
|
292
|
+
*
|
|
293
|
+
* @param {ValidationResult} result - Validation result potentially containing warnings
|
|
294
|
+
* @param {CliConsole} cliConsole - Console for warning output
|
|
295
|
+
* @private
|
|
163
296
|
*/
|
|
164
297
|
function handleValidationWarnings(
|
|
165
298
|
result: ValidationResult,
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
bundle: true,
|
|
6
|
+
minify: false,
|
|
7
|
+
sourcemap: false,
|
|
8
|
+
format: ["cjs"],
|
|
9
|
+
clean: true,
|
|
10
|
+
dts: true,
|
|
11
|
+
treeshake: true,
|
|
12
|
+
platform: "node",
|
|
13
|
+
target: "node18",
|
|
14
|
+
noExternal: ["@ollie-shop/core"],
|
|
15
|
+
});
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { Command } from "@commander-js/extra-typings";
|
|
2
|
-
import { vi } from "vitest";
|
|
3
|
-
/**
|
|
4
|
-
* CLI Testing Helper for Commander.js applications
|
|
5
|
-
* Based on best practices for testing CLI applications with Vitest
|
|
6
|
-
*/
|
|
7
|
-
export interface CLITestResult {
|
|
8
|
-
exitCode: number;
|
|
9
|
-
stdout: string[];
|
|
10
|
-
stderr: string[];
|
|
11
|
-
error?: Error;
|
|
12
|
-
}
|
|
13
|
-
export interface ProcessMocks {
|
|
14
|
-
exit: ReturnType<typeof vi.fn>;
|
|
15
|
-
stdout: {
|
|
16
|
-
write: ReturnType<typeof vi.fn>;
|
|
17
|
-
};
|
|
18
|
-
stderr: {
|
|
19
|
-
write: ReturnType<typeof vi.fn>;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
export interface ConsoleMocks {
|
|
23
|
-
log: ReturnType<typeof vi.fn>;
|
|
24
|
-
error: ReturnType<typeof vi.fn>;
|
|
25
|
-
warn: ReturnType<typeof vi.fn>;
|
|
26
|
-
info: ReturnType<typeof vi.fn>;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Create a test-friendly Commander.js program that captures output
|
|
30
|
-
* and prevents process.exit from terminating the test
|
|
31
|
-
*/
|
|
32
|
-
export declare function createTestProgram(): {
|
|
33
|
-
program: Command;
|
|
34
|
-
mocks: {
|
|
35
|
-
process: ProcessMocks;
|
|
36
|
-
console: ConsoleMocks;
|
|
37
|
-
};
|
|
38
|
-
getResult: () => CLITestResult;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Execute a CLI command with arguments and capture the result
|
|
42
|
-
*/
|
|
43
|
-
export declare function executeCLI(program: Command, args: string[], options?: {
|
|
44
|
-
from: "node" | "electron" | "user";
|
|
45
|
-
}): Promise<CLITestResult>;
|
|
46
|
-
/**
|
|
47
|
-
* Reset all CLI test mocks between tests
|
|
48
|
-
*/
|
|
49
|
-
export declare function resetCLIMocks(): void;
|
|
50
|
-
/**
|
|
51
|
-
* Create mock for inquirer prompts
|
|
52
|
-
*/
|
|
53
|
-
export declare function createInquirerMock(responses: Record<string, unknown>): {
|
|
54
|
-
prompt: import("vitest").Mock<(...args: any[]) => any>;
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Create mock for ora spinner
|
|
58
|
-
*/
|
|
59
|
-
export declare function createSpinnerMock(): {
|
|
60
|
-
mock: {
|
|
61
|
-
start: import("vitest").Mock<(...args: any[]) => any>;
|
|
62
|
-
stop: import("vitest").Mock<(...args: any[]) => any>;
|
|
63
|
-
succeed: import("vitest").Mock<(...args: any[]) => any>;
|
|
64
|
-
fail: import("vitest").Mock<(...args: any[]) => any>;
|
|
65
|
-
warn: import("vitest").Mock<(...args: any[]) => any>;
|
|
66
|
-
info: import("vitest").Mock<(...args: any[]) => any>;
|
|
67
|
-
text: string;
|
|
68
|
-
isSpinning: boolean;
|
|
69
|
-
};
|
|
70
|
-
create: import("vitest").Mock<() => {
|
|
71
|
-
start: import("vitest").Mock<(...args: any[]) => any>;
|
|
72
|
-
stop: import("vitest").Mock<(...args: any[]) => any>;
|
|
73
|
-
succeed: import("vitest").Mock<(...args: any[]) => any>;
|
|
74
|
-
fail: import("vitest").Mock<(...args: any[]) => any>;
|
|
75
|
-
warn: import("vitest").Mock<(...args: any[]) => any>;
|
|
76
|
-
info: import("vitest").Mock<(...args: any[]) => any>;
|
|
77
|
-
text: string;
|
|
78
|
-
isSpinning: boolean;
|
|
79
|
-
}>;
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Assert CLI output contains expected text
|
|
83
|
-
*/
|
|
84
|
-
export declare function expectCLIOutput(result: CLITestResult, expected: {
|
|
85
|
-
stdout?: string | RegExp;
|
|
86
|
-
stderr?: string | RegExp;
|
|
87
|
-
exitCode?: number;
|
|
88
|
-
}): void;
|
|
89
|
-
//# sourceMappingURL=cli-test-helper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-test-helper.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/cli-test-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAU,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,EAAE;QACN,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;KACjC,CAAC;IACF,MAAM,EAAE;QACN,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;KACjC,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9B,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE;QACL,OAAO,EAAE,YAAY,CAAC;QACtB,OAAO,EAAE,YAAY,CAAC;KACvB,CAAC;IACF,SAAS,EAAE,MAAM,aAAa,CAAC;CAChC,CAgGA;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAA;CAAqB,GACjE,OAAO,CAAC,aAAa,CAAC,CAgDxB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAgBpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAgBhC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,QAuBF"}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createTestProgram = createTestProgram;
|
|
4
|
-
exports.executeCLI = executeCLI;
|
|
5
|
-
exports.resetCLIMocks = resetCLIMocks;
|
|
6
|
-
exports.createInquirerMock = createInquirerMock;
|
|
7
|
-
exports.createSpinnerMock = createSpinnerMock;
|
|
8
|
-
exports.expectCLIOutput = expectCLIOutput;
|
|
9
|
-
const extra_typings_1 = require("@commander-js/extra-typings");
|
|
10
|
-
const vitest_1 = require("vitest");
|
|
11
|
-
/**
|
|
12
|
-
* Create a test-friendly Commander.js program that captures output
|
|
13
|
-
* and prevents process.exit from terminating the test
|
|
14
|
-
*/
|
|
15
|
-
function createTestProgram() {
|
|
16
|
-
const stdout = [];
|
|
17
|
-
const stderr = [];
|
|
18
|
-
let exitCode = 0;
|
|
19
|
-
let capturedError;
|
|
20
|
-
// Mock process methods
|
|
21
|
-
const processMocks = {
|
|
22
|
-
exit: vitest_1.vi.fn((code = 0) => {
|
|
23
|
-
exitCode = code;
|
|
24
|
-
// Throw error instead of exiting to prevent test termination
|
|
25
|
-
throw new Error(`process.exit(${code})`);
|
|
26
|
-
}),
|
|
27
|
-
stdout: {
|
|
28
|
-
write: vitest_1.vi.fn((data) => {
|
|
29
|
-
stdout.push(data);
|
|
30
|
-
return true;
|
|
31
|
-
}),
|
|
32
|
-
},
|
|
33
|
-
stderr: {
|
|
34
|
-
write: vitest_1.vi.fn((data) => {
|
|
35
|
-
stderr.push(data);
|
|
36
|
-
return true;
|
|
37
|
-
}),
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
// Mock console methods
|
|
41
|
-
const consoleMocks = {
|
|
42
|
-
log: vitest_1.vi.fn((...args) => {
|
|
43
|
-
stdout.push(`${args.join(" ")}\n`);
|
|
44
|
-
}),
|
|
45
|
-
error: vitest_1.vi.fn((...args) => {
|
|
46
|
-
stderr.push(`${args.join(" ")}\n`);
|
|
47
|
-
}),
|
|
48
|
-
warn: vitest_1.vi.fn((...args) => {
|
|
49
|
-
stderr.push(`${args.join(" ")}\n`);
|
|
50
|
-
}),
|
|
51
|
-
info: vitest_1.vi.fn((...args) => {
|
|
52
|
-
stdout.push(`${args.join(" ")}\n`);
|
|
53
|
-
}),
|
|
54
|
-
};
|
|
55
|
-
// Apply mocks
|
|
56
|
-
vitest_1.vi.spyOn(process, "exit").mockImplementation(((code) => {
|
|
57
|
-
throw new Error(`Process exit with code ${code}`);
|
|
58
|
-
}));
|
|
59
|
-
vitest_1.vi.spyOn(process.stdout, "write").mockImplementation(processMocks.stdout.write);
|
|
60
|
-
vitest_1.vi.spyOn(process.stderr, "write").mockImplementation(processMocks.stderr.write);
|
|
61
|
-
vitest_1.vi.spyOn(console, "log").mockImplementation(consoleMocks.log);
|
|
62
|
-
vitest_1.vi.spyOn(console, "error").mockImplementation(consoleMocks.error);
|
|
63
|
-
vitest_1.vi.spyOn(console, "warn").mockImplementation(consoleMocks.warn);
|
|
64
|
-
vitest_1.vi.spyOn(console, "info").mockImplementation(consoleMocks.info);
|
|
65
|
-
// Also mock global.console which is used by the CLI console utility
|
|
66
|
-
vitest_1.vi.spyOn(global.console, "log").mockImplementation(consoleMocks.log);
|
|
67
|
-
vitest_1.vi.spyOn(global.console, "error").mockImplementation(consoleMocks.error);
|
|
68
|
-
vitest_1.vi.spyOn(global.console, "warn").mockImplementation(consoleMocks.warn);
|
|
69
|
-
vitest_1.vi.spyOn(global.console, "info").mockImplementation(consoleMocks.info);
|
|
70
|
-
// Create program with exitOverride to handle errors gracefully
|
|
71
|
-
const program = new extra_typings_1.Command();
|
|
72
|
-
program
|
|
73
|
-
.exitOverride((err) => {
|
|
74
|
-
capturedError = err;
|
|
75
|
-
exitCode = err.exitCode || 1;
|
|
76
|
-
throw err;
|
|
77
|
-
})
|
|
78
|
-
.configureOutput({
|
|
79
|
-
writeOut: (str) => {
|
|
80
|
-
stdout.push(str);
|
|
81
|
-
},
|
|
82
|
-
writeErr: (str) => {
|
|
83
|
-
stderr.push(str);
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
const getResult = () => ({
|
|
87
|
-
exitCode,
|
|
88
|
-
stdout: [...stdout],
|
|
89
|
-
stderr: [...stderr],
|
|
90
|
-
error: capturedError,
|
|
91
|
-
});
|
|
92
|
-
return {
|
|
93
|
-
program,
|
|
94
|
-
mocks: {
|
|
95
|
-
process: processMocks,
|
|
96
|
-
console: consoleMocks,
|
|
97
|
-
},
|
|
98
|
-
getResult,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Execute a CLI command with arguments and capture the result
|
|
103
|
-
*/
|
|
104
|
-
async function executeCLI(program, args, options = { from: "user" }) {
|
|
105
|
-
const stdout = [];
|
|
106
|
-
const stderr = [];
|
|
107
|
-
let exitCode = 0;
|
|
108
|
-
let capturedError;
|
|
109
|
-
// Capture output
|
|
110
|
-
const originalWriteOut = program.configureOutput().writeOut;
|
|
111
|
-
const originalWriteErr = program.configureOutput().writeErr;
|
|
112
|
-
program.configureOutput({
|
|
113
|
-
writeOut: (str) => {
|
|
114
|
-
stdout.push(str);
|
|
115
|
-
if (originalWriteOut)
|
|
116
|
-
originalWriteOut(str);
|
|
117
|
-
},
|
|
118
|
-
writeErr: (str) => {
|
|
119
|
-
stderr.push(str);
|
|
120
|
-
if (originalWriteErr)
|
|
121
|
-
originalWriteErr(str);
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
try {
|
|
125
|
-
await program.parseAsync(args, options);
|
|
126
|
-
}
|
|
127
|
-
catch (error) {
|
|
128
|
-
capturedError = error;
|
|
129
|
-
// Handle Commander.js specific errors
|
|
130
|
-
if (error && typeof error === "object" && "code" in error) {
|
|
131
|
-
const commanderError = error;
|
|
132
|
-
exitCode = commanderError.exitCode || 1;
|
|
133
|
-
}
|
|
134
|
-
else if (error instanceof Error &&
|
|
135
|
-
error.message.includes("process.exit")) {
|
|
136
|
-
// Handle our mocked process.exit
|
|
137
|
-
const match = error.message.match(/process\.exit\((\d+)\)/);
|
|
138
|
-
exitCode = match?.[1] ? Number.parseInt(match[1], 10) : 1;
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
exitCode = 1;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
exitCode,
|
|
146
|
-
stdout,
|
|
147
|
-
stderr,
|
|
148
|
-
error: capturedError,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Reset all CLI test mocks between tests
|
|
153
|
-
*/
|
|
154
|
-
function resetCLIMocks() {
|
|
155
|
-
vitest_1.vi.clearAllMocks();
|
|
156
|
-
vitest_1.vi.restoreAllMocks();
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Create mock for inquirer prompts
|
|
160
|
-
*/
|
|
161
|
-
function createInquirerMock(responses) {
|
|
162
|
-
return {
|
|
163
|
-
prompt: vitest_1.vi
|
|
164
|
-
.fn()
|
|
165
|
-
.mockImplementation((questions) => {
|
|
166
|
-
const answers = {};
|
|
167
|
-
for (const question of questions) {
|
|
168
|
-
if (question.name && responses[question.name] !== undefined) {
|
|
169
|
-
answers[question.name] = responses[question.name];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return Promise.resolve(answers);
|
|
173
|
-
}),
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Create mock for ora spinner
|
|
178
|
-
*/
|
|
179
|
-
function createSpinnerMock() {
|
|
180
|
-
const mock = {
|
|
181
|
-
start: vitest_1.vi.fn().mockReturnThis(),
|
|
182
|
-
stop: vitest_1.vi.fn().mockReturnThis(),
|
|
183
|
-
succeed: vitest_1.vi.fn().mockReturnThis(),
|
|
184
|
-
fail: vitest_1.vi.fn().mockReturnThis(),
|
|
185
|
-
warn: vitest_1.vi.fn().mockReturnThis(),
|
|
186
|
-
info: vitest_1.vi.fn().mockReturnThis(),
|
|
187
|
-
text: "",
|
|
188
|
-
isSpinning: false,
|
|
189
|
-
};
|
|
190
|
-
return {
|
|
191
|
-
mock,
|
|
192
|
-
create: vitest_1.vi.fn(() => mock),
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Assert CLI output contains expected text
|
|
197
|
-
*/
|
|
198
|
-
function expectCLIOutput(result, expected) {
|
|
199
|
-
if (expected.exitCode !== undefined) {
|
|
200
|
-
(0, vitest_1.expect)(result.exitCode).toBe(expected.exitCode);
|
|
201
|
-
}
|
|
202
|
-
if (expected.stdout !== undefined) {
|
|
203
|
-
const stdoutText = result.stdout.join("");
|
|
204
|
-
if (typeof expected.stdout === "string") {
|
|
205
|
-
(0, vitest_1.expect)(stdoutText).toContain(expected.stdout);
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
(0, vitest_1.expect)(stdoutText).toMatch(expected.stdout);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
if (expected.stderr !== undefined) {
|
|
212
|
-
const stderrText = result.stderr.join("");
|
|
213
|
-
if (typeof expected.stderr === "string") {
|
|
214
|
-
(0, vitest_1.expect)(stderrText).toContain(expected.stderr);
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
(0, vitest_1.expect)(stderrText).toMatch(expected.stderr);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|