@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
|
@@ -16,21 +16,55 @@ export { ComponentNameSchema, FunctionNameSchema };
|
|
|
16
16
|
/**
|
|
17
17
|
* CLI-specific schemas (only for CLI-specific concerns)
|
|
18
18
|
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Schema for file system paths
|
|
22
|
+
* @example "./src/components/header"
|
|
23
|
+
* @example "/absolute/path/to/component"
|
|
24
|
+
*/
|
|
19
25
|
export const PathSchema = z.string().min(1, "Path cannot be empty");
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Schema for store identifiers
|
|
29
|
+
* Must be a valid UUID v4 format
|
|
30
|
+
* @example "123e4567-e89b-12d3-a456-426614174000"
|
|
31
|
+
*/
|
|
21
32
|
export const StoreIdSchema = z.string().uuid("Invalid store ID format");
|
|
22
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Schema for version names
|
|
36
|
+
* @example "Production v2.0"
|
|
37
|
+
* @example "Holiday Sale Version"
|
|
38
|
+
* @minLength 1
|
|
39
|
+
* @maxLength 100
|
|
40
|
+
*/
|
|
23
41
|
export const VersionNameSchema = z
|
|
24
42
|
.string()
|
|
25
43
|
.min(1, "Version name is required")
|
|
26
44
|
.max(100, "Version name is too long (max 100 characters)");
|
|
27
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Schema for function execution priority
|
|
48
|
+
* Higher numbers execute first
|
|
49
|
+
* @minimum 0
|
|
50
|
+
* @maximum 100
|
|
51
|
+
* @example 50 - Default priority
|
|
52
|
+
* @example 90 - High priority (executes early)
|
|
53
|
+
* @example 10 - Low priority (executes late)
|
|
54
|
+
*/
|
|
28
55
|
export const PrioritySchema = z
|
|
29
56
|
.number()
|
|
30
57
|
.int("Priority must be a whole number")
|
|
31
58
|
.min(0, "Priority must be between 0 and 100")
|
|
32
59
|
.max(100, "Priority must be between 0 and 100");
|
|
33
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Schema for URLs and URL patterns
|
|
63
|
+
* Supports both full URLs and path patterns
|
|
64
|
+
* @example "https://api.example.com/webhook"
|
|
65
|
+
* @example "/api/cart/*"
|
|
66
|
+
* @example "/*" - Matches all paths
|
|
67
|
+
*/
|
|
34
68
|
export const UrlSchema = z
|
|
35
69
|
.string()
|
|
36
70
|
.min(1, "URL is required")
|
|
@@ -48,6 +82,13 @@ export const UrlSchema = z
|
|
|
48
82
|
}
|
|
49
83
|
}, "URL must be a valid URL or path pattern");
|
|
50
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Schema for semantic version numbers
|
|
87
|
+
* @pattern ^\d+\.\d+\.\d+$
|
|
88
|
+
* @example "1.0.0"
|
|
89
|
+
* @example "2.4.6"
|
|
90
|
+
* @see https://semver.org/
|
|
91
|
+
*/
|
|
51
92
|
export const SemverSchema = z
|
|
52
93
|
.string()
|
|
53
94
|
.regex(
|
|
@@ -58,6 +99,19 @@ export const SemverSchema = z
|
|
|
58
99
|
/**
|
|
59
100
|
* Component command schemas
|
|
60
101
|
*/
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Options for creating a new component
|
|
105
|
+
* @property {string} [name] - Component name in kebab-case (e.g., "header-banner")
|
|
106
|
+
* @property {"header"|"main"|"footer"|"sidebar"} [slot="main"] - Where the component renders in the checkout
|
|
107
|
+
* @property {boolean} [tests=true] - Whether to generate test files
|
|
108
|
+
* @property {string} [template] - Custom template to use for generation
|
|
109
|
+
* @property {boolean} [interactive] - Use interactive mode with prompts
|
|
110
|
+
* @example
|
|
111
|
+
* // CLI usage:
|
|
112
|
+
* ollieshop component create --name header-banner --slot header
|
|
113
|
+
* ollieshop component create --interactive
|
|
114
|
+
*/
|
|
61
115
|
export const ComponentCreateOptionsSchema = z
|
|
62
116
|
.object({
|
|
63
117
|
name: ComponentNameSchema.optional(), // Optional for interactive mode
|
|
@@ -71,6 +125,18 @@ export const ComponentCreateOptionsSchema = z
|
|
|
71
125
|
path: ["name"],
|
|
72
126
|
});
|
|
73
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Options for building a component
|
|
130
|
+
* @property {string} [path] - Path to component directory (defaults to current directory)
|
|
131
|
+
* @property {boolean} [watch=false] - Watch for file changes and rebuild automatically
|
|
132
|
+
* @property {boolean} [minify=true] - Minify the output bundle
|
|
133
|
+
* @property {boolean} [sourcemap=true] - Generate source maps for debugging
|
|
134
|
+
* @example
|
|
135
|
+
* // CLI usage:
|
|
136
|
+
* ollieshop component build
|
|
137
|
+
* ollieshop component build --watch
|
|
138
|
+
* ollieshop component build --path ./components/header --no-minify
|
|
139
|
+
*/
|
|
74
140
|
export const ComponentBuildOptionsSchema = z.object({
|
|
75
141
|
path: PathSchema.optional(),
|
|
76
142
|
watch: z.boolean().optional(),
|
|
@@ -78,22 +144,57 @@ export const ComponentBuildOptionsSchema = z.object({
|
|
|
78
144
|
sourcemap: z.boolean().optional(),
|
|
79
145
|
});
|
|
80
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Options for validating a component
|
|
149
|
+
* @property {string} [path] - Path to component directory (defaults to current directory)
|
|
150
|
+
* @property {boolean} [strict=false] - Enable strict validation mode with additional checks
|
|
151
|
+
* @property {boolean} [fix=false] - Automatically fix fixable validation issues
|
|
152
|
+
* @example
|
|
153
|
+
* // CLI usage:
|
|
154
|
+
* ollieshop component validate
|
|
155
|
+
* ollieshop component validate --strict
|
|
156
|
+
* ollieshop component validate --fix
|
|
157
|
+
*/
|
|
81
158
|
export const ComponentValidateOptionsSchema = z.object({
|
|
82
159
|
path: PathSchema.optional(),
|
|
83
160
|
strict: z.boolean().optional(),
|
|
84
161
|
fix: z.boolean().optional(),
|
|
85
162
|
});
|
|
86
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Options for deploying a component
|
|
166
|
+
* @property {string} [path] - Path to component directory (defaults to current directory)
|
|
167
|
+
* @property {string} [componentId] - UUID of the component to deploy (internal use)
|
|
168
|
+
* @property {string} [id] - UUID of the component to deploy (CLI flag)
|
|
169
|
+
* @example
|
|
170
|
+
* // CLI usage:
|
|
171
|
+
* ollieshop component deploy --id 123e4567-e89b-12d3-a456-426614174000
|
|
172
|
+
* ollieshop component deploy --id 123e4567-e89b-12d3-a456-426614174000 --path ./dist
|
|
173
|
+
*/
|
|
87
174
|
export const ComponentDeployOptionsSchema = z.object({
|
|
88
175
|
path: PathSchema.optional(),
|
|
89
|
-
componentId: z.string().optional(),
|
|
90
|
-
id: z.string().optional(), // CLI uses --id flag
|
|
91
|
-
wait: z.boolean().optional(),
|
|
176
|
+
componentId: z.string().uuid("Invalid component ID format").optional(),
|
|
177
|
+
id: z.string().uuid("Invalid component ID format").optional(), // CLI uses --id flag
|
|
92
178
|
});
|
|
93
179
|
|
|
94
180
|
/**
|
|
95
181
|
* Function command schemas
|
|
96
182
|
*/
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Options for creating a new function
|
|
186
|
+
* @property {string} name - Function name in kebab-case (e.g., "validate-cart")
|
|
187
|
+
* @property {"request"|"response"} [invocation="request"] - When the function executes in the request lifecycle
|
|
188
|
+
* @property {number} [priority=0] - Execution priority (0-100, higher executes first)
|
|
189
|
+
* @property {"throw"|"skip"} [onError="throw"] - Error handling behavior
|
|
190
|
+
* @property {boolean} [tests=true] - Whether to generate test files
|
|
191
|
+
* @property {string} [template] - Custom template to use for generation
|
|
192
|
+
* @property {string} [description] - Human-readable description of function purpose
|
|
193
|
+
* @example
|
|
194
|
+
* // CLI usage:
|
|
195
|
+
* ollieshop function create --name validate-cart --invocation request --priority 90
|
|
196
|
+
* ollieshop function create --name apply-discount --on-error skip
|
|
197
|
+
*/
|
|
97
198
|
export const FunctionCreateOptionsSchema = z.object({
|
|
98
199
|
name: FunctionNameSchema,
|
|
99
200
|
invocation: FunctionInvocationType.optional().default("request"),
|
|
@@ -104,6 +205,18 @@ export const FunctionCreateOptionsSchema = z.object({
|
|
|
104
205
|
description: z.string().optional(),
|
|
105
206
|
});
|
|
106
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Options for building a function
|
|
210
|
+
* @property {string} [path] - Path to function directory (defaults to current directory)
|
|
211
|
+
* @property {boolean} [watch=false] - Watch for file changes and rebuild automatically
|
|
212
|
+
* @property {boolean} [minify=true] - Minify the output bundle
|
|
213
|
+
* @property {"node16"|"node18"|"node20"} [target="node18"] - Target Node.js runtime version
|
|
214
|
+
* @example
|
|
215
|
+
* // CLI usage:
|
|
216
|
+
* ollieshop function build
|
|
217
|
+
* ollieshop function build --watch --target node20
|
|
218
|
+
* ollieshop function build --no-minify
|
|
219
|
+
*/
|
|
107
220
|
export const FunctionBuildOptionsSchema = z.object({
|
|
108
221
|
path: PathSchema.optional(),
|
|
109
222
|
watch: z.boolean().optional(),
|
|
@@ -117,6 +230,19 @@ export const FunctionValidateOptionsSchema = z.object({
|
|
|
117
230
|
fix: z.boolean().optional(),
|
|
118
231
|
});
|
|
119
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Options for testing a function
|
|
235
|
+
* @property {string} [path] - Path to function directory (defaults to current directory)
|
|
236
|
+
* @property {string} [payload] - JSON payload to send to the function
|
|
237
|
+
* @property {number} [timeout=30000] - Test timeout in milliseconds
|
|
238
|
+
* @property {boolean} [coverage=false] - Generate code coverage report
|
|
239
|
+
* @property {boolean} [watch=false] - Run tests in watch mode
|
|
240
|
+
* @example
|
|
241
|
+
* // CLI usage:
|
|
242
|
+
* ollieshop function test
|
|
243
|
+
* ollieshop function test --payload '{"cart": {"total": 100}}'
|
|
244
|
+
* ollieshop function test --watch --coverage
|
|
245
|
+
*/
|
|
120
246
|
export const FunctionTestOptionsSchema = z.object({
|
|
121
247
|
path: PathSchema.optional(),
|
|
122
248
|
payload: z.string().optional(),
|
|
@@ -125,16 +251,42 @@ export const FunctionTestOptionsSchema = z.object({
|
|
|
125
251
|
watch: z.boolean().optional(),
|
|
126
252
|
});
|
|
127
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Options for deploying a function
|
|
256
|
+
* @property {string} [path] - Path to function directory (defaults to current directory)
|
|
257
|
+
* @property {string} [functionId] - UUID of the function to deploy (internal use)
|
|
258
|
+
* @property {string} [id] - UUID of the function to deploy (CLI flag)
|
|
259
|
+
* @example
|
|
260
|
+
* // CLI usage:
|
|
261
|
+
* ollieshop function deploy --id 123e4567-e89b-12d3-a456-426614174000
|
|
262
|
+
* ollieshop function deploy --id 123e4567-e89b-12d3-a456-426614174000 --path ./dist
|
|
263
|
+
*/
|
|
128
264
|
export const FunctionDeployOptionsSchema = z.object({
|
|
129
265
|
path: PathSchema.optional(),
|
|
130
|
-
functionId: z.string().optional(),
|
|
131
|
-
id: z.string().optional(), // CLI uses --id flag
|
|
132
|
-
wait: z.boolean().optional(),
|
|
266
|
+
functionId: z.string().uuid("Invalid function ID format").optional(),
|
|
267
|
+
id: z.string().uuid("Invalid function ID format").optional(), // CLI uses --id flag
|
|
133
268
|
});
|
|
134
269
|
|
|
135
270
|
/**
|
|
136
271
|
* Development server schemas
|
|
137
272
|
*/
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Options for running a development server
|
|
276
|
+
* @property {number} [port=3000] - Port number to run the server on (1000-65535)
|
|
277
|
+
* @property {string} [host="localhost"] - Host to bind the server to
|
|
278
|
+
* @property {boolean} [open=true] - Open browser automatically when server starts
|
|
279
|
+
* @property {string} [component] - Path to specific component to develop
|
|
280
|
+
* @property {string} [function] - Path to specific function to develop
|
|
281
|
+
* @property {string} [mockData] - Path to mock data file for testing
|
|
282
|
+
* @property {boolean} [hot=true] - Enable hot module replacement
|
|
283
|
+
* @property {boolean} [https=false] - Enable HTTPS with self-signed certificate
|
|
284
|
+
* @example
|
|
285
|
+
* // CLI usage:
|
|
286
|
+
* ollieshop dev
|
|
287
|
+
* ollieshop dev --port 8080 --no-open
|
|
288
|
+
* ollieshop dev --component ./components/header --hot
|
|
289
|
+
*/
|
|
138
290
|
export const DevServerOptionsSchema = z.object({
|
|
139
291
|
port: z.number().min(1000).max(65535).default(3000),
|
|
140
292
|
host: z.string().default("localhost"),
|
|
@@ -149,6 +301,20 @@ export const DevServerOptionsSchema = z.object({
|
|
|
149
301
|
/**
|
|
150
302
|
* Global CLI options schemas
|
|
151
303
|
*/
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Global options available for all CLI commands
|
|
307
|
+
* @property {boolean} [verbose=false] - Show detailed output and debug information
|
|
308
|
+
* @property {boolean} [quiet=false] - Suppress all output except errors
|
|
309
|
+
* @property {boolean} [color=true] - Enable colored output (use --no-color to disable)
|
|
310
|
+
* @property {string} [config] - Path to custom configuration file
|
|
311
|
+
* @property {"error"|"warn"|"info"|"debug"} [logLevel="info"] - Minimum log level to display
|
|
312
|
+
* @example
|
|
313
|
+
* // CLI usage:
|
|
314
|
+
* ollieshop --verbose component create --name header
|
|
315
|
+
* ollieshop --quiet function deploy --id abc-123
|
|
316
|
+
* ollieshop --no-color --log-level debug component build
|
|
317
|
+
*/
|
|
152
318
|
export const GlobalOptionsSchema = z.object({
|
|
153
319
|
verbose: z.boolean().default(false),
|
|
154
320
|
quiet: z.boolean().default(false),
|
|
@@ -160,6 +326,21 @@ export const GlobalOptionsSchema = z.object({
|
|
|
160
326
|
/**
|
|
161
327
|
* Build command schemas
|
|
162
328
|
*/
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Options for building projects, components, or functions
|
|
332
|
+
* @property {string} [path] - Path to build (defaults to current directory)
|
|
333
|
+
* @property {string} [output] - Output directory for build artifacts
|
|
334
|
+
* @property {boolean} [minify=true] - Minify the output
|
|
335
|
+
* @property {boolean} [sourcemap=true] - Generate source maps
|
|
336
|
+
* @property {boolean} [watch=false] - Watch mode for continuous builds
|
|
337
|
+
* @property {boolean} [clean=true] - Clean output directory before building
|
|
338
|
+
* @example
|
|
339
|
+
* // CLI usage:
|
|
340
|
+
* ollieshop build
|
|
341
|
+
* ollieshop build --output ./dist --no-minify
|
|
342
|
+
* ollieshop build --watch --no-clean
|
|
343
|
+
*/
|
|
163
344
|
export const BuildOptionsSchema = z.object({
|
|
164
345
|
path: PathSchema.optional(),
|
|
165
346
|
output: PathSchema.optional(),
|
|
@@ -172,6 +353,18 @@ export const BuildOptionsSchema = z.object({
|
|
|
172
353
|
/**
|
|
173
354
|
* Login/Auth schemas
|
|
174
355
|
*/
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Options for CLI authentication
|
|
359
|
+
* @property {string} [token] - Authentication token (if not using interactive login)
|
|
360
|
+
* @property {boolean} [interactive=true] - Use interactive browser-based login
|
|
361
|
+
* @property {boolean} [save=true] - Save credentials for future use
|
|
362
|
+
* @example
|
|
363
|
+
* // CLI usage:
|
|
364
|
+
* ollieshop login
|
|
365
|
+
* ollieshop login --token abc123
|
|
366
|
+
* ollieshop login --no-save
|
|
367
|
+
*/
|
|
175
368
|
export const LoginOptionsSchema = z.object({
|
|
176
369
|
token: z.string().optional(),
|
|
177
370
|
interactive: z.boolean().default(true),
|
|
@@ -181,6 +374,20 @@ export const LoginOptionsSchema = z.object({
|
|
|
181
374
|
/**
|
|
182
375
|
* Init project schemas
|
|
183
376
|
*/
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Options for initializing a new Ollie Shop project
|
|
380
|
+
* @property {string} [name="my-ollie-shop"] - Project name
|
|
381
|
+
* @property {"default"|"grocery"|"sales"} [template="default"] - Checkout template to use
|
|
382
|
+
* @property {boolean} [git=true] - Initialize git repository
|
|
383
|
+
* @property {boolean} [install=true] - Install dependencies automatically
|
|
384
|
+
* @property {string} [path] - Where to create the project (defaults to project name)
|
|
385
|
+
* @example
|
|
386
|
+
* // CLI usage:
|
|
387
|
+
* ollieshop init --name my-checkout
|
|
388
|
+
* ollieshop init --template grocery --no-install
|
|
389
|
+
* ollieshop init --name holiday-sale --path ./projects/holiday
|
|
390
|
+
*/
|
|
184
391
|
export const InitOptionsSchema = z.object({
|
|
185
392
|
name: z.string().optional(),
|
|
186
393
|
template: Template.optional().default("default"),
|
|
@@ -192,6 +399,18 @@ export const InitOptionsSchema = z.object({
|
|
|
192
399
|
/**
|
|
193
400
|
* Store version command schemas
|
|
194
401
|
*/
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Options for creating a store version
|
|
405
|
+
* @property {string} store - UUID of the store
|
|
406
|
+
* @property {string} name - Version name (1-100 characters)
|
|
407
|
+
* @property {"default"|"grocery"|"sales"} [template] - Checkout template
|
|
408
|
+
* @property {boolean} [active=true] - Whether version is active immediately
|
|
409
|
+
* @example
|
|
410
|
+
* // CLI usage:
|
|
411
|
+
* ollieshop version create --store 123e4567-e89b-12d3-a456-426614174000 --name "Black Friday"
|
|
412
|
+
* ollieshop version create --store abc-123 --name "Test" --template grocery --no-active
|
|
413
|
+
*/
|
|
195
414
|
export const StoreVersionCreateOptionsSchema = z.object({
|
|
196
415
|
store: StoreIdSchema,
|
|
197
416
|
name: VersionNameSchema,
|
|
@@ -291,6 +510,77 @@ export function validateSemver(version: string): boolean {
|
|
|
291
510
|
return SemverSchema.safeParse(version).success;
|
|
292
511
|
}
|
|
293
512
|
|
|
513
|
+
export function validateUUID(id: string): boolean {
|
|
514
|
+
const uuidSchema = z.string().uuid();
|
|
515
|
+
return uuidSchema.safeParse(id).success;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Environment variable validation schemas and helpers
|
|
520
|
+
*/
|
|
521
|
+
export const BuilderApiUrlSchema = z
|
|
522
|
+
.string()
|
|
523
|
+
.url("BUILDER_API_URL must be a valid URL")
|
|
524
|
+
.refine(
|
|
525
|
+
(url) => {
|
|
526
|
+
try {
|
|
527
|
+
const parsed = new URL(url);
|
|
528
|
+
return ["http:", "https:"].includes(parsed.protocol);
|
|
529
|
+
} catch {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
message: "BUILDER_API_URL must use http or https protocol",
|
|
535
|
+
},
|
|
536
|
+
);
|
|
537
|
+
|
|
538
|
+
export const EnvironmentVariablesSchema = z.object({
|
|
539
|
+
BUILDER_API_URL: BuilderApiUrlSchema.optional(),
|
|
540
|
+
DEBUG: z.string().optional(),
|
|
541
|
+
NODE_ENV: z.enum(["development", "test", "production"]).optional(),
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Validates all CLI environment variables
|
|
546
|
+
* @returns {Object} Validation result with success flag and optional errors
|
|
547
|
+
* @returns {boolean} result.success - True if all env vars are valid
|
|
548
|
+
* @returns {string[]} [result.errors] - Array of validation error messages
|
|
549
|
+
* @example
|
|
550
|
+
* const result = validateEnvironmentVariables();
|
|
551
|
+
* if (!result.success) {
|
|
552
|
+
* console.error("Invalid environment:", result.errors);
|
|
553
|
+
* }
|
|
554
|
+
*/
|
|
555
|
+
export function validateEnvironmentVariables(): {
|
|
556
|
+
success: boolean;
|
|
557
|
+
errors?: string[];
|
|
558
|
+
} {
|
|
559
|
+
const envVars = {
|
|
560
|
+
BUILDER_API_URL: process.env.BUILDER_API_URL,
|
|
561
|
+
DEBUG: process.env.DEBUG,
|
|
562
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
const result = EnvironmentVariablesSchema.safeParse(envVars);
|
|
566
|
+
|
|
567
|
+
if (!result.success) {
|
|
568
|
+
return {
|
|
569
|
+
success: false,
|
|
570
|
+
errors: result.error.issues.map(
|
|
571
|
+
(issue) => `${issue.path.join(".")}: ${issue.message}`,
|
|
572
|
+
),
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return { success: true };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
export function validateBuilderApiUrl(url?: string): boolean {
|
|
580
|
+
if (!url) return true; // Optional
|
|
581
|
+
return BuilderApiUrlSchema.safeParse(url).success;
|
|
582
|
+
}
|
|
583
|
+
|
|
294
584
|
/**
|
|
295
585
|
* CLI Data Display Schemas
|
|
296
586
|
* These schemas define the structure for data displayed in CLI commands
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { CliConsole } from "../console";
|
|
2
3
|
import { RichProgressReporter, SimpleProgressReporter } from "../rich-progress";
|
|
3
4
|
|
|
4
5
|
// Mock cli-progress
|
|
@@ -34,10 +35,20 @@ vi.mock("ora", () => ({
|
|
|
34
35
|
|
|
35
36
|
describe("RichProgressReporter", () => {
|
|
36
37
|
let reporter: RichProgressReporter;
|
|
38
|
+
let mockConsole: CliConsole;
|
|
37
39
|
let consoleLogSpy: ReturnType<typeof vi.spyOn>;
|
|
38
40
|
|
|
39
41
|
beforeEach(() => {
|
|
40
|
-
//
|
|
42
|
+
// Create a mock console with all required methods
|
|
43
|
+
mockConsole = {
|
|
44
|
+
info: vi.fn(),
|
|
45
|
+
success: vi.fn(),
|
|
46
|
+
error: vi.fn(),
|
|
47
|
+
warn: vi.fn(),
|
|
48
|
+
debug: vi.fn(),
|
|
49
|
+
log: vi.fn(),
|
|
50
|
+
} as unknown as CliConsole;
|
|
51
|
+
|
|
41
52
|
consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {
|
|
42
53
|
// Intentionally empty for test isolation
|
|
43
54
|
});
|
|
@@ -49,16 +60,16 @@ describe("RichProgressReporter", () => {
|
|
|
49
60
|
});
|
|
50
61
|
|
|
51
62
|
it("should start progress tracking", () => {
|
|
52
|
-
reporter = new RichProgressReporter();
|
|
63
|
+
reporter = new RichProgressReporter(mockConsole);
|
|
53
64
|
reporter.start();
|
|
54
65
|
|
|
55
|
-
expect(
|
|
66
|
+
expect(mockConsole.info).toHaveBeenCalledWith(
|
|
56
67
|
expect.stringContaining("🚀 Starting deployment..."),
|
|
57
68
|
);
|
|
58
69
|
});
|
|
59
70
|
|
|
60
71
|
it("should update progress with build status", () => {
|
|
61
|
-
reporter = new RichProgressReporter();
|
|
72
|
+
reporter = new RichProgressReporter(mockConsole);
|
|
62
73
|
|
|
63
74
|
const progress = {
|
|
64
75
|
phase: "build",
|
|
@@ -72,21 +83,21 @@ describe("RichProgressReporter", () => {
|
|
|
72
83
|
|
|
73
84
|
it("should show success summary", () => {
|
|
74
85
|
// Test just the summary method
|
|
75
|
-
const reporter = new RichProgressReporter();
|
|
86
|
+
const reporter = new RichProgressReporter(mockConsole);
|
|
76
87
|
// Access private method for testing
|
|
77
88
|
const reporterWithPrivate = reporter as unknown as {
|
|
78
89
|
showSuccessSummary(): void;
|
|
79
90
|
};
|
|
80
91
|
reporterWithPrivate.showSuccessSummary();
|
|
81
92
|
|
|
82
|
-
expect(
|
|
93
|
+
expect(mockConsole.success).toHaveBeenCalledWith(
|
|
83
94
|
expect.stringContaining("✅ Deployment completed successfully!"),
|
|
84
95
|
);
|
|
85
96
|
});
|
|
86
97
|
|
|
87
98
|
it("should show failure message", () => {
|
|
88
99
|
// Create a minimal test that doesn't rely on bars
|
|
89
|
-
const reporter = new RichProgressReporter();
|
|
100
|
+
const reporter = new RichProgressReporter(mockConsole);
|
|
90
101
|
// Access private properties for testing
|
|
91
102
|
const reporterWithPrivate = reporter as unknown as {
|
|
92
103
|
multibar: { stop: () => void };
|
|
@@ -97,13 +108,13 @@ describe("RichProgressReporter", () => {
|
|
|
97
108
|
|
|
98
109
|
reporter.stop(false);
|
|
99
110
|
|
|
100
|
-
expect(
|
|
111
|
+
expect(mockConsole.error).toHaveBeenCalledWith(
|
|
101
112
|
expect.stringContaining("❌ Deployment failed"),
|
|
102
113
|
);
|
|
103
114
|
});
|
|
104
115
|
|
|
105
116
|
it("should display build stats when available", () => {
|
|
106
|
-
const reporter = new RichProgressReporter();
|
|
117
|
+
const reporter = new RichProgressReporter(mockConsole);
|
|
107
118
|
|
|
108
119
|
// Set stats directly for testing
|
|
109
120
|
const reporterWithPrivate = reporter as unknown as {
|
|
@@ -120,10 +131,10 @@ describe("RichProgressReporter", () => {
|
|
|
120
131
|
};
|
|
121
132
|
reporterWithSummary.showSuccessSummary();
|
|
122
133
|
|
|
123
|
-
expect(
|
|
134
|
+
expect(mockConsole.info).toHaveBeenCalledWith(
|
|
124
135
|
expect.stringContaining("📊 Build Stats:"),
|
|
125
136
|
);
|
|
126
|
-
expect(
|
|
137
|
+
expect(mockConsole.info).toHaveBeenCalledWith(
|
|
127
138
|
expect.stringContaining("Bundle size: 146.5KB"),
|
|
128
139
|
);
|
|
129
140
|
});
|
|
@@ -37,8 +37,8 @@ export class CLIProgressReporter {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
updateProgress(progress: BuildProgress): void {
|
|
40
|
-
const phaseDisplay = this.formatPhase(progress.
|
|
41
|
-
const etaFormatted = this.formatETA(
|
|
40
|
+
const phaseDisplay = this.formatPhase(progress.status);
|
|
41
|
+
const etaFormatted = this.formatETA(0); // ETA not available in BuildProgress
|
|
42
42
|
|
|
43
43
|
this.bar.update(progress.percentComplete, {
|
|
44
44
|
phase: phaseDisplay,
|
|
@@ -200,11 +200,6 @@ export const COMMON_OPTIONS = {
|
|
|
200
200
|
description: "Path to component or function directory",
|
|
201
201
|
parser: parsePath,
|
|
202
202
|
},
|
|
203
|
-
wait: {
|
|
204
|
-
flags: "-w, --wait",
|
|
205
|
-
description: "Wait for operation to complete",
|
|
206
|
-
defaultValue: false,
|
|
207
|
-
},
|
|
208
203
|
storeId: {
|
|
209
204
|
flags: "-s, --store <id>",
|
|
210
205
|
description: "Store ID (UUID format)",
|
package/src/utils/console.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import inquirer from "inquirer";
|
|
2
3
|
import ora, { type Ora } from "ora";
|
|
3
4
|
import type { OllieShopCLIError } from "./errors";
|
|
4
5
|
|
|
@@ -234,10 +235,38 @@ export class Console {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
async confirm(message: string): Promise<boolean> {
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
// In quiet mode, default to false for non-interactive usage
|
|
239
|
+
if (this.options.quiet) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Check if we're in a TTY environment (interactive terminal)
|
|
244
|
+
if (!process.stdin.isTTY) {
|
|
245
|
+
this.warn(`${message} (y/N) - Non-interactive mode, defaulting to 'No'`);
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
const answer = await inquirer.prompt([
|
|
251
|
+
{
|
|
252
|
+
type: "confirm",
|
|
253
|
+
name: "confirmed",
|
|
254
|
+
message,
|
|
255
|
+
default: false,
|
|
256
|
+
},
|
|
257
|
+
]);
|
|
258
|
+
|
|
259
|
+
return answer.confirmed;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
// Handle Ctrl+C or other interruptions gracefully
|
|
262
|
+
if (error && typeof error === "object" && "isTtyError" in error) {
|
|
263
|
+
this.warn("Interactive prompt not supported in this environment");
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// For other errors, re-throw
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
241
270
|
}
|
|
242
271
|
|
|
243
272
|
listResults<T>(items: T[], formatter: (item: T) => string) {
|
package/src/utils/constants.ts
CHANGED
|
@@ -5,3 +5,35 @@ export const META_FILE = "meta.json";
|
|
|
5
5
|
export const CONFIG_FILE = "ollie.json";
|
|
6
6
|
export const OLLIE_SHOP_ASSETS_DIR = "node_modules/.ollie-shop";
|
|
7
7
|
export const TEMPLATES_DIR = "templates";
|
|
8
|
+
|
|
9
|
+
// Note: Deployment URLs are dynamically generated by the infrastructure
|
|
10
|
+
// Components are deployed to CloudFront (router.url from SST)
|
|
11
|
+
// Functions are deployed to Lambda (managed by AWS)
|
|
12
|
+
|
|
13
|
+
// Error messages with actionable guidance
|
|
14
|
+
export const ERROR_MESSAGES = {
|
|
15
|
+
DEPLOYMENT_TIMEOUT:
|
|
16
|
+
"⏱️ Deployment timed out after 5 minutes. This may indicate a network issue or resource constraints.",
|
|
17
|
+
BUILD_FAILED:
|
|
18
|
+
"❌ Build failed. Check the build logs above for specific error details.",
|
|
19
|
+
BUILD_VALIDATION_FAILED:
|
|
20
|
+
"❌ Build validation failed. Ensure your code meets the required standards.",
|
|
21
|
+
UNKNOWN_ERROR:
|
|
22
|
+
"❌ An unexpected error occurred. Please try again or contact support if the issue persists.",
|
|
23
|
+
COMPONENT_ID_REQUIRED:
|
|
24
|
+
"Component ID is required for deployment. Use: ollieshop component deploy --id <component-id>",
|
|
25
|
+
FUNCTION_ID_REQUIRED:
|
|
26
|
+
"Function ID is required for deployment. Use: ollieshop function deploy --id <function-id>",
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
// Note: Build status messages are available from @ollie-shop/core
|
|
30
|
+
// Use getBuildProgressMessage() from core instead of duplicating
|
|
31
|
+
|
|
32
|
+
// Deployment settings
|
|
33
|
+
export const DEPLOYMENT_SETTINGS = {
|
|
34
|
+
DEFAULT_POLL_INTERVAL_MS: 2000,
|
|
35
|
+
DEFAULT_MAX_WAIT_MS: 300000, // 5 minutes
|
|
36
|
+
PROGRESS_UPDATE_INTERVAL_MS: 1000,
|
|
37
|
+
ESTIMATED_BUILD_DURATION_MS: 30000, // 30 seconds
|
|
38
|
+
MAX_PROGRESS_BEFORE_COMPLETION: 0.95,
|
|
39
|
+
} as const;
|