@simplysm/sd-cli 14.0.7 → 14.0.8
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/capacitor/capacitor.d.ts +1 -1
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +3 -4
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.js +2 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +12 -13
- package/dist/commands/publish.js.map +1 -1
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +19 -13
- package/dist/electron/electron.js.map +1 -1
- package/dist/sd-cli.js +5 -5
- package/dist/sd-cli.js.map +1 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +2 -0
- package/dist/vitest-plugin.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +2 -3
- package/dist/workers/server-build.worker.js.map +1 -1
- package/package.json +4 -5
- package/src/capacitor/capacitor.ts +3 -4
- package/src/commands/check.ts +2 -2
- package/src/commands/publish.ts +12 -13
- package/src/electron/electron.ts +21 -14
- package/src/sd-cli.ts +8 -5
- package/src/vitest-plugin.ts +5 -0
- package/src/workers/server-build.worker.ts +2 -3
- package/tests/capacitor/capacitor-build.spec.ts +9 -7
- package/tests/capacitor/capacitor-icon.spec.ts +9 -7
- package/tests/capacitor/capacitor-init.spec.ts +8 -6
- package/tests/capacitor/capacitor-run.spec.ts +13 -11
- package/tests/capacitor/capacitor-workspace.spec.ts +8 -6
- package/tests/commands/check.spec.ts +5 -2
- package/tests/commands/publish.spec.ts +4 -4
- package/tests/electron/electron.spec.ts +27 -23
- package/tests/workers/server-build-worker.spec.ts +6 -3
|
@@ -25,6 +25,10 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
25
25
|
glob: mockFsxGlob,
|
|
26
26
|
copy: mockFsxCopy,
|
|
27
27
|
},
|
|
28
|
+
cpx: {
|
|
29
|
+
exec: mockCpxExec,
|
|
30
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
31
|
+
},
|
|
28
32
|
}));
|
|
29
33
|
|
|
30
34
|
// env mock
|
|
@@ -35,17 +39,15 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
35
39
|
}),
|
|
36
40
|
}));
|
|
37
41
|
|
|
38
|
-
//
|
|
42
|
+
// cpx mock (was execa) — tracks commands and resolves immediately
|
|
39
43
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
40
|
-
let execaFactory: (...args: unknown[]) => Promise<{ stdout: string; stderr: string }> = () =>
|
|
41
|
-
Promise.resolve({ stdout: "", stderr: "" });
|
|
44
|
+
let execaFactory: (...args: unknown[]) => Promise<{ stdout: string; stderr: string; exitCode: number }> = () =>
|
|
45
|
+
Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
42
46
|
|
|
43
|
-
vi.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}),
|
|
48
|
-
}));
|
|
47
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
48
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
49
|
+
return execaFactory(...args);
|
|
50
|
+
});
|
|
49
51
|
|
|
50
52
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
51
53
|
vi.mock("node:fs", () => ({
|
|
@@ -135,7 +137,7 @@ export default config;`;
|
|
|
135
137
|
mockEnv = { ANDROID_HOME: "C:/Android/Sdk" };
|
|
136
138
|
|
|
137
139
|
execaCalls.length = 0;
|
|
138
|
-
execaFactory = () => Promise.resolve({ stdout: "", stderr: "" });
|
|
140
|
+
execaFactory = () => Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
139
141
|
mockFsWriteFile.mockReset();
|
|
140
142
|
mockFsWriteFile.mockResolvedValue(undefined);
|
|
141
143
|
}
|
|
@@ -195,7 +197,7 @@ describe("Capacitor.run()", () => {
|
|
|
195
197
|
return Promise.reject(new Error("cap run failed"));
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
|
-
return Promise.resolve({ stdout: "", stderr: "" });
|
|
200
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
199
201
|
};
|
|
200
202
|
|
|
201
203
|
const cap = await Capacitor.create(PKG_PATH, {
|
|
@@ -24,6 +24,10 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
24
24
|
glob: mockFsxGlob,
|
|
25
25
|
copy: mockFsxCopy,
|
|
26
26
|
},
|
|
27
|
+
cpx: {
|
|
28
|
+
exec: mockCpxExec,
|
|
29
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
30
|
+
},
|
|
27
31
|
}));
|
|
28
32
|
|
|
29
33
|
let mockEnv: Record<string, unknown> = {};
|
|
@@ -34,12 +38,10 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
34
38
|
}));
|
|
35
39
|
|
|
36
40
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
37
|
-
vi.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}),
|
|
42
|
-
}));
|
|
41
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
42
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
43
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
44
|
+
});
|
|
43
45
|
|
|
44
46
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
45
47
|
vi.mock("node:fs", () => ({
|
|
@@ -35,8 +35,11 @@ vi.mock("../../src/utils/sd-config", () => ({
|
|
|
35
35
|
loadSdConfig: mocks.loadSdConfig,
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
|
-
vi.mock("
|
|
39
|
-
|
|
38
|
+
vi.mock("@simplysm/core-node", () => ({
|
|
39
|
+
cpx: {
|
|
40
|
+
exec: mocks.execa,
|
|
41
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
42
|
+
},
|
|
40
43
|
}));
|
|
41
44
|
|
|
42
45
|
vi.mock("../../src/utils/package-utils", async (importOriginal) => {
|
|
@@ -48,12 +48,12 @@ vi.mock("../../src/utils/replace-deps", () => ({
|
|
|
48
48
|
parseWorkspaceGlobs: mocks.parseWorkspaceGlobs,
|
|
49
49
|
}));
|
|
50
50
|
|
|
51
|
-
vi.mock("execa", () => ({
|
|
52
|
-
execa: mocks.execa,
|
|
53
|
-
}));
|
|
54
|
-
|
|
55
51
|
vi.mock("@simplysm/core-node", () => ({
|
|
56
52
|
fsx: mocks.fsx,
|
|
53
|
+
cpx: {
|
|
54
|
+
exec: mocks.execa,
|
|
55
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
56
|
+
},
|
|
57
57
|
}));
|
|
58
58
|
|
|
59
59
|
vi.mock("@simplysm/core-common", () => {
|
|
@@ -21,13 +21,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
21
21
|
readdir: mockFsxReaddir,
|
|
22
22
|
glob: mockFsxGlob,
|
|
23
23
|
},
|
|
24
|
+
cpx: {
|
|
25
|
+
exec: mockCpxExec,
|
|
26
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
27
|
+
},
|
|
24
28
|
}));
|
|
25
29
|
|
|
26
|
-
//
|
|
27
|
-
const
|
|
28
|
-
vi.mock("execa", () => ({
|
|
29
|
-
execa: mockExeca,
|
|
30
|
-
}));
|
|
30
|
+
// cpx mock (was execa)
|
|
31
|
+
const mockCpxExec = vi.fn().mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
|
|
31
32
|
|
|
32
33
|
// esbuild mock
|
|
33
34
|
const mockEsbuildBuild = vi.fn().mockResolvedValue({});
|
|
@@ -91,13 +92,15 @@ function setupDefaultMocks() {
|
|
|
91
92
|
});
|
|
92
93
|
mockFsxReaddir.mockResolvedValue(["index.html", "assets", "electron"]);
|
|
93
94
|
// Default: glob returns one exe file matching the builder output
|
|
94
|
-
mockFsxGlob.mockImplementation((pattern: string
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
mockFsxGlob.mockImplementation((pattern: string) => {
|
|
96
|
+
const normalized = pattern.replace(/\\/g, "/");
|
|
97
|
+
if (normalized.endsWith(".electron/dist/*.exe")) {
|
|
98
|
+
const dir = normalized.replace("/*.exe", "");
|
|
99
|
+
return Promise.resolve([dir + "/My App Setup 1.0.0.exe"]);
|
|
97
100
|
}
|
|
98
101
|
return Promise.resolve([]);
|
|
99
102
|
});
|
|
100
|
-
|
|
103
|
+
mockCpxExec.mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
|
|
101
104
|
mockEsbuildBuild.mockResolvedValue({});
|
|
102
105
|
}
|
|
103
106
|
|
|
@@ -171,7 +174,7 @@ describe("Electron", () => {
|
|
|
171
174
|
|
|
172
175
|
expect(findElectronPackageJson()).toBeDefined();
|
|
173
176
|
|
|
174
|
-
const execaCalls =
|
|
177
|
+
const execaCalls = mockCpxExec.mock.calls;
|
|
175
178
|
expect(
|
|
176
179
|
execaCalls.find((c) => c[0] === "npm" && (c[1] as string[]).includes("install")),
|
|
177
180
|
).toBeDefined();
|
|
@@ -188,7 +191,7 @@ describe("Electron", () => {
|
|
|
188
191
|
const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
|
|
189
192
|
await electron.initialize();
|
|
190
193
|
|
|
191
|
-
const rebuildCall =
|
|
194
|
+
const rebuildCall = mockCpxExec.mock.calls.find(
|
|
192
195
|
(c) => typeof c[0] === "string" && c[0].includes("electron-rebuild"),
|
|
193
196
|
);
|
|
194
197
|
expect(rebuildCall).toBeUndefined();
|
|
@@ -418,7 +421,8 @@ describe("Electron", () => {
|
|
|
418
421
|
|
|
419
422
|
it("빌드 산출물이 없으면 경고를 출력한다", async () => {
|
|
420
423
|
mockFsxGlob.mockImplementation((pattern: string) => {
|
|
421
|
-
|
|
424
|
+
const normalized = pattern.replace(/\\/g, "/");
|
|
425
|
+
if (normalized.endsWith(".electron/dist/*.exe")) return Promise.resolve([]);
|
|
422
426
|
return Promise.resolve([]);
|
|
423
427
|
});
|
|
424
428
|
|
|
@@ -436,15 +440,15 @@ describe("Electron", () => {
|
|
|
436
440
|
//#region Rule: 개발 모드에서 Electron 앱을 실행한다
|
|
437
441
|
|
|
438
442
|
describe("인수 테스트: run()", () => {
|
|
439
|
-
// Helper: creates a deferred
|
|
440
|
-
function
|
|
443
|
+
// Helper: creates a deferred cpx mock where Electron process can be controlled
|
|
444
|
+
function setupCpxForRun(): {
|
|
441
445
|
electronKill: ReturnType<typeof vi.fn>;
|
|
442
446
|
resolveElectron: () => void;
|
|
443
447
|
} {
|
|
444
448
|
const electronKill = vi.fn();
|
|
445
449
|
let resolveElectron: () => void = () => {};
|
|
446
450
|
|
|
447
|
-
|
|
451
|
+
mockCpxExec.mockImplementation((cmd: string) => {
|
|
448
452
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
449
453
|
// Electron process: create a deferred promise we can resolve externally
|
|
450
454
|
const p = new Promise<void>((resolve) => {
|
|
@@ -453,14 +457,14 @@ describe("Electron", () => {
|
|
|
453
457
|
p.kill = electronKill;
|
|
454
458
|
return p;
|
|
455
459
|
}
|
|
456
|
-
return Promise.resolve({ stdout: "" });
|
|
460
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
457
461
|
});
|
|
458
462
|
|
|
459
463
|
return { electronKill, resolveElectron: () => resolveElectron() };
|
|
460
464
|
}
|
|
461
465
|
|
|
462
466
|
it("creates esbuild context with banner for env and spawns Electron", async () => {
|
|
463
|
-
const { resolveElectron } =
|
|
467
|
+
const { resolveElectron } = setupCpxForRun();
|
|
464
468
|
|
|
465
469
|
const { Electron } = await import("../../src/electron/electron.js");
|
|
466
470
|
const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
|
|
@@ -503,7 +507,7 @@ describe("Electron", () => {
|
|
|
503
507
|
});
|
|
504
508
|
|
|
505
509
|
it("resolves on SIGINT signal", async () => {
|
|
506
|
-
const { electronKill } =
|
|
510
|
+
const { electronKill } = setupCpxForRun();
|
|
507
511
|
|
|
508
512
|
const { Electron } = await import("../../src/electron/electron.js");
|
|
509
513
|
const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
|
|
@@ -526,7 +530,7 @@ describe("Electron", () => {
|
|
|
526
530
|
describe("단위: run() 플러그인 동작", () => {
|
|
527
531
|
it("passes custom env and ELECTRON_DEV_URL via esbuild banner", async () => {
|
|
528
532
|
let resolveElectron: () => void = () => {};
|
|
529
|
-
|
|
533
|
+
mockCpxExec.mockImplementation((cmd: string) => {
|
|
530
534
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
531
535
|
const p = new Promise<void>((resolve) => {
|
|
532
536
|
resolveElectron = resolve;
|
|
@@ -534,7 +538,7 @@ describe("Electron", () => {
|
|
|
534
538
|
p.kill = vi.fn();
|
|
535
539
|
return p;
|
|
536
540
|
}
|
|
537
|
-
return Promise.resolve({ stdout: "" });
|
|
541
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
538
542
|
});
|
|
539
543
|
|
|
540
544
|
const { Electron } = await import("../../src/electron/electron.js");
|
|
@@ -559,7 +563,7 @@ describe("Electron", () => {
|
|
|
559
563
|
|
|
560
564
|
it("calls initialize() before starting esbuild context", async () => {
|
|
561
565
|
let resolveElectron: () => void = () => {};
|
|
562
|
-
|
|
566
|
+
mockCpxExec.mockImplementation((cmd: string) => {
|
|
563
567
|
if (typeof cmd === "string" && cmd.includes("electron")) {
|
|
564
568
|
const p = new Promise<void>((resolve) => {
|
|
565
569
|
resolveElectron = resolve;
|
|
@@ -567,7 +571,7 @@ describe("Electron", () => {
|
|
|
567
571
|
p.kill = vi.fn();
|
|
568
572
|
return p;
|
|
569
573
|
}
|
|
570
|
-
return Promise.resolve({ stdout: "" });
|
|
574
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
571
575
|
});
|
|
572
576
|
|
|
573
577
|
const { Electron } = await import("../../src/electron/electron.js");
|
|
@@ -579,7 +583,7 @@ describe("Electron", () => {
|
|
|
579
583
|
await runPromise;
|
|
580
584
|
|
|
581
585
|
// initialize calls npm install -> execa should have been called with npm install
|
|
582
|
-
const npmInstallCall =
|
|
586
|
+
const npmInstallCall = mockCpxExec.mock.calls.find(
|
|
583
587
|
(c: any[]) => c[0] === "npm" && (c[1] as string[]).includes("install"),
|
|
584
588
|
);
|
|
585
589
|
expect(npmInstallCall).toBeDefined();
|
|
@@ -35,6 +35,8 @@ const mockRunTscPackageBuild = vi.fn(() => ({
|
|
|
35
35
|
warningCount: 0,
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
|
+
const mockCpxExecSync = vi.fn().mockReturnValue({ stdout: "v20.11.0", stderr: "", exitCode: 0 });
|
|
39
|
+
|
|
38
40
|
vi.mock("@simplysm/core-node", () => ({
|
|
39
41
|
createWorker: vi.fn((fns: Record<string, Function>) => {
|
|
40
42
|
workerFns = fns as any;
|
|
@@ -50,6 +52,10 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
50
52
|
pathx: {
|
|
51
53
|
norm: vi.fn((...args: string[]) => path.resolve(...args).replace(/\\/g, "/")),
|
|
52
54
|
},
|
|
55
|
+
cpx: {
|
|
56
|
+
exec: vi.fn().mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
57
|
+
execSync: mockCpxExecSync,
|
|
58
|
+
},
|
|
53
59
|
}));
|
|
54
60
|
|
|
55
61
|
vi.mock("@simplysm/core-common", () => ({
|
|
@@ -95,9 +101,6 @@ vi.mock("fs", () => ({
|
|
|
95
101
|
existsSync: (...args: unknown[]) => mockExistsSync(...(args as [string])),
|
|
96
102
|
}));
|
|
97
103
|
|
|
98
|
-
vi.mock("execa", () => ({
|
|
99
|
-
execaSync: vi.fn(() => ({ stdout: "v20.11.0" })),
|
|
100
|
-
}));
|
|
101
104
|
|
|
102
105
|
// Mock lockfile content for resolveLockedVersion
|
|
103
106
|
let mockLockfileContent = "";
|