@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.
Files changed (265) hide show
  1. package/dist/angular/client-transform-stylesheet.d.ts.map +1 -1
  2. package/dist/angular/client-transform-stylesheet.js.map +1 -1
  3. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  4. package/dist/angular/vite-angular-plugin.js +15 -8
  5. package/dist/angular/vite-angular-plugin.js.map +1 -1
  6. package/dist/angular/vite-postcss-inline-plugin.d.ts.map +1 -1
  7. package/dist/angular/vite-postcss-inline-plugin.js.map +1 -1
  8. package/dist/capacitor/capacitor.d.ts +1 -1
  9. package/dist/capacitor/capacitor.d.ts.map +1 -1
  10. package/dist/capacitor/capacitor.js +43 -44
  11. package/dist/capacitor/capacitor.js.map +1 -1
  12. package/dist/commands/build.d.ts.map +1 -1
  13. package/dist/commands/build.js.map +1 -1
  14. package/dist/commands/check.d.ts.map +1 -1
  15. package/dist/commands/check.js +2 -2
  16. package/dist/commands/check.js.map +1 -1
  17. package/dist/commands/dev.d.ts.map +1 -1
  18. package/dist/commands/dev.js.map +1 -1
  19. package/dist/commands/lint.d.ts.map +1 -1
  20. package/dist/commands/lint.js.map +1 -1
  21. package/dist/commands/publish.d.ts.map +1 -1
  22. package/dist/commands/publish.js +12 -13
  23. package/dist/commands/publish.js.map +1 -1
  24. package/dist/commands/replace-deps.d.ts.map +1 -1
  25. package/dist/commands/replace-deps.js.map +1 -1
  26. package/dist/commands/typecheck.d.ts.map +1 -1
  27. package/dist/commands/typecheck.js +12 -12
  28. package/dist/commands/typecheck.js.map +1 -1
  29. package/dist/commands/watch.d.ts.map +1 -1
  30. package/dist/commands/watch.js.map +1 -1
  31. package/dist/electron/electron.d.ts.map +1 -1
  32. package/dist/electron/electron.js +42 -37
  33. package/dist/electron/electron.js.map +1 -1
  34. package/dist/engines/BaseEngine.d.ts +1 -5
  35. package/dist/engines/BaseEngine.d.ts.map +1 -1
  36. package/dist/engines/BaseEngine.js +7 -16
  37. package/dist/engines/BaseEngine.js.map +1 -1
  38. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  39. package/dist/engines/NgtscEngine.js +10 -11
  40. package/dist/engines/NgtscEngine.js.map +1 -1
  41. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  42. package/dist/engines/ServerEsbuildEngine.js +10 -11
  43. package/dist/engines/ServerEsbuildEngine.js.map +1 -1
  44. package/dist/engines/TscEngine.d.ts.map +1 -1
  45. package/dist/engines/TscEngine.js +10 -11
  46. package/dist/engines/TscEngine.js.map +1 -1
  47. package/dist/engines/ViteEngine.d.ts.map +1 -1
  48. package/dist/engines/ViteEngine.js +3 -13
  49. package/dist/engines/ViteEngine.js.map +1 -1
  50. package/dist/engines/index.d.ts.map +1 -1
  51. package/dist/engines/index.js.map +1 -1
  52. package/dist/engines/types.d.ts +3 -6
  53. package/dist/engines/types.d.ts.map +1 -1
  54. package/dist/engines/types.js.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/infra/ResultCollector.d.ts +1 -1
  58. package/dist/infra/ResultCollector.d.ts.map +1 -1
  59. package/dist/infra/ResultCollector.js.map +1 -1
  60. package/dist/infra/SignalHandler.d.ts.map +1 -1
  61. package/dist/infra/SignalHandler.js.map +1 -1
  62. package/dist/infra/WorkerManager.d.ts.map +1 -1
  63. package/dist/infra/WorkerManager.js.map +1 -1
  64. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  65. package/dist/orchestrators/BuildOrchestrator.js +30 -61
  66. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  67. package/dist/orchestrators/DevWatchOrchestrator.d.ts +2 -0
  68. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  69. package/dist/orchestrators/DevWatchOrchestrator.js +40 -44
  70. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  71. package/dist/sd-cli-entry.d.ts.map +1 -1
  72. package/dist/sd-cli-entry.js +2 -13
  73. package/dist/sd-cli-entry.js.map +1 -1
  74. package/dist/sd-cli.d.ts.map +1 -1
  75. package/dist/sd-cli.js +5 -5
  76. package/dist/sd-cli.js.map +1 -1
  77. package/dist/sd-config.types.d.ts.map +1 -1
  78. package/dist/sd-config.types.js.map +1 -1
  79. package/dist/utils/SdCliReporter.d.ts +18 -0
  80. package/dist/utils/SdCliReporter.d.ts.map +1 -0
  81. package/dist/utils/SdCliReporter.js +144 -0
  82. package/dist/utils/SdCliReporter.js.map +1 -0
  83. package/dist/utils/angular-build.d.ts.map +1 -1
  84. package/dist/utils/angular-build.js.map +1 -1
  85. package/dist/utils/angular-compiler.d.ts.map +1 -1
  86. package/dist/utils/angular-compiler.js +11 -4
  87. package/dist/utils/angular-compiler.js.map +1 -1
  88. package/dist/utils/build-env.d.ts.map +1 -1
  89. package/dist/utils/build-env.js +2 -1
  90. package/dist/utils/build-env.js.map +1 -1
  91. package/dist/utils/concurrency.d.ts.map +1 -1
  92. package/dist/utils/concurrency.js.map +1 -1
  93. package/dist/utils/copy-public.d.ts.map +1 -1
  94. package/dist/utils/copy-public.js +21 -21
  95. package/dist/utils/copy-public.js.map +1 -1
  96. package/dist/utils/copy-src.d.ts.map +1 -1
  97. package/dist/utils/copy-src.js +12 -12
  98. package/dist/utils/copy-src.js.map +1 -1
  99. package/dist/utils/diagnostic-utils.d.ts.map +1 -1
  100. package/dist/utils/diagnostic-utils.js +3 -2
  101. package/dist/utils/diagnostic-utils.js.map +1 -1
  102. package/dist/utils/engine-stop.d.ts.map +1 -1
  103. package/dist/utils/engine-stop.js.map +1 -1
  104. package/dist/utils/esbuild-config.d.ts.map +1 -1
  105. package/dist/utils/esbuild-config.js +2 -0
  106. package/dist/utils/esbuild-config.js.map +1 -1
  107. package/dist/utils/generate-pwa-icons.d.ts.map +1 -1
  108. package/dist/utils/generate-pwa-icons.js.map +1 -1
  109. package/dist/utils/hmr-candidates.d.ts.map +1 -1
  110. package/dist/utils/hmr-candidates.js.map +1 -1
  111. package/dist/utils/lint-utils.d.ts.map +1 -1
  112. package/dist/utils/lint-utils.js.map +1 -1
  113. package/dist/utils/lint-with-program.d.ts.map +1 -1
  114. package/dist/utils/lint-with-program.js +7 -3
  115. package/dist/utils/lint-with-program.js.map +1 -1
  116. package/dist/utils/ngtsc-build-core.d.ts +2 -10
  117. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  118. package/dist/utils/ngtsc-build-core.js +16 -15
  119. package/dist/utils/ngtsc-build-core.js.map +1 -1
  120. package/dist/utils/orchestrator-utils.d.ts.map +1 -1
  121. package/dist/utils/orchestrator-utils.js.map +1 -1
  122. package/dist/utils/output-path-rewriter.d.ts.map +1 -1
  123. package/dist/utils/output-path-rewriter.js +7 -7
  124. package/dist/utils/output-path-rewriter.js.map +1 -1
  125. package/dist/utils/output-utils.d.ts.map +1 -1
  126. package/dist/utils/output-utils.js +1 -1
  127. package/dist/utils/output-utils.js.map +1 -1
  128. package/dist/utils/package-utils.d.ts +4 -0
  129. package/dist/utils/package-utils.d.ts.map +1 -1
  130. package/dist/utils/package-utils.js +34 -13
  131. package/dist/utils/package-utils.js.map +1 -1
  132. package/dist/utils/rebuild-manager.d.ts +1 -1
  133. package/dist/utils/rebuild-manager.d.ts.map +1 -1
  134. package/dist/utils/rebuild-manager.js +3 -1
  135. package/dist/utils/rebuild-manager.js.map +1 -1
  136. package/dist/utils/replace-deps.d.ts.map +1 -1
  137. package/dist/utils/replace-deps.js +10 -10
  138. package/dist/utils/replace-deps.js.map +1 -1
  139. package/dist/utils/scss-compiler.d.ts.map +1 -1
  140. package/dist/utils/scss-compiler.js.map +1 -1
  141. package/dist/utils/sd-config.d.ts.map +1 -1
  142. package/dist/utils/sd-config.js +2 -3
  143. package/dist/utils/sd-config.js.map +1 -1
  144. package/dist/utils/tsc-build.d.ts +3 -1
  145. package/dist/utils/tsc-build.d.ts.map +1 -1
  146. package/dist/utils/tsc-build.js +7 -4
  147. package/dist/utils/tsc-build.js.map +1 -1
  148. package/dist/utils/tsconfig.d.ts.map +1 -1
  149. package/dist/utils/tsconfig.js.map +1 -1
  150. package/dist/utils/typecheck-non-package.d.ts.map +1 -1
  151. package/dist/utils/typecheck-non-package.js +10 -5
  152. package/dist/utils/typecheck-non-package.js.map +1 -1
  153. package/dist/utils/typecheck-serialization.d.ts.map +1 -1
  154. package/dist/utils/typecheck-serialization.js.map +1 -1
  155. package/dist/utils/vite-config.d.ts.map +1 -1
  156. package/dist/utils/vite-config.js +2 -1
  157. package/dist/utils/vite-config.js.map +1 -1
  158. package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
  159. package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
  160. package/dist/utils/worker-events.d.ts +1 -1
  161. package/dist/utils/worker-events.d.ts.map +1 -1
  162. package/dist/utils/worker-events.js +1 -0
  163. package/dist/utils/worker-events.js.map +1 -1
  164. package/dist/utils/worker-utils.d.ts +1 -1
  165. package/dist/utils/worker-utils.d.ts.map +1 -1
  166. package/dist/utils/worker-utils.js +3 -1
  167. package/dist/utils/worker-utils.js.map +1 -1
  168. package/dist/vitest-plugin.d.ts.map +1 -1
  169. package/dist/vitest-plugin.js +2 -0
  170. package/dist/vitest-plugin.js.map +1 -1
  171. package/dist/workers/client.worker.d.ts.map +1 -1
  172. package/dist/workers/client.worker.js +4 -0
  173. package/dist/workers/client.worker.js.map +1 -1
  174. package/dist/workers/library-build.worker.d.ts +2 -10
  175. package/dist/workers/library-build.worker.d.ts.map +1 -1
  176. package/dist/workers/library-build.worker.js +38 -14
  177. package/dist/workers/library-build.worker.js.map +1 -1
  178. package/dist/workers/lint.worker.d.ts.map +1 -1
  179. package/dist/workers/lint.worker.js.map +1 -1
  180. package/dist/workers/ngtsc-build.worker.d.ts.map +1 -1
  181. package/dist/workers/ngtsc-build.worker.js +40 -14
  182. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  183. package/dist/workers/server-build.worker.d.ts +2 -10
  184. package/dist/workers/server-build.worker.d.ts.map +1 -1
  185. package/dist/workers/server-build.worker.js +30 -22
  186. package/dist/workers/server-build.worker.js.map +1 -1
  187. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  188. package/dist/workers/server-runtime.worker.js.map +1 -1
  189. package/package.json +4 -5
  190. package/src/angular/vite-angular-plugin.ts +18 -9
  191. package/src/capacitor/capacitor.ts +43 -44
  192. package/src/commands/check.ts +2 -2
  193. package/src/commands/publish.ts +12 -13
  194. package/src/commands/typecheck.ts +12 -12
  195. package/src/electron/electron.ts +44 -38
  196. package/src/engines/BaseEngine.ts +8 -19
  197. package/src/engines/NgtscEngine.ts +11 -11
  198. package/src/engines/ServerEsbuildEngine.ts +11 -11
  199. package/src/engines/TscEngine.ts +11 -11
  200. package/src/engines/ViteEngine.ts +3 -14
  201. package/src/engines/types.ts +3 -6
  202. package/src/infra/ResultCollector.ts +1 -1
  203. package/src/orchestrators/BuildOrchestrator.ts +31 -62
  204. package/src/orchestrators/DevWatchOrchestrator.ts +41 -44
  205. package/src/sd-cli-entry.ts +2 -12
  206. package/src/sd-cli.ts +8 -5
  207. package/src/utils/SdCliReporter.ts +177 -0
  208. package/src/utils/angular-compiler.ts +11 -4
  209. package/src/utils/build-env.ts +2 -1
  210. package/src/utils/copy-public.ts +21 -21
  211. package/src/utils/copy-src.ts +12 -12
  212. package/src/utils/diagnostic-utils.ts +3 -2
  213. package/src/utils/esbuild-config.ts +2 -0
  214. package/src/utils/lint-with-program.ts +7 -3
  215. package/src/utils/ngtsc-build-core.ts +18 -18
  216. package/src/utils/output-path-rewriter.ts +7 -7
  217. package/src/utils/output-utils.ts +1 -1
  218. package/src/utils/package-utils.ts +37 -13
  219. package/src/utils/rebuild-manager.ts +4 -2
  220. package/src/utils/replace-deps.ts +10 -10
  221. package/src/utils/sd-config.ts +2 -3
  222. package/src/utils/tsc-build.ts +9 -4
  223. package/src/utils/typecheck-non-package.ts +10 -5
  224. package/src/utils/vite-config.ts +2 -1
  225. package/src/utils/worker-events.ts +2 -1
  226. package/src/utils/worker-utils.ts +3 -1
  227. package/src/vitest-plugin.ts +5 -0
  228. package/src/workers/client.worker.ts +4 -0
  229. package/src/workers/library-build.worker.ts +48 -18
  230. package/src/workers/ngtsc-build.worker.ts +48 -13
  231. package/src/workers/server-build.worker.ts +32 -26
  232. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +11 -7
  233. package/tests/angular/vite-angular-plugin-lint.spec.ts +6 -1
  234. package/tests/capacitor/capacitor-build.spec.ts +14 -7
  235. package/tests/capacitor/capacitor-icon.spec.ts +14 -7
  236. package/tests/capacitor/capacitor-init.spec.ts +13 -6
  237. package/tests/capacitor/capacitor-run.spec.ts +18 -11
  238. package/tests/capacitor/capacitor-workspace.spec.ts +13 -6
  239. package/tests/commands/check.spec.ts +5 -2
  240. package/tests/commands/publish.spec.ts +4 -4
  241. package/tests/commands/typecheck.spec.ts +20 -31
  242. package/tests/electron/electron.spec.ts +32 -23
  243. package/tests/engines/base-engine.spec.ts +15 -21
  244. package/tests/engines/engine-lint-integration.spec.ts +5 -10
  245. package/tests/engines/ngtsc-engine.spec.ts +27 -41
  246. package/tests/engines/server-esbuild-engine.spec.ts +18 -29
  247. package/tests/engines/tsc-engine.spec.ts +14 -23
  248. package/tests/engines/vite-engine.spec.ts +10 -15
  249. package/tests/infra/result-collector.spec.ts +2 -2
  250. package/tests/orchestrators/build-orchestrator.spec.ts +19 -29
  251. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +110 -95
  252. package/tests/utils/copy-src.spec.ts +25 -19
  253. package/tests/utils/diagnostic-utils.spec.ts +72 -0
  254. package/tests/utils/ngtsc-build-core-angular-compiler.spec.ts +2 -3
  255. package/tests/utils/output-path-rewriter.spec.ts +7 -6
  256. package/tests/utils/output-utils.spec.ts +5 -5
  257. package/tests/utils/rebuild-manager.spec.ts +1 -1
  258. package/tests/utils/sd-config.spec.ts +4 -0
  259. package/tests/utils/tsc-build.spec.ts +23 -5
  260. package/tests/workers/library-build-worker.spec.ts +113 -20
  261. package/tests/workers/ngtsc-build-lint.spec.ts +3 -6
  262. package/tests/workers/ngtsc-build-worker.spec.ts +11 -13
  263. package/tests/workers/server-build-lint.spec.ts +4 -1
  264. package/tests/workers/server-build-worker.spec.ts +25 -25
  265. package/tests/angular/migration-cleanup.spec.ts +0 -59
