@simplysm/sd-cli 13.0.75 → 13.0.77

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 (167) hide show
  1. package/README.md +341 -16
  2. package/dist/builders/DtsBuilder.js +2 -2
  3. package/dist/builders/DtsBuilder.js.map +1 -1
  4. package/dist/builders/LibraryBuilder.d.ts +3 -3
  5. package/dist/builders/LibraryBuilder.d.ts.map +1 -1
  6. package/dist/builders/LibraryBuilder.js +2 -2
  7. package/dist/builders/LibraryBuilder.js.map +1 -1
  8. package/dist/builders/types.d.ts +7 -1
  9. package/dist/builders/types.d.ts.map +1 -1
  10. package/dist/capacitor/capacitor.d.ts +5 -0
  11. package/dist/capacitor/capacitor.d.ts.map +1 -1
  12. package/dist/capacitor/capacitor.js +59 -59
  13. package/dist/capacitor/capacitor.js.map +1 -1
  14. package/dist/commands/check.js +4 -4
  15. package/dist/commands/check.js.map +1 -1
  16. package/dist/commands/device.js +3 -3
  17. package/dist/commands/device.js.map +1 -1
  18. package/dist/commands/lint.d.ts +2 -2
  19. package/dist/commands/lint.d.ts.map +1 -1
  20. package/dist/commands/lint.js +4 -98
  21. package/dist/commands/lint.js.map +1 -1
  22. package/dist/commands/publish.js +20 -20
  23. package/dist/commands/publish.js.map +1 -1
  24. package/dist/commands/replace-deps.js +1 -1
  25. package/dist/commands/replace-deps.js.map +1 -1
  26. package/dist/commands/typecheck.js +9 -9
  27. package/dist/commands/typecheck.js.map +1 -1
  28. package/dist/electron/electron.js +16 -16
  29. package/dist/electron/electron.js.map +1 -1
  30. package/dist/orchestrators/BuildOrchestrator.js +6 -6
  31. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  32. package/dist/orchestrators/DevOrchestrator.d.ts +7 -6
  33. package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
  34. package/dist/orchestrators/DevOrchestrator.js +157 -203
  35. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  36. package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
  37. package/dist/orchestrators/WatchOrchestrator.js +3 -4
  38. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  39. package/dist/sd-cli.js +1 -1
  40. package/dist/sd-cli.js.map +1 -1
  41. package/dist/sd-config.types.d.ts +9 -3
  42. package/dist/sd-config.types.d.ts.map +1 -1
  43. package/dist/utils/copy-public.d.ts.map +1 -1
  44. package/dist/utils/copy-public.js +23 -27
  45. package/dist/utils/copy-public.js.map +1 -1
  46. package/dist/utils/copy-src.d.ts.map +1 -1
  47. package/dist/utils/copy-src.js +7 -7
  48. package/dist/utils/copy-src.js.map +1 -1
  49. package/dist/utils/esbuild-config.d.ts.map +1 -1
  50. package/dist/utils/esbuild-config.js +36 -42
  51. package/dist/utils/esbuild-config.js.map +1 -1
  52. package/dist/utils/replace-deps.js +7 -7
  53. package/dist/utils/replace-deps.js.map +1 -1
  54. package/dist/utils/sd-config.js +2 -2
  55. package/dist/utils/sd-config.js.map +1 -1
  56. package/dist/utils/template.js +7 -7
  57. package/dist/utils/template.js.map +1 -1
  58. package/dist/utils/tsconfig.d.ts +1 -2
  59. package/dist/utils/tsconfig.d.ts.map +1 -1
  60. package/dist/utils/tsconfig.js +5 -8
  61. package/dist/utils/tsconfig.js.map +1 -1
  62. package/dist/utils/typecheck-serialization.js +2 -2
  63. package/dist/utils/typecheck-serialization.js.map +1 -1
  64. package/dist/utils/vite-config.d.ts +2 -0
  65. package/dist/utils/vite-config.d.ts.map +1 -1
  66. package/dist/utils/vite-config.js +36 -3
  67. package/dist/utils/vite-config.js.map +1 -1
  68. package/dist/utils/worker-events.d.ts +11 -1
  69. package/dist/utils/worker-events.d.ts.map +1 -1
  70. package/dist/utils/worker-events.js +3 -5
  71. package/dist/utils/worker-events.js.map +1 -1
  72. package/dist/utils/worker-utils.d.ts +2 -2
  73. package/dist/utils/worker-utils.d.ts.map +1 -1
  74. package/dist/utils/worker-utils.js +1 -1
  75. package/dist/utils/worker-utils.js.map +1 -1
  76. package/dist/workers/client.worker.d.ts +1 -1
  77. package/dist/workers/client.worker.js +3 -3
  78. package/dist/workers/client.worker.js.map +1 -1
  79. package/dist/workers/dts.worker.d.ts +1 -1
  80. package/dist/workers/dts.worker.d.ts.map +1 -1
  81. package/dist/workers/dts.worker.js +13 -28
  82. package/dist/workers/dts.worker.js.map +1 -1
  83. package/dist/workers/library.worker.d.ts +1 -1
  84. package/dist/workers/library.worker.js +4 -4
  85. package/dist/workers/library.worker.js.map +1 -1
  86. package/dist/workers/lint.worker.d.ts +1 -1
  87. package/dist/workers/server-runtime.worker.d.ts +1 -1
  88. package/dist/workers/server-runtime.worker.js +4 -4
  89. package/dist/workers/server-runtime.worker.js.map +1 -1
  90. package/dist/workers/server.worker.d.ts +1 -1
  91. package/dist/workers/server.worker.js +6 -6
  92. package/dist/workers/server.worker.js.map +1 -1
  93. package/package.json +4 -5
  94. package/src/builders/DtsBuilder.ts +2 -2
  95. package/src/builders/LibraryBuilder.ts +7 -10
  96. package/src/builders/types.ts +6 -1
  97. package/src/capacitor/capacitor.ts +61 -60
  98. package/src/commands/check.ts +4 -4
  99. package/src/commands/device.ts +3 -3
  100. package/src/commands/lint.ts +6 -117
  101. package/src/commands/publish.ts +20 -20
  102. package/src/commands/replace-deps.ts +1 -1
  103. package/src/commands/typecheck.ts +9 -9
  104. package/src/electron/electron.ts +16 -16
  105. package/src/orchestrators/BuildOrchestrator.ts +6 -6
  106. package/src/orchestrators/DevOrchestrator.ts +210 -256
  107. package/src/orchestrators/WatchOrchestrator.ts +8 -10
  108. package/src/sd-cli.ts +1 -1
  109. package/src/sd-config.types.ts +10 -3
  110. package/src/utils/copy-public.ts +22 -26
  111. package/src/utils/copy-src.ts +7 -7
  112. package/src/utils/esbuild-config.ts +51 -63
  113. package/src/utils/replace-deps.ts +7 -7
  114. package/src/utils/sd-config.ts +2 -2
  115. package/src/utils/template.ts +7 -7
  116. package/src/utils/tsconfig.ts +6 -10
  117. package/src/utils/typecheck-serialization.ts +2 -2
  118. package/src/utils/vite-config.ts +376 -341
  119. package/src/utils/worker-events.ts +13 -10
  120. package/src/utils/worker-utils.ts +45 -45
  121. package/src/workers/client.worker.ts +3 -3
  122. package/src/workers/dts.worker.ts +451 -467
  123. package/src/workers/library.worker.ts +4 -4
  124. package/src/workers/server-runtime.worker.ts +4 -4
  125. package/src/workers/server.worker.ts +572 -572
  126. package/templates/init/package.json.hbs +2 -3
  127. package/templates/init/packages/client-admin/package.json.hbs +5 -5
  128. package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +2 -2
  129. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +86 -105
  130. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +1 -1
  131. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +4 -12
  132. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +0 -2
  133. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +1 -1
  134. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +1 -1
  135. package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +36 -43
  136. package/templates/init/packages/db-main/package.json.hbs +2 -2
  137. package/templates/init/packages/server/package.json.hbs +4 -4
  138. package/templates/init/tests/e2e/package.json.hbs +1 -1
  139. package/tests/get-compiler-options-for-package.spec.ts +13 -72
  140. package/tests/get-package-source-files.spec.ts +0 -42
  141. package/tests/get-types-from-package-json.spec.ts +15 -30
  142. package/tests/infra/ResultCollector.spec.ts +0 -9
  143. package/tests/infra/WorkerManager.spec.ts +0 -34
  144. package/tests/load-ignore-patterns.spec.ts +15 -40
  145. package/tests/load-sd-config.spec.ts +16 -53
  146. package/tests/publish-config-narrowing.spec.ts +20 -0
  147. package/tests/run-lint.spec.ts +38 -87
  148. package/tests/run-typecheck.spec.ts +194 -303
  149. package/tests/run-watch.spec.ts +0 -34
  150. package/tests/sd-cli.spec.ts +0 -88
  151. package/tests/sd-public-dev-plugin-mime.spec.ts +19 -0
  152. package/dist/builders/index.d.ts +0 -5
  153. package/dist/builders/index.d.ts.map +0 -1
  154. package/dist/builders/index.js +0 -5
  155. package/dist/builders/index.js.map +0 -6
  156. package/dist/infra/index.d.ts +0 -4
  157. package/dist/infra/index.d.ts.map +0 -1
  158. package/dist/infra/index.js +0 -4
  159. package/dist/infra/index.js.map +0 -6
  160. package/dist/orchestrators/index.d.ts +0 -4
  161. package/dist/orchestrators/index.d.ts.map +0 -1
  162. package/dist/orchestrators/index.js +0 -4
  163. package/dist/orchestrators/index.js.map +0 -6
  164. package/src/builders/index.ts +0 -4
  165. package/src/infra/index.ts +0 -3
  166. package/src/orchestrators/index.ts +0 -3
  167. package/templates/init/stylelint.config.ts +0 -1
