@lizard-build/cli 4.0.37 → 4.0.38
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/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +18 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +5 -2
- package/dist/commands/login.js +17 -10
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/sandbox.js +15 -2
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/up.js +2 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/lib/config.js +7 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/default-project.d.ts +17 -0
- package/dist/lib/default-project.js +31 -0
- package/dist/lib/default-project.js.map +1 -0
- package/dist/lib/skills-data.generated.js +1 -1
- package/dist/lib/skills-data.generated.js.map +1 -1
- package/dist/lib/updater.d.ts +1 -1
- package/dist/lib/updater.js +1 -1
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +10 -2
- package/src/commands/init.ts +21 -0
- package/src/commands/login.ts +18 -10
- package/src/commands/sandbox.ts +19 -3
- package/src/commands/up.ts +2 -2
- package/src/lib/config.ts +7 -0
- package/src/lib/default-project.ts +47 -0
- package/src/lib/updater.ts +1 -1
- package/test/unit/default-project.test.ts +104 -0
- package/test/unit/login.test.ts +7 -10
- package/test/unit/sandbox.test.ts +37 -1
package/test/unit/login.test.ts
CHANGED
|
@@ -186,20 +186,17 @@ describe("account state", () => {
|
|
|
186
186
|
|
|
187
187
|
test("the closing note leads with sandboxes, aligned in two columns", () => {
|
|
188
188
|
const plain = (t: string) => t.replace(/\x1b\[[0-9;]*m/g, "");
|
|
189
|
-
expect(plain(nextStepsNote(
|
|
190
|
-
"lizard
|
|
191
|
-
"lizard sandbox create Start a sandbox in it",
|
|
192
|
-
"lizard up Or deploy this folder",
|
|
193
|
-
]);
|
|
194
|
-
expect(plain(nextStepsNote(true)).split("\n")).toEqual([
|
|
195
|
-
"lizard sandbox create Start a sandbox in this project",
|
|
189
|
+
expect(plain(nextStepsNote()).split("\n")).toEqual([
|
|
190
|
+
"lizard sandbox create Start a sandbox",
|
|
196
191
|
"lizard up Or deploy this folder",
|
|
197
192
|
]);
|
|
198
193
|
});
|
|
199
194
|
|
|
200
|
-
test("an unlinked folder
|
|
201
|
-
expect(nextSteps(false).map((s) => s.command)).toEqual(["lizard skills get core", "lizard
|
|
195
|
+
test("no lizard init needed: an unlinked folder uses the default project", () => {
|
|
196
|
+
expect(nextSteps(false).map((s) => s.command)).toEqual(["lizard skills get core", "lizard sandbox create", "lizard up"]);
|
|
197
|
+
expect(nextSteps(false)[1].why).toContain("default project");
|
|
202
198
|
expect(nextSteps(true).map((s) => s.command)).toEqual(["lizard skills get core", "lizard sandbox create", "lizard up"]);
|
|
199
|
+
expect(nextSteps(true)[1].why).toContain("linked project");
|
|
203
200
|
});
|
|
204
201
|
});
|
|
205
202
|
|
|
@@ -239,7 +236,7 @@ describe("lizard login --json", () => {
|
|
|
239
236
|
expect(out).toMatchObject({ status: "complete", username: "ada", email: "ada@example.com", source: "browser" });
|
|
240
237
|
expect(out.account.state).toBe("trial_available");
|
|
241
238
|
expect(out.account.billingUrl).toBe("https://lizard.build/profile/account-billing");
|
|
242
|
-
expect(out.next.map((s: { command: string }) => s.command)).toContain("lizard
|
|
239
|
+
expect(out.next.map((s: { command: string }) => s.command)).toContain("lizard sandbox create");
|
|
243
240
|
expect(loadConfig().pendingAuth).toBeUndefined();
|
|
244
241
|
expect(loadConfig().credentials?.username).toBe("ada");
|
|
245
242
|
});
|
|
@@ -3,6 +3,7 @@ import { Command } from "commander";
|
|
|
3
3
|
import { registerSandbox } from "../../src/commands/sandbox.js";
|
|
4
4
|
import { api, APIError } from "../../src/lib/api.js";
|
|
5
5
|
import { printJSON } from "../../src/lib/format.js";
|
|
6
|
+
import { getProjectLink, resolveProjectId } from "../../src/lib/config.js";
|
|
6
7
|
|
|
7
8
|
vi.mock("../../src/lib/api.js", () => {
|
|
8
9
|
class APIError extends Error {
|
|
@@ -13,8 +14,8 @@ vi.mock("../../src/lib/api.js", () => {
|
|
|
13
14
|
vi.mock("open", () => ({ default: vi.fn().mockResolvedValue(undefined) }));
|
|
14
15
|
vi.mock("../../src/lib/config.js", () => ({
|
|
15
16
|
resolveProjectId: vi.fn().mockResolvedValue("project-test"),
|
|
17
|
+
getProjectLink: vi.fn(() => ({ projectId: "project-test" })),
|
|
16
18
|
}));
|
|
17
|
-
vi.mock("../../src/lib/config.js", () => ({ resolveProjectId: vi.fn().mockResolvedValue("project-test") }));
|
|
18
19
|
vi.mock("../../src/lib/format.js", () => ({ isJSONMode: () => true, printJSON: vi.fn() }));
|
|
19
20
|
|
|
20
21
|
function create(args: string[]) {
|
|
@@ -46,6 +47,41 @@ describe("sandbox create timeout", () => {
|
|
|
46
47
|
});
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
describe("sandbox create without a project", () => {
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
vi.clearAllMocks();
|
|
53
|
+
vi.mocked(api.post).mockResolvedValue({ id: "sandbox-test" });
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("an unlinked folder sends no project and leaves the choice to the platform", async () => {
|
|
57
|
+
vi.mocked(getProjectLink).mockReturnValueOnce(null);
|
|
58
|
+
await create([]);
|
|
59
|
+
expect(resolveProjectId).not.toHaveBeenCalled();
|
|
60
|
+
expect(api.post).toHaveBeenCalledWith("/api/sandboxes", expect.objectContaining({ projectId: undefined }));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("a linked folder or --project still sends its project", async () => {
|
|
64
|
+
await create([]);
|
|
65
|
+
expect(api.post).toHaveBeenCalledWith("/api/sandboxes", expect.objectContaining({ projectId: "project-test" }));
|
|
66
|
+
vi.mocked(getProjectLink).mockReturnValueOnce(null);
|
|
67
|
+
await create(["--project", "web"]);
|
|
68
|
+
expect(resolveProjectId).toHaveBeenLastCalledWith("web");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("an unlinked --volume still resolves a project, since a volume name lives in one", async () => {
|
|
72
|
+
vi.mocked(getProjectLink).mockReturnValueOnce(null);
|
|
73
|
+
await create(["--volume", "data"]);
|
|
74
|
+
expect(resolveProjectId).toHaveBeenCalledWith(undefined);
|
|
75
|
+
expect(api.post).toHaveBeenCalledWith("/api/sandboxes", expect.objectContaining({ projectId: "project-test", volumeName: "data" }));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("a platform that still wants a project gets the old message", async () => {
|
|
79
|
+
vi.mocked(getProjectLink).mockReturnValueOnce(null);
|
|
80
|
+
vi.mocked(api.post).mockRejectedValueOnce(new APIError(400, "A project is required", "PROJECT_REQUIRED"));
|
|
81
|
+
await expect(create([])).rejects.toThrow("No project linked. Run `lizard init` or pass --project <id>.");
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
49
85
|
describe("unsupported sandbox commands", () => {
|
|
50
86
|
it.each(["fork", "snapshot-fork", "logs"])(
|
|
51
87
|
"rejects %s without making an API request", async (name) => {
|