@simplysm/sd-cli 14.0.15 โ†’ 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 (216) hide show
  1. package/README.md +4 -3
  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 +24 -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 +1 -1
  17. package/dist/commands/device.d.ts.map +1 -1
  18. package/dist/commands/device.js +61 -12
  19. package/dist/commands/device.js.map +1 -1
  20. package/dist/commands/lint.d.ts +0 -1
  21. package/dist/commands/lint.d.ts.map +1 -1
  22. package/dist/commands/lint.js +2 -3
  23. package/dist/commands/lint.js.map +1 -1
  24. package/dist/commands/publish.js +3 -3
  25. package/dist/commands/publish.js.map +1 -1
  26. package/dist/commands/replace-deps.js +1 -1
  27. package/dist/commands/replace-deps.js.map +1 -1
  28. package/dist/commands/typecheck.d.ts.map +1 -1
  29. package/dist/commands/typecheck.js +1 -2
  30. package/dist/commands/typecheck.js.map +1 -1
  31. package/dist/electron/electron.d.ts +3 -2
  32. package/dist/electron/electron.d.ts.map +1 -1
  33. package/dist/electron/electron.js +54 -31
  34. package/dist/electron/electron.js.map +1 -1
  35. package/dist/engines/BaseEngine.js +1 -1
  36. package/dist/engines/BaseEngine.js.map +1 -1
  37. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  38. package/dist/engines/NgtscEngine.js +0 -1
  39. package/dist/engines/NgtscEngine.js.map +1 -1
  40. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  41. package/dist/engines/ServerEsbuildEngine.js +0 -1
  42. package/dist/engines/ServerEsbuildEngine.js.map +1 -1
  43. package/dist/engines/TscEngine.d.ts.map +1 -1
  44. package/dist/engines/TscEngine.js +0 -1
  45. package/dist/engines/TscEngine.js.map +1 -1
  46. package/dist/engines/ViteEngine.d.ts.map +1 -1
  47. package/dist/engines/ViteEngine.js +10 -1
  48. package/dist/engines/ViteEngine.js.map +1 -1
  49. package/dist/engines/index.d.ts +0 -10
  50. package/dist/engines/index.d.ts.map +1 -1
  51. package/dist/engines/index.js +0 -5
  52. package/dist/engines/index.js.map +1 -1
  53. package/dist/engines/types.d.ts +0 -1
  54. package/dist/engines/types.d.ts.map +1 -1
  55. package/dist/infra/SignalHandler.d.ts +1 -6
  56. package/dist/infra/SignalHandler.d.ts.map +1 -1
  57. package/dist/infra/SignalHandler.js +4 -13
  58. package/dist/infra/SignalHandler.js.map +1 -1
  59. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  60. package/dist/orchestrators/BuildOrchestrator.js +7 -12
  61. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  62. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  63. package/dist/orchestrators/DevWatchOrchestrator.js +18 -11
  64. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  65. package/dist/sd-cli-entry.d.ts +0 -1
  66. package/dist/sd-cli-entry.d.ts.map +1 -1
  67. package/dist/sd-cli-entry.js +13 -16
  68. package/dist/sd-cli-entry.js.map +1 -1
  69. package/dist/sd-cli.js +1 -1
  70. package/dist/sd-cli.js.map +1 -1
  71. package/dist/sd-config.types.d.ts +12 -2
  72. package/dist/sd-config.types.d.ts.map +1 -1
  73. package/dist/utils/angular-compiler.d.ts.map +1 -1
  74. package/dist/utils/angular-compiler.js +20 -13
  75. package/dist/utils/angular-compiler.js.map +1 -1
  76. package/dist/utils/esbuild-config.d.ts +1 -1
  77. package/dist/utils/esbuild-config.d.ts.map +1 -1
  78. package/dist/utils/esbuild-config.js +1 -4
  79. package/dist/utils/esbuild-config.js.map +1 -1
  80. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  81. package/dist/utils/ngtsc-build-core.js +3 -0
  82. package/dist/utils/ngtsc-build-core.js.map +1 -1
  83. package/dist/utils/orchestrator-utils.js +1 -1
  84. package/dist/utils/orchestrator-utils.js.map +1 -1
  85. package/dist/utils/tsc-build.d.ts +5 -0
  86. package/dist/utils/tsc-build.d.ts.map +1 -1
  87. package/dist/utils/tsc-build.js +2 -1
  88. package/dist/utils/tsc-build.js.map +1 -1
  89. package/dist/utils/vite-config.d.ts +1 -1
  90. package/dist/utils/vite-config.d.ts.map +1 -1
  91. package/dist/utils/vite-config.js +22 -53
  92. package/dist/utils/vite-config.js.map +1 -1
  93. package/dist/utils/vite-pwa-plugin.d.ts +9 -0
  94. package/dist/utils/vite-pwa-plugin.d.ts.map +1 -0
  95. package/dist/utils/vite-pwa-plugin.js +139 -0
  96. package/dist/utils/vite-pwa-plugin.js.map +1 -0
  97. package/dist/utils/worker-utils.d.ts +2 -5
  98. package/dist/utils/worker-utils.d.ts.map +1 -1
  99. package/dist/utils/worker-utils.js +5 -11
  100. package/dist/utils/worker-utils.js.map +1 -1
  101. package/dist/workers/client.worker.d.ts.map +1 -1
  102. package/dist/workers/client.worker.js +9 -3
  103. package/dist/workers/client.worker.js.map +1 -1
  104. package/dist/workers/library-build.worker.d.ts.map +1 -1
  105. package/dist/workers/library-build.worker.js +6 -2
  106. package/dist/workers/library-build.worker.js.map +1 -1
  107. package/dist/workers/ngtsc-build.worker.js +2 -2
  108. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  109. package/dist/workers/server-build.worker.d.ts.map +1 -1
  110. package/dist/workers/server-build.worker.js +6 -2
  111. package/dist/workers/server-build.worker.js.map +1 -1
  112. package/dist/workers/server-runtime.worker.js +4 -4
  113. package/dist/workers/server-runtime.worker.js.map +1 -1
  114. package/docs/config.md +30 -2
  115. package/docs/pwa-configuration-types.md +1 -1
  116. package/package.json +8 -10
  117. package/src/angular/client-transform-stylesheet.ts +104 -2
  118. package/src/angular/vite-angular-plugin.ts +92 -31
  119. package/src/capacitor/capacitor.ts +25 -26
  120. package/src/commands/check.ts +8 -11
  121. package/src/commands/device.ts +71 -17
  122. package/src/commands/lint.ts +2 -3
  123. package/src/commands/publish.ts +3 -3
  124. package/src/commands/replace-deps.ts +1 -1
  125. package/src/commands/typecheck.ts +1 -2
  126. package/src/electron/electron.ts +62 -43
  127. package/src/engines/BaseEngine.ts +1 -1
  128. package/src/engines/NgtscEngine.ts +0 -1
  129. package/src/engines/ServerEsbuildEngine.ts +0 -1
  130. package/src/engines/TscEngine.ts +0 -1
  131. package/src/engines/ViteEngine.ts +9 -1
  132. package/src/engines/index.ts +0 -10
  133. package/src/engines/types.ts +0 -1
  134. package/src/infra/SignalHandler.ts +4 -14
  135. package/src/orchestrators/BuildOrchestrator.ts +7 -9
  136. package/src/orchestrators/DevWatchOrchestrator.ts +22 -10
  137. package/src/sd-cli-entry.ts +17 -24
  138. package/src/sd-cli.ts +1 -1
  139. package/src/sd-config.types.ts +13 -2
  140. package/src/utils/angular-compiler.ts +21 -21
  141. package/src/utils/esbuild-config.ts +2 -5
  142. package/src/utils/ngtsc-build-core.ts +7 -0
  143. package/src/utils/orchestrator-utils.ts +1 -1
  144. package/src/utils/tsc-build.ts +7 -0
  145. package/src/utils/vite-config.ts +23 -55
  146. package/src/utils/vite-pwa-plugin.ts +168 -0
  147. package/src/utils/worker-utils.ts +5 -11
  148. package/src/workers/client.worker.ts +11 -3
  149. package/src/workers/library-build.worker.ts +6 -2
  150. package/src/workers/ngtsc-build.worker.ts +2 -2
  151. package/src/workers/server-build.worker.ts +7 -2
  152. package/src/workers/server-runtime.worker.ts +4 -4
  153. package/tests/angular/client-transform-stylesheet.spec.ts +43 -0
  154. package/tests/angular/find-affected-by-scss.spec.ts +37 -0
  155. package/tests/angular/fixtures/basic-app/scss/_colors.scss +1 -0
  156. package/tests/angular/fixtures/basic-app/scss/_variables.scss +3 -0
  157. package/tests/angular/fixtures/basic-app/src/styled.component.ts +14 -0
  158. package/tests/angular/linker-disk-cache.spec.ts +158 -0
  159. package/tests/angular/scss-disk-cache.spec.ts +162 -0
  160. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +15 -15
  161. package/tests/angular/vite-angular-plugin-hmr.spec.ts +9 -9
  162. package/tests/angular/vite-angular-plugin-lint.spec.ts +4 -4
  163. package/tests/angular/vite-angular-plugin-scss-hmr.spec.ts +87 -0
  164. package/tests/angular/vite-angular-plugin.spec.ts +15 -15
  165. package/tests/capacitor/capacitor-icon.spec.ts +2 -4
  166. package/tests/capacitor/capacitor-init.spec.ts +2 -4
  167. package/tests/capacitor/capacitor-workspace.spec.ts +2 -4
  168. package/tests/commands/device.spec.ts +108 -8
  169. package/tests/commands/publish.spec.ts +2 -2
  170. package/tests/commands/typecheck.spec.ts +1 -1
  171. package/tests/electron/electron.spec.ts +24 -17
  172. package/tests/engines/ngtsc-engine.spec.ts +0 -3
  173. package/tests/engines/server-esbuild-engine.spec.ts +0 -3
  174. package/tests/engines/tsc-engine.spec.ts +1 -2
  175. package/tests/engines/vite-engine.spec.ts +0 -2
  176. package/tests/infra/signal-handler.spec.ts +1 -12
  177. package/tests/orchestrators/build-orchestrator.spec.ts +1 -7
  178. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +24 -66
  179. package/tests/utils/angular-compiler.spec.ts +1396 -32
  180. package/tests/utils/esbuild-config.spec.ts +4 -7
  181. package/tests/utils/{ngtsc-build-core-angular-compiler.spec.ts โ†’ ngtsc-build-core.spec.ts} +142 -11
  182. package/tests/utils/orchestrator-utils.spec.ts +2 -2
  183. package/tests/utils/sd-config.spec.ts +2 -2
  184. package/tests/utils/tsc-build.spec.ts +4 -1
  185. package/tests/utils/vite-config.spec.ts +130 -261
  186. package/tests/utils/vite-pwa-plugin.acc.spec.ts +143 -0
  187. package/tests/utils/vite-pwa-plugin.spec.ts +350 -0
  188. package/tests/utils/worker-utils.spec.ts +8 -7
  189. package/tests/workers/client-worker.spec.ts +50 -1
  190. package/tests/workers/dev-port-file.verify.md +6 -0
  191. package/tests/workers/library-build-lint.spec.ts +1 -1
  192. package/tests/workers/library-build-worker.spec.ts +1 -1
  193. package/tests/workers/ngtsc-build-lint.spec.ts +1 -1
  194. package/tests/workers/server-build-lint.spec.ts +1 -1
  195. package/tests/workers/server-build-worker.spec.ts +1 -1
  196. package/tests/workers/server-runtime-worker.spec.ts +8 -1
  197. package/dist/infra/WorkerManager.d.ts +0 -40
  198. package/dist/infra/WorkerManager.d.ts.map +0 -1
  199. package/dist/infra/WorkerManager.js +0 -59
  200. package/dist/infra/WorkerManager.js.map +0 -1
  201. package/dist/utils/SdCliReporter.d.ts +0 -18
  202. package/dist/utils/SdCliReporter.d.ts.map +0 -1
  203. package/dist/utils/SdCliReporter.js +0 -144
  204. package/dist/utils/SdCliReporter.js.map +0 -1
  205. package/src/infra/WorkerManager.ts +0 -65
  206. package/src/utils/SdCliReporter.ts +0 -177
  207. package/tests/angular/scss-compiler-async.spec.ts +0 -54
  208. package/tests/commands/dev.spec.ts +0 -53
  209. package/tests/commands/watch.spec.ts +0 -53
  210. package/tests/infra/worker-manager.spec.ts +0 -63
  211. package/tests/utils/angular-compiler-emit.spec.ts +0 -570
  212. package/tests/utils/angular-compiler-init.spec.ts +0 -705
  213. package/tests/utils/angular-compiler-update.spec.ts +0 -293
  214. package/tests/utils/build-env.spec.ts +0 -33
  215. package/tests/utils/ngtsc-build-core-transform-stylesheet.spec.ts +0 -124
  216. package/tests/utils/ngtsc-scss-refactor.spec.ts +0 -47