@@ -49,21 +49,25 @@ vi.mock("@simplysm/core-node", () => {
49
49
  });
50
50
 
51
51
  return {
52
- fsExists: vi.fn(),
53
- fsExistsSync: vi.fn(() => false),
54
- fsReadJson: vi.fn(),
55
- fsReadSync: vi.fn(() => ""),
56
- pathPosix: vi.fn(posix),
57
- pathIsChildPath: vi.fn(isChildPath),
58
- pathFilterByTargets: vi.fn((files: string[], targets: string[], cwd: string) => {
59
- if (targets.length === 0) return files;
60
- return files.filter((file) => {
61
- const relativePath = posix(file.replace(cwd + "/", ""));
62
- return targets.some(
63
- (target) => relativePath === target || isChildPath(relativePath, target),
64
- );
65
- });
66
- }),
52
+ fsx: {
53
+ exists: vi.fn(),
54
+ existsSync: vi.fn(() => false),
55
+ readJson: vi.fn(),
56
+ readSync: vi.fn(() => ""),
57
+ },
58
+ pathx: {
59
+ posix: vi.fn(posix),
60
+ isChildPath: vi.fn(isChildPath),
61
+ filterByTargets: vi.fn((files: string[], targets: string[], cwd: string) => {
62
+ if (targets.length === 0) return files;
63
+ return files.filter((file) => {
64
+ const relativePath = posix(file.replace(cwd + "/", ""));
65
+ return targets.some(
66
+ (target) => relativePath === target || isChildPath(relativePath, target),
67
+ );
68
+ });
69
+ }),
70
+ },
67
71
  Worker: {
68
72
  create: vi.fn(() => createMockWorkerProxy()),
69
73
  },
@@ -98,9 +102,40 @@ vi.mock("jiti", () => ({
98
102
 
99
103
  import path from "path";
100
104
  import ts from "typescript";
101
- import { fsExists, fsReadJson } from "@simplysm/core-node";
105
+ import { fsx } from "@simplysm/core-node";
102
106
  import { runTypecheck } from "../src/commands/typecheck";
103
107
 
108
+ /**
109
+ * Create mock parsed tsconfig
110
+ */
111
+ function createMockParsedCommandLine(overrides: Partial<ts.ParsedCommandLine> = {}): ts.ParsedCommandLine {
112
+ return {
113
+ options: {},
114
+ fileNames: [],
115
+ errors: [],
116
+ ...overrides,
117
+ } as ts.ParsedCommandLine;
118
+ }
119
+
120
+ /**
121
+ * Create mock diagnostic array
122
+ */
123
+ function createMockDiagnosticArray(diagnostics: ts.Diagnostic[] = []): ts.SortedReadonlyArray<ts.Diagnostic> {
124
+ return ts.sortAndDeduplicateDiagnostics(diagnostics);
125
+ }
126
+
127
+ /**
128
+ * Create mock Worker
129
+ */
130
+ function createMockWorker<T extends Record<string, unknown>>(overrides?: Partial<T>): any {
131
+ return {
132
+ on: vi.fn(),
133
+ send: vi.fn(),
134
+ terminate: vi.fn().mockResolvedValue(undefined),
135
+ ...overrides,
136
+ };
137
+ }
138
+
104
139
  describe("runTypecheck", () => {
105
140
  let originalExitCode: typeof process.exitCode;
106
141
  let originalCwd: () => string;
@@ -123,11 +158,13 @@ describe("runTypecheck", () => {
123
158
  config: {},
124
159
  });
125
160
 
126
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
127
- options: { lib: ["ES2024"], types: [] },
128
- fileNames: [],
129
- errors: [],
130
- } as unknown as ts.ParsedCommandLine);
161
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
162
+ createMockParsedCommandLine({
163
+ options: { lib: ["ES2024"], types: [] },
164
+ fileNames: [],
165
+ errors: [],
166
+ }),
167
+ );
131
168
 
132
169
  await runTypecheck({ targets: [], options: [] });
133
170
 
@@ -154,11 +191,13 @@ describe("runTypecheck", () => {
154
191
  config: {},
155
192
  });
156
193
 
157
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
158
- options: {},
159
- fileNames: [],
160
- errors: [{ category: ts.DiagnosticCategory.Error, messageText: "Parse error" }],
161
- } as unknown as ts.ParsedCommandLine);
194
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
195
+ createMockParsedCommandLine({
196
+ options: {},
197
+ fileNames: [],
198
+ errors: [{ category: ts.DiagnosticCategory.Error, messageText: "Parse error", code: 0, file: undefined, start: undefined, length: undefined } as ts.Diagnostic],
199
+ }),
200
+ );
162
201
 
