@simplysm/sd-cli 13.0.76 → 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 (154) 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.js +4 -4
  19. package/dist/commands/lint.js.map +1 -1
  20. package/dist/commands/publish.js +20 -20
  21. package/dist/commands/publish.js.map +1 -1
  22. package/dist/commands/replace-deps.js +1 -1
  23. package/dist/commands/replace-deps.js.map +1 -1
  24. package/dist/commands/typecheck.js +9 -9
  25. package/dist/commands/typecheck.js.map +1 -1
  26. package/dist/electron/electron.js +16 -16
  27. package/dist/electron/electron.js.map +1 -1
  28. package/dist/orchestrators/BuildOrchestrator.js +6 -6
  29. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  30. package/dist/orchestrators/DevOrchestrator.d.ts +7 -6
  31. package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
  32. package/dist/orchestrators/DevOrchestrator.js +157 -203
  33. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  34. package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
  35. package/dist/orchestrators/WatchOrchestrator.js +3 -4
  36. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  37. package/dist/sd-cli.js +1 -1
  38. package/dist/sd-cli.js.map +1 -1
  39. package/dist/sd-config.types.d.ts +9 -3
  40. package/dist/sd-config.types.d.ts.map +1 -1
  41. package/dist/utils/copy-public.d.ts.map +1 -1
  42. package/dist/utils/copy-public.js +23 -27
  43. package/dist/utils/copy-public.js.map +1 -1
  44. package/dist/utils/copy-src.d.ts.map +1 -1
  45. package/dist/utils/copy-src.js +7 -7
  46. package/dist/utils/copy-src.js.map +1 -1
  47. package/dist/utils/esbuild-config.d.ts.map +1 -1
  48. package/dist/utils/esbuild-config.js +36 -42
  49. package/dist/utils/esbuild-config.js.map +1 -1
  50. package/dist/utils/replace-deps.js +7 -7
  51. package/dist/utils/replace-deps.js.map +1 -1
  52. package/dist/utils/sd-config.js +2 -2
  53. package/dist/utils/sd-config.js.map +1 -1
  54. package/dist/utils/template.js +7 -7
  55. package/dist/utils/template.js.map +1 -1
  56. package/dist/utils/tsconfig.d.ts +1 -2
  57. package/dist/utils/tsconfig.d.ts.map +1 -1
  58. package/dist/utils/tsconfig.js +5 -8
  59. package/dist/utils/tsconfig.js.map +1 -1
  60. package/dist/utils/typecheck-serialization.js +2 -2
  61. package/dist/utils/typecheck-serialization.js.map +1 -1
  62. package/dist/utils/vite-config.d.ts +2 -0
  63. package/dist/utils/vite-config.d.ts.map +1 -1
  64. package/dist/utils/vite-config.js +36 -3
  65. package/dist/utils/vite-config.js.map +1 -1
  66. package/dist/utils/worker-events.d.ts +11 -1
  67. package/dist/utils/worker-events.d.ts.map +1 -1
  68. package/dist/utils/worker-events.js +3 -5
  69. package/dist/utils/worker-events.js.map +1 -1
  70. package/dist/utils/worker-utils.d.ts +2 -2
  71. package/dist/utils/worker-utils.d.ts.map +1 -1
  72. package/dist/utils/worker-utils.js +1 -1
  73. package/dist/utils/worker-utils.js.map +1 -1
  74. package/dist/workers/client.worker.d.ts +1 -1
  75. package/dist/workers/client.worker.js +3 -3
  76. package/dist/workers/client.worker.js.map +1 -1
  77. package/dist/workers/dts.worker.d.ts +1 -1
  78. package/dist/workers/dts.worker.d.ts.map +1 -1
  79. package/dist/workers/dts.worker.js +13 -28
  80. package/dist/workers/dts.worker.js.map +1 -1
  81. package/dist/workers/library.worker.d.ts +1 -1
  82. package/dist/workers/library.worker.js +4 -4
  83. package/dist/workers/library.worker.js.map +1 -1
  84. package/dist/workers/lint.worker.d.ts +1 -1
  85. package/dist/workers/server-runtime.worker.d.ts +1 -1
  86. package/dist/workers/server-runtime.worker.js +4 -4
  87. package/dist/workers/server-runtime.worker.js.map +1 -1
  88. package/dist/workers/server.worker.d.ts +1 -1
  89. package/dist/workers/server.worker.js +6 -6
  90. package/dist/workers/server.worker.js.map +1 -1
  91. package/package.json +4 -4
  92. package/src/builders/DtsBuilder.ts +2 -2
  93. package/src/builders/LibraryBuilder.ts +7 -10
  94. package/src/builders/types.ts +6 -1
  95. package/src/capacitor/capacitor.ts +61 -60
  96. package/src/commands/check.ts +4 -4
  97. package/src/commands/device.ts +3 -3
  98. package/src/commands/lint.ts +4 -4
  99. package/src/commands/publish.ts +20 -20
  100. package/src/commands/replace-deps.ts +1 -1
  101. package/src/commands/typecheck.ts +9 -9
  102. package/src/electron/electron.ts +16 -16
  103. package/src/orchestrators/BuildOrchestrator.ts +6 -6
  104. package/src/orchestrators/DevOrchestrator.ts +210 -256
  105. package/src/orchestrators/WatchOrchestrator.ts +8 -10
  106. package/src/sd-cli.ts +1 -1
  107. package/src/sd-config.types.ts +10 -3
  108. package/src/utils/copy-public.ts +22 -26
  109. package/src/utils/copy-src.ts +7 -7
  110. package/src/utils/esbuild-config.ts +51 -63
  111. package/src/utils/replace-deps.ts +7 -7
  112. package/src/utils/sd-config.ts +2 -2
  113. package/src/utils/template.ts +7 -7
  114. package/src/utils/tsconfig.ts +6 -10
  115. package/src/utils/typecheck-serialization.ts +2 -2
  116. package/src/utils/vite-config.ts +376 -341
  117. package/src/utils/worker-events.ts +13 -10
  118. package/src/utils/worker-utils.ts +45 -45
  119. package/src/workers/client.worker.ts +3 -3
  120. package/src/workers/dts.worker.ts +451 -467
  121. package/src/workers/library.worker.ts +4 -4
  122. package/src/workers/server-runtime.worker.ts +4 -4
  123. package/src/workers/server.worker.ts +572 -572
  124. package/templates/init/package.json.hbs +2 -2
  125. package/templates/init/packages/client-admin/package.json.hbs +5 -5
  126. package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +2 -2
  127. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +1 -1
  128. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +1 -1
  129. package/templates/init/packages/db-main/package.json.hbs +2 -2
  130. package/templates/init/packages/server/package.json.hbs +4 -4
  131. package/templates/init/tests/e2e/package.json.hbs +1 -1
  132. package/tests/get-compiler-options-for-package.spec.ts +13 -27
  133. package/tests/get-types-from-package-json.spec.ts +15 -11
  134. package/tests/load-ignore-patterns.spec.ts +15 -11
  135. package/tests/load-sd-config.spec.ts +16 -14
  136. package/tests/publish-config-narrowing.spec.ts +20 -0
  137. package/tests/run-lint.spec.ts +38 -34
  138. package/tests/run-typecheck.spec.ts +194 -135
  139. package/tests/sd-public-dev-plugin-mime.spec.ts +19 -0
  140. package/dist/builders/index.d.ts +0 -5
  141. package/dist/builders/index.d.ts.map +0 -1
  142. package/dist/builders/index.js +0 -5
  143. package/dist/builders/index.js.map +0 -6
  144. package/dist/infra/index.d.ts +0 -4
  145. package/dist/infra/index.d.ts.map +0 -1
  146. package/dist/infra/index.js +0 -4
  147. package/dist/infra/index.js.map +0 -6
  148. package/dist/orchestrators/index.d.ts +0 -4
  149. package/dist/orchestrators/index.d.ts.map +0 -1
  150. package/dist/orchestrators/index.js +0 -4
  151. package/dist/orchestrators/index.js.map +0 -6
  152. package/src/builders/index.ts +0 -4
  153. package/src/infra/index.ts +0 -3
  154. package/src/orchestrators/index.ts +0 -3
