@simplysm/sd-cli 14.0.7 → 14.0.9
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/client-transform-stylesheet.d.ts.map +1 -1
- package/dist/angular/client-transform-stylesheet.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +15 -8
- 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.map +1 -1
- package/dist/capacitor/capacitor.d.ts +1 -1
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +43 -44
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +2 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.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/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +12 -12
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js.map +1 -1
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +42 -37
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts +1 -5
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +7 -16
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +10 -11
- package/dist/engines/NgtscEngine.js.map +1 -1
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +10 -11
- package/dist/engines/ServerEsbuildEngine.js.map +1 -1
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +10 -11
- package/dist/engines/TscEngine.js.map +1 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +3 -13
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts.map +1 -1
- package/dist/engines/index.js.map +1 -1
- package/dist/engines/types.d.ts +3 -6
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/engines/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infra/ResultCollector.d.ts +1 -1
- package/dist/infra/ResultCollector.d.ts.map +1 -1
- package/dist/infra/ResultCollector.js.map +1 -1
- package/dist/infra/SignalHandler.d.ts.map +1 -1
- package/dist/infra/SignalHandler.js.map +1 -1
- package/dist/infra/WorkerManager.d.ts.map +1 -1
- package/dist/infra/WorkerManager.js.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +30 -61
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +2 -0
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +40 -44
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +2 -13
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.d.ts.map +1 -1
- package/dist/sd-cli.js +5 -5
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/sd-config.types.js.map +1 -1
- package/dist/utils/SdCliReporter.d.ts +18 -0
- package/dist/utils/SdCliReporter.d.ts.map +1 -0
- package/dist/utils/SdCliReporter.js +144 -0
- package/dist/utils/SdCliReporter.js.map +1 -0
- package/dist/utils/angular-build.d.ts.map +1 -1
- package/dist/utils/angular-build.js.map +1 -1
- package/dist/utils/angular-compiler.d.ts.map +1 -1
- package/dist/utils/angular-compiler.js +11 -4
- package/dist/utils/angular-compiler.js.map +1 -1
- package/dist/utils/build-env.d.ts.map +1 -1
- package/dist/utils/build-env.js +2 -1
- package/dist/utils/build-env.js.map +1 -1
- package/dist/utils/concurrency.d.ts.map +1 -1
- package/dist/utils/concurrency.js.map +1 -1
- package/dist/utils/copy-public.d.ts.map +1 -1
- package/dist/utils/copy-public.js +21 -21
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts.map +1 -1
- package/dist/utils/copy-src.js +12 -12
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/diagnostic-utils.d.ts.map +1 -1
- package/dist/utils/diagnostic-utils.js +3 -2
- package/dist/utils/diagnostic-utils.js.map +1 -1
- package/dist/utils/engine-stop.d.ts.map +1 -1
- package/dist/utils/engine-stop.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +2 -0
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/generate-pwa-icons.d.ts.map +1 -1
- package/dist/utils/generate-pwa-icons.js.map +1 -1
- package/dist/utils/hmr-candidates.d.ts.map +1 -1
- package/dist/utils/hmr-candidates.js.map +1 -1
- package/dist/utils/lint-utils.d.ts.map +1 -1
- package/dist/utils/lint-utils.js.map +1 -1
- package/dist/utils/lint-with-program.d.ts.map +1 -1
- package/dist/utils/lint-with-program.js +7 -3
- package/dist/utils/lint-with-program.js.map +1 -1
- package/dist/utils/ngtsc-build-core.d.ts +2 -10
- package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
- package/dist/utils/ngtsc-build-core.js +16 -15
- package/dist/utils/ngtsc-build-core.js.map +1 -1
- package/dist/utils/orchestrator-utils.d.ts.map +1 -1
- package/dist/utils/orchestrator-utils.js.map +1 -1
- package/dist/utils/output-path-rewriter.d.ts.map +1 -1
- package/dist/utils/output-path-rewriter.js +7 -7
- package/dist/utils/output-path-rewriter.js.map +1 -1
- package/dist/utils/output-utils.d.ts.map +1 -1
- package/dist/utils/output-utils.js +1 -1
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/utils/package-utils.d.ts +4 -0
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +34 -13
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/rebuild-manager.d.ts +1 -1
- package/dist/utils/rebuild-manager.d.ts.map +1 -1
- package/dist/utils/rebuild-manager.js +3 -1
- package/dist/utils/rebuild-manager.js.map +1 -1
- package/dist/utils/replace-deps.d.ts.map +1 -1
- package/dist/utils/replace-deps.js +10 -10
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/scss-compiler.d.ts.map +1 -1
- package/dist/utils/scss-compiler.js.map +1 -1
- package/dist/utils/sd-config.d.ts.map +1 -1
- package/dist/utils/sd-config.js +2 -3
- package/dist/utils/sd-config.js.map +1 -1
- package/dist/utils/tsc-build.d.ts +3 -1
- package/dist/utils/tsc-build.d.ts.map +1 -1
- package/dist/utils/tsc-build.js +7 -4
- package/dist/utils/tsc-build.js.map +1 -1
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-non-package.d.ts.map +1 -1
- package/dist/utils/typecheck-non-package.js +10 -5
- package/dist/utils/typecheck-non-package.js.map +1 -1
- package/dist/utils/typecheck-serialization.d.ts.map +1 -1
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +2 -1
- 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.map +1 -1
- package/dist/utils/worker-events.d.ts +1 -1
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +1 -0
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +1 -1
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +3 -1
- package/dist/utils/worker-utils.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/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +4 -0
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/library-build.worker.d.ts +2 -10
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +38 -14
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts.map +1 -1
- package/dist/workers/lint.worker.js.map +1 -1
- package/dist/workers/ngtsc-build.worker.d.ts.map +1 -1
- package/dist/workers/ngtsc-build.worker.js +40 -14
- package/dist/workers/ngtsc-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts +2 -10
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +30 -22
- 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.map +1 -1
- package/package.json +4 -5
- package/src/angular/vite-angular-plugin.ts +18 -9
- package/src/capacitor/capacitor.ts +43 -44
- package/src/commands/check.ts +2 -2
- package/src/commands/publish.ts +12 -13
- package/src/commands/typecheck.ts +12 -12
- package/src/electron/electron.ts +44 -38
- package/src/engines/BaseEngine.ts +8 -19
- package/src/engines/NgtscEngine.ts +11 -11
- package/src/engines/ServerEsbuildEngine.ts +11 -11
- package/src/engines/TscEngine.ts +11 -11
- package/src/engines/ViteEngine.ts +3 -14
- package/src/engines/types.ts +3 -6
- package/src/infra/ResultCollector.ts +1 -1
- package/src/orchestrators/BuildOrchestrator.ts +31 -62
- package/src/orchestrators/DevWatchOrchestrator.ts +41 -44
- package/src/sd-cli-entry.ts +2 -12
- package/src/sd-cli.ts +8 -5
- package/src/utils/SdCliReporter.ts +177 -0
- package/src/utils/angular-compiler.ts +11 -4
- package/src/utils/build-env.ts +2 -1
- package/src/utils/copy-public.ts +21 -21
- package/src/utils/copy-src.ts +12 -12
- package/src/utils/diagnostic-utils.ts +3 -2
- package/src/utils/esbuild-config.ts +2 -0
- package/src/utils/lint-with-program.ts +7 -3
- package/src/utils/ngtsc-build-core.ts +18 -18
- package/src/utils/output-path-rewriter.ts +7 -7
- package/src/utils/output-utils.ts +1 -1
- package/src/utils/package-utils.ts +37 -13
- package/src/utils/rebuild-manager.ts +4 -2
- package/src/utils/replace-deps.ts +10 -10
- package/src/utils/sd-config.ts +2 -3
- package/src/utils/tsc-build.ts +9 -4
- package/src/utils/typecheck-non-package.ts +10 -5
- package/src/utils/vite-config.ts +2 -1
- package/src/utils/worker-events.ts +2 -1
- package/src/utils/worker-utils.ts +3 -1
- package/src/vitest-plugin.ts +5 -0
- package/src/workers/client.worker.ts +4 -0
- package/src/workers/library-build.worker.ts +48 -18
- package/src/workers/ngtsc-build.worker.ts +48 -13
- package/src/workers/server-build.worker.ts +32 -26
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +11 -7
- package/tests/angular/vite-angular-plugin-lint.spec.ts +6 -1
- package/tests/capacitor/capacitor-build.spec.ts +14 -7
- package/tests/capacitor/capacitor-icon.spec.ts +14 -7
- package/tests/capacitor/capacitor-init.spec.ts +13 -6
- package/tests/capacitor/capacitor-run.spec.ts +18 -11
- package/tests/capacitor/capacitor-workspace.spec.ts +13 -6
- package/tests/commands/check.spec.ts +5 -2
- package/tests/commands/publish.spec.ts +4 -4
- package/tests/commands/typecheck.spec.ts +20 -31
- package/tests/electron/electron.spec.ts +32 -23
- package/tests/engines/base-engine.spec.ts +15 -21
- package/tests/engines/engine-lint-integration.spec.ts +5 -10
- package/tests/engines/ngtsc-engine.spec.ts +27 -41
- package/tests/engines/server-esbuild-engine.spec.ts +18 -29
- package/tests/engines/tsc-engine.spec.ts +14 -23
- package/tests/engines/vite-engine.spec.ts +10 -15
- package/tests/infra/result-collector.spec.ts +2 -2
- package/tests/orchestrators/build-orchestrator.spec.ts +19 -29
- package/tests/orchestrators/dev-watch-orchestrator.spec.ts +110 -95
- package/tests/utils/copy-src.spec.ts +25 -19
- package/tests/utils/diagnostic-utils.spec.ts +72 -0
- package/tests/utils/ngtsc-build-core-angular-compiler.spec.ts +2 -3
- package/tests/utils/output-path-rewriter.spec.ts +7 -6
- package/tests/utils/output-utils.spec.ts +5 -5
- package/tests/utils/rebuild-manager.spec.ts +1 -1
- package/tests/utils/sd-config.spec.ts +4 -0
- package/tests/utils/tsc-build.spec.ts +23 -5
- package/tests/workers/library-build-worker.spec.ts +113 -20
- package/tests/workers/ngtsc-build-lint.spec.ts +3 -6
- package/tests/workers/ngtsc-build-worker.spec.ts +11 -13
- package/tests/workers/server-build-lint.spec.ts +4 -1
- package/tests/workers/server-build-worker.spec.ts +25 -25
- package/tests/angular/migration-cleanup.spec.ts +0 -59
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import ts from "typescript";
|
|
3
|
-
import { createWorker, FsWatcher } from "@simplysm/core-node";
|
|
3
|
+
import { createWorker, FsWatcher, pathx } from "@simplysm/core-node";
|
|
4
4
|
import { err as errNs } from "@simplysm/core-common";
|
|
5
5
|
import { consola } from "consola";
|
|
6
6
|
import { registerCleanupHandlers, createOnceGuard, applyDebugLevel } from "../utils/worker-utils";
|
|
@@ -22,6 +22,7 @@ import { LintWithProgramRunner, type LintWithProgramResult } from "../utils/lint
|
|
|
22
22
|
import {
|
|
23
23
|
parseTsconfig,
|
|
24
24
|
getPackageSourceFiles,
|
|
25
|
+
getPackageFiles,
|
|
25
26
|
getCompilerOptionsForEnv,
|
|
26
27
|
} from "../utils/tsconfig";
|
|
27
28
|
import { AngularCompiler, AngularSourceFileCache } from "../utils/angular-compiler";
|
|
@@ -50,6 +51,7 @@ let fsWatcher: FsWatcher | undefined;
|
|
|
50
51
|
async function cleanup(): Promise<void> {
|
|
51
52
|
const watcherToClose = fsWatcher;
|
|
52
53
|
fsWatcher = undefined;
|
|
54
|
+
lastSourceFilePaths = undefined;
|
|
53
55
|
|
|
54
56
|
if (watcherToClose != null) {
|
|
55
57
|
await watcherToClose.close();
|
|
@@ -65,15 +67,17 @@ registerCleanupHandlers(cleanup, logger);
|
|
|
65
67
|
async function build(info: NgtscBuildInfo): Promise<NgtscBuildResult> {
|
|
66
68
|
logger.debug(`[${info.name}] ngtsc worker build 시작 (pkgDir: ${info.pkgDir})`);
|
|
67
69
|
const { program, ...result } = await runNgtscBuild({ ...info, env: info.output.env });
|
|
68
|
-
logger.debug(`[${info.name}] ngtsc worker build 완료 (
|
|
70
|
+
logger.debug(`[${info.name}] ngtsc worker build 완료 (build.success: ${result.build.success})`);
|
|
69
71
|
|
|
70
72
|
// Run lint if enabled and program is available
|
|
71
73
|
if (info.output.lint === true && program != null) {
|
|
74
|
+
logger.debug(`[${info.name}] lint 시작`);
|
|
72
75
|
const lintRunner = new LintWithProgramRunner({
|
|
73
76
|
cwd: info.cwd,
|
|
74
77
|
pkgName: info.name,
|
|
75
78
|
});
|
|
76
79
|
result.lint = await lintRunner.lint({ program });
|
|
80
|
+
logger.debug(`[${info.name}] lint 완료`);
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
return result;
|
|
@@ -88,8 +92,17 @@ const guardStartWatch = createOnceGuard("startWatch");
|
|
|
88
92
|
let watchInfo: NgtscBuildInfo | undefined;
|
|
89
93
|
let currentScssDependencies: Map<string, Set<string>> | undefined;
|
|
90
94
|
let watchLintRunner: LintWithProgramRunner | undefined;
|
|
95
|
+
let lastSourceFilePaths: Set<string> | undefined;
|
|
91
96
|
const sideEffectScssRegistry = new Map<string, SideEffectScssEntry>();
|
|
92
97
|
|
|
98
|
+
function extractSourceFilePaths(program: ReturnType<AngularCompiler["getTsProgram"]>): Set<string> {
|
|
99
|
+
const paths = new Set<string>();
|
|
100
|
+
for (const sf of program.getSourceFiles()) {
|
|
101
|
+
paths.add(pathx.posix(sf.fileName));
|
|
102
|
+
}
|
|
103
|
+
return paths;
|
|
104
|
+
}
|
|
105
|
+
|
|
93
106
|
/**
|
|
94
107
|
* Perform a watch build (initial or incremental) using AngularCompiler.
|
|
95
108
|
* Returns NgtscCombinedBuildEvent for sending to the engine.
|
|
@@ -105,8 +118,9 @@ async function performWatchBuild(
|
|
|
105
118
|
affectedFileNames?: ReadonlySet<string>,
|
|
106
119
|
hasScssChanges = true,
|
|
107
120
|
): Promise<NgtscCombinedBuildEvent> {
|
|
121
|
+
logger.debug(`[${info.name}] performWatchBuild 시작`);
|
|
108
122
|
const pkgSrcDir = path.join(info.pkgDir, "src");
|
|
109
|
-
const normalizedSrcDir =
|
|
123
|
+
const normalizedSrcDir = pathx.posix(pkgSrcDir);
|
|
110
124
|
|
|
111
125
|
// Collect diagnostics — workspace scope (no package-level filtering)
|
|
112
126
|
const allDiagnostics = [...compiler.collectDiagnostics()].filter(
|
|
@@ -124,7 +138,7 @@ async function performWatchBuild(
|
|
|
124
138
|
const loadPaths = buildScssLoadPaths(info);
|
|
125
139
|
const emitResults = compiler.emitAffectedFiles({
|
|
126
140
|
sourceFilter: (fileName: string) =>
|
|
127
|
-
|
|
141
|
+
pathx.posix(fileName).startsWith(normalizedSrcDir + "/"),
|
|
128
142
|
});
|
|
129
143
|
writeEmitResults(emitResults, info.pkgDir, {
|
|
130
144
|
loadPaths,
|
|
@@ -146,6 +160,7 @@ async function performWatchBuild(
|
|
|
146
160
|
// Run lint if enabled
|
|
147
161
|
let lint: LintWithProgramResult | undefined;
|
|
148
162
|
if (info.output.lint === true) {
|
|
163
|
+
logger.debug(`[${info.name}] lint 시작`);
|
|
149
164
|
if (watchLintRunner == null) {
|
|
150
165
|
watchLintRunner = new LintWithProgramRunner({
|
|
151
166
|
cwd: info.cwd,
|
|
@@ -156,11 +171,12 @@ async function performWatchBuild(
|
|
|
156
171
|
program: compiler.getTsProgram(),
|
|
157
172
|
affectedFiles: affectedFileNames,
|
|
158
173
|
});
|
|
174
|
+
logger.debug(`[${info.name}] lint 완료`);
|
|
159
175
|
}
|
|
160
176
|
|
|
177
|
+
logger.debug(`[${info.name}] performWatchBuild 완료`);
|
|
161
178
|
return {
|
|
162
|
-
|
|
163
|
-
dts: {
|
|
179
|
+
build: {
|
|
164
180
|
success: errorCount === 0 && scssErrors.length === 0 && globalScssErrors.length === 0,
|
|
165
181
|
errors: allErrors.length > 0 ? allErrors : undefined,
|
|
166
182
|
},
|
|
@@ -175,17 +191,16 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
175
191
|
try {
|
|
176
192
|
// Parse tsconfig and prepare compiler options
|
|
177
193
|
const parsedConfig = parseTsconfig(watchInfo.pkgDir);
|
|
178
|
-
const sourceFiles =
|
|
194
|
+
const sourceFiles = watchInfo.output.includeTests === true
|
|
195
|
+
? getPackageFiles(watchInfo.pkgDir, parsedConfig)
|
|
196
|
+
: getPackageSourceFiles(watchInfo.pkgDir, parsedConfig);
|
|
179
197
|
const baseOptions =
|
|
180
198
|
watchInfo.env != null
|
|
181
199
|
? getCompilerOptionsForEnv(parsedConfig.options, watchInfo.env, watchInfo.pkgDir)
|
|
182
200
|
: parsedConfig.options;
|
|
183
201
|
const compilerOptions = buildCompilerOptions(baseOptions, watchInfo.pkgDir, watchInfo.output);
|
|
184
202
|
|
|
185
|
-
|
|
186
|
-
const rootTsconfigPath = path.join(watchInfo.cwd, "tsconfig.json");
|
|
187
|
-
const rootRawConfig = ts.readConfigFile(rootTsconfigPath, ts.sys.readFile);
|
|
188
|
-
const angularOptions = rootRawConfig.config?.angularCompilerOptions ?? {};
|
|
203
|
+
const angularOptions = (parsedConfig.raw?.angularCompilerOptions ?? {}) as Record<string, unknown>;
|
|
189
204
|
|
|
190
205
|
// SCSS closure variables
|
|
191
206
|
const scssErrors: string[] = [];
|
|
@@ -204,6 +219,7 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
204
219
|
});
|
|
205
220
|
// Initial build
|
|
206
221
|
await compiler.initialize();
|
|
222
|
+
lastSourceFilePaths = extractSourceFilePaths(compiler.getTsProgram());
|
|
207
223
|
const initialResult = await performWatchBuild(watchInfo, compiler, scssDependencies, scssErrors);
|
|
208
224
|
sender.send("build", initialResult);
|
|
209
225
|
|
|
@@ -215,6 +231,7 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
215
231
|
);
|
|
216
232
|
|
|
217
233
|
// Start FsWatcher
|
|
234
|
+
logger.debug(`[${watchInfo.name}] FsWatcher 시작`);
|
|
218
235
|
const watchPaths = [
|
|
219
236
|
path.join(watchInfo.pkgDir, "src", "**", "*.{ts,scss,css}"),
|
|
220
237
|
path.join(watchInfo.pkgDir, "scss", "**", "*.{scss,css}"),
|
|
@@ -234,7 +251,9 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
234
251
|
|
|
235
252
|
fsWatcher.onChange({ delay: 300 }, async (changedFiles) => {
|
|
236
253
|
try {
|
|
237
|
-
|
|
254
|
+
const hasFileAddOrRemove = changedFiles.some(
|
|
255
|
+
(c) => c.event === "add" || c.event === "unlink",
|
|
256
|
+
);
|
|
238
257
|
|
|
239
258
|
// Collect modified files (all changed + SCSS dependency reverse-lookup)
|
|
240
259
|
const modifiedFiles = new Set<string>();
|
|
@@ -254,6 +273,19 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
254
273
|
}
|
|
255
274
|
}
|
|
256
275
|
|
|
276
|
+
// Dependency filter: skip rebuild if no relevant changes
|
|
277
|
+
if (!hasFileAddOrRemove && lastSourceFilePaths != null) {
|
|
278
|
+
const hasRelevantChange = [...modifiedFiles].some((p) =>
|
|
279
|
+
lastSourceFilePaths!.has(p),
|
|
280
|
+
);
|
|
281
|
+
if (!hasRelevantChange) {
|
|
282
|
+
logger.debug("변경된 파일이 빌드에 포함되지 않아 리빌드 건너뜀");
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
sender.send("buildStart", {});
|
|
288
|
+
|
|
257
289
|
// Clear SCSS errors for fresh rebuild
|
|
258
290
|
scssErrors.length = 0;
|
|
259
291
|
scssDependencies.clear();
|
|
@@ -261,10 +293,13 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
261
293
|
// Incremental rebuild via AngularCompiler.update()
|
|
262
294
|
const updateResult = await compiler.update(modifiedFiles);
|
|
263
295
|
|
|
296
|
+
// Update source file paths after rebuild
|
|
297
|
+
lastSourceFilePaths = extractSourceFilePaths(compiler.getTsProgram());
|
|
298
|
+
|
|
264
299
|
// Convert affected ts.SourceFile set to file name strings for incremental lint
|
|
265
300
|
const affectedFileNames = new Set<string>();
|
|
266
301
|
for (const sf of updateResult.affectedFiles) {
|
|
267
|
-
affectedFileNames.add(sf.fileName
|
|
302
|
+
affectedFileNames.add(pathx.posix(sf.fileName));
|
|
268
303
|
}
|
|
269
304
|
|
|
270
305
|
const hasScssChanges = changedFiles.some(
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs";
|
|
3
|
-
import { execaSync } from "execa";
|
|
4
3
|
import esbuild from "esbuild";
|
|
5
|
-
import { createWorker, FsWatcher, pathx } from "@simplysm/core-node";
|
|
4
|
+
import { cpx, createWorker, FsWatcher, pathx } from "@simplysm/core-node";
|
|
6
5
|
import { err as errNs } from "@simplysm/core-common";
|
|
7
6
|
import { consola } from "consola";
|
|
8
7
|
import type { BuildOutput } from "../engines/types";
|
|
@@ -70,8 +69,7 @@ export interface ServerWatchInfo {
|
|
|
70
69
|
* Server build result (aligned with LibraryBuildResult + mainJsPath)
|
|
71
70
|
*/
|
|
72
71
|
export interface ServerBuildResult {
|
|
73
|
-
|
|
74
|
-
dts: { success: boolean; errors?: string[]; diagnostics: SerializedDiagnostic[] };
|
|
72
|
+
build: { success: boolean; errors?: string[]; warnings?: string[]; diagnostics: SerializedDiagnostic[] };
|
|
75
73
|
lint?: LintWithProgramResult;
|
|
76
74
|
mainJsPath: string;
|
|
77
75
|
}
|
|
@@ -80,8 +78,7 @@ export interface ServerBuildResult {
|
|
|
80
78
|
* Combined build event for watch mode
|
|
81
79
|
*/
|
|
82
80
|
export interface ServerCombinedBuildEvent {
|
|
83
|
-
|
|
84
|
-
dts: { success: boolean; errors?: string[] };
|
|
81
|
+
build: { success: boolean; errors?: string[]; warnings?: string[] };
|
|
85
82
|
lint?: LintWithProgramResult;
|
|
86
83
|
mainJsPath: string;
|
|
87
84
|
}
|
|
@@ -231,7 +228,7 @@ function generateProductionFiles(
|
|
|
231
228
|
distPkgJson["dependencies"] = resolveLockedVersions(info.cwd, externals);
|
|
232
229
|
}
|
|
233
230
|
if (info.packageManager === "volta") {
|
|
234
|
-
const nodeVersion =
|
|
231
|
+
const nodeVersion = cpx.execSync("node", ["-v"]).stdout.trim();
|
|
235
232
|
distPkgJson["volta"] = { node: nodeVersion };
|
|
236
233
|
}
|
|
237
234
|
fs.writeFileSync(path.join(distDir, "package.json"), JSON.stringify(distPkgJson, undefined, 2));
|
|
@@ -325,7 +322,7 @@ registerCleanupHandlers(cleanup, logger);
|
|
|
325
322
|
* One-time build (production)
|
|
326
323
|
*/
|
|
327
324
|
async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
328
|
-
const mainJsPath =
|
|
325
|
+
const mainJsPath = pathx.posixResolve(info.pkgDir, "dist", "main.js");
|
|
329
326
|
logger.debug(`[${info.name}] server worker build 시작 (js: ${info.output.js}, dts: ${info.output.dts})`);
|
|
330
327
|
|
|
331
328
|
try {
|
|
@@ -370,6 +367,7 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
370
367
|
output: { js: false, dts: info.output.dts },
|
|
371
368
|
parsedConfig,
|
|
372
369
|
env: info.output.env,
|
|
370
|
+
includeTests: info.output.includeTests,
|
|
373
371
|
});
|
|
374
372
|
|
|
375
373
|
const jsResult = esbuildPromise
|
|
@@ -379,11 +377,13 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
379
377
|
// Run lint if enabled and program is available
|
|
380
378
|
let lint: LintWithProgramResult | undefined;
|
|
381
379
|
if (info.output.lint === true && tscResult.program != null) {
|
|
380
|
+
logger.debug(`[${info.name}] lint 시작`);
|
|
382
381
|
const lintRunner = new LintWithProgramRunner({
|
|
383
382
|
cwd: info.cwd,
|
|
384
383
|
pkgName: info.name,
|
|
385
384
|
});
|
|
386
385
|
lint = await lintRunner.lint({ program: tscResult.program });
|
|
386
|
+
logger.debug(`[${info.name}] lint 완료`);
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
// Generate production artifacts only when JS output is requested
|
|
@@ -396,16 +396,13 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
396
396
|
generateProductionFiles(info, external);
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
-
|
|
399
|
+
const allErrors = [...(jsResult.errors ?? []), ...(tscResult.errors ?? [])];
|
|
400
|
+
logger.debug(`[${info.name}] server worker build 완료 (js: ${jsResult.success}, tsc: ${tscResult.success})`);
|
|
400
401
|
return {
|
|
401
|
-
|
|
402
|
-
success: jsResult.success,
|
|
403
|
-
errors:
|
|
402
|
+
build: {
|
|
403
|
+
success: jsResult.success && tscResult.success,
|
|
404
|
+
errors: allErrors.length > 0 ? allErrors : undefined,
|
|
404
405
|
warnings: jsResult.warnings,
|
|
405
|
-
},
|
|
406
|
-
dts: {
|
|
407
|
-
success: tscResult.success,
|
|
408
|
-
errors: tscResult.errors,
|
|
409
406
|
diagnostics: tscResult.diagnostics,
|
|
410
407
|
},
|
|
411
408
|
lint,
|
|
@@ -419,8 +416,7 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
419
416
|
logger.debug(`[${info.name}] 스택 트레이스:\n${stack}`);
|
|
420
417
|
}
|
|
421
418
|
return {
|
|
422
|
-
|
|
423
|
-
dts: { success: false, errors: [message], diagnostics: [] },
|
|
419
|
+
build: { success: false, errors: [message], diagnostics: [] },
|
|
424
420
|
mainJsPath,
|
|
425
421
|
};
|
|
426
422
|
}
|
|
@@ -437,7 +433,8 @@ let watchLintRunner: LintWithProgramRunner | undefined;
|
|
|
437
433
|
*/
|
|
438
434
|
async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
439
435
|
const info = watchInfo!;
|
|
440
|
-
|
|
436
|
+
logger.debug(`[${info.name}] rebuildAll 시작`);
|
|
437
|
+
const mainJsPath = pathx.posixResolve(info.pkgDir, "dist", "main.js");
|
|
441
438
|
const parsedConfig = parseTsconfig(info.pkgDir);
|
|
442
439
|
|
|
443
440
|
// esbuild rebuild (async)
|
|
@@ -469,11 +466,13 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
469
466
|
output: { js: false, dts: info.output.dts },
|
|
470
467
|
parsedConfig,
|
|
471
468
|
env: info.output.env,
|
|
469
|
+
includeTests: info.output.includeTests,
|
|
472
470
|
});
|
|
473
471
|
|
|
474
472
|
// Run lint if enabled and program is available
|
|
475
473
|
let lint: LintWithProgramResult | undefined;
|
|
476
474
|
if (info.output.lint === true && tscResult.program != null) {
|
|
475
|
+
logger.debug(`[${info.name}] lint 시작`);
|
|
477
476
|
if (watchLintRunner == null) {
|
|
478
477
|
watchLintRunner = new LintWithProgramRunner({
|
|
479
478
|
cwd: info.cwd,
|
|
@@ -484,15 +483,21 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
484
483
|
program: tscResult.program,
|
|
485
484
|
affectedFiles: tscResult.affectedFiles,
|
|
486
485
|
});
|
|
486
|
+
logger.debug(`[${info.name}] lint 완료`);
|
|
487
487
|
}
|
|
488
488
|
|
|
489
489
|
const jsResult = esbuildPromise
|
|
490
490
|
? await esbuildPromise
|
|
491
491
|
: { success: true, errors: undefined, warnings: undefined };
|
|
492
492
|
|
|
493
|
+
const allErrors = [...(jsResult.errors ?? []), ...(tscResult.errors ?? [])];
|
|
494
|
+
logger.debug(`[${info.name}] rebuildAll 완료`);
|
|
493
495
|
return {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
+
build: {
|
|
497
|
+
success: jsResult.success && tscResult.success,
|
|
498
|
+
errors: allErrors.length > 0 ? allErrors : undefined,
|
|
499
|
+
warnings: jsResult.warnings,
|
|
500
|
+
},
|
|
496
501
|
lint,
|
|
497
502
|
mainJsPath,
|
|
498
503
|
};
|
|
@@ -542,6 +547,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
542
547
|
}
|
|
543
548
|
|
|
544
549
|
// Initial build: esbuild + tsc parallel
|
|
550
|
+
sender.send("buildStart", {});
|
|
545
551
|
const initialResult = await rebuildAll();
|
|
546
552
|
|
|
547
553
|
// Write .config.json on first build
|
|
@@ -561,17 +567,17 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
561
567
|
// Server package itself + workspace dependency packages source
|
|
562
568
|
const watchDirs = [
|
|
563
569
|
info.pkgDir,
|
|
564
|
-
...workspaceDeps.map((d) =>
|
|
570
|
+
...workspaceDeps.map((d) => pathx.posixResolve(info.cwd, "packages", d)),
|
|
565
571
|
];
|
|
566
572
|
for (const dir of watchDirs) {
|
|
567
|
-
watchPaths.push(
|
|
573
|
+
watchPaths.push(pathx.posixResolve(dir, "src", "**", "*"));
|
|
568
574
|
}
|
|
569
575
|
|
|
570
576
|
// ReplaceDeps dependency packages dist
|
|
571
577
|
for (const pkg of replaceDeps) {
|
|
572
|
-
watchPaths.push(
|
|
578
|
+
watchPaths.push(pathx.posixResolve(info.cwd, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}"));
|
|
573
579
|
watchPaths.push(
|
|
574
|
-
|
|
580
|
+
pathx.posixResolve(info.pkgDir, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}"),
|
|
575
581
|
);
|
|
576
582
|
}
|
|
577
583
|
|
|
@@ -628,7 +634,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
628
634
|
|
|
629
635
|
// Filter by metafile inputs
|
|
630
636
|
const metafileAbsPaths = new Set(
|
|
631
|
-
Object.keys(lastMetafile.inputs).map((key) => pathx.
|
|
637
|
+
Object.keys(lastMetafile.inputs).map((key) => pathx.posixResolve(info.cwd, key)),
|
|
632
638
|
);
|
|
633
639
|
|
|
634
640
|
const hasRelevantChange = changes.some((c) => metafileAbsPaths.has(c.path));
|
|
@@ -138,8 +138,8 @@ describe("sdAngularPlugin CSS HMR compatibility", () => {
|
|
|
138
138
|
await (plugin as any).buildEnd?.call({});
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
-
// Unit: .scss
|
|
142
|
-
it("
|
|
141
|
+
// Unit: .scss 파일이 TS 프로그램에 없으면 리빌드를 건너뛴다
|
|
142
|
+
it("skips .scss files not in the TypeScript program", async () => {
|
|
143
143
|
const onBuildStart = vi.fn();
|
|
144
144
|
const onBuild = vi.fn();
|
|
145
145
|
const plugin = sdAngularPlugin({
|
|
@@ -151,6 +151,10 @@ describe("sdAngularPlugin CSS HMR compatibility", () => {
|
|
|
151
151
|
|
|
152
152
|
await (plugin as any).buildStart?.call({});
|
|
153
153
|
|
|
154
|
+
// buildStart 완료 후 초기 빌드 결과 콜백 리셋
|
|
155
|
+
onBuildStart.mockClear();
|
|
156
|
+
onBuild.mockClear();
|
|
157
|
+
|
|
154
158
|
const scssFilePath = path
|
|
155
159
|
.join(FIXTURE_DIR, "src/styles.scss")
|
|
156
160
|
.replace(/\\/g, "/");
|
|
@@ -163,12 +167,12 @@ describe("sdAngularPlugin CSS HMR compatibility", () => {
|
|
|
163
167
|
read: () => Promise.resolve(""),
|
|
164
168
|
});
|
|
165
169
|
|
|
166
|
-
// .scss
|
|
167
|
-
expect(
|
|
170
|
+
// .scss 파일이 TS 프로그램에 없으므로 undefined 반환 (리빌드 건너뜀)
|
|
171
|
+
expect(result).toBeUndefined();
|
|
168
172
|
|
|
169
|
-
// Angular compiler update가
|
|
170
|
-
expect(onBuildStart).toHaveBeenCalled();
|
|
171
|
-
expect(onBuild).toHaveBeenCalled();
|
|
173
|
+
// Angular compiler update가 호출되지 않아야 한다
|
|
174
|
+
expect(onBuildStart).not.toHaveBeenCalled();
|
|
175
|
+
expect(onBuild).not.toHaveBeenCalled();
|
|
172
176
|
|
|
173
177
|
await (plugin as any).buildEnd?.call({});
|
|
174
178
|
});
|
|
@@ -19,7 +19,12 @@ vi.mock("../../src/utils/lint-with-program", () => ({
|
|
|
19
19
|
LintWithProgramRunner: MockLintWithProgramRunner,
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
|
-
const mockTsProgram = {
|
|
22
|
+
const mockTsProgram = {
|
|
23
|
+
getSourceFiles: () => [
|
|
24
|
+
{ fileName: "/workspace/packages/client/src/main.ts" },
|
|
25
|
+
{ fileName: "/workspace/packages/client/src/app.ts" },
|
|
26
|
+
],
|
|
27
|
+
};
|
|
23
28
|
|
|
24
29
|
const mockCompiler = {
|
|
25
30
|
initialize: vi.fn().mockResolvedValue({ affectedFiles: new Set() }),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
3
|
|
|
3
4
|
//#region Mocks
|
|
@@ -25,6 +26,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
25
26
|
glob: mockFsxGlob,
|
|
26
27
|
copy: mockFsxCopy,
|
|
27
28
|
},
|
|
29
|
+
cpx: {
|
|
30
|
+
exec: mockCpxExec,
|
|
31
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
32
|
+
},
|
|
33
|
+
pathx: {
|
|
34
|
+
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
35
|
+
posix: (p: string) => p.replace(/\\/g, "/"),
|
|
36
|
+
},
|
|
28
37
|
}));
|
|
29
38
|
|
|
30
39
|
// env mock
|
|
@@ -35,14 +44,12 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
35
44
|
}),
|
|
36
45
|
}));
|
|
37
46
|
|
|
38
|
-
//
|
|
47
|
+
// cpx mock (was execa)
|
|
39
48
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
40
|
-
vi.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}),
|
|
45
|
-
}));
|
|
49
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
50
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
51
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
52
|
+
});
|
|
46
53
|
|
|
47
54
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
48
55
|
vi.mock("node:fs", () => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
3
|
|
|
3
4
|
//#region Mocks
|
|
@@ -23,6 +24,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
23
24
|
rm: mockFsxRm,
|
|
24
25
|
glob: mockFsxGlob,
|
|
25
26
|
},
|
|
27
|
+
cpx: {
|
|
28
|
+
exec: mockCpxExec,
|
|
29
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
30
|
+
},
|
|
31
|
+
pathx: {
|
|
32
|
+
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
33
|
+
posix: (p: string) => p.replace(/\\/g, "/"),
|
|
34
|
+
},
|
|
26
35
|
}));
|
|
27
36
|
|
|
28
37
|
// env mock
|
|
@@ -33,14 +42,12 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
33
42
|
}),
|
|
34
43
|
}));
|
|
35
44
|
|
|
36
|
-
//
|
|
45
|
+
// cpx mock (was execa)
|
|
37
46
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
38
|
-
vi.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}),
|
|
43
|
-
}));
|
|
47
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
48
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
49
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
50
|
+
});
|
|
44
51
|
|
|
45
52
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
46
53
|
vi.mock("node:fs", () => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
3
|
|
|
3
4
|
//#region Mocks
|
|
@@ -24,6 +25,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
24
25
|
glob: mockFsxGlob,
|
|
25
26
|
copy: mockFsxCopy,
|
|
26
27
|
},
|
|
28
|
+
cpx: {
|
|
29
|
+
exec: mockCpxExec,
|
|
30
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
31
|
+
},
|
|
32
|
+
pathx: {
|
|
33
|
+
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
34
|
+
posix: (p: string) => p.replace(/\\/g, "/"),
|
|
35
|
+
},
|
|
27
36
|
}));
|
|
28
37
|
|
|
29
38
|
let mockEnv: Record<string, unknown> = {};
|
|
@@ -34,12 +43,10 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
34
43
|
}));
|
|
35
44
|
|
|
36
45
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
37
|
-
vi.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}),
|
|
42
|
-
}));
|
|
46
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
47
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
48
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
49
|
+
});
|
|
43
50
|
|
|
44
51
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
45
52
|
vi.mock("node:fs", () => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
3
|
|
|
3
4
|
//#region Mocks
|
|
@@ -25,6 +26,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
25
26
|
glob: mockFsxGlob,
|
|
26
27
|
copy: mockFsxCopy,
|
|
27
28
|
},
|
|
29
|
+
cpx: {
|
|
30
|
+
exec: mockCpxExec,
|
|
31
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
32
|
+
},
|
|
33
|
+
pathx: {
|
|
34
|
+
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
35
|
+
posix: (p: string) => p.replace(/\\/g, "/"),
|
|
36
|
+
},
|
|
28
37
|
}));
|
|
29
38
|
|
|
30
39
|
// env mock
|
|
@@ -35,17 +44,15 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
35
44
|
}),
|
|
36
45
|
}));
|
|
37
46
|
|
|
38
|
-
//
|
|
47
|
+
// cpx mock (was execa) — tracks commands and resolves immediately
|
|
39
48
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
40
|
-
let execaFactory: (...args: unknown[]) => Promise<{ stdout: string; stderr: string }> = () =>
|
|
41
|
-
Promise.resolve({ stdout: "", stderr: "" });
|
|
49
|
+
let execaFactory: (...args: unknown[]) => Promise<{ stdout: string; stderr: string; exitCode: number }> = () =>
|
|
50
|
+
Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
42
51
|
|
|
43
|
-
vi.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}),
|
|
48
|
-
}));
|
|
52
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
53
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
54
|
+
return execaFactory(...args);
|
|
55
|
+
});
|
|
49
56
|
|
|
50
57
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
51
58
|
vi.mock("node:fs", () => ({
|
|
@@ -135,7 +142,7 @@ export default config;`;
|
|
|
135
142
|
mockEnv = { ANDROID_HOME: "C:/Android/Sdk" };
|
|
136
143
|
|
|
137
144
|
execaCalls.length = 0;
|
|
138
|
-
execaFactory = () => Promise.resolve({ stdout: "", stderr: "" });
|
|
145
|
+
execaFactory = () => Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
139
146
|
mockFsWriteFile.mockReset();
|
|
140
147
|
mockFsWriteFile.mockResolvedValue(undefined);
|
|
141
148
|
}
|
|
@@ -195,7 +202,7 @@ describe("Capacitor.run()", () => {
|
|
|
195
202
|
return Promise.reject(new Error("cap run failed"));
|
|
196
203
|
}
|
|
197
204
|
}
|
|
198
|
-
return Promise.resolve({ stdout: "", stderr: "" });
|
|
205
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
199
206
|
};
|
|
200
207
|
|
|
201
208
|
const cap = await Capacitor.create(PKG_PATH, {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
3
|
|
|
3
4
|
//#region Mocks
|
|
@@ -24,6 +25,14 @@ vi.mock("@simplysm/core-node", () => ({
|
|
|
24
25
|
glob: mockFsxGlob,
|
|
25
26
|
copy: mockFsxCopy,
|
|
26
27
|
},
|
|
28
|
+
cpx: {
|
|
29
|
+
exec: mockCpxExec,
|
|
30
|
+
execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
31
|
+
},
|
|
32
|
+
pathx: {
|
|
33
|
+
posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
|
|
34
|
+
posix: (p: string) => p.replace(/\\/g, "/"),
|
|
35
|
+
},
|
|
27
36
|
}));
|
|
28
37
|
|
|
29
38
|
let mockEnv: Record<string, unknown> = {};
|
|
@@ -34,12 +43,10 @@ vi.mock("@simplysm/core-common", () => ({
|
|
|
34
43
|
}));
|
|
35
44
|
|
|
36
45
|
const execaCalls: { command: string; args: string[] }[] = [];
|
|
37
|
-
vi.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}),
|
|
42
|
-
}));
|
|
46
|
+
const mockCpxExec = vi.fn((...args: unknown[]) => {
|
|
47
|
+
execaCalls.push({ command: args[0] as string, args: (args[1] as string[] | undefined) ?? [] });
|
|
48
|
+
return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
|
|
49
|
+
});
|
|
43
50
|
|
|
44
51
|
const mockFsWriteFile = vi.fn().mockResolvedValue(undefined);
|
|
45
52
|
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) => {
|