163
202
  vi.mocked(ts.formatDiagnosticsWithColorAndContext).mockReturnValue("");
164
203
 
@@ -172,21 +211,23 @@ describe("runTypecheck", () => {
172
211
  config: {},
173
212
  });
174
213
 
175
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
176
- options: { lib: ["ES2024"], types: [] },
177
- fileNames: [
178
- "/project/packages/core-common/src/index.ts",
179
- "/project/packages/core-node/src/index.ts",
180
- "/project/packages/cli/src/index.ts",
181
- ],
182
- errors: [],
183
- } as unknown as ts.ParsedCommandLine);
214
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
215
+ createMockParsedCommandLine({
216
+ options: { lib: ["ES2024"], types: [] },
217
+ fileNames: [
218
+ "/project/packages/core-common/src/index.ts",
219
+ "/project/packages/core-node/src/index.ts",
220
+ "/project/packages/cli/src/index.ts",
221
+ ],
222
+ errors: [],
223
+ }),
224
+ );
184
225
 
185
- vi.mocked(fsExists).mockResolvedValue(false);
186
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
226
+ vi.mocked(fsx.exists).mockResolvedValue(false);
227
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
187
228
 
188
229
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
189
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
230
+ createMockDiagnosticArray([]),
190
231
  );
191
232
 