@@ -1,10 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import { existsSync } from "node:fs";
3
3
  import path from "path";
4
- import { execa } from "execa";
5
4
  import { symlink } from "fs/promises";
6
5
  import { createRequire } from "module";
7
- import { fsx } from "@simplysm/core-node";
6
+ import { cpx, fsx, pathx } from "@simplysm/core-node";
8
7
  import { env } from "@simplysm/core-common";
9
8
  import { consola } from "consola";
10
9
  import type { SdCapacitorConfig } from "../sd-config.types.js";
@@ -53,7 +52,7 @@ export class Capacitor {
53
52
  ) {
54
53
  this._platforms = Object.keys(this._config.platform ?? {});
55
54
  this._npmConfig = npmConfig;
56
- this._capPath = path.resolve(this._pkgPath, ".capacitor");
55
+ this._capPath = pathx.posixResolve(this._pkgPath, ".capacitor");
57
56
  }
58
57
 
59
58
  /**
@@ -66,7 +65,7 @@ export class Capacitor {
66
65
  ): Promise<Capacitor> {
67
66
  Capacitor._validateConfig(config);
68
67
 
69
- const npmConfig = await fsx.readJson<NpmConfig>(path.resolve(pkgPath, "package.json"));
68
+ const npmConfig = await fsx.readJson<NpmConfig>(pathx.posixResolve(pkgPath, "package.json"));
70
69
  return new Capacitor(pkgPath, config, npmConfig, exclude ?? []);
71
70
  }
72
71
 
@@ -154,11 +153,11 @@ export class Capacitor {
154
153
  }
155
154
 
156
155
  /**
157
- * 명령어 실행 (execa — Windows .cmd 자동 resolve)
156
+ * 명령어 실행
158
157
  */
