@ollie-shop/cli 0.3.3 → 1.0.0
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 +1003 -40565
- 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 +533 -0
- package/tsconfig.json +10 -15
- package/tsup.config.ts +8 -10
- 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
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import * as core from "@ollie-shop/core";
|
|
2
|
-
import type { VersionListItem } from "../schemas/command.schema";
|
|
3
|
-
import { console as cliConsole } from "../utils/console";
|
|
4
|
-
import { handleError } from "../utils/error-handler";
|
|
5
|
-
|
|
6
|
-
interface CreateOptions {
|
|
7
|
-
store: string;
|
|
8
|
-
name: string;
|
|
9
|
-
template?: string;
|
|
10
|
-
active?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface ListOptions {
|
|
14
|
-
store: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function create(options: CreateOptions): Promise<void> {
|
|
18
|
-
const spinner = cliConsole.spinner("Creating version...");
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
const version = await core.createVersion({
|
|
22
|
-
storeId: options.store,
|
|
23
|
-
name: options.name,
|
|
24
|
-
template: options.template || "default",
|
|
25
|
-
active: options.active ?? true,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
spinner.succeed(`Version "${version.name}" created successfully`);
|
|
29
|
-
|
|
30
|
-
cliConsole.info("\nVersion details:");
|
|
31
|
-
cliConsole.table([
|
|
32
|
-
{
|
|
33
|
-
ID: version.id,
|
|
34
|
-
Name: version.name,
|
|
35
|
-
Template: version.template || "default",
|
|
36
|
-
Active: version.active ? "✓" : "✗",
|
|
37
|
-
Default: version.default ? "✓" : "✗",
|
|
38
|
-
},
|
|
39
|
-
]);
|
|
40
|
-
|
|
41
|
-
if (!version.active) {
|
|
42
|
-
cliConsole.dim("\nNote: This version is inactive. Activate it with:");
|
|
43
|
-
cliConsole.dim(` ollieshop version activate ${version.id}`);
|
|
44
|
-
}
|
|
45
|
-
} catch (error) {
|
|
46
|
-
spinner.fail("Failed to create version");
|
|
47
|
-
handleError(error);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function list(options: ListOptions): Promise<void> {
|
|
52
|
-
const spinner = cliConsole.spinner("Loading versions...");
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
const versions: VersionListItem[] = await core.listVersions(options.store);
|
|
56
|
-
|
|
57
|
-
spinner.succeed();
|
|
58
|
-
|
|
59
|
-
if (versions.length === 0) {
|
|
60
|
-
cliConsole.warn("No versions found for this store");
|
|
61
|
-
cliConsole.dim("\nCreate a version with:");
|
|
62
|
-
cliConsole.dim(
|
|
63
|
-
` ollieshop version create --store ${options.store} --name "My Version"`,
|
|
64
|
-
);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
cliConsole.info(
|
|
69
|
-
`Found ${versions.length} version${versions.length === 1 ? "" : "s"}:\n`,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
cliConsole.table(
|
|
73
|
-
versions.map((v) => ({
|
|
74
|
-
ID: v.id,
|
|
75
|
-
Name: v.name,
|
|
76
|
-
Template: v.template || "default",
|
|
77
|
-
Active: v.active ? "✓" : "✗",
|
|
78
|
-
Default: v.default ? "✓" : "✗",
|
|
79
|
-
Created: new Date(v.createdAt).toLocaleDateString(),
|
|
80
|
-
})),
|
|
81
|
-
);
|
|
82
|
-
} catch (error) {
|
|
83
|
-
spinner.fail("Failed to list versions");
|
|
84
|
-
handleError(error);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export async function get(versionId: string): Promise<void> {
|
|
89
|
-
const spinner = cliConsole.spinner("Loading version...");
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
const version = await core.getVersion(versionId);
|
|
93
|
-
|
|
94
|
-
spinner.succeed();
|
|
95
|
-
|
|
96
|
-
cliConsole.info("Version details:\n");
|
|
97
|
-
|
|
98
|
-
const details = {
|
|
99
|
-
ID: version.id,
|
|
100
|
-
Name: version.name,
|
|
101
|
-
"Store ID": version.storeId,
|
|
102
|
-
Template: version.template || "default",
|
|
103
|
-
Active: version.active ? "Yes" : "No",
|
|
104
|
-
Default: version.default ? "Yes" : "No",
|
|
105
|
-
Created: new Date(version.createdAt).toLocaleString(),
|
|
106
|
-
Updated: new Date(version.updatedAt).toLocaleString(),
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
for (const [key, value] of Object.entries(details)) {
|
|
110
|
-
cliConsole.log(`${cliConsole.bold(`${key}:`)} ${value}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (version.theme) {
|
|
114
|
-
cliConsole.info("\nTheme configuration:");
|
|
115
|
-
cliConsole.json(version.theme);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (version.props) {
|
|
119
|
-
cliConsole.info("\nProps configuration:");
|
|
120
|
-
cliConsole.json(version.props);
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
spinner.fail("Failed to get version");
|
|
124
|
-
handleError(error);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export async function setDefault(versionId: string): Promise<void> {
|
|
129
|
-
const spinner = cliConsole.spinner("Setting default version...");
|
|
130
|
-
|
|
131
|
-
try {
|
|
132
|
-
await core.setDefaultVersion(versionId);
|
|
133
|
-
|
|
134
|
-
spinner.succeed("Version set as default successfully");
|
|
135
|
-
|
|
136
|
-
cliConsole.dim(
|
|
137
|
-
"\nThis version will now be used for all new checkout sessions.",
|
|
138
|
-
);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
spinner.fail("Failed to set default version");
|
|
141
|
-
handleError(error);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export async function activate(versionId: string): Promise<void> {
|
|
146
|
-
const spinner = cliConsole.spinner("Activating version...");
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const version = await core.activateVersion(versionId);
|
|
150
|
-
|
|
151
|
-
spinner.succeed(`Version "${version.name}" activated successfully`);
|
|
152
|
-
|
|
153
|
-
if (!version.default) {
|
|
154
|
-
cliConsole.dim("\nTo make this the default version, run:");
|
|
155
|
-
cliConsole.dim(` ollieshop version set-default ${versionId}`);
|
|
156
|
-
}
|
|
157
|
-
} catch (error) {
|
|
158
|
-
spinner.fail("Failed to activate version");
|
|
159
|
-
handleError(error);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export async function deactivate(versionId: string): Promise<void> {
|
|
164
|
-
const spinner = cliConsole.spinner("Deactivating version...");
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
const version = await core.deactivateVersion(versionId);
|
|
168
|
-
|
|
169
|
-
spinner.succeed(`Version "${version.name}" deactivated successfully`);
|
|
170
|
-
|
|
171
|
-
cliConsole.warn(
|
|
172
|
-
"\nWarning: This version can no longer be used for checkout sessions.",
|
|
173
|
-
);
|
|
174
|
-
} catch (error) {
|
|
175
|
-
spinner.fail("Failed to deactivate version");
|
|
176
|
-
handleError(error);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export async function clone(sourceId: string, name: string): Promise<void> {
|
|
181
|
-
const spinner = cliConsole.spinner("Cloning version...");
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
const newVersion = await core.cloneVersion(sourceId, name);
|
|
185
|
-
|
|
186
|
-
spinner.succeed(`Version cloned successfully as "${newVersion.name}"`);
|
|
187
|
-
|
|
188
|
-
cliConsole.info("\nCloned version details:");
|
|
189
|
-
cliConsole.table([
|
|
190
|
-
{
|
|
191
|
-
ID: newVersion.id,
|
|
192
|
-
Name: newVersion.name,
|
|
193
|
-
Template: newVersion.template || "default",
|
|
194
|
-
Active: newVersion.active ? "✓" : "✗",
|
|
195
|
-
Default: newVersion.default ? "✓" : "✗",
|
|
196
|
-
},
|
|
197
|
-
]);
|
|
198
|
-
|
|
199
|
-
cliConsole.dim("\nNote: The cloned version is inactive. To activate it:");
|
|
200
|
-
cliConsole.dim(` ollieshop version activate ${newVersion.id}`);
|
|
201
|
-
} catch (error) {
|
|
202
|
-
spinner.fail("Failed to clone version");
|
|
203
|
-
handleError(error);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export async function deleteVersion(
|
|
208
|
-
versionId: string,
|
|
209
|
-
force?: boolean,
|
|
210
|
-
): Promise<void> {
|
|
211
|
-
// Confirm deletion if not forced
|
|
212
|
-
if (!force) {
|
|
213
|
-
const confirmed = await cliConsole.confirm(
|
|
214
|
-
"Are you sure you want to delete this version? This action cannot be undone.",
|
|
215
|
-
);
|
|
216
|
-
|
|
217
|
-
if (!confirmed) {
|
|
218
|
-
cliConsole.info("Deletion cancelled");
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const spinner = cliConsole.spinner("Deleting version...");
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
await core.deleteVersion(versionId);
|
|
227
|
-
|
|
228
|
-
spinner.succeed("Version deleted successfully");
|
|
229
|
-
} catch (error) {
|
|
230
|
-
spinner.fail("Failed to delete version");
|
|
231
|
-
handleError(error);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import type { Command } from "@commander-js/extra-typings";
|
|
2
|
-
import {
|
|
3
|
-
createTestProgram,
|
|
4
|
-
executeCLI,
|
|
5
|
-
resetCLIMocks,
|
|
6
|
-
} from "@tests/helpers/cli-test-helper";
|
|
7
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
8
|
-
import { registerComponentCommands } from "../component";
|
|
9
|
-
|
|
10
|
-
// Mock the component actions module
|
|
11
|
-
vi.mock("../../actions/component.actions", () => ({
|
|
12
|
-
createComponent: vi.fn(),
|
|
13
|
-
listComponents: vi.fn(),
|
|
14
|
-
deployComponent: vi.fn(),
|
|
15
|
-
validateComponent: vi.fn(),
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
import * as componentActions from "../../actions/component.actions";
|
|
19
|
-
|
|
20
|
-
describe("Component Command Validation and DX", () => {
|
|
21
|
-
let program: Command;
|
|
22
|
-
let testSetup: ReturnType<typeof createTestProgram>;
|
|
23
|
-
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
testSetup = createTestProgram();
|
|
26
|
-
program = testSetup.program;
|
|
27
|
-
registerComponentCommands(program);
|
|
28
|
-
vi.clearAllMocks();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
resetCLIMocks();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe("validation messages", () => {
|
|
36
|
-
it("should provide helpful error for uppercase component names", async () => {
|
|
37
|
-
const result = await executeCLI(program, [
|
|
38
|
-
"component",
|
|
39
|
-
"create",
|
|
40
|
-
"--name",
|
|
41
|
-
"TestComponent",
|
|
42
|
-
]);
|
|
43
|
-
|
|
44
|
-
// The validation errors are written through console.error which is captured by our mocks
|
|
45
|
-
const consoleErrorCalls = testSetup.mocks.console.error.mock.calls;
|
|
46
|
-
const consoleLogCalls = testSetup.mocks.console.log.mock.calls;
|
|
47
|
-
|
|
48
|
-
const consoleOutput = [
|
|
49
|
-
...consoleErrorCalls.map((call) => call.join(" ")),
|
|
50
|
-
...consoleLogCalls.map((call) => call.join(" ")),
|
|
51
|
-
].join("\n");
|
|
52
|
-
|
|
53
|
-
expect(result.exitCode).toBe(1);
|
|
54
|
-
expect(consoleOutput).toContain("Validation failed");
|
|
55
|
-
expect(consoleOutput).toContain("name:");
|
|
56
|
-
expect(consoleOutput).toContain("Must be lowercase with hyphens only");
|
|
57
|
-
expect(consoleOutput).toContain("Examples:");
|
|
58
|
-
expect(componentActions.createComponent).not.toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("should provide helpful error for component names with spaces", async () => {
|
|
62
|
-
const result = await executeCLI(program, [
|
|
63
|
-
"component",
|
|
64
|
-
"create",
|
|
65
|
-
"--name",
|
|
66
|
-
"test component",
|
|
67
|
-
]);
|
|
68
|
-
|
|
69
|
-
const consoleOutput = testSetup.mocks.console.error.mock.calls
|
|
70
|
-
.map((call) => call.join(" "))
|
|
71
|
-
.join("\n");
|
|
72
|
-
|
|
73
|
-
expect(result.exitCode).toBe(1);
|
|
74
|
-
expect(consoleOutput).toContain("Validation failed");
|
|
75
|
-
expect(consoleOutput).toContain("Must be lowercase with hyphens only");
|
|
76
|
-
expect(componentActions.createComponent).not.toHaveBeenCalled();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("should provide helpful error for component names with underscores", async () => {
|
|
80
|
-
const result = await executeCLI(program, [
|
|
81
|
-
"component",
|
|
82
|
-
"create",
|
|
83
|
-
"--name",
|
|
84
|
-
"test_component",
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
const consoleOutput = testSetup.mocks.console.error.mock.calls
|
|
88
|
-
.map((call) => call.join(" "))
|
|
89
|
-
.join("\n");
|
|
90
|
-
|
|
91
|
-
expect(result.exitCode).toBe(1);
|
|
92
|
-
expect(consoleOutput).toContain("Validation failed");
|
|
93
|
-
expect(consoleOutput).toContain("Must be lowercase with hyphens only");
|
|
94
|
-
expect(componentActions.createComponent).not.toHaveBeenCalled();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should fail when name is missing", async () => {
|
|
98
|
-
const result = await executeCLI(program, [
|
|
99
|
-
"component",
|
|
100
|
-
"create",
|
|
101
|
-
"--slot",
|
|
102
|
-
"header",
|
|
103
|
-
]);
|
|
104
|
-
|
|
105
|
-
expect(result.exitCode).toBe(1);
|
|
106
|
-
expect(componentActions.createComponent).not.toHaveBeenCalled();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("should provide helpful error for invalid slot", async () => {
|
|
110
|
-
const result = await executeCLI(program, [
|
|
111
|
-
"component",
|
|
112
|
-
"create",
|
|
113
|
-
"--name",
|
|
114
|
-
"test-component",
|
|
115
|
-
"--slot",
|
|
116
|
-
"invalid",
|
|
117
|
-
]);
|
|
118
|
-
|
|
119
|
-
// The slot validation happens at the Commander.js level with a parser
|
|
120
|
-
// So we get a different error message format
|
|
121
|
-
const allOutput = [
|
|
122
|
-
...result.stderr,
|
|
123
|
-
...testSetup.mocks.console.error.mock.calls.map((call) =>
|
|
124
|
-
call.join(" "),
|
|
125
|
-
),
|
|
126
|
-
].join("\n");
|
|
127
|
-
|
|
128
|
-
expect(result.exitCode).toBe(1);
|
|
129
|
-
expect(allOutput).toContain("Invalid component slot");
|
|
130
|
-
expect(allOutput).toContain(
|
|
131
|
-
"Valid slots: header, footer, sidebar, main, checkout-summary, payment-method, shipping-method, customer-info, order-confirmation",
|
|
132
|
-
);
|
|
133
|
-
expect(componentActions.createComponent).not.toHaveBeenCalled();
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe("unknown options and commands", () => {
|
|
138
|
-
it("should provide helpful error for unknown options", async () => {
|
|
139
|
-
const result = await executeCLI(program, [
|
|
140
|
-
"component",
|
|
141
|
-
"create",
|
|
142
|
-
"--name",
|
|
143
|
-
"test",
|
|
144
|
-
"--unknown",
|
|
145
|
-
]);
|
|
146
|
-
|
|
147
|
-
expect(result.exitCode).toBe(1);
|
|
148
|
-
// Commander.js formats the error as "error: unknown option '--unknown'"
|
|
149
|
-
expect(result.stderr.join("")).toContain("unknown option '--unknown'");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should provide helpful error for unknown commands", async () => {
|
|
153
|
-
const result = await executeCLI(program, [
|
|
154
|
-
"component",
|
|
155
|
-
"craete",
|
|
156
|
-
"--name",
|
|
157
|
-
"test",
|
|
158
|
-
]);
|
|
159
|
-
|
|
160
|
-
expect(result.exitCode).toBe(1);
|
|
161
|
-
// Commander.js formats the error as "error: unknown command 'craete'"
|
|
162
|
-
expect(result.stderr.join("")).toContain("unknown command 'craete'");
|
|
163
|
-
// Commander has built-in suggestions
|
|
164
|
-
expect(result.stderr.join("")).toContain("Did you mean");
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
describe("valid inputs", () => {
|
|
169
|
-
it("should accept valid kebab-case component names", async () => {
|
|
170
|
-
vi.mocked(componentActions.createComponent).mockResolvedValue();
|
|
171
|
-
|
|
172
|
-
const result = await executeCLI(program, [
|
|
173
|
-
"component",
|
|
174
|
-
"create",
|
|
175
|
-
"--name",
|
|
176
|
-
"header-navigation",
|
|
177
|
-
]);
|
|
178
|
-
|
|
179
|
-
expect(result.exitCode).toBe(0);
|
|
180
|
-
expect(componentActions.createComponent).toHaveBeenCalledWith(
|
|
181
|
-
expect.objectContaining({
|
|
182
|
-
name: "header-navigation",
|
|
183
|
-
slot: "main",
|
|
184
|
-
tests: true,
|
|
185
|
-
interactive: false,
|
|
186
|
-
}),
|
|
187
|
-
expect.any(Object),
|
|
188
|
-
);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("should accept component names with numbers", async () => {
|
|
192
|
-
vi.mocked(componentActions.createComponent).mockResolvedValue();
|
|
193
|
-
|
|
194
|
-
const result = await executeCLI(program, [
|
|
195
|
-
"component",
|
|
196
|
-
"create",
|
|
197
|
-
"--name",
|
|
198
|
-
"product-list-v2",
|
|
199
|
-
]);
|
|
200
|
-
|
|
201
|
-
expect(result.exitCode).toBe(0);
|
|
202
|
-
expect(componentActions.createComponent).toHaveBeenCalledWith(
|
|
203
|
-
expect.objectContaining({
|
|
204
|
-
name: "product-list-v2",
|
|
205
|
-
}),
|
|
206
|
-
expect.any(Object),
|
|
207
|
-
);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it("should accept single word lowercase names", async () => {
|
|
211
|
-
vi.mocked(componentActions.createComponent).mockResolvedValue();
|
|
212
|
-
|
|
213
|
-
const result = await executeCLI(program, [
|
|
214
|
-
"component",
|
|
215
|
-
"create",
|
|
216
|
-
"--name",
|
|
217
|
-
"header",
|
|
218
|
-
]);
|
|
219
|
-
|
|
220
|
-
expect(result.exitCode).toBe(0);
|
|
221
|
-
expect(componentActions.createComponent).toHaveBeenCalledWith(
|
|
222
|
-
expect.objectContaining({
|
|
223
|
-
name: "header",
|
|
224
|
-
}),
|
|
225
|
-
expect.any(Object),
|
|
226
|
-
);
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
describe("help command", () => {
|
|
231
|
-
it("should show examples in help output", async () => {
|
|
232
|
-
const result = await executeCLI(program, [
|
|
233
|
-
"component",
|
|
234
|
-
"create",
|
|
235
|
-
"--help",
|
|
236
|
-
]);
|
|
237
|
-
|
|
238
|
-
const output = result.stdout.join("") + result.stderr.join("");
|
|
239
|
-
expect(output).toContain("Examples:");
|
|
240
|
-
expect(output).toContain("Create a header component:");
|
|
241
|
-
expect(output).toContain(
|
|
242
|
-
"$ ollieshop component create --name header --slot header",
|
|
243
|
-
);
|
|
244
|
-
expect(output).toContain("Create a component with TypeScript:");
|
|
245
|
-
expect(output).toContain(
|
|
246
|
-
"$ ollieshop component create --name product-list --typescript",
|
|
247
|
-
);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
});
|