192
233
  await runTypecheck({
@@ -203,19 +244,21 @@ describe("runTypecheck", () => {
203
244
  config: {},
204
245
  });
205
246
 
206
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
207
- options: { lib: ["ES2024"], types: [] },
208
- fileNames: [
209
- "/project/packages/core-common/src/index.ts",
210
- "/project/packages/core-common/tests/utils.spec.ts",
211
- "/project/packages/core-node/src/index.ts",
212
- "/project/packages/cli/src/index.ts",
213
- ],
214
- errors: [],
215
- } as unknown as ts.ParsedCommandLine);
247
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
248
+ createMockParsedCommandLine({
249
+ options: { lib: ["ES2024"], types: [] },
250
+ fileNames: [
251
+ "/project/packages/core-common/src/index.ts",
252
+ "/project/packages/core-common/tests/utils.spec.ts",
253
+ "/project/packages/core-node/src/index.ts",
254
+ "/project/packages/cli/src/index.ts",
255
+ ],
256
+ errors: [],
257
+ }),
258
+ );
216
259
 
217
- vi.mocked(fsExists).mockResolvedValue(false);
218
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
260
+ vi.mocked(fsx.exists).mockResolvedValue(false);
261
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
219
262
 
220
263
  const { Worker } = await import("@simplysm/core-node");
221
264
  const mockBuildDts = vi.fn(() =>
@@ -226,13 +269,15 @@ describe("runTypecheck", () => {
226
269
  warningCount: 0,
227
270
  }),
228
271
  );