159
158
  private async _exec(command: string, args: string[], cwd: string): Promise<string> {
160
159
  Capacitor._logger.debug(`명령어 실행: ${command} ${args.join(" ")}`);
161
- const { stdout } = await execa(command, args, { cwd });
160
+ const { stdout } = await cpx.exec(command, args, { cwd });
162
161
  Capacitor._logger.debug(`실행 결과: ${stdout}`);
163
162
  return stdout;
164
163
  }
@@ -171,7 +170,7 @@ export class Capacitor {
171
170
  * 동시 실행 방지 잠금 획득
172
171
  */
173
172
  private async _acquireLock(): Promise<void> {
174
- const lockPath = path.resolve(this._capPath, Capacitor._LOCK_FILE_NAME);
173
+ const lockPath = pathx.posixResolve(this._capPath, Capacitor._LOCK_FILE_NAME);
175
174
  await fsx.mkdir(this._capPath);
176
175
  try {
177
176
  await fs.promises.writeFile(lockPath, String(process.pid), { flag: "wx" });
@@ -195,7 +194,7 @@ export class Capacitor {
195
194
  * 동시 실행 방지 잠금 해제
196
195
  */
197
196
  private async _releaseLock(): Promise<void> {
198
- const lockPath = path.resolve(this._capPath, Capacitor._LOCK_FILE_NAME);
197
+ const lockPath = pathx.posixResolve(this._capPath, Capacitor._LOCK_FILE_NAME);
199
198
  await fsx.rm(lockPath);
200
199
  }
201
200
 
@@ -237,7 +236,7 @@ export class Capacitor {
237
236
  */
238
237
  private async _initCap(): Promise<boolean> {
239
238
  const { depChanged, workspacePlugins } = await this._setupNpmConf();
240
- const nodeModulesExists = await fsx.exists(path.resolve(this._capPath, "node_modules"));
239
+ const nodeModulesExists = await fsx.exists(pathx.posixResolve(this._capPath, "node_modules"));
241
240
 
242
241
  if (!depChanged && nodeModulesExists) {
243
242
  // 의존성 미변경이어도 workspace 플러그인 symlink는 항상 갱신
@@ -253,16 +252,16 @@ export class Capacitor {
253
252
  await this._linkWorkspacePlugins(workspacePlugins);
254
253
 
255
254
  // 멱등성: capacitor.config.ts가 없을 때만 cap init 실행
256
- const configPath = path.resolve(this._capPath, "capacitor.config.ts");
255
+ const configPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
257
256
  if (!(await fsx.exists(configPath))) {
258
257
  await this._execCap(["init", this._config.appId, this._config.appId]);
259
258
  }
260
259
 
261
260
  // 기본 www/index.html 생성
262
- const wwwPath = path.resolve(this._capPath, "www");
261
+ const wwwPath = pathx.posixResolve(this._capPath, "www");
263
262
  await fsx.mkdir(wwwPath);
264
263
  await fsx.write(
265
- path.resolve(wwwPath, "index.html"),
264
+ pathx.posixResolve(wwwPath, "index.html"),
266
265
  "<!DOCTYPE html><html><head></head><body></body></html>",
267
266
  );
268
267
 
@@ -273,7 +272,7 @@ export class Capacitor {
273
272
  * package.json 설정
274
273
  */
275
274
  private async _setupNpmConf(): Promise<{ depChanged: boolean; workspacePlugins: string[] }> {
276
- const projNpmConfigPath = path.resolve(this._findWorkspaceRoot(), "package.json");
275
+ const projNpmConfigPath = pathx.posixResolve(this._findWorkspaceRoot(), "package.json");
277
276
 
278
277
  // 루트 package.json 존재 확인
279
278
  if (!(await fsx.exists(projNpmConfigPath))) {
@@ -282,7 +281,7 @@ export class Capacitor {
282
281
 
283
282
  const projNpmConfig = await fsx.readJson<NpmConfig>(projNpmConfigPath);
284
283
 
285
- const capNpmConfPath = path.resolve(this._capPath, "package.json");
284
+ const capNpmConfPath = pathx.posixResolve(this._capPath, "package.json");
286
285
  const orgCapNpmConf: NpmConfig = (await fsx.exists(capNpmConfPath))
287
286
  ? await fsx.readJson<NpmConfig>(capNpmConfPath)
288
287
  : { name: "", version: "" };
@@ -372,7 +371,7 @@ export class Capacitor {
372
371
  * capacitor.config.ts 생성
373
372
  */
374
373
  private async _writeCapConf(): Promise<void> {
375
- const confPath = path.resolve(this._capPath, "capacitor.config.ts");
374
+ const confPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
376
375
 
377
376
  // 플러그인 옵션 생성
378
377
  const pluginOptions: Record<string, Record<string, unknown>> = {};
@@ -412,7 +411,7 @@ export default config;
412
411
  */
413
412
  private async _addPlatforms(): Promise<void> {
414
413
  for (const platform of this._platforms) {
415
- const platformPath = path.resolve(this._capPath, platform);
414
+ const platformPath = pathx.posixResolve(this._capPath, platform);
416
415
  if (await fsx.exists(platformPath)) {
417
416
  Capacitor._logger.debug(`플랫폼이 이미 존재합니다: ${platform}`);
418
417
  continue;
@@ -428,7 +427,7 @@ export default config;
428
427
  private async _setupIcon(): Promise<void> {
429
428
  if (this._config.icon == null) return;
430
429
 
431
- const iconPath = path.resolve(this._pkgPath, this._config.icon);
430
+ const iconPath = pathx.posixResolve(this._pkgPath, this._config.icon);
432
431
 
433
432
  if (!(await fsx.exists(iconPath))) {
434
433
  Capacitor._logger.warn(`아이콘 파일을 찾을 수 없습니다: ${iconPath}`);
@@ -448,9 +447,9 @@ export default config;
448
447
  .toBuffer();
449
448
 
450
449
  // 1024x1024 투명 캔버스에 합성
451
- const assetsDir = path.resolve(this._capPath, "assets");
450
+ const assetsDir = pathx.posixResolve(this._capPath, "assets");
452
451
  await fsx.mkdir(assetsDir);
453
- const logoPath = path.resolve(assetsDir, "logo.png");
452
+ const logoPath = pathx.posixResolve(assetsDir, "logo.png");
454
453
 
455
454
  await sharp({
456
455
  create: {
@@ -494,7 +493,7 @@ export default config;
494
493
  * Android 네이티브 설정 구성
495
494
  */
496
495
  private async _configureAndroid(): Promise<void> {
497
- const androidPath = path.resolve(this._capPath, "android");
496
+ const androidPath = pathx.posixResolve(this._capPath, "android");
498
497
 
499
498
  // Android 디렉토리 존재 확인
500
499
  if (!(await fsx.exists(androidPath))) {
@@ -511,7 +510,7 @@ export default config;
511
510
  * JAVA_HOME 경로 설정 (gradle.properties)
512
511
  */
513
512
  private async _configureAndroidJavaHomePath(androidPath: string): Promise<void> {
514
- const gradlePropsPath = path.resolve(androidPath, "gradle.properties");
513
+ const gradlePropsPath = pathx.posixResolve(androidPath, "gradle.properties");
515
514
 
516
515
  if (!(await fsx.exists(gradlePropsPath))) {
517
516
  Capacitor._logger.warn(`gradle.properties 파일을 찾을 수 없습니다: ${gradlePropsPath}`);
@@ -556,12 +555,12 @@ export default config;
556
555
  * Android SDK 경로 설정 (local.properties)
557
556
  */
558
557
  private async _configureAndroidSdkPath(androidPath: string): Promise<void> {
559
- const localPropsPath = path.resolve(androidPath, "local.properties");
558
+ const localPropsPath = pathx.posixResolve(androidPath, "local.properties");
560
559
 
561
560
  const sdkPath = await this._findAndroidSdk();
562
561
  if (sdkPath != null) {
563
562
  // Gradle 호환: 항상 forward slash 사용
564
- await fsx.write(localPropsPath, `sdk.dir=${sdkPath.replace(/\\/g, "/")}\n`);
563
+ await fsx.write(localPropsPath, `sdk.dir=${pathx.posix(sdkPath)}\n`);
565
564
  } else {
566
565
  throw new Error(
567
566
  "Android SDK를 찾을 수 없습니다.\n" +
@@ -581,8 +580,8 @@ export default config;
581
580
  }
582
581
 
583
582
  const candidates = [
584
- path.resolve((env["LOCALAPPDATA"] as string | undefined) ?? "", "Android/Sdk"),
585
- path.resolve((env["HOME"] as string | undefined) ?? "", "Android/Sdk"),
583
+ pathx.posixResolve((env["LOCALAPPDATA"] as string | undefined) ?? "", "Android/Sdk"),
584
+ pathx.posixResolve((env["HOME"] as string | undefined) ?? "", "Android/Sdk"),
586
585
  "C:/Program Files/Android/Sdk",
587
586
  "C:/Android/Sdk",
588
587
  ];
@@ -603,7 +602,7 @@ export default config;
603
602
  * XML 구조가 변경되면 정규식이 실패할 수 있음.
604
603
  */
605
604
  private async _configureAndroidManifest(androidPath: string): Promise<void> {
606
- const manifestPath = path.resolve(androidPath, "app/src/main/AndroidManifest.xml");
605
+ const manifestPath = pathx.posixResolve(androidPath, "app/src/main/AndroidManifest.xml");
607
606
 
608
607
  if (!(await fsx.exists(manifestPath))) {
609
608
  throw new Error(`AndroidManifest.xml 파일을 찾을 수 없습니다: ${manifestPath}`);
@@ -675,7 +674,7 @@ export default config;
675
674
  * build.gradle 수정 (서명 설정 제외)
676
675
  */
677
676
  private async _configureAndroidBuildGradle(androidPath: string): Promise<void> {
678
- const buildGradlePath = path.resolve(androidPath, "app/build.gradle");
677
+ const buildGradlePath = pathx.posixResolve(androidPath, "app/build.gradle");
679
678
 
680
679
  if (!(await fsx.exists(buildGradlePath))) {
681
680
  throw new Error(`build.gradle 파일을 찾을 수 없습니다: ${buildGradlePath}`);
@@ -755,7 +754,7 @@ export default config;
755
754
  * WebView가 이 URL에서 웹 에셋을 로드하여 Hot Reload가 동작한다.
756
755
  */
757
756
  private async _updateServerUrl(url: string): Promise<void> {
758
- const configPath = path.resolve(this._capPath, "capacitor.config.ts");
757
+ const configPath = pathx.posixResolve(this._capPath, "capacitor.config.ts");
759
758
  let content = await fsx.read(configPath);
760
759
 
761
760
  if (content.includes("url:")) {
@@ -792,7 +791,7 @@ export default config;
792
791
  const signConfig = this._config.platform?.android?.sign;
793
792
  if (!isDebug && signConfig != null) {
794
793
  await this._configureSigningConfig(
795
- path.resolve(this._capPath, "android"),
794
+ pathx.posixResolve(this._capPath, "android"),
796
795
  signConfig,
797
796
  );
798
797
  } else if (!isDebug) {
@@ -818,16 +817,16 @@ export default config;
818
817
  sign: import("../sd-config.types.js").SdCapacitorSignConfig,
819
818
  ): Promise<void> {
820
819
  // keystore 파일 확인 및 복사
821
- const keystoreSrc = path.resolve(this._pkgPath, sign.keystore);
820
+ const keystoreSrc = pathx.posixResolve(this._pkgPath, sign.keystore);
822
821
  if (!(await fsx.exists(keystoreSrc))) {
823
822
  throw new Error(`keystore 파일을 찾을 수 없습니다: ${keystoreSrc}`);
824
823
  }
825
824
 
826
- const keystoreDest = path.resolve(androidPath, "app", "android.keystore");
825
+ const keystoreDest = pathx.posixResolve(androidPath, "app", "android.keystore");
827
826
  await fsx.copy(keystoreSrc, keystoreDest);
828
827
 
829
828
  // build.gradle에 signingConfigs 추가
830
- const buildGradlePath = path.resolve(androidPath, "app/build.gradle");
829
+ const buildGradlePath = pathx.posixResolve(androidPath, "app/build.gradle");
831
830
  let content = await fsx.read(buildGradlePath);
832
831
 
833
832
  // 이미 signingConfigs가 있으면 스킵
@@ -873,11 +872,11 @@ export default config;
873
872
  gradleTask = "assembleRelease";
874
873
  }
875
874
 
876
- const androidPath = path.resolve(this._capPath, "android");
875
+ const androidPath = pathx.posixResolve(this._capPath, "android");
877
876
  const isWindows = process.platform === "win32";
878
877
  const gradlew = isWindows
879
- ? path.resolve(androidPath, "gradlew.bat")
880
- : path.resolve(androidPath, "gradlew");
878
+ ? pathx.posixResolve(androidPath, "gradlew.bat")
879
+ : pathx.posixResolve(androidPath, "gradlew");
881
880
 
882
881
  await this._exec(gradlew, [gradleTask, "--no-daemon"], androidPath);
883
882
  }
@@ -892,7 +891,7 @@ export default config;
892
891
  ): Promise<void> {
893
892
  const ext = isBundle ? "aab" : "apk";
894
893
  const outputType = isBundle ? "bundle" : "apk";
895
- const androidBuildPath = path.resolve(
894
+ const androidBuildPath = pathx.posixResolve(
896
895
  this._capPath,
897
896
  "android/app/build/outputs",
898
897
  outputType,
@@ -900,7 +899,7 @@ export default config;
900
899
  );
901
900
 
902
901
  // 빌드 산출물 찾기
903
- const candidates = await fsx.glob(path.resolve(androidBuildPath, `app-*.${ext}`));
902
+ const candidates = await fsx.glob(pathx.posixResolve(androidBuildPath, `app-*.${ext}`));
904
903
  if (candidates.length === 0) {
905
904
  throw new Error(`빌드 산출물을 찾을 수 없습니다: ${androidBuildPath}`);
906
905
  }
@@ -908,8 +907,8 @@ export default config;
908
907
  const isUnsigned = builtFile.includes("unsigned");
909
908
 
910
909
  // 출력 디렉토리 생성
911
- const androidOutPath = path.resolve(outPath, "android");
912
- const updatesPath = path.resolve(androidOutPath, "updates");
910
+ const androidOutPath = pathx.posixResolve(outPath, "android");
911
+ const updatesPath = pathx.posixResolve(androidOutPath, "updates");
913
912
  await fsx.mkdir(androidOutPath);
914
913
  await fsx.mkdir(updatesPath);
915
914
 
@@ -919,8 +918,8 @@ export default config;
919
918
  const versionedName = `${this._npmConfig.version}.${ext}`;
920
919
 
921
920
  // 복사
922
- await fsx.copy(builtFile, path.resolve(androidOutPath, latestName));
923
- await fsx.copy(builtFile, path.resolve(updatesPath, versionedName));
921
+ await fsx.copy(builtFile, pathx.posixResolve(androidOutPath, latestName));
922
+ await fsx.copy(builtFile, pathx.posixResolve(updatesPath, versionedName));
924
923
  }
925
924
 
926
925
  //#endregion
@@ -934,13 +933,13 @@ export default config;
934
933
  private async _linkWorkspacePlugins(plugins: string[]): Promise<void> {
935
934
  if (plugins.length === 0) return;
936
935
 
937
- const require = createRequire(path.resolve(this._pkgPath, "package.json"));
936
+ const require = createRequire(pathx.posixResolve(this._pkgPath, "package.json"));
938
937
 
939
938
  for (const plugin of plugins) {
940
939
  const pluginPkgJsonPath = require.resolve(`${plugin}/package.json`);
941
940
  const pluginDir = path.dirname(pluginPkgJsonPath);
942
941
 
943
- const linkPath = path.resolve(this._capPath, "node_modules", ...plugin.split("/"));
942
+ const linkPath = pathx.posixResolve(this._capPath, "node_modules", ...plugin.split("/"));
944
943
 
945
944
  // scope 디렉토리 생성 (예: @simplysm/)
946
945
  await fsx.mkdir(path.dirname(linkPath));
@@ -965,7 +964,7 @@ export default config;
965
964
  if (parent === dir) {
966
965
  throw new Error(`워크스페이스 루트를 찾을 수 없습니다: ${this._pkgPath}`);
967
966
  }
968
- if (existsSync(path.join(parent, "pnpm-workspace.yaml"))) {
967
+ if (existsSync(pathx.posixResolve(parent, "pnpm-workspace.yaml"))) {
969
968
  return parent;
970
969
  }
971
970
  dir = parent;
@@ -1,4 +1,4 @@
1
- import { execa } from "execa";
1
+ import { cpx } from "@simplysm/core-node";
2
2
  import { err as errNs } from "@simplysm/core-common";
3
3
  import { executeTypecheck, type TypecheckResult } from "./typecheck";
4
4
  import { executeLint, type LintResult } from "./lint";
@@ -34,7 +34,7 @@ async function spawnVitest(targets: string[]): Promise<CheckResult> {
34
34
  const args = ["vitest", ...targets, "--run"];
35
35
  logger.debug("vitest 실행", { args });
36
36
  logger.start("테스트 실행 중...");
37
- const result = await execa("pnpm", args, { cwd: process.cwd(), reject: false });
37
+ const result = await cpx.exec("pnpm", args, { cwd: process.cwd(), reject: false });
38
38
  const output = result.stdout + result.stderr;
39
39
  const code = result.exitCode;
40
40
 
@@ -2,13 +2,12 @@ import path from "path";
2
2
  import semver from "semver";
3
3
  import { consola } from "consola";
4
4
  import { StorageFactory } from "@simplysm/storage";
5
- import { fsx } from "@simplysm/core-node";
5
+ import { cpx, fsx } from "@simplysm/core-node";
6
6
  import { env, json } from "@simplysm/core-common";
7
7
  import "@simplysm/core-common";
8
8
  import type { SdConfig, SdPublishConfig } from "../sd-config.types";
9
9
  import { loadSdConfig } from "../utils/sd-config";
10
10
  import { validateTargets } from "../utils/package-utils";
11
- import { execa } from "execa";
12
11
  import { runBuild } from "./build";
13
12
  import { parseWorkspaceGlobs } from "../utils/replace-deps";
14
13
  import os from "os";
@@ -353,7 +352,7 @@ async function publishPackage(
353
352
  logger.debug(`[${pkgName}] pnpm ${args.join(" ")}`);
354
353
  }
355
354
 
356
- await execa("pnpm", args, { cwd: pkgPath });
355
+ await cpx.exec("pnpm", args, { cwd: pkgPath });
357
356
  } else if (publishConfig.type === "local-directory") {
358
357
  // 로컬 디렉토리에 복사
359
358
  const targetPath = replaceEnvVariables(publishConfig.path, version, projectPath);
@@ -560,7 +559,7 @@ export async function runPublish(options: PublishOptions): Promise<void> {
560
559
  if (publishPackages.some((p) => p.config.type === "npm")) {
561
560
  logger.debug("npm 인증 검증 중...");
562
561
  try {
563
- const { stdout: whoami } = await execa("npm", ["whoami"]);
562
+ const { stdout: whoami } = await cpx.exec("npm", ["whoami"]);
564
563
  if (whoami.trim() === "") {
565
564
  throw new Error("npm 로그인 정보를 찾을 수 없습니다.");
566
565
  }
@@ -590,13 +589,13 @@ export async function runPublish(options: PublishOptions): Promise<void> {
590
589
  if (!noBuild && hasGit) {
591
590
  logger.debug("git 커밋 상태 확인 중...");
592
591
  try {
593
- const { stdout: diff } = await execa("git", ["diff", "--name-only"]);
594
- const { stdout: stagedDiff } = await execa("git", ["diff", "--cached", "--name-only"]);
592
+ const { stdout: diff } = await cpx.exec("git", ["diff", "--name-only"]);
593
+ const { stdout: stagedDiff } = await cpx.exec("git", ["diff", "--cached", "--name-only"]);
595
594
 
596
595
  if (diff.trim() !== "" || stagedDiff.trim() !== "") {
597
596
  logger.info("커밋되지 않은 변경사항 감지. claude로 자동 커밋 시도 중...");
598
597
  try {
599
- await execa("claude", [
598
+ await cpx.exec("claude", [
600
599
  "-p",
601
600
  "/sd-commit all",
602
601
  "--dangerously-skip-permissions",
@@ -684,11 +683,11 @@ export async function runPublish(options: PublishOptions): Promise<void> {
684
683
  } else {
685
684
  logger.debug("Git commit/tag/push...");
686
685
  try {
687
- await execa("git", ["add", ..._changedFiles]);
688
- await execa("git", ["commit", "-m", `v${version}`]);
689
- await execa("git", ["tag", "-a", `v${version}`, "-m", `v${version}`]);
690
- await execa("git", ["push"]);
691
- await execa("git", ["push", "--tags"]);
686
+ await cpx.exec("git", ["add", ..._changedFiles]);
687
+ await cpx.exec("git", ["commit", "-m", `v${version}`]);
688
+ await cpx.exec("git", ["tag", "-a", `v${version}`, "-m", `v${version}`]);
689
+ await cpx.exec("git", ["push"]);
690
+ await cpx.exec("git", ["push", "--tags"]);
692
691
  logger.debug("Git 작업 완료");
693
692
  } catch (err) {
694
693
  logger.error(
@@ -807,7 +806,7 @@ export async function runPublish(options: PublishOptions): Promise<void> {
807
806
  logger.info(`[DRY-RUN] 실행 예정: ${cmd} ${args.join(" ")}`);
808
807
  } else {
809
808
  logger.debug(`실행 중: ${cmd} ${args.join(" ")}`);
810
- await execa(cmd, args, { cwd });
809
+ await cpx.exec(cmd, args, { cwd });
811
810
  }
812
811
  } catch (err) {
813
812
  // postPublish 실패 시 경고만 출력 (배포 롤백 불가)
@@ -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: path.join(cwd, relPath),
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.dts.success ? "완료" : "실패"}`);
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
- js: { success: true, errors: [], warnings: [] },
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 dtsDiags = engineResult.dts.diagnostics.map((d) => deserializeDiagnostic(d, fileCache));
221
- allDiagnostics.push(...dtsDiags);
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 += dtsDiags.filter((d) => d.category === 1).length;
225
- totalWarningCount += dtsDiags.filter((d) => d.category === 0).length;
226
- if (!engineResult.dts.success && dtsDiags.length === 0) {
227
- for (const errMsg of engineResult.dts.errors) {
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.dts.errors.length || 1;
237
+ totalErrorCount += engineResult.build.errors.length || 1;
238
238
  }
239
239
 
240
240
  // Lint 결과 수집