@simplysm/sd-cli 14.0.8 → 14.0.10
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.map +1 -1
- package/dist/capacitor/capacitor.js +41 -41
- 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.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.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 +26 -27
- 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.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.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 +28 -19
- 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 -4
- package/src/angular/vite-angular-plugin.ts +18 -9
- package/src/capacitor/capacitor.ts +41 -41
- package/src/commands/typecheck.ts +12 -12
- package/src/electron/electron.ts +26 -27
- 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/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/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 +30 -23
- 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 +5 -0
- package/tests/capacitor/capacitor-icon.spec.ts +5 -0
- package/tests/capacitor/capacitor-init.spec.ts +5 -0
- package/tests/capacitor/capacitor-run.spec.ts +5 -0
- package/tests/capacitor/capacitor-workspace.spec.ts +5 -0
- package/tests/commands/typecheck.spec.ts +20 -31
- package/tests/electron/electron.spec.ts +5 -0
- 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 +17 -19
- package/tests/workers/server-build-lint.spec.ts +4 -1
- package/tests/workers/server-build-worker.spec.ts +19 -22
- package/tests/angular/migration-cleanup.spec.ts +0 -59
|
@@ -5,6 +5,7 @@ import os from "os";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import ts from "typescript";
|
|
7
7
|
import { consola } from "consola";
|
|
8
|
+
import { pathx } from "@simplysm/core-node";
|
|
8
9
|
import {
|
|
9
10
|
AngularCompiler,
|
|
10
11
|
AngularSourceFileCache,
|
|
@@ -151,6 +152,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
151
152
|
...opts,
|
|
152
153
|
noEmit: false,
|
|
153
154
|
declaration: false,
|
|
155
|
+
declarationMap: false,
|
|
154
156
|
}),
|
|
155
157
|
});
|
|
156
158
|
|
|
@@ -173,7 +175,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
173
175
|
// 영향받은 파일 emit + 캐시 (소스 파일 경로를 key로 사용)
|
|
174
176
|
emittedFiles.clear();
|
|
175
177
|
for (const result of compiler.emitAffectedFiles()) {
|
|
176
|
-
emittedFiles.set(
|
|
178
|
+
emittedFiles.set(pathx.posix(result.sourceFileName), result.contents);
|
|
177
179
|
}
|
|
178
180
|
logger.debug(`emit 완료: ${emittedFiles.size}개 파일`);
|
|
179
181
|
|
|
@@ -223,6 +225,17 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
223
225
|
return;
|
|
224
226
|
}
|
|
225
227
|
|
|
228
|
+
// Dependency filter: skip if file is not in the TypeScript program
|
|
229
|
+
const normalizedFile = pathx.posix(file);
|
|
230
|
+
const programFiles = compiler.getTsProgram().getSourceFiles();
|
|
231
|
+
const isInProgram = programFiles.some(
|
|
232
|
+
(sf) => pathx.posix(sf.fileName) === normalizedFile,
|
|
233
|
+
);
|
|
234
|
+
if (!isInProgram) {
|
|
235
|
+
logger.debug(`변경된 파일이 빌드에 포함되지 않아 리빌드 건너뜀: ${normalizedFile}`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
226
239
|
// 경쟁 조건 방지: 이전 HMR 처리 완료 대기
|
|
227
240
|
const prevLock = hmrLock;
|
|
228
241
|
let releaseLock!: () => void;
|
|
@@ -248,7 +261,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
248
261
|
|
|
249
262
|
const affectedPaths: string[] = [];
|
|
250
263
|
for (const result of compiler.emitAffectedFiles()) {
|
|
251
|
-
const normalizedPath =
|
|
264
|
+
const normalizedPath = pathx.posix(result.sourceFileName);
|
|
252
265
|
emittedFiles.set(normalizedPath, result.contents);
|
|
253
266
|
affectedPaths.push(normalizedPath);
|
|
254
267
|
}
|
|
@@ -259,7 +272,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
259
272
|
// Convert affected ts.SourceFile set to file name strings for incremental lint
|
|
260
273
|
const affectedFileNames = new Set<string>();
|
|
261
274
|
for (const sf of updateResult.affectedFiles) {
|
|
262
|
-
affectedFileNames.add(
|
|
275
|
+
affectedFileNames.add(pathx.posix(sf.fileName));
|
|
263
276
|
}
|
|
264
277
|
|
|
265
278
|
// Lint execution (if enabled)
|
|
@@ -280,7 +293,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
280
293
|
|
|
281
294
|
const affectedSet = new Set(affectedPaths);
|
|
282
295
|
return modules.filter(
|
|
283
|
-
(m) => m.file != null && affectedSet.has(
|
|
296
|
+
(m) => m.file != null && affectedSet.has(pathx.posix(m.file)),
|
|
284
297
|
);
|
|
285
298
|
} catch (err) {
|
|
286
299
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -295,7 +308,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
|
|
|
295
308
|
async transform(_code, id) {
|
|
296
309
|
if (!id.endsWith(".ts") && !id.endsWith(".tsx")) return;
|
|
297
310
|
|
|
298
|
-
const normalizedId =
|
|
311
|
+
const normalizedId = pathx.posix(id);
|
|
299
312
|
const emittedContent = emittedFiles.get(normalizedId);
|
|
300
313
|
if (emittedContent == null) return;
|
|
301
314
|
|
|
@@ -407,10 +420,6 @@ function angularComponentMiddleware(
|
|
|
407
420
|
};
|
|
408
421
|
}
|
|
409
422
|
|
|
410
|
-
function normalizePath(p: string): string {
|
|
411
|
-
return p.replace(/\\/g, "/");
|
|
412
|
-
}
|
|
413
|
-
|
|
414
423
|
function reportDiagnostics(diagnostics: DiagnosticResult): void {
|
|
415
424
|
for (const error of diagnostics.errors) {
|
|
416
425
|
const loc =
|
|
@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { symlink } from "fs/promises";
|
|
5
5
|
import { createRequire } from "module";
|
|
6
|
-
import { cpx, fsx } from "@simplysm/core-node";
|
|
6
|
+
import { cpx, fsx, pathx } from "@simplysm/core-node";
|
|
7
7
|
import { env } from "@simplysm/core-common";
|
|
8
8
|
import { consola } from "consola";
|
|
9
9
|
import type { SdCapacitorConfig } from "../sd-config.types.js";
|
|
@@ -52,7 +52,7 @@ export class Capacitor {
|
|
|
52
52
|
) {
|
|
53
53
|
this._platforms = Object.keys(this._config.platform ?? {});
|
|
54
54
|
this._npmConfig = npmConfig;
|
|
55
|
-
this._capPath =
|
|
55
|
+
this._capPath = pathx.posixResolve(this._pkgPath, ".capacitor");
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -65,7 +65,7 @@ export class Capacitor {
|
|
|
65
65
|
): Promise<Capacitor> {
|
|
66
66
|
Capacitor._validateConfig(config);
|
|
67
67
|
|
|
68
|
-
const npmConfig = await fsx.readJson<NpmConfig>(
|
|
68
|
+
const npmConfig = await fsx.readJson<NpmConfig>(pathx.posixResolve(pkgPath, "package.json"));
|
|
69
69
|
return new Capacitor(pkgPath, config, npmConfig, exclude ?? []);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -170,7 +170,7 @@ export class Capacitor {
|
|
|
170
170
|
* 동시 실행 방지 잠금 획득
|
|
171
171
|
*/
|
|
172
172
|
private async _acquireLock(): Promise<void> {
|
|
173
|
-
const lockPath =
|
|
173
|
+
const lockPath = pathx.posixResolve(this._capPath, Capacitor._LOCK_FILE_NAME);
|
|
174
174
|
await fsx.mkdir(this._capPath);
|
|
175
175
|
try {
|
|
176
176
|
await fs.promises.writeFile(lockPath, String(process.pid), { flag: "wx" });
|
|
@@ -194,7 +194,7 @@ export class Capacitor {
|
|
|
194
194
|
* 동시 실행 방지 잠금 해제
|
|
195
195
|
*/
|
|
196
196
|
private async _releaseLock(): Promise<void> {
|
|
197
|
-
const lockPath =
|
|
197
|
+
const lockPath = pathx.posixResolve(this._capPath, Capacitor._LOCK_FILE_NAME);
|
|
198
198
|
await fsx.rm(lockPath);
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -236,7 +236,7 @@ export class Capacitor {
|
|
|
236
236
|
*/
|
|
237
237
|
private async _initCap(): Promise<boolean> {
|
|
238
238
|
const { depChanged, workspacePlugins } = await this._setupNpmConf();
|
|
239
|
-
const nodeModulesExists = await fsx.exists(
|
|
239
|
+
const nodeModulesExists = await fsx.exists(pathx.posixResolve(this._capPath, "node_modules"));
|
|
240
240
|
|
|
241
241
|
if (!depChanged && nodeModulesExists) {
|
|
242
242
|
// 의존성 미변경이어도 workspace 플러그인 symlink는 항상 갱신
|
|
@@ -252,16 +252,16 @@ export class Capacitor {
|
|
|
252
252
|
await this._linkWorkspacePlugins(workspacePlugins);
|
|
253
253
|
|
|
254
254
|
// 멱등성: capacitor.config.ts가 없을 때만 cap init 실행
|
|
255
|
-
const configPath =
|
|
255
|
+
const configPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
|
|
256
256
|
if (!(await fsx.exists(configPath))) {
|
|
257
257
|
await this._execCap(["init", this._config.appId, this._config.appId]);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// 기본 www/index.html 생성
|
|
261
|
-
const wwwPath =
|
|
261
|
+
const wwwPath = pathx.posixResolve(this._capPath, "www");
|
|
262
262
|
await fsx.mkdir(wwwPath);
|
|
263
263
|
await fsx.write(
|
|
264
|
-
|
|
264
|
+
pathx.posixResolve(wwwPath, "index.html"),
|
|
265
265
|
"<!DOCTYPE html><html><head></head><body></body></html>",
|
|
266
266
|
);
|
|
267
267
|
|
|
@@ -272,7 +272,7 @@ export class Capacitor {
|
|
|
272
272
|
* package.json 설정
|
|
273
273
|
*/
|
|
274
274
|
private async _setupNpmConf(): Promise<{ depChanged: boolean; workspacePlugins: string[] }> {
|
|
275
|
-
const projNpmConfigPath =
|
|
275
|
+
const projNpmConfigPath = pathx.posixResolve(this._findWorkspaceRoot(), "package.json");
|
|
276
276
|
|
|
277
277
|
// 루트 package.json 존재 확인
|
|
278
278
|
if (!(await fsx.exists(projNpmConfigPath))) {
|
|
@@ -281,7 +281,7 @@ export class Capacitor {
|
|
|
281
281
|
|
|
282
282
|
const projNpmConfig = await fsx.readJson<NpmConfig>(projNpmConfigPath);
|
|
283
283
|
|
|
284
|
-
const capNpmConfPath =
|
|
284
|
+
const capNpmConfPath = pathx.posixResolve(this._capPath, "package.json");
|
|
285
285
|
const orgCapNpmConf: NpmConfig = (await fsx.exists(capNpmConfPath))
|
|
286
286
|
? await fsx.readJson<NpmConfig>(capNpmConfPath)
|
|
287
287
|
: { name: "", version: "" };
|
|
@@ -371,7 +371,7 @@ export class Capacitor {
|
|
|
371
371
|
* capacitor.config.ts 생성
|
|
372
372
|
*/
|
|
373
373
|
private async _writeCapConf(): Promise<void> {
|
|
374
|
-
const confPath =
|
|
374
|
+
const confPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
|
|
375
375
|
|
|
376
376
|
// 플러그인 옵션 생성
|
|
377
377
|
const pluginOptions: Record<string, Record<string, unknown>> = {};
|
|
@@ -411,7 +411,7 @@ export default config;
|
|
|
411
411
|
*/
|
|
412
412
|
private async _addPlatforms(): Promise<void> {
|
|
413
413
|
for (const platform of this._platforms) {
|
|
414
|
-
const platformPath =
|
|
414
|
+
const platformPath = pathx.posixResolve(this._capPath, platform);
|
|
415
415
|
if (await fsx.exists(platformPath)) {
|
|
416
416
|
Capacitor._logger.debug(`플랫폼이 이미 존재합니다: ${platform}`);
|
|
417
417
|
continue;
|
|
@@ -427,7 +427,7 @@ export default config;
|
|
|
427
427
|
private async _setupIcon(): Promise<void> {
|
|
428
428
|
if (this._config.icon == null) return;
|
|
429
429
|
|
|
430
|
-
const iconPath =
|
|
430
|
+
const iconPath = pathx.posixResolve(this._pkgPath, this._config.icon);
|
|
431
431
|
|
|
432
432
|
if (!(await fsx.exists(iconPath))) {
|
|
433
433
|
Capacitor._logger.warn(`아이콘 파일을 찾을 수 없습니다: ${iconPath}`);
|
|
@@ -447,9 +447,9 @@ export default config;
|
|
|
447
447
|
.toBuffer();
|
|
448
448
|
|
|
449
449
|
// 1024x1024 투명 캔버스에 합성
|
|
450
|
-
const assetsDir =
|
|
450
|
+
const assetsDir = pathx.posixResolve(this._capPath, "assets");
|
|
451
451
|
await fsx.mkdir(assetsDir);
|
|
452
|
-
const logoPath =
|
|
452
|
+
const logoPath = pathx.posixResolve(assetsDir, "logo.png");
|
|
453
453
|
|
|
454
454
|
await sharp({
|
|
455
455
|
create: {
|
|
@@ -493,7 +493,7 @@ export default config;
|
|
|
493
493
|
* Android 네이티브 설정 구성
|
|
494
494
|
*/
|
|
495
495
|
private async _configureAndroid(): Promise<void> {
|
|
496
|
-
const androidPath =
|
|
496
|
+
const androidPath = pathx.posixResolve(this._capPath, "android");
|
|
497
497
|
|
|
498
498
|
// Android 디렉토리 존재 확인
|
|
499
499
|
if (!(await fsx.exists(androidPath))) {
|
|
@@ -510,7 +510,7 @@ export default config;
|
|
|
510
510
|
* JAVA_HOME 경로 설정 (gradle.properties)
|
|
511
511
|
*/
|
|
512
512
|
private async _configureAndroidJavaHomePath(androidPath: string): Promise<void> {
|
|
513
|
-
const gradlePropsPath =
|
|
513
|
+
const gradlePropsPath = pathx.posixResolve(androidPath, "gradle.properties");
|
|
514
514
|
|
|
515
515
|
if (!(await fsx.exists(gradlePropsPath))) {
|
|
516
516
|
Capacitor._logger.warn(`gradle.properties 파일을 찾을 수 없습니다: ${gradlePropsPath}`);
|
|
@@ -555,12 +555,12 @@ export default config;
|
|
|
555
555
|
* Android SDK 경로 설정 (local.properties)
|
|
556
556
|
*/
|
|
557
557
|
private async _configureAndroidSdkPath(androidPath: string): Promise<void> {
|
|
558
|
-
const localPropsPath =
|
|
558
|
+
const localPropsPath = pathx.posixResolve(androidPath, "local.properties");
|
|
559
559
|
|
|
560
560
|
const sdkPath = await this._findAndroidSdk();
|
|
561
561
|
if (sdkPath != null) {
|
|
562
562
|
// Gradle 호환: 항상 forward slash 사용
|
|
563
|
-
await fsx.write(localPropsPath, `sdk.dir=${
|
|
563
|
+
await fsx.write(localPropsPath, `sdk.dir=${pathx.posix(sdkPath)}\n`);
|
|
564
564
|
} else {
|
|
565
565
|
throw new Error(
|
|
566
566
|
"Android SDK를 찾을 수 없습니다.\n" +
|
|
@@ -580,8 +580,8 @@ export default config;
|
|
|
580
580
|
}
|
|
581
581
|
|
|
582
582
|
const candidates = [
|
|
583
|
-
|
|
584
|
-
|
|
583
|
+
pathx.posixResolve((env["LOCALAPPDATA"] as string | undefined) ?? "", "Android/Sdk"),
|
|
584
|
+
pathx.posixResolve((env["HOME"] as string | undefined) ?? "", "Android/Sdk"),
|
|
585
585
|
"C:/Program Files/Android/Sdk",
|
|
586
586
|
"C:/Android/Sdk",
|
|
587
587
|
];
|
|
@@ -602,7 +602,7 @@ export default config;
|
|
|
602
602
|
* XML 구조가 변경되면 정규식이 실패할 수 있음.
|
|
603
603
|
*/
|
|
604
604
|
private async _configureAndroidManifest(androidPath: string): Promise<void> {
|
|
605
|
-
const manifestPath =
|
|
605
|
+
const manifestPath = pathx.posixResolve(androidPath, "app/src/main/AndroidManifest.xml");
|
|
606
606
|
|
|
607
607
|
if (!(await fsx.exists(manifestPath))) {
|
|
608
608
|
throw new Error(`AndroidManifest.xml 파일을 찾을 수 없습니다: ${manifestPath}`);
|
|
@@ -674,7 +674,7 @@ export default config;
|
|
|
674
674
|
* build.gradle 수정 (서명 설정 제외)
|
|
675
675
|
*/
|
|
676
676
|
private async _configureAndroidBuildGradle(androidPath: string): Promise<void> {
|
|
677
|
-
const buildGradlePath =
|
|
677
|
+
const buildGradlePath = pathx.posixResolve(androidPath, "app/build.gradle");
|
|
678
678
|
|
|
679
679
|
if (!(await fsx.exists(buildGradlePath))) {
|
|
680
680
|
throw new Error(`build.gradle 파일을 찾을 수 없습니다: ${buildGradlePath}`);
|
|
@@ -754,7 +754,7 @@ export default config;
|
|
|
754
754
|
* WebView가 이 URL에서 웹 에셋을 로드하여 Hot Reload가 동작한다.
|
|
755
755
|
*/
|
|
756
756
|
private async _updateServerUrl(url: string): Promise<void> {
|
|
757
|
-
const configPath =
|
|
757
|
+
const configPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
|
|
758
758
|
let content = await fsx.read(configPath);
|
|
759
759
|
|
|
760
760
|
if (content.includes("url:")) {
|
|
@@ -791,7 +791,7 @@ export default config;
|
|
|
791
791
|
const signConfig = this._config.platform?.android?.sign;
|
|
792
792
|
if (!isDebug && signConfig != null) {
|
|
793
793
|
await this._configureSigningConfig(
|
|
794
|
-
|
|
794
|
+
pathx.posixResolve(this._capPath, "android"),
|
|
795
795
|
signConfig,
|
|
796
796
|
);
|
|
797
797
|
} else if (!isDebug) {
|
|
@@ -817,16 +817,16 @@ export default config;
|
|
|
817
817
|
sign: import("../sd-config.types.js").SdCapacitorSignConfig,
|
|
818
818
|
): Promise<void> {
|
|
819
819
|
// keystore 파일 확인 및 복사
|
|
820
|
-
const keystoreSrc =
|
|
820
|
+
const keystoreSrc = pathx.posixResolve(this._pkgPath, sign.keystore);
|
|
821
821
|
if (!(await fsx.exists(keystoreSrc))) {
|
|
822
822
|
throw new Error(`keystore 파일을 찾을 수 없습니다: ${keystoreSrc}`);
|
|
823
823
|
}
|
|
824
824
|
|
|
825
|
-
const keystoreDest =
|
|
825
|
+
const keystoreDest = pathx.posixResolve(androidPath, "app", "android.keystore");
|
|
826
826
|
await fsx.copy(keystoreSrc, keystoreDest);
|
|
827
827
|
|
|
828
828
|
// build.gradle에 signingConfigs 추가
|
|
829
|
-
const buildGradlePath =
|
|
829
|
+
const buildGradlePath = pathx.posixResolve(androidPath, "app/build.gradle");
|
|
830
830
|
let content = await fsx.read(buildGradlePath);
|
|
831
831
|
|
|
832
832
|
// 이미 signingConfigs가 있으면 스킵
|
|
@@ -872,11 +872,11 @@ export default config;
|
|
|
872
872
|
gradleTask = "assembleRelease";
|
|
873
873
|
}
|
|
874
874
|
|
|
875
|
-
const androidPath =
|
|
875
|
+
const androidPath = pathx.posixResolve(this._capPath, "android");
|
|
876
876
|
const isWindows = process.platform === "win32";
|
|
877
877
|
const gradlew = isWindows
|
|
878
|
-
?
|
|
879
|
-
:
|
|
878
|
+
? pathx.posixResolve(androidPath, "gradlew.bat")
|
|
879
|
+
: pathx.posixResolve(androidPath, "gradlew");
|
|
880
880
|
|
|
881
881
|
await this._exec(gradlew, [gradleTask, "--no-daemon"], androidPath);
|
|
882
882
|
}
|
|
@@ -891,7 +891,7 @@ export default config;
|
|
|
891
891
|
): Promise<void> {
|
|
892
892
|
const ext = isBundle ? "aab" : "apk";
|
|
893
893
|
const outputType = isBundle ? "bundle" : "apk";
|
|
894
|
-
const androidBuildPath =
|
|
894
|
+
const androidBuildPath = pathx.posixResolve(
|
|
895
895
|
this._capPath,
|
|
896
896
|
"android/app/build/outputs",
|
|
897
897
|
outputType,
|
|
@@ -899,7 +899,7 @@ export default config;
|
|
|
899
899
|
);
|
|
900
900
|
|
|
901
901
|
// 빌드 산출물 찾기
|
|
902
|
-
const candidates = await fsx.glob(
|
|
902
|
+
const candidates = await fsx.glob(pathx.posixResolve(androidBuildPath, `app-*.${ext}`));
|
|
903
903
|
if (candidates.length === 0) {
|
|
904
904
|
throw new Error(`빌드 산출물을 찾을 수 없습니다: ${androidBuildPath}`);
|
|
905
905
|
}
|
|
@@ -907,8 +907,8 @@ export default config;
|
|
|
907
907
|
const isUnsigned = builtFile.includes("unsigned");
|
|
908
908
|
|
|
909
909
|
// 출력 디렉토리 생성
|
|
910
|
-
const androidOutPath =
|
|
911
|
-
const updatesPath =
|
|
910
|
+
const androidOutPath = pathx.posixResolve(outPath, "android");
|
|
911
|
+
const updatesPath = pathx.posixResolve(androidOutPath, "updates");
|
|
912
912
|
await fsx.mkdir(androidOutPath);
|
|
913
913
|
await fsx.mkdir(updatesPath);
|
|
914
914
|
|
|
@@ -918,8 +918,8 @@ export default config;
|
|
|
918
918
|
const versionedName = `${this._npmConfig.version}.${ext}`;
|
|
919
919
|
|
|
920
920
|
// 복사
|
|
921
|
-
await fsx.copy(builtFile,
|
|
922
|
-
await fsx.copy(builtFile,
|
|
921
|
+
await fsx.copy(builtFile, pathx.posixResolve(androidOutPath, latestName));
|
|
922
|
+
await fsx.copy(builtFile, pathx.posixResolve(updatesPath, versionedName));
|
|
923
923
|
}
|
|
924
924
|
|
|
925
925
|
//#endregion
|
|
@@ -933,13 +933,13 @@ export default config;
|
|
|
933
933
|
private async _linkWorkspacePlugins(plugins: string[]): Promise<void> {
|
|
934
934
|
if (plugins.length === 0) return;
|
|
935
935
|
|
|
936
|
-
const require = createRequire(
|
|
936
|
+
const require = createRequire(pathx.posixResolve(this._pkgPath, "package.json"));
|
|
937
937
|
|
|
938
938
|
for (const plugin of plugins) {
|
|
939
939
|
const pluginPkgJsonPath = require.resolve(`${plugin}/package.json`);
|
|
940
940
|
const pluginDir = path.dirname(pluginPkgJsonPath);
|
|
941
941
|
|
|
942
|
-
const linkPath =
|
|
942
|
+
const linkPath = pathx.posixResolve(this._capPath, "node_modules", ...plugin.split("/"));
|
|
943
943
|
|
|
944
944
|
// scope 디렉토리 생성 (예: @simplysm/)
|
|
945
945
|
await fsx.mkdir(path.dirname(linkPath));
|
|
@@ -964,7 +964,7 @@ export default config;
|
|
|
964
964
|
if (parent === dir) {
|
|
965
965
|
throw new Error(`워크스페이스 루트를 찾을 수 없습니다: ${this._pkgPath}`);
|
|
966
966
|
}
|
|
967
|
-
if (existsSync(
|
|
967
|
+
if (existsSync(pathx.posixResolve(parent, "pnpm-workspace.yaml"))) {
|
|
968
968
|
return parent;
|
|
969
969
|
}
|
|
970
970
|
dir = parent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
import path from "path";
|
|
3
2
|
import { err as errNs } from "@simplysm/core-common";
|
|
3
|
+
import { pathx } from "@simplysm/core-node";
|
|
4
4
|
import { consola } from "consola";
|
|
5
5
|
import type { SdConfig } from "../sd-config.types";
|
|
6
6
|
import { loadSdConfig } from "../utils/sd-config";
|
|
@@ -136,7 +136,7 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
|
|
|
136
136
|
for (const env of envs) {
|
|
137
137
|
typecheckTasks.push({
|
|
138
138
|
name,
|
|
139
|
-
dir:
|
|
139
|
+
dir: pathx.posixResolve(cwd, relPath),
|
|
140
140
|
config: typecheckConfig,
|
|
141
141
|
env,
|
|
142
142
|
});
|
|
@@ -182,9 +182,10 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
|
|
|
182
182
|
js: false,
|
|
183
183
|
dts: false,
|
|
184
184
|
env: task.env,
|
|
185
|
+
includeTests: true,
|
|
185
186
|
...(options.lint === true ? { lint: true } : {}),
|
|
186
187
|
});
|
|
187
|
-
logger.debug(`[${label}] 타입체크 ${result.
|
|
188
|
+
logger.debug(`[${label}] 타입체크 ${result.build.success ? "완료" : "실패"}`);
|
|
188
189
|
return result;
|
|
189
190
|
} catch (err) {
|
|
190
191
|
const message = errNs.message(err);
|
|
@@ -195,8 +196,7 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
|
|
|
195
196
|
}
|
|
196
197
|
return {
|
|
197
198
|
success: false,
|
|
198
|
-
|
|
199
|
-
dts: {
|
|
199
|
+
build: {
|
|
200
200
|
success: false,
|
|
201
201
|
errors: [`[${label}] ${message}`],
|
|
202
202
|
warnings: [],
|
|
@@ -217,14 +217,14 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
|
|
|
217
217
|
for (const settled of results) {
|
|
218
218
|
if (settled.status !== "fulfilled") continue;
|
|
219
219
|
const engineResult = settled.value;
|
|
220
|
-
const
|
|
221
|
-
allDiagnostics.push(...
|
|
220
|
+
const buildDiags = engineResult.build.diagnostics.map((d) => deserializeDiagnostic(d, fileCache));
|
|
221
|
+
allDiagnostics.push(...buildDiags);
|
|
222
222
|
// 역직렬화된 진단 정보에서 에러/경고 수 집계
|
|
223
223
|
// 숫자 카테고리 값 사용 (ts.DiagnosticCategory: Error=1, Warning=0)
|
|
224
|
-
totalErrorCount +=
|
|
225
|
-
totalWarningCount +=
|
|
226
|
-
if (!engineResult.
|
|
227
|
-
for (const errMsg of engineResult.
|
|
224
|
+
totalErrorCount += buildDiags.filter((d) => d.category === 1).length;
|
|
225
|
+
totalWarningCount += buildDiags.filter((d) => d.category === 0).length;
|
|
226
|
+
if (!engineResult.build.success && buildDiags.length === 0) {
|
|
227
|
+
for (const errMsg of engineResult.build.errors) {
|
|
228
228
|
allDiagnostics.push({
|
|
229
229
|
category: 1,
|
|
230
230
|
code: 0,
|
|
@@ -234,7 +234,7 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
|
|
|
234
234
|
length: undefined,
|
|
235
235
|
});
|
|
236
236
|
}
|
|
237
|
-
totalErrorCount += engineResult.
|
|
237
|
+
totalErrorCount += engineResult.build.errors.length || 1;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
// Lint 결과 수집
|
package/src/electron/electron.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import path from "path";
|
|
2
1
|
import os from "os";
|
|
3
2
|
import fs from "fs";
|
|
4
3
|
import module from "module";
|
|
5
|
-
import { cpx, fsx } from "@simplysm/core-node";
|
|
4
|
+
import { cpx, fsx, pathx } from "@simplysm/core-node";
|
|
6
5
|
import { consola } from "consola";
|
|
7
6
|
import type { SdElectronConfig } from "../sd-config.types.js";
|
|
8
7
|
import { createEnvBanner } from "../utils/esbuild-config.js";
|
|
@@ -25,7 +24,7 @@ export class Electron {
|
|
|
25
24
|
private readonly _npmConfig: NpmConfig,
|
|
26
25
|
private readonly _exclude: string[],
|
|
27
26
|
) {
|
|
28
|
-
this._electronPath =
|
|
27
|
+
this._electronPath = pathx.posixResolve(this._pkgPath, ".electron");
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
static async create(
|
|
@@ -35,7 +34,7 @@ export class Electron {
|
|
|
35
34
|
): Promise<Electron> {
|
|
36
35
|
Electron._validateConfig(config);
|
|
37
36
|
|
|
38
|
-
const npmConfig = await fsx.readJson<NpmConfig>(
|
|
37
|
+
const npmConfig = await fsx.readJson<NpmConfig>(pathx.posixResolve(pkgPath, "package.json"));
|
|
39
38
|
return new Electron(pkgPath, config, npmConfig, exclude ?? []);
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -46,7 +45,7 @@ export class Electron {
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
private _localBin(name: string): string {
|
|
49
|
-
return
|
|
48
|
+
return pathx.posixResolve(this._pkgPath, "node_modules/.bin", name);
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
private async _exec(
|
|
@@ -56,7 +55,7 @@ export class Electron {
|
|
|
56
55
|
env?: Record<string, string>,
|
|
57
56
|
): Promise<string> {
|
|
58
57
|
Electron._logger.debug(`실행: ${cmd} ${args.join(" ")}`);
|
|
59
|
-
const { stdout: result } = await cpx.exec(cmd, args, { cwd, env });
|
|
58
|
+
const { stdout: result } = await cpx.exec(cmd, args, { cwd, env, shell: true });
|
|
60
59
|
Electron._logger.debug(`결과: ${result}`);
|
|
61
60
|
return result;
|
|
62
61
|
}
|
|
@@ -64,7 +63,7 @@ export class Electron {
|
|
|
64
63
|
//#region Public Methods
|
|
65
64
|
|
|
66
65
|
async initialize(): Promise<void> {
|
|
67
|
-
const srcPath =
|
|
66
|
+
const srcPath = pathx.posixResolve(this._electronPath, "src");
|
|
68
67
|
|
|
69
68
|
await this._setupPackageJson(srcPath);
|
|
70
69
|
await this._exec("npm", ["install"], srcPath);
|
|
@@ -76,12 +75,12 @@ export class Electron {
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
async run(url: string): Promise<void> {
|
|
79
|
-
const srcPath =
|
|
78
|
+
const srcPath = pathx.posixResolve(this._electronPath, "src");
|
|
80
79
|
|
|
81
80
|
await this.initialize();
|
|
82
81
|
|
|
83
82
|
const esbuild = await import("esbuild");
|
|
84
|
-
const entryPoint =
|
|
83
|
+
const entryPoint = pathx.posixResolve(this._pkgPath, "src/electron-main.ts");
|
|
85
84
|
|
|
86
85
|
if (!(await fsx.exists(entryPoint))) {
|
|
87
86
|
throw new Error(`electron-main.ts 파일을 찾을 수 없습니다: ${entryPoint}`);
|
|
@@ -115,7 +114,7 @@ export class Electron {
|
|
|
115
114
|
|
|
116
115
|
const ctx = await esbuild.context({
|
|
117
116
|
entryPoints: [entryPoint],
|
|
118
|
-
outfile:
|
|
117
|
+
outfile: pathx.posixResolve(srcPath, "electron-main.js"),
|
|
119
118
|
platform: "node",
|
|
120
119
|
target: "node20",
|
|
121
120
|
format: "cjs",
|
|
@@ -178,7 +177,7 @@ export class Electron {
|
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
async build(outPath: string): Promise<void> {
|
|
181
|
-
const srcPath =
|
|
180
|
+
const srcPath = pathx.posixResolve(this._electronPath, "src");
|
|
182
181
|
|
|
183
182
|
await this._bundleMainProcess(srcPath);
|
|
184
183
|
await this._copyWebAssets(outPath, srcPath);
|
|
@@ -224,7 +223,7 @@ export class Electron {
|
|
|
224
223
|
packageJson["scripts"] = { postinstall: this._config.postInstallScript };
|
|
225
224
|
}
|
|
226
225
|
|
|
227
|
-
await fsx.writeJson(
|
|
226
|
+
await fsx.writeJson(pathx.posixResolve(srcPath, "package.json"), packageJson, { space: 2 });
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
//#endregion
|
|
@@ -233,7 +232,7 @@ export class Electron {
|
|
|
233
232
|
|
|
234
233
|
private async _bundleMainProcess(outDir: string): Promise<void> {
|
|
235
234
|
const esbuild = await import("esbuild");
|
|
236
|
-
const entryPoint =
|
|
235
|
+
const entryPoint = pathx.posixResolve(this._pkgPath, "src/electron-main.ts");
|
|
237
236
|
|
|
238
237
|
if (!(await fsx.exists(entryPoint))) {
|
|
239
238
|
throw new Error(`electron-main.ts 파일을 찾을 수 없습니다: ${entryPoint}`);
|
|
@@ -248,7 +247,7 @@ export class Electron {
|
|
|
248
247
|
|
|
249
248
|
await esbuild.build({
|
|
250
249
|
entryPoints: [entryPoint],
|
|
251
|
-
outfile:
|
|
250
|
+
outfile: pathx.posixResolve(outDir, "electron-main.js"),
|
|
252
251
|
platform: "node",
|
|
253
252
|
target: "node20",
|
|
254
253
|
format: "cjs",
|
|
@@ -267,16 +266,16 @@ export class Electron {
|
|
|
267
266
|
for (const item of items) {
|
|
268
267
|
if (item === "electron") continue;
|
|
269
268
|
|
|
270
|
-
const source =
|
|
271
|
-
const dest =
|
|
269
|
+
const source = pathx.posixResolve(outPath, item);
|
|
270
|
+
const dest = pathx.posixResolve(srcPath, item);
|
|
272
271
|
await fsx.copy(source, dest);
|
|
273
272
|
}
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
private static _canCreateSymlink(): boolean {
|
|
277
276
|
const tmpDir = os.tmpdir();
|
|
278
|
-
const testTarget =
|
|
279
|
-
const testLink =
|
|
277
|
+
const testTarget = pathx.posixResolve(tmpDir, "sd-electron-symlink-test-target.txt");
|
|
278
|
+
const testLink = pathx.posixResolve(tmpDir, "sd-electron-symlink-test-link.txt");
|
|
280
279
|
|
|
281
280
|
try {
|
|
282
281
|
fs.writeFileSync(testTarget, "test");
|
|
@@ -297,7 +296,7 @@ export class Electron {
|
|
|
297
296
|
);
|
|
298
297
|
}
|
|
299
298
|
|
|
300
|
-
const distPath =
|
|
299
|
+
const distPath = pathx.posixResolve(this._electronPath, "dist");
|
|
301
300
|
|
|
302
301
|
const builderConfig: Record<string, unknown> = {
|
|
303
302
|
appId: this._config.appId,
|
|
@@ -317,10 +316,10 @@ export class Electron {
|
|
|
317
316
|
};
|
|
318
317
|
|
|
319
318
|
if (this._config.installerIcon != null) {
|
|
320
|
-
builderConfig["icon"] =
|
|
319
|
+
builderConfig["icon"] = pathx.posixResolve(this._pkgPath, this._config.installerIcon);
|
|
321
320
|
}
|
|
322
321
|
|
|
323
|
-
const configFilePath =
|
|
322
|
+
const configFilePath = pathx.posixResolve(this._electronPath, "builder-config.json");
|
|
324
323
|
await fsx.writeJson(configFilePath, builderConfig, { space: 2 });
|
|
325
324
|
|
|
326
325
|
await this._exec(
|
|
@@ -331,8 +330,8 @@ export class Electron {
|
|
|
331
330
|
}
|
|
332
331
|
|
|
333
332
|
private async _copyBuildOutput(outPath: string): Promise<void> {
|
|
334
|
-
const distPath =
|
|
335
|
-
const electronOutPath =
|
|
333
|
+
const distPath = pathx.posixResolve(this._electronPath, "dist");
|
|
334
|
+
const electronOutPath = pathx.posixResolve(outPath, "electron");
|
|
336
335
|
await fsx.mkdir(electronOutPath);
|
|
337
336
|
|
|
338
337
|
const rawName = this._npmConfig.description ?? this._npmConfig.name;
|
|
@@ -341,7 +340,7 @@ export class Electron {
|
|
|
341
340
|
const isPortable = this._config.portable === true;
|
|
342
341
|
|
|
343
342
|
// exe 파일 동적 탐색 — Setup 또는 portable exe를 우선 선택
|
|
344
|
-
const allExeFiles = await fsx.glob(
|
|
343
|
+
const allExeFiles = await fsx.glob(pathx.posixResolve(distPath, "*.exe"));
|
|
345
344
|
if (allExeFiles.length === 0) {
|
|
346
345
|
Electron._logger.warn(`빌드 산출물(.exe)을 찾을 수 없습니다: ${distPath}`);
|
|
347
346
|
return;
|
|
@@ -351,11 +350,11 @@ export class Electron {
|
|
|
351
350
|
allExeFiles.find((f) => f.toLowerCase().includes(keyword.toLowerCase())) ?? allExeFiles[0];
|
|
352
351
|
|
|
353
352
|
const latestFileName = `${safeName}${isPortable ? "-portable" : ""}-latest.exe`;
|
|
354
|
-
await fsx.copy(sourcePath,
|
|
353
|
+
await fsx.copy(sourcePath, pathx.posixResolve(electronOutPath, latestFileName));
|
|
355
354
|
|
|
356
|
-
const updatesPath =
|
|
355
|
+
const updatesPath = pathx.posixResolve(electronOutPath, "updates");
|
|
357
356
|
await fsx.mkdir(updatesPath);
|
|
358
|
-
await fsx.copy(sourcePath,
|
|
357
|
+
await fsx.copy(sourcePath, pathx.posixResolve(updatesPath, `${version}.exe`));
|
|
359
358
|
}
|
|
360
359
|
|
|
361
360
|
//#endregion
|