229
- vi.mocked(Worker.create).mockReturnValue({
230
- build: mockBuildDts,
231
- terminate: vi.fn(() => Promise.resolve()),
232
- } as unknown as ReturnType<typeof Worker.create>);
272
+ vi.mocked(Worker.create).mockReturnValue(
273
+ createMockWorker({
274
+ build: mockBuildDts,
275
+ terminate: vi.fn(() => Promise.resolve()),
276
+ }),
277
+ );
233
278
 
234
279
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
235
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
280
+ createMockDiagnosticArray([]),
236
281
  );
237
282
 
238
283
  await runTypecheck({
@@ -252,130 +297,21 @@ describe("runTypecheck", () => {
252
297
  config: {},
253
298
  });
254
299
 
255
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
256
- options: { lib: ["ES2024"], types: [] },
257
- fileNames: ["/project/sd.config.ts"],
258
- errors: [],
259
- } as unknown as ts.ParsedCommandLine);
260
-
261
- vi.mocked(fsExists).mockResolvedValue(false);
262
-
263
- vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
264
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
265
- );
266
-
267
- // Should proceed without error even if sd.config.ts fails to load
268
- await runTypecheck({ targets: [], options: [] });
269
-
270
- expect(process.exitCode).toBeUndefined();
271
- });
272
-
273
- it("uses default value when default export is not a function", async () => {
274
- vi.mocked(ts.readConfigFile).mockReturnValue({
275
- config: {},
276
- });
277
-
278
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
279
- options: { lib: ["ES2024"], types: [] },
280
- fileNames: ["/project/packages/core-common/src/index.ts"],
281
- errors: [],
282
- } as unknown as ts.ParsedCommandLine);
283
-
284
- vi.mocked(fsExists).mockResolvedValue(false);
285
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
286
-
287
- // When sd.config.ts's default export is an object, not a function
288
- mockJitiImport.mockResolvedValue({
289
- default: { packages: {} }, // object, not a function
290
- });
291
-
292
- vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
293
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
300
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
301
+ createMockParsedCommandLine({
302
+ options: { lib: ["ES2024"], types: [] },
303
+ fileNames: ["/project/sd.config.ts"],
304
+ errors: [],
305
+ }),
294
306
  );
295
307
 
296
- // Should proceed with default value without error
297
- await runTypecheck({ targets: [], options: [] });
298
-
299
- expect(process.exitCode).toBeUndefined();
300
- });
301
-
302
- it("uses default value when no default export in sd.config.ts", async () => {
303
- vi.mocked(ts.readConfigFile).mockReturnValue({
304
- config: {},
305
- });
306
-
307
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
308
- options: { lib: ["ES2024"], types: [] },
309
- fileNames: ["/project/packages/core-common/src/index.ts"],
310
- errors: [],
311
- } as unknown as ts.ParsedCommandLine);
312
-
313
- vi.mocked(fsExists).mockResolvedValue(false);
314
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
315
-
316
- // When sd.config.ts has no default export
317
- mockJitiImport.mockResolvedValue({
318
- someOtherExport: () => ({}),
319
- });
320
-
321
- const { Worker } = await import("@simplysm/core-node");
322
- vi.mocked(Worker.create).mockReturnValue({
323
- build: vi.fn(() =>
324
- Promise.resolve({
325
- success: true,
326
- diagnostics: [],
327
- errorCount: 0,
328
- warningCount: 0,
329
- }),
330
- ),
331
- terminate: vi.fn(() => Promise.resolve()),
332
- } as unknown as ReturnType<typeof Worker.create>);
308
+ vi.mocked(fsx.exists).mockResolvedValue(false);
333
309
 
