@simplysm/sd-cli 14.0.16 → 14.0.17

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 (202) hide show
  1. package/README.md +2 -1
  2. package/dist/angular/client-transform-stylesheet.d.ts +2 -0
  3. package/dist/angular/client-transform-stylesheet.d.ts.map +1 -1
  4. package/dist/angular/client-transform-stylesheet.js +88 -2
  5. package/dist/angular/client-transform-stylesheet.js.map +1 -1
  6. package/dist/angular/vite-angular-plugin.d.ts +7 -0
  7. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  8. package/dist/angular/vite-angular-plugin.js +78 -16
  9. package/dist/angular/vite-angular-plugin.js.map +1 -1
  10. package/dist/capacitor/capacitor.d.ts.map +1 -1
  11. package/dist/capacitor/capacitor.js +9 -13
  12. package/dist/capacitor/capacitor.js.map +1 -1
  13. package/dist/commands/check.d.ts.map +1 -1
  14. package/dist/commands/check.js +8 -9
  15. package/dist/commands/check.js.map +1 -1
  16. package/dist/commands/device.d.ts.map +1 -1
  17. package/dist/commands/device.js +33 -1
  18. package/dist/commands/device.js.map +1 -1
  19. package/dist/commands/lint.d.ts +0 -1
  20. package/dist/commands/lint.d.ts.map +1 -1
  21. package/dist/commands/lint.js +2 -3
  22. package/dist/commands/lint.js.map +1 -1
  23. package/dist/commands/publish.js +2 -2
  24. package/dist/commands/publish.js.map +1 -1
  25. package/dist/commands/typecheck.d.ts.map +1 -1
  26. package/dist/commands/typecheck.js +0 -1
  27. package/dist/commands/typecheck.js.map +1 -1
  28. package/dist/electron/electron.d.ts +3 -2
  29. package/dist/electron/electron.d.ts.map +1 -1
  30. package/dist/electron/electron.js +54 -31
  31. package/dist/electron/electron.js.map +1 -1
  32. package/dist/engines/BaseEngine.js +1 -1
  33. package/dist/engines/BaseEngine.js.map +1 -1
  34. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  35. package/dist/engines/NgtscEngine.js +0 -1
  36. package/dist/engines/NgtscEngine.js.map +1 -1
  37. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  38. package/dist/engines/ServerEsbuildEngine.js +0 -1
  39. package/dist/engines/ServerEsbuildEngine.js.map +1 -1
  40. package/dist/engines/TscEngine.d.ts.map +1 -1
  41. package/dist/engines/TscEngine.js +0 -1
  42. package/dist/engines/TscEngine.js.map +1 -1
  43. package/dist/engines/ViteEngine.d.ts.map +1 -1
  44. package/dist/engines/ViteEngine.js +8 -1
  45. package/dist/engines/ViteEngine.js.map +1 -1
  46. package/dist/engines/index.d.ts +0 -10
  47. package/dist/engines/index.d.ts.map +1 -1
  48. package/dist/engines/index.js +0 -5
  49. package/dist/engines/index.js.map +1 -1
  50. package/dist/engines/types.d.ts +0 -1
  51. package/dist/engines/types.d.ts.map +1 -1
  52. package/dist/infra/SignalHandler.d.ts +1 -6
  53. package/dist/infra/SignalHandler.d.ts.map +1 -1
  54. package/dist/infra/SignalHandler.js +4 -13
  55. package/dist/infra/SignalHandler.js.map +1 -1
  56. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  57. package/dist/orchestrators/BuildOrchestrator.js +7 -12
  58. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  59. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  60. package/dist/orchestrators/DevWatchOrchestrator.js +17 -10
  61. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  62. package/dist/sd-cli-entry.d.ts +0 -1
  63. package/dist/sd-cli-entry.d.ts.map +1 -1
  64. package/dist/sd-cli-entry.js +7 -8
  65. package/dist/sd-cli-entry.js.map +1 -1
  66. package/dist/sd-config.types.d.ts +11 -1
  67. package/dist/sd-config.types.d.ts.map +1 -1
  68. package/dist/utils/angular-compiler.d.ts.map +1 -1
  69. package/dist/utils/angular-compiler.js +20 -13
  70. package/dist/utils/angular-compiler.js.map +1 -1
  71. package/dist/utils/esbuild-config.d.ts +1 -1
  72. package/dist/utils/esbuild-config.d.ts.map +1 -1
  73. package/dist/utils/esbuild-config.js +1 -4
  74. package/dist/utils/esbuild-config.js.map +1 -1
  75. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  76. package/dist/utils/ngtsc-build-core.js +3 -0
  77. package/dist/utils/ngtsc-build-core.js.map +1 -1
  78. package/dist/utils/tsc-build.d.ts +5 -0
  79. package/dist/utils/tsc-build.d.ts.map +1 -1
  80. package/dist/utils/tsc-build.js +2 -1
  81. package/dist/utils/tsc-build.js.map +1 -1
  82. package/dist/utils/vite-config.d.ts +1 -1
  83. package/dist/utils/vite-config.d.ts.map +1 -1
  84. package/dist/utils/vite-config.js +22 -53
  85. package/dist/utils/vite-config.js.map +1 -1
  86. package/dist/utils/vite-pwa-plugin.d.ts +9 -0
  87. package/dist/utils/vite-pwa-plugin.d.ts.map +1 -0
  88. package/dist/utils/vite-pwa-plugin.js +139 -0
  89. package/dist/utils/vite-pwa-plugin.js.map +1 -0
  90. package/dist/utils/worker-utils.d.ts +2 -5
  91. package/dist/utils/worker-utils.d.ts.map +1 -1
  92. package/dist/utils/worker-utils.js +5 -11
  93. package/dist/utils/worker-utils.js.map +1 -1
  94. package/dist/workers/client.worker.d.ts.map +1 -1
  95. package/dist/workers/client.worker.js +9 -3
  96. package/dist/workers/client.worker.js.map +1 -1
  97. package/dist/workers/library-build.worker.d.ts.map +1 -1
  98. package/dist/workers/library-build.worker.js +6 -2
  99. package/dist/workers/library-build.worker.js.map +1 -1
  100. package/dist/workers/ngtsc-build.worker.js +2 -2
  101. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  102. package/dist/workers/server-build.worker.d.ts.map +1 -1
  103. package/dist/workers/server-build.worker.js +6 -2
  104. package/dist/workers/server-build.worker.js.map +1 -1
  105. package/dist/workers/server-runtime.worker.js +4 -4
  106. package/dist/workers/server-runtime.worker.js.map +1 -1
  107. package/docs/config.md +26 -0
  108. package/docs/pwa-configuration-types.md +1 -1
  109. package/package.json +8 -10
  110. package/src/angular/client-transform-stylesheet.ts +104 -2
  111. package/src/angular/vite-angular-plugin.ts +92 -31
  112. package/src/capacitor/capacitor.ts +10 -26
  113. package/src/commands/check.ts +8 -11
  114. package/src/commands/device.ts +38 -3
  115. package/src/commands/lint.ts +2 -3
  116. package/src/commands/publish.ts +2 -2
  117. package/src/commands/typecheck.ts +0 -1
  118. package/src/electron/electron.ts +62 -43
  119. package/src/engines/BaseEngine.ts +1 -1
  120. package/src/engines/NgtscEngine.ts +0 -1
  121. package/src/engines/ServerEsbuildEngine.ts +0 -1
  122. package/src/engines/TscEngine.ts +0 -1
  123. package/src/engines/ViteEngine.ts +7 -1
  124. package/src/engines/index.ts +0 -10
  125. package/src/engines/types.ts +0 -1
  126. package/src/infra/SignalHandler.ts +4 -14
  127. package/src/orchestrators/BuildOrchestrator.ts +7 -9
  128. package/src/orchestrators/DevWatchOrchestrator.ts +21 -9
  129. package/src/sd-cli-entry.ts +11 -16
  130. package/src/sd-config.types.ts +12 -1
  131. package/src/utils/angular-compiler.ts +21 -21
  132. package/src/utils/esbuild-config.ts +2 -5
  133. package/src/utils/ngtsc-build-core.ts +7 -0
  134. package/src/utils/tsc-build.ts +7 -0
  135. package/src/utils/vite-config.ts +23 -55
  136. package/src/utils/vite-pwa-plugin.ts +168 -0
  137. package/src/utils/worker-utils.ts +5 -11
  138. package/src/workers/client.worker.ts +11 -3
  139. package/src/workers/library-build.worker.ts +6 -2
  140. package/src/workers/ngtsc-build.worker.ts +2 -2
  141. package/src/workers/server-build.worker.ts +7 -2
  142. package/src/workers/server-runtime.worker.ts +4 -4
  143. package/tests/angular/client-transform-stylesheet.spec.ts +43 -0
  144. package/tests/angular/find-affected-by-scss.spec.ts +37 -0
  145. package/tests/angular/fixtures/basic-app/scss/_colors.scss +1 -0
  146. package/tests/angular/fixtures/basic-app/scss/_variables.scss +3 -0
  147. package/tests/angular/fixtures/basic-app/src/styled.component.ts +14 -0
  148. package/tests/angular/linker-disk-cache.spec.ts +158 -0
  149. package/tests/angular/scss-disk-cache.spec.ts +162 -0
  150. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +15 -15
  151. package/tests/angular/vite-angular-plugin-hmr.spec.ts +9 -9
  152. package/tests/angular/vite-angular-plugin-lint.spec.ts +4 -4
  153. package/tests/angular/vite-angular-plugin-scss-hmr.spec.ts +87 -0
  154. package/tests/angular/vite-angular-plugin.spec.ts +15 -15
  155. package/tests/capacitor/capacitor-icon.spec.ts +2 -4
  156. package/tests/capacitor/capacitor-init.spec.ts +2 -4
  157. package/tests/capacitor/capacitor-workspace.spec.ts +2 -4
  158. package/tests/commands/device.spec.ts +100 -0
  159. package/tests/electron/electron.spec.ts +24 -17
  160. package/tests/engines/ngtsc-engine.spec.ts +0 -3
  161. package/tests/engines/server-esbuild-engine.spec.ts +0 -3
  162. package/tests/engines/tsc-engine.spec.ts +1 -2
  163. package/tests/engines/vite-engine.spec.ts +0 -2
  164. package/tests/infra/signal-handler.spec.ts +1 -12
  165. package/tests/orchestrators/build-orchestrator.spec.ts +0 -6
  166. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +24 -66
  167. package/tests/utils/angular-compiler.spec.ts +1396 -32
  168. package/tests/utils/esbuild-config.spec.ts +4 -7
  169. package/tests/utils/{ngtsc-build-core-angular-compiler.spec.ts → ngtsc-build-core.spec.ts} +142 -11
  170. package/tests/utils/tsc-build.spec.ts +4 -1
  171. package/tests/utils/vite-config.spec.ts +130 -261
  172. package/tests/utils/vite-pwa-plugin.acc.spec.ts +143 -0
  173. package/tests/utils/vite-pwa-plugin.spec.ts +350 -0
  174. package/tests/utils/worker-utils.spec.ts +8 -7
  175. package/tests/workers/client-worker.spec.ts +50 -1
  176. package/tests/workers/dev-port-file.verify.md +6 -0
  177. package/tests/workers/library-build-lint.spec.ts +1 -1
  178. package/tests/workers/library-build-worker.spec.ts +1 -1
  179. package/tests/workers/ngtsc-build-lint.spec.ts +1 -1
  180. package/tests/workers/server-build-lint.spec.ts +1 -1
  181. package/tests/workers/server-build-worker.spec.ts +1 -1
  182. package/tests/workers/server-runtime-worker.spec.ts +8 -1
  183. package/dist/infra/WorkerManager.d.ts +0 -40
  184. package/dist/infra/WorkerManager.d.ts.map +0 -1
  185. package/dist/infra/WorkerManager.js +0 -59
  186. package/dist/infra/WorkerManager.js.map +0 -1
  187. package/dist/utils/SdCliReporter.d.ts +0 -18
  188. package/dist/utils/SdCliReporter.d.ts.map +0 -1
  189. package/dist/utils/SdCliReporter.js +0 -144
  190. package/dist/utils/SdCliReporter.js.map +0 -1
  191. package/src/infra/WorkerManager.ts +0 -65
  192. package/src/utils/SdCliReporter.ts +0 -177
  193. package/tests/angular/scss-compiler-async.spec.ts +0 -54
  194. package/tests/commands/dev.spec.ts +0 -53
  195. package/tests/commands/watch.spec.ts +0 -53
  196. package/tests/infra/worker-manager.spec.ts +0 -63
  197. package/tests/utils/angular-compiler-emit.spec.ts +0 -570
  198. package/tests/utils/angular-compiler-init.spec.ts +0 -705
  199. package/tests/utils/angular-compiler-update.spec.ts +0 -293
  200. package/tests/utils/build-env.spec.ts +0 -33
  201. package/tests/utils/ngtsc-build-core-transform-stylesheet.spec.ts +0 -124
  202. package/tests/utils/ngtsc-scss-refactor.spec.ts +0 -47
