@mark1russell7/client-vitest 0.0.0-stage → 0.1.0

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 (56) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +440 -2
  4. package/README_NEW.md +513 -0
  5. package/dist/.tsbuildinfo +1 -0
  6. package/dist/index.d.ts +4 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +4 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/module.d.ts +11 -0
  11. package/dist/module.d.ts.map +1 -0
  12. package/dist/module.js +83 -0
  13. package/dist/module.js.map +1 -0
  14. package/dist/procedures/vitest/index.d.ts +5 -0
  15. package/dist/procedures/vitest/index.d.ts.map +1 -0
  16. package/dist/procedures/vitest/index.js +5 -0
  17. package/dist/procedures/vitest/index.js.map +1 -0
  18. package/dist/procedures/vitest/list.d.ts +13 -0
  19. package/dist/procedures/vitest/list.d.ts.map +1 -0
  20. package/dist/procedures/vitest/list.js +32 -0
  21. package/dist/procedures/vitest/list.js.map +1 -0
  22. package/dist/procedures/vitest/run.d.ts +17 -0
  23. package/dist/procedures/vitest/run.d.ts.map +1 -0
  24. package/dist/procedures/vitest/run.js +110 -0
  25. package/dist/procedures/vitest/run.js.map +1 -0
  26. package/dist/procedures/vitest/stop.d.ts +13 -0
  27. package/dist/procedures/vitest/stop.d.ts.map +1 -0
  28. package/dist/procedures/vitest/stop.js +25 -0
  29. package/dist/procedures/vitest/stop.js.map +1 -0
  30. package/dist/procedures/vitest/watch.d.ts +14 -0
  31. package/dist/procedures/vitest/watch.d.ts.map +1 -0
  32. package/dist/procedures/vitest/watch.js +37 -0
  33. package/dist/procedures/vitest/watch.js.map +1 -0
  34. package/dist/register.d.ts +8 -0
  35. package/dist/register.d.ts.map +1 -0
  36. package/dist/register.js +14 -0
  37. package/dist/register.js.map +1 -0
  38. package/dist/types.d.ts +85 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +80 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/vitest-cli.d.ts +10 -0
  43. package/dist/vitest-cli.d.ts.map +1 -0
  44. package/dist/vitest-cli.js +28 -0
  45. package/dist/vitest-cli.js.map +1 -0
  46. package/package.json +74 -3
  47. package/src/index.ts +3 -0
  48. package/src/module.ts +104 -0
  49. package/src/procedures/vitest/index.ts +4 -0
  50. package/src/procedures/vitest/list.ts +33 -0
  51. package/src/procedures/vitest/run.ts +145 -0
  52. package/src/procedures/vitest/stop.ts +29 -0
  53. package/src/procedures/vitest/watch.ts +46 -0
  54. package/src/register.ts +17 -0
  55. package/src/types.ts +164 -0
  56. package/src/vitest-cli.ts +28 -0