334
310
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
335
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
336
- );
337
-
338
- // Should proceed with default value without error
339
- await runTypecheck({ targets: [], options: [] });
340
-
341
- expect(process.exitCode).toBeUndefined();
342
- });
343
-
344
- it("typecheck multiple packages", async () => {
345
- vi.mocked(ts.readConfigFile).mockReturnValue({
346
- config: {},
347
- });
348
-
349
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
350
- options: { lib: ["ES2024", "DOM"], types: [] },
351
- fileNames: [
352
- "/project/packages/core-node/src/index.ts",
353
- "/project/packages/core-browser/src/index.ts",
354
- "/project/packages/core-common/src/index.ts",
355
- ],
356
- errors: [],
357
- } as unknown as ts.ParsedCommandLine);
358
-
359
- vi.mocked(fsExists).mockResolvedValue(false);
360
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
361
-
362
- const { Worker } = await import("@simplysm/core-node");
363
- vi.mocked(Worker.create).mockReturnValue({
364
- build: vi.fn(() =>
365
- Promise.resolve({
366
- success: true,
367
- diagnostics: [],
368
- errorCount: 0,
369
- warningCount: 0,
370
- }),
371
- ),
372
- terminate: vi.fn(() => Promise.resolve()),
373
- } as unknown as ReturnType<typeof Worker.create>);
374
-
375
- vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
376
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
311
+ createMockDiagnosticArray([]),
377
312
  );
378
313
 
314
+ // Should proceed without error even if sd.config.ts fails to load
379
315
  await runTypecheck({ targets: [], options: [] });
380
316
 
381
317
  expect(process.exitCode).toBeUndefined();
@@ -384,38 +320,42 @@ describe("runTypecheck", () => {
384
320
  it("sets exitCode to 1 when typecheck errors occur", async () => {
385
321
  vi.mocked(ts.readConfigFile).mockReturnValue({ config: {} });
386
322
 
387
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
388
- options: { lib: ["ES2024"], types: [] },
389
- fileNames: ["/project/packages/core-common/src/index.ts"],
390
- errors: [],
391
- } as unknown as ts.ParsedCommandLine);
323
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
324
+ createMockParsedCommandLine({
325
+ options: { lib: ["ES2024"], types: [] },
326
+ fileNames: ["/project/packages/core-common/src/index.ts"],
327
+ errors: [],
328
+ }),
329
+ );
392
330
 
393
- vi.mocked(fsExists).mockResolvedValue(false);
394
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
331
+ vi.mocked(fsx.exists).mockResolvedValue(false);
332
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
395
333
 
396
334
  // Mock Worker to return error results
397
335
  const { Worker } = await import("@simplysm/core-node");
398
- vi.mocked(Worker.create).mockReturnValue({
399
- build: vi.fn(() =>
400
- Promise.resolve({
401
- success: false,
402
- diagnostics: [
403
- {
404
- category: 1,
405
- code: 2322,
406
- messageText: "Type error",
407
- fileName: "/project/packages/core-common/src/index.ts",
408
- },
409
- ],
410
- errorCount: 1,
411
- warningCount: 0,
412
- }),
413
- ),
414
- terminate: vi.fn(() => Promise.resolve()),
415
- } as unknown as ReturnType<typeof Worker.create>);
336
+ vi.mocked(Worker.create).mockReturnValue(
337
+ createMockWorker({
338
+ build: vi.fn(() =>
339
+ Promise.resolve({
340
+ success: false,
341
+ diagnostics: [
342
+ {
343
+ category: 1,
344
+ code: 2322,
345
+ messageText: "Type error",
346
+ fileName: "/project/packages/core-common/src/index.ts",
347
+ },
348
+ ],
349
+ errorCount: 1,
350
+ warningCount: 0,
351
+ }),
352
+ ),
353
+ terminate: vi.fn(() => Promise.resolve()),
354
+ }),
355
+ );
416
356
 
417
357
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
418
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
358
+ createMockDiagnosticArray([]),
419
359
  );
420
360
  vi.mocked(ts.formatDiagnosticsWithColorAndContext).mockReturnValue("");
421
361
 