@@ -40,19 +40,23 @@ vi.mock("@simplysm/core-node", () => {
40
40
  return child.startsWith(parentWithSlash);
41
41
  };
42
42
  return {
43
- fsExists: vi.fn(),
44
- fsGlob: vi.fn(),
45
- pathPosix: vi.fn(posix),
46
- pathIsChildPath: vi.fn(isChildPath),
47
- pathFilterByTargets: vi.fn((files: string[], targets: string[], cwd: string) => {
48
- if (targets.length === 0) return files;
49
- return files.filter((file) => {
50
- const relativePath = posix(file.replace(cwd + "/", ""));
51
- return targets.some(
52
- (target) => relativePath === target || isChildPath(relativePath, target),
53
- );
54
- });
55
- }),
43
+ fsx: {
44
+ exists: vi.fn(),
45
+ glob: vi.fn(),
46
+ },
47
+ pathx: {
48
+ posix: vi.fn(posix),
49
+ isChildPath: vi.fn(isChildPath),
50
+ filterByTargets: vi.fn((files: string[], targets: string[], cwd: string) => {
51
+ if (targets.length === 0) return files;
52
+ return files.filter((file) => {
53
+ const relativePath = posix(file.replace(cwd + "/", ""));
54
+ return targets.some(
55
+ (target) => relativePath === target || isChildPath(relativePath, target),
56
+ );
57
+ });
58
+ }),
59
+ },
56
60
  };
57
61
  });