@@ -1,12 +1,12 @@
1
1
  import { createWorker } from "@simplysm/core-node";
2
- import { err as errNs } from "@simplysm/core-common";
2
+ import { env, err as errNs } from "@simplysm/core-common";
3
3
  import { consola } from "consola";
4
4
  import proxy from "@fastify/http-proxy";
5
5
  import net from "net";
6
6
  import { pathToFileURL } from "url";
7
- import { registerCleanupHandlers, applyDebugLevel } from "../utils/worker-utils.js";
7
+ import { registerCleanupHandlers, setupWorkerConsola } from "../utils/worker-utils.js";
8
8
  //#endregion
9
- applyDebugLevel();
9
+ setupWorkerConsola();
10
10
  const logger = consola.withTag("sd:cli:server-runtime:worker");
11
11
  /** ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค (์ •๋ฆฌ ๋Œ€์ƒ) */
12
12
  let serverInstance;
@@ -74,7 +74,7 @@ async function start(info) {
74
74
  // main.js import ์ „์— ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ process.env์— ์ฃผ์ž…
75
75
  if (info.env != null) {
76
76
  for (const [key, value] of Object.entries(info.env)) {
77
- process.env[key] = value;
77
+ env(key, value);
78
78
  }
79
79
  }
80
80
  // main.js import (์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค๋ฅผ exportํ•ด์•ผ ํ•จ)
@@ -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":"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"}
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).
@@ -41,6 +67,7 @@ Configuration for client (Angular/Vite) packages.
41
67
  ```typescript
42
68
  interface SdClientPackageConfig {
43
69
  target: "client";
70
+ framework?: "angular" | "solid";
44
71
  server: string | number;
45
72
  env?: Record<string, string>;
46
73
  publish?: SdPublishConfig;
@@ -56,6 +83,7 @@ interface SdClientPackageConfig {
56
83
  | Field | Type | Description |
57
84
  |-------|------|-------------|
58
85
  | `target` | `"client"` | Fixed value |
86
+ | `framework` | `"angular" \| "solid"` | Client framework selection. Defaults to `"angular"` when not specified |
59
87
  | `server` | `string \| number` | Server package name to connect to (e.g., `"solid-demo-server"`), or Vite port number (backward compatibility) |
60
88
  | `env` | `Record<string, string>` | Environment variables to substitute during build (replaces `process.env` with object) |
61
89
  | `publish` | `SdPublishConfig` | Publish configuration |
@@ -173,7 +201,7 @@ Parameters passed to the `sd.config.ts` function.
173
201
  interface SdConfigParams {
174
202
  cwd: string;
175
203
  dev: boolean;
176
- options: string[];
204
+ opt: string[];
177
205
  }
178
206
  ```