@@ -427,15 +367,17 @@ describe("runTypecheck", () => {
427
367
  it("creates other task when non-package files (like tests/) are included", async () => {
428
368
  vi.mocked(ts.readConfigFile).mockReturnValue({ config: {} });
429
369
 
430
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
431
- options: { lib: ["ES2024"], types: [] },
432
- fileNames: ["/project/packages/core-node/src/index.ts", "/project/tests/orm/some-test.ts"],
433
- errors: [],
434
- } as unknown as ts.ParsedCommandLine);
370
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
371
+ createMockParsedCommandLine({
372
+ options: { lib: ["ES2024"], types: [] },
373
+ fileNames: ["/project/packages/core-node/src/index.ts", "/project/tests/orm/some-test.ts"],
374
+ errors: [],
375
+ }),
376
+ );
435
377
 
436
- vi.mocked(fsExists).mockResolvedValue(false);
378
+ vi.mocked(fsx.exists).mockResolvedValue(false);
437
379
  // Set core-node as node target package
438
- vi.mocked(fsReadJson).mockImplementation((filePath: string) => {
380
+ vi.mocked(fsx.readJson).mockImplementation((filePath: string) => {
439
381
  if (filePath.includes("core-node")) {
440
382
  return Promise.resolve({ name: "@simplysm/core-node" });
441
383
  }
@@ -452,7 +394,7 @@ describe("runTypecheck", () => {
452
394
  });
453
395
 
454
396
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
455
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
397
+ createMockDiagnosticArray([]),
456
398
  );
457
399
 
458
400
  const { Worker } = await import("@simplysm/core-node");
@@ -464,10 +406,12 @@ describe("runTypecheck", () => {
464
406
  warningCount: 0,
465
407
  }),
466
408
  );
467
- vi.mocked(Worker.create).mockReturnValue({
468
- build: mockBuildDts,
469
- terminate: vi.fn(() => Promise.resolve()),
470
- } as unknown as ReturnType<typeof Worker.create>);
409
+ vi.mocked(Worker.create).mockReturnValue(
410
+ createMockWorker({
411
+ build: mockBuildDts,
412
+ terminate: vi.fn(() => Promise.resolve()),
413
+ }),
414
+ );
471
415
 
472
416
  await runTypecheck({ targets: [], options: [] });
473
417
 
@@ -486,44 +430,6 @@ describe("runTypecheck", () => {
486
430
  expect(pkgCall).toBeDefined();
487
431
  });
488
432
 
489
- it("does not create other task when only packages/ files exist", async () => {
490
- vi.mocked(ts.readConfigFile).mockReturnValue({ config: {} });
491
-
492
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
493
- options: { lib: ["ES2024"], types: [] },
494
- fileNames: ["/project/packages/core-common/src/index.ts"],
495
- errors: [],
496
- } as unknown as ts.ParsedCommandLine);
497
-
498
- vi.mocked(fsExists).mockResolvedValue(false);
499
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
500
-
501
- vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
502
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
503
- );
504
-
505
- const { Worker } = await import("@simplysm/core-node");
506
- const mockBuildDts = vi.fn(() =>
507
- Promise.resolve({
508
- success: true,
509
- diagnostics: [],
510
- errorCount: 0,
511
- warningCount: 0,
512
- }),
513
- );
514
- vi.mocked(Worker.create).mockReturnValue({
515
- build: mockBuildDts,
516
- terminate: vi.fn(() => Promise.resolve()),
517
- } as unknown as ReturnType<typeof Worker.create>);
518
-
519
- await runTypecheck({ targets: [], options: [] });
520
-
521
- // Should have no call with name="root"
522
- const nonPkgCall = (mockBuildDts.mock.calls as unknown[][]).find(
523
- (call) => (call[0] as { name: string }).name === "root",
524
- );
525
- expect(nonPkgCall).toBeUndefined();
526
- });
527
433
  });
528
434
 
