@simplysm/sd-cli 14.0.18 → 14.0.21
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/angular/vite-angular-plugin.d.ts +2 -0
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +57 -28
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/vite-postcss-inline-plugin.d.ts.map +1 -1
- package/dist/angular/vite-postcss-inline-plugin.js +4 -1
- package/dist/angular/vite-postcss-inline-plugin.js.map +1 -1
- package/dist/capacitor/capacitor-android.d.ts +16 -0
- package/dist/capacitor/capacitor-android.d.ts.map +1 -0
- package/dist/capacitor/capacitor-android.js +289 -0
- package/dist/capacitor/capacitor-android.js.map +1 -0
- package/dist/capacitor/capacitor.d.ts +0 -50
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +16 -281
- 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/device.d.ts.map +1 -1
- package/dist/commands/device.js +3 -2
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/lint.d.ts +1 -42
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +1 -151
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +2 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/typecheck.d.ts +3 -40
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +3 -232
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +20 -8
- package/dist/electron/electron.js.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +1 -0
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +16 -0
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
- package/dist/orchestrators/TypecheckOrchestrator.d.ts +74 -0
- package/dist/orchestrators/TypecheckOrchestrator.d.ts.map +1 -0
- package/dist/orchestrators/TypecheckOrchestrator.js +285 -0
- package/dist/orchestrators/TypecheckOrchestrator.js.map +1 -0
- package/dist/sd-cli.js +6 -1
- package/dist/sd-cli.js.map +1 -1
- package/dist/utils/lint-core.d.ts +43 -0
- package/dist/utils/lint-core.d.ts.map +1 -0
- package/dist/utils/lint-core.js +154 -0
- package/dist/utils/lint-core.js.map +1 -0
- package/dist/utils/lint-utils.d.ts +1 -1
- package/dist/utils/lint-utils.d.ts.map +1 -1
- package/dist/utils/server-production-files.d.ts +22 -0
- package/dist/utils/server-production-files.d.ts.map +1 -0
- package/dist/utils/server-production-files.js +162 -0
- package/dist/utils/server-production-files.js.map +1 -0
- package/dist/utils/vite-config.d.ts +1 -1
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +76 -26
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.js +7 -1
- package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +1 -1
- package/dist/workers/lint.worker.d.ts.map +1 -1
- package/dist/workers/lint.worker.js +1 -1
- package/dist/workers/lint.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +11 -161
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +15 -0
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/package.json +9 -7
- package/src/angular/vite-angular-plugin.ts +88 -34
- package/src/angular/vite-postcss-inline-plugin.ts +5 -1
- package/src/capacitor/capacitor-android.ts +368 -0
- package/src/capacitor/capacitor.ts +18 -363
- package/src/commands/check.ts +2 -2
- package/src/commands/device.ts +3 -2
- package/src/commands/lint.ts +1 -201
- package/src/commands/publish.ts +2 -1
- package/src/commands/typecheck.ts +7 -292
- package/src/electron/electron.ts +15 -8
- package/src/orchestrators/DevWatchOrchestrator.ts +18 -0
- package/src/orchestrators/TypecheckOrchestrator.ts +364 -0
- package/src/sd-cli.ts +6 -1
- package/src/utils/lint-core.ts +205 -0
- package/src/utils/lint-utils.ts +1 -1
- package/src/utils/server-production-files.ts +186 -0
- package/src/utils/vite-config.ts +83 -27
- package/src/utils/vite-scope-watch-plugin.ts +6 -1
- package/src/workers/lint.worker.ts +1 -1
- package/src/workers/server-build.worker.ts +10 -185
- package/src/workers/server-runtime.worker.ts +15 -0
- package/tests/angular/linker-disk-cache.spec.ts +31 -25
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +15 -15
- package/tests/angular/vite-angular-plugin-hmr.spec.ts +9 -9
- package/tests/angular/vite-angular-plugin-legacy-watch.spec.ts +108 -0
- package/tests/angular/vite-angular-plugin-lint.spec.ts +4 -4
- package/tests/angular/vite-angular-plugin-scss-hmr.spec.ts +10 -15
- package/tests/angular/vite-angular-plugin.spec.ts +80 -15
- package/tests/angular/vite-postcss-inline-plugin.spec.ts +10 -0
- package/tests/capacitor/capacitor-android-exports.verify.md +11 -0
- package/tests/capacitor/capacitor-android.spec.ts +219 -0
- package/tests/capacitor/capacitor-build.spec.ts +17 -21
- package/tests/capacitor/capacitor-icon.spec.ts +17 -19
- package/tests/capacitor/capacitor-init.spec.ts +18 -14
- package/tests/capacitor/capacitor-run.spec.ts +10 -24
- package/tests/capacitor/capacitor-workspace.spec.ts +30 -25
- package/tests/commands/check.spec.ts +2 -2
- package/tests/commands/device.spec.ts +12 -7
- package/tests/commands/lint.spec.ts +33 -194
- package/tests/commands/publish-set.verify.md +7 -0
- package/tests/electron/electron-symlink-cleanup.verify.md +8 -0
- package/tests/electron/electron.spec.ts +27 -2
- package/tests/orchestrators/dist-delete-watcher.verify.md +10 -0
- package/tests/orchestrators/typecheck-orchestrator.spec.ts +180 -0
- package/tests/sd-cli-catch-all.verify.md +7 -0
- package/tests/utils/lint-core-import-paths.verify.md +10 -0
- package/tests/utils/lint-core.spec.ts +188 -0
- package/tests/utils/server-production-files-import-paths.verify.md +14 -0
- package/tests/utils/vite-config.spec.ts +255 -133
- package/tests/utils/vite-scope-watch-plugin.spec.ts +22 -0
- package/tests/workers/server-build-context-dispose.verify.md +8 -0
- package/tests/workers/server-runtime-worker.spec.ts +48 -4
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
|
|
3
|
+
// Hoisted mock references — available inside vi.mock factories
|
|
4
|
+
const mocks = vi.hoisted(() => ({
|
|
5
|
+
fsxExists: vi.fn<(path: string) => Promise<boolean>>(),
|
|
6
|
+
fsxGlob: vi.fn<(...args: unknown[]) => Promise<string[]>>(),
|
|
7
|
+
filterByTargets: vi.fn(
|
|
8
|
+
(files: string[], _targets: string[], _cwd: string) => files,
|
|
9
|
+
),
|
|
10
|
+
lintFiles: vi.fn<() => Promise<Array<{ errorCount: number; warningCount: number }>>>(),
|
|
11
|
+
loadFormatter: vi.fn(),
|
|
12
|
+
outputFixes: vi.fn(),
|
|
13
|
+
jitiImport: vi.fn(),
|
|
14
|
+
eslintCtor: vi.fn(),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
vi.mock("@simplysm/core-node", () => ({
|
|
18
|
+
fsx: { exists: mocks.fsxExists, glob: mocks.fsxGlob },
|
|
19
|
+
pathx: { filterByTargets: mocks.filterByTargets },
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
vi.mock("eslint", () => ({
|
|
23
|
+
ESLint: class MockESLint {
|
|
24
|
+
constructor(options: unknown) { mocks.eslintCtor(options); }
|
|
25
|
+
lintFiles = mocks.lintFiles;
|
|
26
|
+
loadFormatter = mocks.loadFormatter;
|
|
27
|
+
static outputFixes = mocks.outputFixes;
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
vi.mock("jiti", () => ({
|
|
32
|
+
createJiti: vi.fn(() => ({ import: mocks.jitiImport })),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
vi.mock("consola", () => {
|
|
36
|
+
const fns = (): Record<string, unknown> => ({
|
|
37
|
+
debug: vi.fn(), start: vi.fn(), success: vi.fn(),
|
|
38
|
+
info: vi.fn(), error: vi.fn(), warn: vi.fn(), log: vi.fn(),
|
|
39
|
+
withTag: vi.fn(() => fns()),
|
|
40
|
+
level: 0,
|
|
41
|
+
});
|
|
42
|
+
const c = fns();
|
|
43
|
+
return { consola: c, default: c, LogLevels: {} };
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const { loadIgnorePatterns, executeLint } = await import("../../src/utils/lint-core");
|
|
47
|
+
|
|
48
|
+
//#region loadIgnorePatterns
|
|
49
|
+
|
|
50
|
+
describe("loadIgnorePatterns", () => {
|
|
51
|
+
beforeEach(() => vi.clearAllMocks());
|
|
52
|
+
|
|
53
|
+
it("extracts globalIgnores patterns from eslint config", async () => {
|
|
54
|
+
mocks.fsxExists.mockImplementation((p) =>
|
|
55
|
+
Promise.resolve(typeof p === "string" && p.endsWith("eslint.config.ts")),
|
|
56
|
+
);
|
|
57
|
+
mocks.jitiImport.mockResolvedValue({
|
|
58
|
+
default: [
|
|
59
|
+
{ ignores: ["dist/**", "node_modules/**"] },
|
|
60
|
+
{ files: ["*.ts"], rules: {} }, // not globalIgnores — has files key
|
|
61
|
+
{ ignores: [".cache/**"] },
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const result = await loadIgnorePatterns("/project");
|
|
66
|
+
expect(result).toEqual(["dist/**", "node_modules/**", ".cache/**"]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("ignores config objects that have files key", async () => {
|
|
70
|
+
mocks.fsxExists.mockImplementation((p) =>
|
|
71
|
+
Promise.resolve(typeof p === "string" && p.endsWith("eslint.config.ts")),
|
|
72
|
+
);
|
|
73
|
+
mocks.jitiImport.mockResolvedValue({
|
|
74
|
+
default: [{ files: ["*.ts"], ignores: ["dist/**"] }],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const result = await loadIgnorePatterns("/project");
|
|
78
|
+
expect(result).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("throws when no eslint config file found", async () => {
|
|
82
|
+
mocks.fsxExists.mockResolvedValue(false);
|
|
83
|
+
|
|
84
|
+
await expect(loadIgnorePatterns("/project")).rejects.toThrow(
|
|
85
|
+
"ESLint 설정 파일",
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
|
|
92
|
+
//#region executeLint
|
|
93
|
+
|
|
94
|
+
describe("executeLint", () => {
|
|
95
|
+
beforeEach(() => {
|
|
96
|
+
vi.clearAllMocks();
|
|
97
|
+
// Default: eslint config exists with no ignores
|
|
98
|
+
mocks.fsxExists.mockImplementation((p) =>
|
|
99
|
+
Promise.resolve(typeof p === "string" && p.endsWith("eslint.config.ts")),
|
|
100
|
+
);
|
|
101
|
+
mocks.jitiImport.mockResolvedValue({ default: [] });
|
|
102
|
+
mocks.fsxGlob.mockResolvedValue(["/project/src/a.ts", "/project/src/b.ts"]);
|
|
103
|
+
mocks.filterByTargets.mockImplementation((files) => files);
|
|
104
|
+
mocks.lintFiles.mockResolvedValue([{ errorCount: 0, warningCount: 0 }]);
|
|
105
|
+
mocks.loadFormatter.mockResolvedValue({
|
|
106
|
+
format: vi.fn().mockResolvedValue(""),
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("lints all collected files and returns success when no errors", async () => {
|
|
111
|
+
const result = await executeLint({ targets: [], fix: false, timing: false });
|
|
112
|
+
|
|
113
|
+
expect(result.success).toBe(true);
|
|
114
|
+
expect(result.errorCount).toBe(0);
|
|
115
|
+
expect(result.warningCount).toBe(0);
|
|
116
|
+
expect(mocks.lintFiles).toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("filters files by targets via pathx.filterByTargets", async () => {
|
|
120
|
+
const filteredFiles = ["/project/packages/core-common/src/a.ts"];
|
|
121
|
+
mocks.filterByTargets.mockReturnValue(filteredFiles);
|
|
122
|
+
|
|
123
|
+
await executeLint({ targets: ["packages/core-common"], fix: false, timing: false });
|
|
124
|
+
|
|
125
|
+
expect(mocks.filterByTargets).toHaveBeenCalledWith(
|
|
126
|
+
expect.any(Array),
|
|
127
|
+
["packages/core-common"],
|
|
128
|
+
expect.any(String),
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("applies auto-fix when fix option is true", async () => {
|
|
133
|
+
await executeLint({ targets: [], fix: true, timing: false });
|
|
134
|
+
|
|
135
|
+
expect(mocks.outputFixes).toHaveBeenCalled();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("sets TIMING env variable when timing option is true", async () => {
|
|
139
|
+
const origTiming = process.env["TIMING"];
|
|
140
|
+
|
|
141
|
+
await executeLint({ targets: [], fix: false, timing: true });
|
|
142
|
+
|
|
143
|
+
expect(process.env["TIMING"]).toBe("1");
|
|
144
|
+
|
|
145
|
+
// Cleanup
|
|
146
|
+
if (origTiming == null) delete process.env["TIMING"];
|
|
147
|
+
else process.env["TIMING"] = origTiming;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("creates ESLint with cache enabled and correct cache location", async () => {
|
|
151
|
+
await executeLint({ targets: [], fix: false, timing: false });
|
|
152
|
+
|
|
153
|
+
expect(mocks.eslintCtor).toHaveBeenCalledWith(
|
|
154
|
+
expect.objectContaining({
|
|
155
|
+
cache: true,
|
|
156
|
+
cacheLocation: expect.stringContaining("eslint.cache"),
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("returns error count and formatted output when lint errors found", async () => {
|
|
162
|
+
mocks.lintFiles.mockResolvedValue([
|
|
163
|
+
{ errorCount: 3, warningCount: 1 },
|
|
164
|
+
{ errorCount: 1, warningCount: 2 },
|
|
165
|
+
]);
|
|
166
|
+
mocks.loadFormatter.mockResolvedValue({
|
|
167
|
+
format: vi.fn().mockResolvedValue("error details"),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const result = await executeLint({ targets: [], fix: false, timing: false });
|
|
171
|
+
|
|
172
|
+
expect(result.success).toBe(false);
|
|
173
|
+
expect(result.errorCount).toBe(4);
|
|
174
|
+
expect(result.warningCount).toBe(3);
|
|
175
|
+
expect(result.formattedOutput).toBe("error details");
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("returns success when no files to lint", async () => {
|
|
179
|
+
mocks.fsxGlob.mockResolvedValue([]);
|
|
180
|
+
|
|
181
|
+
const result = await executeLint({ targets: [], fix: false, timing: false });
|
|
182
|
+
|
|
183
|
+
expect(result.success).toBe(true);
|
|
184
|
+
expect(mocks.lintFiles).not.toHaveBeenCalled();
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# server-build.worker 비즈니스 로직 분리 — LLM 검증
|
|
2
|
+
|
|
3
|
+
## 검증 항목
|
|
4
|
+
|
|
5
|
+
- [x] 4개 함수가 utils/server-production-files.ts에 export되어 있다: line 14, 27, 68, 87에 각각 export function 확인
|
|
6
|
+
- [x] worker에서 4개 함수 정의가 제거되었다: worker에 함수 정의 없음, import와 호출만 존재
|
|
7
|
+
- [x] worker에서 collectAllExternals, generateProductionFiles를 새 모듈에서 import한다: line 19 `import { collectAllExternals, generateProductionFiles } from "../utils/server-production-files"`
|
|
8
|
+
- [x] collectAllExternals 시그니처: `(pkgDir: string, manualExternals?: string[]) => string[]` — line 14 확인
|
|
9
|
+
- [x] parseLockfileVersions 시그니처: `(cwd: string) => Map<string, string>` — line 27 확인
|
|
10
|
+
- [x] resolveLockedVersions 시그니처: `(cwd: string, pkgNames: string[]) => Record<string, string>` — line 68 확인
|
|
11
|
+
- [x] generateProductionFiles 시그니처: `(info: ServerBuildInfo, externals: string[]) => void` — line 87 확인
|
|
12
|
+
- [x] worker에 build, rebuildAll, startWatch, stopWatch, cleanup, createEsbuildWatchContext가 존재한다: line 116, 148, 259, 336, 359, 488 확인
|
|
13
|
+
- [x] worker에서 cpx import가 제거되었다: grep 결과 매칭 없음
|
|
14
|
+
- [x] worker에서 collectAllDependencyExternals import가 제거되었다: grep 결과 매칭 없음
|