@@ -1 +1 @@
1
- {"version":3,"file":"server-runtime.worker.js","sourceRoot":"","sources":["../../src/workers/server-runtime.worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-runtime.worker.js","sourceRoot":"","sources":["../../src/workers/server-runtime.worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAoCpF,YAAY;AAEZ,kBAAkB,EAAE,CAAC;AAErB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;AAE/D,sBAAsB;AACtB,IAAI,cAA0D,CAAC;AAE/D;;GAEG;AACH,KAAK,UAAU,OAAO;IACpB,MAAM,MAAM,GAAG,cAAc,CAAC;IAC9B,cAAc,GAAG,SAAS,CAAC;IAC3B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,qDAAqD;AACrD,gEAAgE;AAChE,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;QACnB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;KAC5B,CAAC,CAAC;IACH,wBAAwB;IACxB,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;QACnB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;KAC/B,CAAC,CAAC;IACH,wBAAwB;IACxB,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAEzC;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,UAAU,GAAG,EAAE;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC;QAC3B,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mCAAmC,SAAS,QAAQ,SAAS,GAAG,UAAU,GAAG,CAAC,GAAG,CAClF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,KAAK,CAAC,IAA4B;IAC/C,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAEpC,0CAA0C;QAC1C,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpD,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACjC,IAAI,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAChF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,mBAAmB;QACnB,cAAc,GAAG,MAAM,CAAC;QAExB,0BAA0B;QAC1B,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5D,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,uBAAuB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpE,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE;oBACnC,MAAM,EAAE,IAAI,IAAI,EAAE;oBAClB,QAAQ,EAAE,oBAAoB,IAAI,EAAE;oBACpC,aAAa,EAAE,IAAI,IAAI,EAAE;oBACzB,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QACzC,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAC5D,IAAI,aAAa,KAAK,YAAY,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,MAAM,YAAY,UAAU,aAAa,MAAM,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,aAAa,CAAC;QACtC,CAAC;QACD,MAAM,CAAC,KAAK,CACV,MAAM,MAAM,CAAC,aAAa,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CACrF,CAAC;QAEF,QAAQ;QACR,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC5B,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAE1E,MAAM,CAAC,KAAK,CACV,gBAAgB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,IAAI,CAC9D,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;YACnB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;SAC5B,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,CAAqD;IAC9E,KAAK;CACN,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
package/docs/config.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Config
2
2
 
3
+ ## `NpmConfig`
4
+
5
+ npm `package.json` structure.
6
+
7
+ ```typescript
8
+ interface NpmConfig {
9
+ name: string;
10
+ version: string;
11
+ description?: string;
12
+ dependencies?: Record<string, string>;
13
+ devDependencies?: Record<string, string>;
14
+ peerDependencies?: Record<string, string>;
15
+ volta?: unknown;
16
+ }
17
+ ```
18
+
19
+ | Field | Type | Description |
20
+ |-------|------|-------------|
21
+ | `name` | `string` | Package name |
22
+ | `version` | `string` | Package version |
23
+ | `description` | `string` | Package description |
24
+ | `dependencies` | `Record<string, string>` | Production dependencies |
25
+ | `devDependencies` | `Record<string, string>` | Development dependencies |
26
+ | `peerDependencies` | `Record<string, string>` | Peer dependencies |
27
+ | `volta` | `unknown` | Volta configuration |
28
+
3
29
  ## `BuildTarget`
4
30
 
5
31
  Build target type (built with esbuild).
@@ -18,7 +18,7 @@ interface SdPwaConfig {
18
18
 
19
19
  ## `SdPwaManifestConfig`
20
20
 
21
- PWA manifest configuration (subset of VitePWA manifest options).
21
+ PWA manifest configuration.
22
22
 
23
23
  ```typescript
24
24
  interface SdPwaManifestConfig {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-cli",
3
- "version": "14.0.16",
3
+ "version": "14.0.17",
4
4
  "description": "Simplysm package - CLI tool",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -26,25 +26,23 @@
26
26
  "@inquirer/prompts": "^8.3.2",
27
27
  "browserslist-to-esbuild": "^2.1.1",
28
28
  "consola": "^3.4.2",
29
- "esbuild": "^0.27.5",
29
+ "esbuild": "^0.27.7",
30
30
  "eslint": "^9.39.4",
31
31
  "glob": "^13.0.6",
32
32
  "jiti": "^2.6.1",
33
33
  "mime": "^4.1.0",
34
34
  "postcss": "^8.5.8",
35
- "sass": "^1.98.0",
35
+ "sass": "^1.99.0",
36
36
  "semver": "^7.7.4",
37
37
  "sharp": "^0.34.5",
38
38
  "ssh2": "^1.17.0",
39
39
  "typescript": "^5.9.3",
40
- "vite": "^7.3.1",
41
- "vite-plugin-pwa": "^1.2.0",
42
- "vite-tsconfig-paths": "^6.1.1",
43
- "yargs": "^18.0.0",
40
+ "vite": "^8.0.3",
44
41
  "vite-plugin-solid": "^2.11.11",
45
- "@simplysm/core-node": "14.0.16",
46
- "@simplysm/core-common": "14.0.16",
47
- "@simplysm/storage": "14.0.16"
42
+ "yargs": "^18.0.0",
43
+ "@simplysm/core-node": "14.0.17",
44
+ "@simplysm/core-common": "14.0.17",
45
+ "@simplysm/storage": "14.0.17"
48
46
  },
49
47
  "devDependencies": {
50
48
  "@types/semver": "^7.7.1",
@@ -1,3 +1,6 @@
1
+ import { createHash } from "crypto";
2
+ import fsp from "fs/promises";
3
+ import path from "path";
1
4
  import postcss from "postcss";
2
5
  import { compileScssFileAsync, compileScssStringAsync } from "../utils/scss-compiler.js";
3
6
 
@@ -6,6 +9,41 @@ export interface ClientTransformStylesheetOptions {
6
9
  postCssPlugins?: unknown[];
7
10
  scssErrors: string[];
8
11
  scssDependencies: Map<string, Set<string>>;
12
+ /** SCSS 캐시 디렉토리 (미지정 시 캐시 비활성화) */
13
+ cacheDir?: string;
14
+ }
15
+
16
+ interface ScssCacheEntry {
17
+ fileHash: string;
18
+ deps: Array<{ path: string; hash: string }>;
19
+ css: string;
20
+ }
21
+
22
+ function computeHash(content: string): string {
23
+ return createHash("sha256").update(content).digest("hex");
24
+ }
25
+
26
+ function cachePathFor(cacheDir: string, scssFilePath: string): string {
27
+ const pathHash = computeHash(scssFilePath).slice(0, 16);
28
+ return path.join(cacheDir, `${pathHash}.json`);
29
+ }
30
+
31
+ async function loadCacheEntry(cachePath: string): Promise<ScssCacheEntry | undefined> {
32
+ try {
33
+ const raw = await fsp.readFile(cachePath, "utf-8");
34
+ return JSON.parse(raw) as ScssCacheEntry;
35
+ } catch {
36
+ return undefined;
37
+ }
38
+ }
39
+
40
+ async function readFileHash(filePath: string): Promise<string | undefined> {
41
+ try {
42
+ const content = await fsp.readFile(filePath, "utf-8");
43
+ return computeHash(content);
44
+ } catch {
45
+ return undefined;
46
+ }
9
47
  }
10
48
 
11
49
  /**
@@ -19,7 +57,7 @@ export interface ClientTransformStylesheetOptions {
19
57
  export function createClientTransformStylesheet(
20
58
  options: ClientTransformStylesheetOptions,
21
59
  ): (data: string, containingFile: string, stylesheetFile?: string) => Promise<string | null> {
22
- const { loadPaths, postCssPlugins, scssErrors, scssDependencies } = options;
60
+ const { loadPaths, postCssPlugins, scssErrors, scssDependencies, cacheDir } = options;
23
61
 
24
62
  const postCssProcessor =
25
63
  postCssPlugins != null && postCssPlugins.length > 0
@@ -35,9 +73,73 @@ export function createClientTransformStylesheet(
35
73
  if (stylesheetFile != null) {
36
74
  if (stylesheetFile.endsWith(".scss")) {
37
75
  try {
76
+ if (cacheDir != null) {
77
+ const content = await fsp.readFile(stylesheetFile, "utf-8");
78
+ const fileHash = computeHash(content);
79
+ const cachePath = cachePathFor(cacheDir, stylesheetFile);
80
+ const cached = await loadCacheEntry(cachePath);
81
+
82
+ if (cached != null && cached.fileHash === fileHash) {
83
+ let allDepsMatch = true;
84
+ for (const dep of cached.deps) {
85
+ const currentHash = await readFileHash(dep.path);
86
+ if (currentHash !== dep.hash) {
87
+ allDepsMatch = false;
88
+ break;
89
+ }
90
+ }
91
+
92
+ if (allDepsMatch) {
93
+ if (cached.deps.length > 0) {
94
+ scssDependencies.set(stylesheetFile, new Set(cached.deps.map((d) => d.path)));
95
+ }
96
+ let css = cached.css;
97
+ if (postCssProcessor != null) {
98
+ css = (await postCssProcessor.process(css, { from: stylesheetFile })).css;
99
+ }
100
+ return css;
101
+ }
102
+ }
103
+
104
+ // 캐시 미스: compileScssStringAsync로 이중 읽기 회피 (D5)
105
+ const result = await compileScssStringAsync(content, stylesheetFile, loadPaths);
106
+
107
+ if (result.dependencies.length > 0) {
108
+ scssDependencies.set(stylesheetFile, new Set(result.dependencies));
109
+ }
110
+
111
+ const depHashes: Array<{ path: string; hash: string }> = [];
112
+ let allDepsHashed = true;
113
+ for (const depPath of result.dependencies) {
114
+ const depHash = await readFileHash(depPath);
115
+ if (depHash != null) {
116
+ depHashes.push({ path: depPath, hash: depHash });
117
+ } else {
118
+ allDepsHashed = false;
119
+ break;
120
+ }
121
+ }
122
+
123
+ if (allDepsHashed) {
124
+ const entry: ScssCacheEntry = { fileHash, deps: depHashes, css: result.css };
125
+ try {
126
+ await fsp.mkdir(cacheDir, { recursive: true });
127
+ await fsp.writeFile(cachePath, JSON.stringify(entry));
128
+ } catch {
129
+ // cache write failure — non-fatal
130
+ }
131
+ }
132
+
133
+ let css = result.css;
134
+ if (postCssProcessor != null) {
135
+ css = (await postCssProcessor.process(css, { from: stylesheetFile })).css;
136
+ }
137
+ return css;
138
+ }
139
+
140
+ // cacheDir 없음: 기존 동작
38
141
  const result = await compileScssFileAsync(stylesheetFile, loadPaths);
39
142
 
40
- // 의존성 수집
41
143
  if (result.dependencies.length > 0) {
42
144
  scssDependencies.set(stylesheetFile, new Set(result.dependencies));
43
145
  }
@@ -1,6 +1,8 @@
1
- import type { Plugin, ModuleNode, ViteDevServer } from "vite";
1
+ import type { Plugin, EnvironmentModuleNode, HotUpdateOptions, ViteDevServer } from "vite";
2
2
  import type { IncomingMessage, ServerResponse } from "http";
3
3
  import { JavaScriptTransformer } from "@angular/build/private";
4
+ import { createHash } from "crypto";
5
+ import fsp from "fs/promises";
4
6
  import os from "os";
5
7
  import path from "path";
6
8
  import ts from "typescript";
@@ -45,6 +47,25 @@ export interface SdAngularPluginOptions {
45
47
  browserslist?: string[];
46
48
  /** PostCSS 플러그인 배열 */
47
49
  postCssPlugins?: unknown[];
50
+ /** Linker 캐시 디렉토리 (기본값: {cwd}/.cache/linker/{sm|nosm}) */
51
+ linkerCacheDir?: string;
52
+ }
53
+
54
+ /**
55
+ * SCSS 의존성 역방향 탐색.
56
+ * 변경된 SCSS 파일을 @use하는 owner 파일(TS 또는 SCSS)을 찾는다.
57
+ */
58
+ export function findAffectedByScss(
59
+ normalizedScssPath: string,
60
+ scssDependencies: Map<string, Set<string>>,
61
+ ): string[] {
62
+ const affected: string[] = [];
63
+ for (const [ownerFile, deps] of scssDependencies) {
64
+ if (deps.has(normalizedScssPath)) {
65
+ affected.push(ownerFile);
66
+ }
67
+ }
68
+ return affected;
48
69
  }
49
70
 
50
71
  /**
@@ -114,6 +135,10 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
114
135
  enforce: "pre",
115
136
 
116
137
  config() {
138
+ const linkerCacheDir =
139
+ options.linkerCacheDir ??
140
+ path.join(process.cwd(), ".cache", "linker", enableSourcemap ? "sm" : "nosm");
141
+
117
142
  return {
118
143
  define: {
119
144
  ngDevMode: options.dev ? undefined : "false",
@@ -121,18 +146,37 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
121
146
  ngHmrMode: options.dev && !options.legacyModule ? undefined : "false",
122
147
  },
123
148
  optimizeDeps: {
124
- esbuildOptions: {
149
+ rolldownOptions: {
125
150
  plugins: [
126
151
  {
127
152
  name: "angular-vite-optimize-deps",
128
- setup(build: { onLoad: Function }) {
129
- build.onLoad(
130
- { filter: /\.[cm]?js$/ },
131
- async (args: { path: string }) => ({
132
- contents: await prebundleTransformer.transformFile(args.path),
133
- loader: "js" as const,
134
- }),
135
- );
153
+ async load(id: string) {
154
+ if (!/\.[cm]?js$/.test(id)) return null;
155
+
156
+ const content = await fsp.readFile(id, "utf-8");
157
+ const hash = createHash("sha256").update(content).digest("hex");
158
+ const cachePath = path.join(linkerCacheDir, `${hash}.js`);
159
+
160
+ try {
161
+ return await fsp.readFile(cachePath, "utf-8");
162
+ } catch {
163
+ // cache miss
164
+ }
165
+
166
+ const result = await prebundleTransformer.transformFile(id);
167
+ const resultStr =
168
+ typeof result === "string"
169
+ ? result
170
+ : new TextDecoder().decode(result);
171
+
172
+ try {
173
+ await fsp.mkdir(linkerCacheDir, { recursive: true });
174
+ await fsp.writeFile(cachePath, resultStr);
175
+ } catch {
176
+ // cache write failure — non-fatal
177
+ }
178
+
179
+ return resultStr;
136
180
  },
137
181
  },
138
182
  ],
@@ -165,6 +209,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
165
209
  postCssPlugins: options.postCssPlugins,
166
210
  scssErrors,
167
211
  scssDependencies,
212
+ cacheDir: path.join(workspaceRoot, ".cache", "scss"),
168
213
  });
169
214
 
170
215
  // externalStylesheets (client mode에서 stylesheet SHA256 ID 매핑)
@@ -236,16 +281,10 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
236
281
  });
237
282
  },
238
283
 
239
- async handleHotUpdate({
284
+ async hotUpdate({
240
285
  file,
241
286
  modules,
242
- }: {
243
- file: string;
244
- modules: ModuleNode[];
245
- server: ViteDevServer;
246
- timestamp: number;
247
- read: () => string | Promise<string>;
248
- }): Promise<ModuleNode[] | void> {
287
+ }: HotUpdateOptions): Promise<EnvironmentModuleNode[] | void> {
249
288
  if (compiler == null || !options.dev) return;
250
289
  if (
251
290
  !file.endsWith(".ts") &&
@@ -255,15 +294,25 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
255
294
  return;
256
295
  }
257
296
 
258
- // 의존성 필터: TypeScript program에 포함되지 않은 파일은 건너뜀
259
297
  const normalizedFile = pathx.posix(file);
260
- const programFiles = compiler.getTsProgram().getSourceFiles();
261
- const isInProgram = programFiles.some(
262
- (sf) => pathx.posix(sf.fileName) === normalizedFile,
263
- );
264
- if (!isInProgram) {
265
- logger.debug(`변경된 파일이 빌드에 포함되지 않아 리빌드 건너뜀: ${normalizedFile}`);
266
- return;
298
+ let filesToUpdate: string[];
299
+
300
+ if (file.endsWith(".scss")) {
301
+ // SCSS @use 의존성 역방향 탐색: 변경된 SCSS를 @use하는 파일을 찾아 재컴파일
302
+ const affectedOwnerFiles = findAffectedByScss(normalizedFile, scssDependencies);
303
+ if (affectedOwnerFiles.length === 0) return;
304
+ filesToUpdate = affectedOwnerFiles;
305
+ } else {
306
+ // 의존성 필터: TypeScript program에 포함되지 않은 파일은 건너뜀
307
+ const programFiles = compiler.getTsProgram().getSourceFiles();
308
+ const isInProgram = programFiles.some(
309
+ (sf) => pathx.posix(sf.fileName) === normalizedFile,
310
+ );
311
+ if (!isInProgram) {
312
+ logger.debug(`변경된 파일이 빌드에 포함되지 않아 리빌드 건너뜀: ${normalizedFile}`);
313
+ return;
314
+ }
315
+ filesToUpdate = [file];
267
316
  }
268
317
 
269
318
  // 경쟁 조건 방지: 이전 HMR 처리 완료 대기
@@ -280,7 +329,7 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
280
329
  // rebuild 시작 시 이전 templateUpdates 정리
281
330
  templateUpdates.clear();
282
331
 
283
- const updateResult = await compiler.update([file]);
332
+ const updateResult = await compiler.update(filesToUpdate);
284
333
 
285
334
  // templateUpdates 수집
286
335
  if (updateResult.templateUpdates != null) {
@@ -321,10 +370,22 @@ export function sdAngularPlugin(options: SdAngularPluginOptions): Plugin {
321
370
  lint: lintResult,
322
371
  });
323
372
 
324
- const affectedSet = new Set(affectedPaths);
325
- return modules.filter(
326
- (m) => m.file != null && affectedSet.has(pathx.posix(m.file)),
327
- );
373
+ if (file.endsWith(".scss")) {
374
+ // SCSS: moduleGraph에서 영향받은 TS 모듈 조회
375
+ const moduleGraph = this.environment.moduleGraph;
376
+ const result: EnvironmentModuleNode[] = [];
377
+ for (const p of affectedPaths) {
378
+ const mods = moduleGraph.getModulesByFile(p);
379
+ if (mods) result.push(...mods);
380
+ }
381
+ return result;
382
+ } else {
383
+ // TS/HTML: 전달받은 modules에서 영향받은 모듈 필터
384
+ const affectedSet = new Set(affectedPaths);
385
+ return modules.filter(
386
+ (m) => m.file != null && affectedSet.has(pathx.posix(m.file)),
387
+ );
388
+ }
328
389
  } catch (err) {
329
390
  const message = err instanceof Error ? err.message : String(err);
330
391
  logger.error(`HMR recompile failed: ${message}`);
@@ -6,19 +6,7 @@ import { createRequire } from "module";
6
6
  import { cpx, fsx, pathx } from "@simplysm/core-node";
7
7
  import { env } from "@simplysm/core-common";
8
8
  import { consola, LogLevels } from "consola";
9
- import type { SdCapacitorConfig } from "../sd-config.types.js";
10
-
11
- /**
12
- * package.json 타입
13
- */
14
- interface NpmConfig {
15
- name: string;
16
- version: string;
17
- dependencies?: Record<string, string>;
18
- devDependencies?: Record<string, string>;
19
- peerDependencies?: Record<string, string>;
20
- volta?: unknown;
21
- }
9
+ import type { NpmConfig, SdCapacitorConfig } from "../sd-config.types.js";
22
10
 
23
11
  /**
24
12
  * 설정 검증 에러
@@ -275,10 +263,6 @@ export class Capacitor {
275
263
  if (!(await fsx.exists(workspaceYamlPath))) {
276
264
  await fsx.write(workspaceYamlPath, "");
277
265
  }
278
- const lockfilePath = pathx.posixResolve(this._capPath, "pnpm-lock.yaml");
279
- if (!(await fsx.exists(lockfilePath))) {
280
- await fsx.write(lockfilePath, "");
281
- }
282
266
 
283
267
  // pnpm install + 빌드 스크립트 승인
284
268
  Capacitor._logger.debug("pnpm install 시작");
@@ -340,15 +324,15 @@ export class Capacitor {
340
324
 
341
325
  // 기본 의존성
342
326
  capNpmConf.dependencies = capNpmConf.dependencies ?? {};
343
- capNpmConf.dependencies["@capacitor/core"] = "^7.0.0";
344
- capNpmConf.dependencies["@capacitor/app"] = "^7.0.0";
327
+ capNpmConf.dependencies["@capacitor/core"] = "^7";
328
+ capNpmConf.dependencies["@capacitor/app"] = "^7";
345
329
  for (const platform of this._platforms) {
346
- capNpmConf.dependencies[`@capacitor/${platform}`] = "^7.0.0";
330
+ capNpmConf.dependencies[`@capacitor/${platform}`] = "^7";
347
331
  }
348
332
 
349
333
  capNpmConf.devDependencies = capNpmConf.devDependencies ?? {};
350
- capNpmConf.devDependencies["@capacitor/cli"] = "^7.0.0";
351
- capNpmConf.devDependencies["@capacitor/assets"] = "^3.0.0";
334
+ capNpmConf.devDependencies["@capacitor/cli"] = "^7";
335
+ capNpmConf.devDependencies["@capacitor/assets"] = "^3";
352
336
 
353
337
  // 플러그인 패키지 설정
354
338
  const mainDeps = {
@@ -640,15 +624,15 @@ export default config;
640
624
  */
641
625
  private async _findAndroidSdk(): Promise<string | undefined> {
642
626
  const androidHome =
643
- (env["ANDROID_HOME"] as string | undefined) ??
644
- (env["ANDROID_SDK_ROOT"] as string | undefined);
627
+ env("ANDROID_HOME") ??
628
+ env("ANDROID_SDK_ROOT");
645
629
  if (androidHome != null && (await fsx.exists(androidHome))) {
646
630
  return androidHome;
647
631
  }
648
632
 
649
633
  const candidates = [
650
- pathx.posixResolve((env["LOCALAPPDATA"] as string | undefined) ?? "", "Android/Sdk"),
651
- pathx.posixResolve((env["HOME"] as string | undefined) ?? "", "Android/Sdk"),
634
+ pathx.posixResolve(env("LOCALAPPDATA") ?? "", "Android/Sdk"),
635
+ pathx.posixResolve(env("HOME") ?? "", "Android/Sdk"),
652
636
  "C:/Program Files/Android/Sdk",
653
637
  "C:/Android/Sdk",
654
638
  ];
@@ -34,25 +34,22 @@ 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 cpx.spawn("pnpm", args, { cwd: process.cwd(), reject: false });
38
- const output = result.stdout + result.stderr;
37
+ const result = await cpx.spawn("pnpm", args, {
38
+ cwd: process.cwd(),
39
+ reject: false,
40
+ stdio: "inherit",
41
+ });
39
42
  const code = result.exitCode;
40
43
 
41
- const failMatch =
42
- output.match(/(\d+)\s+tests?\s+failed/i) ??
43
- output.match(/Tests\s+(\d+)\s+failed/i) ??
44
- output.match(/(\d+)\s+fail/i);
45
- const failCount = failMatch ? Number(failMatch[1]) : 0;
46
-
47
44
  logger.success("테스트 실행 완료");
48
- logger.info("테스트 완료", { errorCount: failCount, warningCount: 0 });
45
+ logger.info("테스트 완료", { errorCount: code === 0 ? 0 : 1, warningCount: 0 });
49
46
 
50
47
  return {
51
48
  name: "TEST",
52
49
  success: code === 0,
53
- errorCount: failCount,
50
+ errorCount: code === 0 ? 0 : 1,
54
51
  warningCount: 0,
55
- formattedOutput: code === 0 ? "" : output,
52
+ formattedOutput: "",
56
53
  };
57
54
  } catch (err) {
58
55
  logger.fail("테스트 실행 실패");
@@ -1,3 +1,6 @@
1
+ import fs from "node:fs";
2
+ import http from "node:http";
3
+ import path from "path";
1
4
  import { consola } from "consola";
2
5
  import { pathx } from "@simplysm/core-node";
3
6
  import { SdError } from "@simplysm/core-common";
@@ -61,9 +64,26 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
61
64
  if (typeof clientConfig.server === "number") {
62
65
  serverUrl = `http://localhost:${clientConfig.server}/${targetName}/`;
63
66
  } else {
64
- throw new SdError(
65
- `--url 옵션이 필요합니다. server가 패키지명으로 설정되어 있습니다: ${clientConfig.server}`,
66
- );
67
+ // server가 패키지명(string)인 경우: .dev-port 파일에서 포트 자동 탐지
68
+ const portFile = path.join(pkgDir, "dist", ".dev-port");
69
+ let portStr: string;
70
+ try {
71
+ portStr = fs.readFileSync(portFile, "utf-8").trim();
72
+ } catch {
73
+ throw new SdError(
74
+ "dev 서버가 실행 중이 아닙니다. 먼저 pnpm dev를 실행해주세요.",
75
+ );
76
+ }
77
+ const port = Number(portStr);
78
+ serverUrl = `http://localhost:${port}/${targetName}/`;
79
+
80
+ // HTTP 헬스체크
81
+ const alive = await checkDevServer(serverUrl);
82
+ if (!alive) {
83
+ throw new SdError(
84
+ "dev 서버가 응답하지 않습니다. pnpm dev를 다시 실행해주세요.",
85
+ );
86
+ }
67
87
  }
68
88
  }
69
89
 
@@ -82,3 +102,18 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
82
102
  throw new SdError(`${targetName}에 capacitor 또는 electron 설정이 없습니다.`);
83
103
  }
84
104
  }