58
62
 
@@ -81,7 +85,7 @@ vi.mock("consola", () => {
81
85
  };
82
86
  });
83
87
 
84
- import { fsExists, fsGlob } from "@simplysm/core-node";
88
+ import { fsx } from "@simplysm/core-node";
85
89
  import { runLint, executeLint } from "../src/commands/lint";
86
90
 
87
91
  describe("runLint", () => {
@@ -108,7 +112,7 @@ describe("runLint", () => {
108
112
 
109
113
  it("sets exitCode to 1 when lint errors occur", async () => {
110
114
  const cwd = "/project";
111
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
115
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
112
116
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
113
117
  });
114
118
 
@@ -116,7 +120,7 @@ describe("runLint", () => {
116
120
  default: [{ ignores: ["node_modules/**"] }],
117
121
  });
118
122
 
119
- vi.mocked(fsGlob).mockResolvedValue(["/project/src/index.ts"]);
123
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/src/index.ts"]);
120
124
 
121
125
  mockState.lintResults = [{ errorCount: 2, warningCount: 0 }];
122
126
 
@@ -127,7 +131,7 @@ describe("runLint", () => {
127
131
 
128
132
  it("does not set exitCode when no lint errors", async () => {
129
133
  const cwd = "/project";
130
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
134
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
131
135
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
132
136
  });
133
137
 
@@ -135,7 +139,7 @@ describe("runLint", () => {
135
139
  default: [{ ignores: ["node_modules/**"] }],
136
140
  });
137
141
 
138
- vi.mocked(fsGlob).mockResolvedValue(["/project/src/index.ts"]);
142
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/src/index.ts"]);
139
143
 
140
144
  mockState.lintResults = [{ errorCount: 0, warningCount: 0 }];
141
145
 
@@ -146,7 +150,7 @@ describe("runLint", () => {
146
150
 
147
151
  it("filters files using targets option", async () => {
148
152
  const cwd = "/project";
149
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
153
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
150
154
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
151
155
  });
152
156
 
@@ -154,7 +158,7 @@ describe("runLint", () => {
154
158
  default: [{ ignores: ["node_modules/**"] }],
155
159
  });
156
160
 
157
- vi.mocked(fsGlob).mockResolvedValue([
161
+ vi.mocked(fsx.glob).mockResolvedValue([
158
162
  "/project/packages/core-common/src/index.ts",
159
163
  "/project/packages/core-node/src/index.ts",
160
164
  "/project/packages/cli/src/index.ts",
@@ -174,7 +178,7 @@ describe("runLint", () => {
174
178
 
175
179
  it("filters files from all paths when multiple targets specified", async () => {
176
180
  const cwd = "/project";
177
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
181
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
178
182
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
179
183
  });
180
184
 
@@ -182,7 +186,7 @@ describe("runLint", () => {
182
186
  default: [{ ignores: ["node_modules/**"] }],
183
187
  });
184
188
 
185
- vi.mocked(fsGlob).mockResolvedValue([
189
+ vi.mocked(fsx.glob).mockResolvedValue([
186
190
  "/project/packages/core-common/src/index.ts",
187
191
  "/project/packages/core-node/src/index.ts",
188
192
  "/project/packages/cli/src/index.ts",
@@ -206,7 +210,7 @@ describe("runLint", () => {
206
210
 
207
211
  it("calls ESLint.outputFixes when fix option is enabled", async () => {
208
212
  const cwd = "/project";
209
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
213
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
210
214
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
211
215
  });
212
216
 
@@ -214,7 +218,7 @@ describe("runLint", () => {
214
218
  default: [{ ignores: ["node_modules/**"] }],
215
219
  });
216
220
 
217
- vi.mocked(fsGlob).mockResolvedValue(["/project/src/index.ts"]);
221
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/src/index.ts"]);
218
222
 
219
223
  mockState.lintResults = [{ errorCount: 0, warningCount: 0 }];
220
224
 
@@ -225,7 +229,7 @@ describe("runLint", () => {
225
229
 
226
230
  it("exits early when no files to lint", async () => {
227
231
  const cwd = "/project";
228
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
232
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
229
233
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
230
234
  });
231
235
 
@@ -233,7 +237,7 @@ describe("runLint", () => {
233
237
  default: [{ ignores: ["node_modules/**"] }],
234
238
  });
235
239
 
236
- vi.mocked(fsGlob).mockResolvedValue([]);
240
+ vi.mocked(fsx.glob).mockResolvedValue([]);
237
241
 
238
242
  await runLint({ targets: [], fix: false, timing: false });
239
243
 
@@ -244,7 +248,7 @@ describe("runLint", () => {
244
248
 
245
249
  it("throws error when ESLint config file is not found", async () => {
246
250
  // When all config files are missing
247
- vi.mocked(fsExists).mockResolvedValue(false);
251
+ vi.mocked(fsx.exists).mockResolvedValue(false);
248
252
 
249
253
  await expect(runLint({ targets: [], fix: false, timing: false })).rejects.toThrow(
250
254
  "Cannot find ESLint config file",
@@ -257,7 +261,7 @@ describe("runLint", () => {
257
261
 
258
262
  it("sets TIMING environment variable when timing option is enabled", async () => {
259
263
  const cwd = "/project";
260
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
264
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
261
265
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
262
266
  });
263
267
 
@@ -265,7 +269,7 @@ describe("runLint", () => {
265
269
  default: [{ ignores: ["node_modules/**"] }],
266
270
  });
267
271
 
268
- vi.mocked(fsGlob).mockResolvedValue(["/project/src/index.ts"]);
272
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/src/index.ts"]);
269
273
 
270
274
  mockState.lintResults = [{ errorCount: 0, warningCount: 0 }];
271
275
 
@@ -287,7 +291,7 @@ describe("runLint", () => {
287
291
 
288
292
  it("uses eslint.config.mts when eslint.config.ts is not found", async () => {
289
293
  const cwd = "/project";
290
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
294
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
291
295
  // eslint.config.ts does not exist, only eslint.config.mts
292
296
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.mts"));
293
297
  });
@@ -296,7 +300,7 @@ describe("runLint", () => {
296
300
  default: [{ ignores: ["dist/**"] }],
297
301
  });
298
302
 
299
- vi.mocked(fsGlob).mockResolvedValue(["/project/src/index.ts"]);
303
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/src/index.ts"]);
300
304
 
301
305
  mockState.lintResults = [{ errorCount: 0, warningCount: 0 }];
302
306
 
@@ -324,7 +328,7 @@ describe("executeLint", () => {
324
328
 
325
329
  // Default ESLint config mock
326
330
  const cwd = "/project";
327
- vi.mocked(fsExists).mockImplementation((filePath: string) => {
331
+ vi.mocked(fsx.exists).mockImplementation((filePath: string) => {
328
332
  return Promise.resolve(filePath === path.join(cwd, "eslint.config.ts"));
329
333
  });
330
334
  mockJitiImportFn.mockResolvedValue({
@@ -339,7 +343,7 @@ describe("executeLint", () => {
339
343
 
340
344
  it("returns success result when no errors", async () => {
341
345
  mockState.lintResults = [{ errorCount: 0, warningCount: 0 }];
342
- vi.mocked(fsGlob).mockResolvedValue(["/project/packages/core-common/src/index.ts"]);
346
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/packages/core-common/src/index.ts"]);
343
347
 
344
348
  const result = await executeLint({ targets: [], fix: false, timing: false });
345
349
 
@@ -350,7 +354,7 @@ describe("executeLint", () => {
350
354
 
351
355
  it("returns failure result when errors exist", async () => {
352
356
  mockState.lintResults = [{ errorCount: 2, warningCount: 1 }];
353
- vi.mocked(fsGlob).mockResolvedValue(["/project/packages/core-common/src/index.ts"]);
357
+ vi.mocked(fsx.glob).mockResolvedValue(["/project/packages/core-common/src/index.ts"]);
354
358
 
355
359
  const result = await executeLint({ targets: [], fix: false, timing: false });
356
360
 
@@ -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,16 +297,18 @@ 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);
300
+ vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue(
301
+ createMockParsedCommandLine({
302
+ options: { lib: ["ES2024"], types: [] },
303
+ fileNames: ["/project/sd.config.ts"],
304
+ errors: [],
305
+ }),
306
+ );
260
307
 
261
- vi.mocked(fsExists).mockResolvedValue(false);
308
+ vi.mocked(fsx.exists).mockResolvedValue(false);
262
309
 
263
310
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
264
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
311
+ createMockDiagnosticArray([]),
265
312
  );
266
313
 
267
314
  // Should proceed without error even if sd.config.ts fails to load
@@ -273,38 +320,42 @@ describe("runTypecheck", () => {
273
320
  it("sets exitCode to 1 when typecheck errors occur", async () => {
274
321
  vi.mocked(ts.readConfigFile).mockReturnValue({ config: {} });
275
322
 
276
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
277
- options: { lib: ["ES2024"], types: [] },
278
- fileNames: ["/project/packages/core-common/src/index.ts"],
279
- errors: [],
280
- } 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
+ );
281
330
 
282
- vi.mocked(fsExists).mockResolvedValue(false);
283
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
331
+ vi.mocked(fsx.exists).mockResolvedValue(false);
332
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
284
333
 
285
334
  // Mock Worker to return error results
286
335
  const { Worker } = await import("@simplysm/core-node");
287
- vi.mocked(Worker.create).mockReturnValue({
288
- build: vi.fn(() =>
289
- Promise.resolve({
290
- success: false,
291
- diagnostics: [
292
- {
293
- category: 1,
294
- code: 2322,
295
- messageText: "Type error",
296
- fileName: "/project/packages/core-common/src/index.ts",
297
- },
298
- ],
299
- errorCount: 1,
300
- warningCount: 0,
301
- }),
302
- ),
303
- terminate: vi.fn(() => Promise.resolve()),
304
- } 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
+ );
305
356
 
306
357
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
307
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
358
+ createMockDiagnosticArray([]),
308
359
  );
309
360
  vi.mocked(ts.formatDiagnosticsWithColorAndContext).mockReturnValue("");
310
361
 
@@ -316,15 +367,17 @@ describe("runTypecheck", () => {
316
367
  it("creates other task when non-package files (like tests/) are included", async () => {
317
368
  vi.mocked(ts.readConfigFile).mockReturnValue({ config: {} });
318
369
 
319
- vi.mocked(ts.parseJsonConfigFileContent).mockReturnValue({
320
- options: { lib: ["ES2024"], types: [] },
321
- fileNames: ["/project/packages/core-node/src/index.ts", "/project/tests/orm/some-test.ts"],
322
- errors: [],
323
- } 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
+ );
324
377
 
325
- vi.mocked(fsExists).mockResolvedValue(false);
378
+ vi.mocked(fsx.exists).mockResolvedValue(false);
326
379
  // Set core-node as node target package
327
- vi.mocked(fsReadJson).mockImplementation((filePath: string) => {
380
+ vi.mocked(fsx.readJson).mockImplementation((filePath: string) => {
328
381
  if (filePath.includes("core-node")) {
329
382
  return Promise.resolve({ name: "@simplysm/core-node" });
330
383
  }
@@ -341,7 +394,7 @@ describe("runTypecheck", () => {
341
394
  });
342
395
 
343
396
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
344
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
397
+ createMockDiagnosticArray([]),
345
398
  );
346
399
 
347
400
  const { Worker } = await import("@simplysm/core-node");
@@ -353,10 +406,12 @@ describe("runTypecheck", () => {
353
406
  warningCount: 0,
354
407
  }),
355
408
  );
356
- vi.mocked(Worker.create).mockReturnValue({
357
- build: mockBuildDts,
358
- terminate: vi.fn(() => Promise.resolve()),
359
- } 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
+ );
360
415
 
361
416
  await runTypecheck({ targets: [], options: [] });
362
417
 
@@ -406,23 +461,25 @@ describe("executeTypecheck", () => {
406
461
  errors: [],
407
462
  } as never);
408
463
 
409
- vi.mocked(fsExists).mockResolvedValue(false);
410
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
411
-
412
- vi.mocked(Worker.create).mockReturnValue({
413
- build: vi.fn(() =>
414
- Promise.resolve({
415
- success: true,
416
- diagnostics: [],
417
- errorCount: 0,
418
- warningCount: 0,
419
- }),
420
- ),
421
- terminate: vi.fn(() => Promise.resolve()),
422
- } 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
+ );
423
480
 
424
481
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockReturnValue(
425
- [] as unknown as ts.SortedReadonlyArray<ts.Diagnostic>,
482
+ createMockDiagnosticArray([]),
426
483
  );
427
484
 
428
485
  const result = await executeTypecheck({ targets: [], options: [] });
@@ -444,28 +501,30 @@ describe("executeTypecheck", () => {
444
501
  errors: [],
445
502
  } as never);
446
503
 
447
- vi.mocked(fsExists).mockResolvedValue(false);
448
- vi.mocked(fsReadJson).mockResolvedValue({ devDependencies: {} });
504
+ vi.mocked(fsx.exists).mockResolvedValue(false);
505
+ vi.mocked(fsx.readJson).mockResolvedValue({ devDependencies: {} });
449
506
 
450
507
  // Mock worker to return error results
451
- vi.mocked(Worker.create).mockReturnValue({
452
- build: vi.fn(() =>
453
- Promise.resolve({
454
- success: false,
455
- diagnostics: [
456
- {
457
- category: 1,
458
- code: 2322,
459
- messageText: "Type error",
460
- fileName: "/project/packages/core-common/src/index.ts",
461
- },
462
- ],
463
- errorCount: 1,
464
- warningCount: 0,
465
- }),
466
- ),
467
- terminate: vi.fn(() => Promise.resolve()),
468
- } 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
+ );
469
528
 
470
529
  vi.mocked(ts.sortAndDeduplicateDiagnostics).mockImplementation(
471
530
  (diagnostics) => diagnostics as ts.SortedReadonlyArray<ts.Diagnostic>,