529
435
  describe("executeTypecheck", () => {
@@ -555,23 +461,25 @@ describe("executeTypecheck", () => {
555
461
  errors: [],
556
462
  } as never);
557
463
 
558
- vi.mocked(fsExists).mockResolvedValue(false);
559
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
560
-
561
- vi.mocked(Worker.create).mockReturnValue({
562
- build: vi.fn(() =>
563
- Promise.resolve({
564
- success: true,
565
- diagnostics: [],
566
- errorCount: 0,
567
- warningCount: 0,
568
- }),
569
- ),
570
- terminate: vi.fn(() => Promise.resolve()),
571
- } as unknown as ReturnType<typeof Worker.create>);
464
+ vi.mocked(fsx.exists).mockResolvedValue(false);
465
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
466
+
467
+ vi.mocked(Worker.create).mockReturnValue(
468
+ createMockWorker({
469
+ build: vi.fn(() =>
470
+ Promise.resolve({
471
+ success: true,
472
+ diagnostics: [],
473
+ errorCount: 0,
474
+ warningCount: 0,
475
+ }),
476
+ ),
477
+ terminate: vi.fn(() => Promise.resolve()),
478
+ }),
479
+ );
572
480
 
573
481
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
574
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
482
+ createMockDiagnosticArray([]),
575
483
  );
576
484
 
577
485
  const result = await executeTypecheck({ targets: [], options: [] });
@@ -593,28 +501,30 @@ describe("executeTypecheck", () => {
593
501
  errors: [],
594
502
  } as never);
595
503
 
596
- vi.mocked(fsExists).mockResolvedValue(false);
597
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
504
+ vi.mocked(fsx.exists).mockResolvedValue(false);
505
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
598
506
 
599
507
  // Mock worker to return error results
600
- vi.mocked(Worker.create).mockReturnValue({
601
- build: vi.fn(() =>
602
- Promise.resolve({
603
- success: false,
604
- diagnostics: [
605
- {
606
- category: 1,
607
- code: 2322,
608
- messageText: "Type error",
609
- fileName: "/project/packages/core-common/src/index.ts",
610
- },
611
- ],
612
- errorCount: 1,
613
- warningCount: 0,
614
- }),
615
- ),
616
- terminate: vi.fn(() => Promise.resolve()),
617
- } as unknown as ReturnType<typeof Worker.create>);
508
+ vi.mocked(Worker.create).mockReturnValue(
509
+ createMockWorker({
510
+ build: vi.fn(() =>
511
+ Promise.resolve({
512
+ success: false,
513
+ diagnostics: [
514
+ {
515
+ category: 1,
516
+ code: 2322,
517
+ messageText: "Type error",
518
+ fileName: "/project/packages/core-common/src/index.ts",
519
+ },
520
+ ],
521
+ errorCount: 1,
522
+ warningCount: 0,
523
+ }),
524
+ ),
525
+ terminate: vi.fn(() => Promise.resolve()),
526
+ }),
527
+ );
618
528
 
619
529
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockImplementation(
620
530
  (diagnostics) => diagnostics as ts.SortedReadonlyArray<ts.Diagnostic>,
@@ -631,23 +541,4 @@ describe("executeTypecheck", () => {
631
541
  expect(process.exitCode).toBeUndefined();
632
542
  });
633
543
 
634
- it("returns failure result when tsconfig.json fails to load", async () => {
635
- const { executeTypecheck } = await import("../src/commands/typecheck");
636
-
637
- vi.mocked(ts.readConfigFile).mockReturnValue({
638
- error: {
639
- category: ts.DiagnosticCategory.Error,
640
- messageText: "Failed to read tsconfig.json",
641
- } as ts.Diagnostic,
642
- });
643
-
644
- vi.mocked(ts.formatDiagnosticsWithColorAndContext).mockReturnValue("");
645
-
646
- const result = await executeTypecheck({ targets: [], options: [] });
647
-
648
- expect(result.success).toBe(false);
649
- expect(result.errorCount).toBe(1);
650
- // executeTypecheck should not set process.exitCode
651
- expect(process.exitCode).toBeUndefined();
652
- });
653
544
  });
@@ -38,38 +38,4 @@ describe("filterPackagesByTargets", () => {
38
38
  expect(result["core-node"]).toEqual({ target: "node" });
39
39
  });
40
40
 
41
- it("returns empty result when specifying non-existent package", () => {
42
- const result = filterPackagesByTargets(mockPackages, ["non-existent"]);
43
-
44
- expect(Object.keys(result)).toHaveLength(0);
45
- });
46
-
47
- it("ignores undefined package config", () => {
48
- const result = filterPackagesByTargets(mockPackages, ["empty-pkg"]);
49
-
50
- expect(Object.keys(result)).toHaveLength(0);
51
- });
52
-
53
- it("filters client target packages", () => {
54
- const result = filterPackagesByTargets(mockPackages, ["solid-demo"]);
55
-
56
- expect(Object.keys(result)).toHaveLength(1);
57
- expect(result["solid-demo"]).toEqual({ target: "client", server: 3000 });
58
- });
59
-
60
- it("handles empty packages object", () => {
61
- const result = filterPackagesByTargets({}, []);
62
-
63
- expect(Object.keys(result)).toHaveLength(0);
64
- });
65
-
66
- it("handles case where all packages are scripts", () => {
67
- const scriptsOnly: Record<string, SdPackageConfig> = {
68
- pkg1: { target: "scripts" },
69
- pkg2: { target: "scripts" },
70
- };
71
- const result = filterPackagesByTargets(scriptsOnly, []);
72
-
73
- expect(Object.keys(result)).toHaveLength(0);
74
- });
75
41
  });