105
+
106
+ /** dev 서버가 응답하는지 HTTP GET으로 확인한다. */
107
+ function checkDevServer(url: string): Promise<boolean> {
108
+ return new Promise((resolve) => {
109
+ const req = http.get(url, (res) => {
110
+ res.resume();
111
+ resolve(true);
112
+ });
113
+ req.on("error", () => resolve(false));
114
+ req.setTimeout(3000, () => {
115
+ req.destroy();
116
+ resolve(false);
117
+ });
118
+ });
119
+ }
@@ -2,8 +2,7 @@ import { ESLint } from "eslint";
2
2
  import { createJiti } from "jiti";
3
3
  import path from "path";
4
4
  import { fsx, pathx } from "@simplysm/core-node";
5
- import "@simplysm/core-common";
6
- import { SdError } from "@simplysm/core-common";
5
+ import { env, SdError } from "@simplysm/core-common";
7
6
  import { consola } from "consola";
8
7
 
9
8
  //#region Types
@@ -128,7 +127,7 @@ export async function executeLint(options: LintOptions): Promise<LintResult> {
128
127
 
129
128
  // TIMING 환경변수 설정
130
129
  if (timing) {
131
- process.env["TIMING"] = "1";
130
+ env("TIMING", "1");
132
131
  }
133
132
 
134
133
  // ESLint 설정 로드
@@ -61,7 +61,7 @@ function replaceEnvVariables(str: string, version: string, projectPath: string):
61
61
  if (envName === "PROJECT") {
62
62
  return projectPath;
63
63
  }
64
- return (env[envName] as string | undefined) ?? match;
64
+ return env(envName) ?? match;
65
65
  });
66
66
 
67
67
  // 치환되지 않은 환경변수가 남아있으면 에러 발생
@@ -147,7 +147,7 @@ async function ensureSshAuth(
147
147
  // 개인키 파싱 시도 (암호화 또는 형식 오류 시 Error 반환)
148
148
  const parsed = utils.parseKey(privateKeyData);
149
149
  const isKeyEncrypted = parsed instanceof Error;
150
- const sshAgent = process.env["SSH_AUTH_SOCK"];
150
+ const sshAgent = env("SSH_AUTH_SOCK");
151
151
 
152
152
  // 각 서버에 대해 키 인증 검증
153
153
  for (const [label, target] of sshTargets) {
@@ -189,7 +189,6 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
189
189
  logger.debug(`[${label}] 스택 트레이스:\n${stack}`);
190
190
  }
191
191
  return {
192
- success: false,
193
192
  build: {
194
193
  success: false,
195
194
  errors: [`[${label}] ${message}`],