package/README_NEW.md ADDED
@@ -0,0 +1,513 @@
1
+ # @mark1russell7/client-vitest
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@mark1russell7/client-vitest.svg)](https://www.npmjs.com/package/@mark1russell7/client-vitest)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Vitest-specific test procedures with direct Node.js integration - run and watch tests with structured output.
7
+
8
+ ## Overview
9
+
10
+ `client-vitest` provides client procedures that directly integrate with Vitest using Node.js `child_process`. Unlike `client-test` (which uses shell.exec), this package spawns Vitest processes directly and parses JSON output for structured test results including detailed coverage metrics.
11
+
12
+ ### Key Features
13
+
14
+ - **Direct Vitest Integration**: Spawns vitest via `child_process.spawn`
15
+ - **Structured Output**: Parses JSON reporter for detailed test results
16
+ - **Coverage Metrics**: Returns line/branch/function/statement coverage percentages
17
+ - **Watch Mode**: Background process management with PID tracking
18
+ - **Pattern Support**: Include/exclude test file patterns
19
+ - **Reporter Options**: default, verbose, json, junit
20
+ - **Zero Shell Overhead**: No shell intermediary
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @mark1russell7/client-vitest
26
+ ```
27
+
28
+ ### Dependencies
29
+
30
+ - `vitest` - Test runner
31
+ - `@vitest/coverage-v8` - Coverage provider
32
+ - `@mark1russell7/client` - Client RPC system
33
+ - `zod` - Schema validation
34
+
35
+ ## Architecture
36
+
37
+ ```mermaid
38
+ graph TB
39
+ subgraph "Application Layer"
40
+ App[Application Code]
41
+ CLI[CLI Commands]
42
+ end
43
+
44
+ subgraph "client-vitest Package"
45
+ Register[register.ts<br/>Auto-registration]
46
+ VitestRun[vitest.run<br/>Procedure]
47
+ VitestWatch[vitest.watch<br/>Procedure]
48
+ Schemas[Zod Schemas<br/>Input Validation]
49
+ end
50
+
51
+ subgraph "Execution Layer"
52
+ Spawn[child_process.spawn]
53
+ Vitest[Vitest Process<br/>JSON Reporter]
54
+ end
55
+
56
+ App -->|call vitest.run| VitestRun
57
+ CLI -->|call vitest.watch| VitestWatch
58
+
59
+ Register -->|registers| VitestRun
60
+ Register -->|registers| VitestWatch
61
+
62
+ VitestRun -->|validates| Schemas
63
+ VitestWatch -->|validates| Schemas
64
+
65
+ VitestRun -->|spawn('npx vitest')| Spawn
66
+ VitestWatch -->|spawn detached| Spawn
67
+
68
+ Spawn -->|executes| Vitest
69
+ Vitest -->|JSON stdout| VitestRun
70
+ Vitest -->|PID| VitestWatch
71
+
72
+ style Register fill:#e1f5ff
73
+ style VitestRun fill:#e8f5e9
74
+ style VitestWatch fill:#e8f5e9
75
+ style Schemas fill:#fff4e1
76
+ ```
77
+
78
+ ### Execution Flow
79
+
80
+ ```mermaid
81
+ sequenceDiagram
82
+ participant App as Application
83
+ participant Client as Client RPC
84
+ participant VitestProc as vitest.run
85
+ participant Spawn as child_process
86
+ participant Vitest as Vitest (JSON)
87
+
88
+ App->>Client: call(["vitest", "run"], {coverage: true})
89
+ Client->>VitestProc: Route to handler
90
+ VitestProc->>VitestProc: Validate input (Zod)
91
+ VitestProc->>VitestProc: Build args ["vitest", "run", "--reporter", "json"]
92
+ VitestProc->>Spawn: spawn("npx", args)
93
+ Spawn->>Vitest: Start process
94
+ Vitest->>Vitest: Run tests
95
+ Vitest->>Vitest: Collect coverage
96
+ Vitest-->>Spawn: JSON output to stdout
97
+ Spawn-->>VitestProc: Accumulate stdout
98
+ Spawn-->>VitestProc: Close event (exit code)
99
+ VitestProc->>VitestProc: Parse JSON result
100
+ VitestProc->>VitestProc: Extract test counts & coverage
101
+ VitestProc-->>Client: {success, passed, failed, coverage}
102
+ Client-->>App: Structured result
103
+ ```
104
+
105
+ ## Usage
106
+
107
+ ### Basic Test Execution
108
+
109
+ ```typescript
110
+ import { Client } from "@mark1russell7/client";
111
+
112
+ const client = new Client();
113
+
114
+ // Run all tests
115
+ const result = await client.call(["vitest", "run"], {
116
+ cwd: "/path/to/package"
117
+ });
118
+
119
+ console.log(`Passed: ${result.passed}`);
120
+ console.log(`Failed: ${result.failed}`);
121
+ console.log(`Skipped: ${result.skipped}`);
122
+ console.log(`Duration: ${result.duration}ms`);
123
+ ```
124
+
125
+ ### Coverage Collection
126
+
127
+ ```typescript
128
+ // Run with coverage
129
+ const result = await client.call(["vitest", "run"], {
130
+ cwd: "/path/to/package",
131
+ coverage: true
132
+ });
133
+
134
+ if (result.coverage) {
135
+ console.log(`Lines: ${result.coverage.lines}%`);
136
+ console.log(`Branches: ${result.coverage.branches}%`);
137
+ console.log(`Functions: ${result.coverage.functions}%`);
138
+ console.log(`Statements: ${result.coverage.statements}%`);
139
+ }
140
+ ```
141
+
142
+ ### Pattern Matching
143
+
144
+ ```typescript
145
+ // Run specific test files
146
+ await client.call(["vitest", "run"], {
147
+ include: ["src/**/*.unit.test.ts", "src/**/*.spec.ts"],
148
+ exclude: ["**/*.e2e.test.ts", "**/*.integration.test.ts"]
149
+ });
150
+ ```
151
+
152
+ ### Watch Mode
153
+
154
+ ```typescript
155
+ // Start watch mode (detached process)
156
+ const watchResult = await client.call(["vitest", "watch"], {
157
+ cwd: "/path/to/package",
158
+ include: ["src/**/*.test.ts"]
159
+ });
160
+
161
+ console.log(`Vitest watching (PID: ${watchResult.pid})`);
162
+ console.log(`Status: ${watchResult.status}`); // "started"
163
+
164
+ // Process runs in background, unref'd from parent
165
+ ```
166
+
167
+ ### Reporter Selection
168
+
169
+ ```typescript
170
+ // Use verbose reporter
171
+ await client.call(["vitest", "run"], {
172
+ reporter: "verbose"
173
+ });
174
+
175
+ // Use JUnit for CI
176
+ await client.call(["vitest", "run"], {
177
+ reporter: "junit"
178
+ });
179
+ ```
180
+
181
+ ## API Reference
182
+
183
+ ### Procedures
184
+
185
+ #### `vitest.run`
186
+
187
+ Run Vitest tests once with structured output.
188
+
189
+ **Path:** `["vitest", "run"]`
190
+
191
+ **Input:**
192
+ ```typescript
193
+ {
194
+ cwd?: string; // Working directory
195
+ include?: string[]; // Patterns to include
196
+ exclude?: string[]; // Patterns to exclude
197
+ watch?: boolean; // Enable watch mode
198
+ coverage?: boolean; // Collect coverage
199
+ reporter?: "default" | "verbose" | "json" | "junit"; // Reporter type
200
+ passWithNoTests?: boolean; // Pass if no tests found
201
+ }
202
+ ```
203
+
204
+ **Output:**
205
+ ```typescript
206
+ {
207
+ success: boolean; // All tests passed
208
+ passed: number; // Count of passed tests
209
+ failed: number; // Count of failed tests
210
+ skipped: number; // Count of skipped tests
211
+ duration: number; // Duration in milliseconds
212
+ coverage?: { // Coverage metrics (if coverage: true)
213
+ lines: number; // Line coverage %
214
+ branches: number; // Branch coverage %
215
+ functions: number; // Function coverage %
216
+ statements: number; // Statement coverage %
217
+ };
218
+ }
219
+ ```
220
+
221
+ **CLI Shortcuts:**
222
+ - `-c` / `--coverage` - Enable coverage
223
+
224
+ #### `vitest.watch`
225
+
226
+ Start Vitest in watch mode as a detached background process.
227
+
228
+ **Path:** `["vitest", "watch"]`
229
+
230
+ **Input:**
231
+ ```typescript
232
+ {
233
+ cwd?: string; // Working directory
234
+ include?: string[]; // Patterns to include
235
+ }
236
+ ```
237
+
238
+ **Output:**
239
+ ```typescript
240
+ {
241
+ pid: number; // Process ID
242
+ status: "started" | "stopped"; // Status
243
+ }
244
+ ```
245
+
246
+ **Note:** The process is spawned as detached with stdio: "ignore" and unref'd, so it runs independently of the parent process.
247
+
248
+ ### Types
249
+
250
+ ```typescript
251
+ import type {
252
+ VitestRunInput,
253
+ VitestRunOutput,
254
+ VitestWatchInput,
255
+ VitestWatchOutput,
256
+ } from "@mark1russell7/client-vitest";
257
+ ```
258
+
259
+ #### Schemas
260
+
261
+ ```typescript
262
+ import {
263
+ VitestRunInputSchema,
264
+ VitestRunOutputSchema,
265
+ VitestWatchInputSchema,
266
+ VitestWatchOutputSchema,
267
+ } from "@mark1russell7/client-vitest";
268
+
269
+ // Validate input
270
+ const validated = VitestRunInputSchema.parse({
271
+ cwd: "/path",
272
+ coverage: true
273
+ });
274
+ ```
275
+
276
+ ## Examples
277
+
278
+ ### Example 1: CI/CD with Coverage Thresholds
279
+
280
+ ```typescript
281
+ const result = await client.call(["vitest", "run"], {
282
+ cwd: "/path/to/package",
283
+ coverage: true
284
+ });
285
+
286
+ if (!result.success) {
287
+ console.error(`Tests failed: ${result.failed} failures`);
288
+ process.exit(1);
289
+ }
290
+
291
+ if (result.coverage && result.coverage.lines < 80) {
292
+ console.error(`Coverage ${result.coverage.lines}% below 80% threshold`);
293
+ process.exit(1);
294
+ }
295
+
296
+ console.log("Tests passed with adequate coverage!");
297
+ ```
298
+
299
+ ### Example 2: Unit vs Integration Tests
300
+
301
+ ```typescript
302
+ // Run unit tests
303
+ const unitResult = await client.call(["vitest", "run"], {
304
+ include: ["**/*.unit.test.ts"],
305
+ reporter: "verbose"
306
+ });
307
+
308
+ // Run integration tests separately
309
+ const integrationResult = await client.call(["vitest", "run"], {
310
+ include: ["**/*.integration.test.ts"],
311
+ exclude: ["**/*.unit.test.ts"]
312
+ });
313
+
314
+ console.log(`Unit: ${unitResult.passed} passed`);
315
+ console.log(`Integration: ${integrationResult.passed} passed`);
316
+ ```
317
+
318
+ ### Example 3: Development Watch Mode
319
+
320
+ ```typescript
321
+ // Start watch mode for active development
322
+ const { pid } = await client.call(["vitest", "watch"], {
323
+ cwd: process.cwd(),
324
+ include: ["src/**/*.test.ts"]
325
+ });
326
+
327
+ console.log(`Vitest watching in background (PID: ${pid})`);
328
+ console.log("Make changes to trigger re-runs...");
329
+ ```
330
+
331
+ ### Example 4: Multiple Reporters
332
+
333
+ ```typescript
334
+ // Generate multiple output formats
335
+ const reporters = ["default", "json", "junit"] as const;
336
+
337
+ for (const reporter of reporters) {
338
+ await client.call(["vitest", "run"], {
339
+ reporter,
340
+ coverage: reporter === "default"
341
+ });
342
+ }
343
+ ```
344
+
345
+ ### Example 5: Conditional Coverage
346
+
347
+ ```typescript
348
+ // Only collect coverage on CI
349
+ const isCI = process.env.CI === "true";
350
+
351
+ const result = await client.call(["vitest", "run"], {
352
+ cwd: "/path/to/package",
353
+ coverage: isCI,
354
+ reporter: isCI ? "json" : "default"
355
+ });
356
+ ```
357
+
358
+ ## vs client-test
359
+
360
+ | Feature | client-test | client-vitest |
361
+ |---------|-------------|---------------|
362
+ | **Execution** | Via client-shell (shell.exec) | Direct child_process.spawn |
363
+ | **Output** | Raw stdout/stderr strings | Parsed JSON structured output |
364
+ | **Coverage** | Regex-parsed percentage | Full metrics (lines/branches/functions/statements) |
365
+ | **Test Runner** | Generic (vitest/jest/etc) | Vitest-specific |
366
+ | **Result Detail** | Basic pass/fail + duration | Test counts + coverage breakdown |
367
+ | **Watch Mode** | Basic watch flag | Detached process with PID |
368
+ | **Use Case** | General test execution | Detailed vitest integration |
369
+
370
+ ## Integration with Ecosystem
371
+
372
+ ### Dependency Graph
373
+
374
+ ```mermaid
375
+ graph LR
376
+ clientVitest[client-vitest]
377
+ client[client]
378
+ vitest[vitest]
379
+ coverage[vitest/coverage-v8]
380
+ zod[zod]
381
+
382
+ clientVitest --> client
383
+ clientVitest --> vitest
384
+ clientVitest --> coverage
385
+ clientVitest --> zod
386
+
387
+ style clientVitest fill:#e1f5ff
388
+ ```
389
+
390
+ ### Used By
391
+
392
+ - Projects requiring detailed vitest metrics
393
+ - Coverage-driven CI/CD pipelines
394
+ - Development workflows with watch mode
395
+ - Multi-package monorepos using vitest
396
+
397
+ ### Works With
398
+
399
+ - **client-dag**: Batch test execution
400
+ - **client-lib**: Package-aware testing
401
+ - **Bundle packages**: Test procedure aggregation
402
+
403
+ ## Configuration
404
+
405
+ ### Auto-Registration
406
+
407
+ ```json
408
+ {
409
+ "client": {
410
+ "procedures": "./dist/register.js"
411
+ }
412
+ }
413
+ ```
414
+
415
+ ### Vitest Configuration
416
+
417
+ Respects your project's `vitest.config.ts`:
418
+
419
+ ```typescript
420
+ // vitest.config.ts
421
+ export default {
422
+ test: {
423
+ coverage: {
424
+ provider: 'v8',
425
+ reporter: ['text', 'json', 'html'],
426
+ lines: 80,
427
+ functions: 80,
428
+ branches: 75,
429
+ statements: 80
430
+ },
431
+ include: ['src/**/*.test.ts'],
432
+ exclude: ['node_modules', 'dist']
433
+ }
434
+ };
435
+ ```
436
+
437
+ ## Package Structure
438
+
439
+ ```
440
+ client-vitest/
441
+ ├── src/
442
+ │ ├── index.ts # Main exports
443
+ │ ├── types.ts # Zod schemas & types
444
+ │ ├── register.ts # Procedure registration
445
+ │ └── procedures/
446
+ │ └── vitest/
447
+ │ ├── index.ts # Procedure exports
448
+ │ ├── run.ts # vitest.run implementation
449
+ │ └── watch.ts # vitest.watch implementation
450
+ ├── dist/ # Compiled output
451
+ ├── package.json
452
+ ├── tsconfig.json
453
+ └── README.md
454
+ ```
455
+
456
+ ## Development
457
+
458
+ ### Build
459
+
460
+ ```bash
461
+ npm run build
462
+ ```
463
+
464
+ ### Type Check
465
+
466
+ ```bash
467
+ npm run typecheck
468
+ ```
469
+
470
+ ### Clean
471
+
472
+ ```bash
473
+ npm run clean
474
+ ```
475
+
476
+ ## Troubleshooting
477
+
478
+ ### JSON Parsing Fails
479
+
480
+ If JSON parsing fails, the procedure falls back to basic success/fail based on exit code. Ensure vitest is outputting JSON:
481
+
482
+ ```bash
483
+ # Test manually
484
+ npx vitest run --reporter json
485
+ ```
486
+
487
+ ### Coverage Not Collected
488
+
489
+ Install the coverage provider:
490
+
491
+ ```bash
492
+ npm install --save-dev @vitest/coverage-v8
493
+ ```
494
+
495
+ ### Watch Mode Not Working
496
+
497
+ Watch mode spawns a detached process. It won't block the parent. To verify:
498
+
499
+ ```bash
500
+ # Check running processes
501
+ ps aux | grep vitest
502
+ ```
503
+
504
+ ## License
505
+
506
+ MIT - Mark Russell
507
+
508
+ ## Related Packages
509
+
510
+ - `@mark1russell7/client` - Client RPC system
511
+ - `@mark1russell7/client-test` - Generic test execution
512
+ - `vitest` - Test runner
513
+ - `@vitest/coverage-v8` - Coverage provider