179
207
 
@@ -181,7 +209,7 @@ interface SdConfigParams {
181
209
  |-------|------|-------------|
182
210
  | `cwd` | `string` | Current working directory |
183
211
  | `dev` | `boolean` | Development mode flag |
184
- | `options` | `string[]` | Additional options (from CLI's `-o` flag) |
212
+ | `opt` | `string[]` | Additional options (from CLI's `-o` flag) |
185
213
 
186
214
  ## `SdConfigFn`
187
215
 
@@ -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.15",
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.15",
46
- "@simplysm/storage": "14.0.15",
47
- "@simplysm/core-common": "14.0.15"
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
  ];
@@ -860,6 +844,21 @@ export default config;
860
844
  await this._updateServerUrl(url);
861
845
 
862
846
  for (const platform of this._platforms) {
847
+ // Android + localhost URL์ด๋ฉด adb reverse๋กœ ํฌํŠธ ํฌ์›Œ๋”ฉ
848
+ if (platform === "android") {
849
+ const urlObj = new URL(url);
850
+ if (urlObj.hostname === "localhost" || urlObj.hostname === "127.0.0.1") {
851
+ const port = urlObj.port || (urlObj.protocol === "https:" ? "443" : "80");
852
+ Capacitor._logger.debug(`[${platform}] adb reverse tcp:${port} ์„ค์ •`);
853
+ try {
854
+ await this._exec("adb", ["reverse", `tcp:${port}`, `tcp:${port}`], this._capPath);
855
+ } catch (err) {
856
+ const errMsg = err instanceof Error ? err.message : String(err);
857
+ Capacitor._logger.warn(`adb reverse ์‹คํŒจ โ€” USB ์—ฐ๊ฒฐ์„ ํ™•์ธํ•˜์„ธ์š”: ${errMsg}`);
858
+ }
859
+ }
860
+ }
861
+
863
862
  Capacitor._logger.debug(`[${platform}] cap copy ์‹œ์ž‘`);
864
863
  await this._execCap(["copy", platform]);
865
864
  Capacitor._logger.debug(`[${platform}] cap copy ์™„๋ฃŒ`);
@@ -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("ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹คํŒจ");