uilint-coverage 0.2.150

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/node/coverage-detect.ts"],"sourcesContent":["/**\n * Coverage detection utilities for vitest projects.\n *\n * Detects vitest installation, configuration, and coverage data.\n */\n\nimport { existsSync, readFileSync, statSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface CoverageSetupInfo {\n /** Whether vitest is in dependencies */\n hasVitest: boolean;\n /** Whether vitest config exists */\n hasVitestConfig: boolean;\n /** Path to vitest config if found */\n vitestConfigPath: string | null;\n /** Whether coverage is configured in vitest */\n hasCoverageConfig: boolean;\n /** Coverage provider (v8 or istanbul) */\n coverageProvider: \"v8\" | \"istanbul\" | null;\n /** Whether coverage data file exists */\n hasCoverageData: boolean;\n /** Path to coverage data */\n coverageDataPath: string | null;\n\n // Preparation flags\n /** Whether @vitest/coverage-v8 (or coverage-istanbul) package is missing */\n needsCoveragePackage: boolean;\n /** Whether vitest.config needs coverage block added */\n needsCoverageConfig: boolean;\n /** Age of coverage data in milliseconds (null if no data) */\n coverageDataAge: number | null;\n}\n\nconst VITEST_CONFIG_FILES = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n];\n\ninterface PackageDepsInfo {\n hasVitest: boolean;\n hasCoveragePackage: boolean;\n}\n\n/**\n * Check if vitest and coverage packages are in package.json\n */\nfunction checkPackageDeps(projectPath: string): PackageDepsInfo {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) return { hasVitest: false, hasCoveragePackage: false };\n\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n const hasVitest = \"vitest\" in deps;\n const hasCoveragePackage =\n \"@vitest/coverage-v8\" in deps || \"@vitest/coverage-istanbul\" in deps;\n\n return { hasVitest, hasCoveragePackage };\n } catch {\n return { hasVitest: false, hasCoveragePackage: false };\n }\n}\n\n/**\n * Find the vitest config file in the project\n */\nfunction findVitestConfig(projectPath: string): string | null {\n for (const configFile of VITEST_CONFIG_FILES) {\n const configPath = join(projectPath, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n return null;\n}\n\n/**\n * Parse vitest config to extract coverage settings\n */\nfunction parseCoverageConfig(configPath: string): {\n hasCoverageConfig: boolean;\n coverageProvider: \"v8\" | \"istanbul\" | null;\n} {\n try {\n const content = readFileSync(configPath, \"utf-8\");\n\n // Check if coverage block exists using regex\n const hasCoverageConfig = /coverage\\s*:\\s*\\{/.test(content);\n\n if (!hasCoverageConfig) {\n return { hasCoverageConfig: false, coverageProvider: null };\n }\n\n // Extract provider value using regex\n // Match patterns like: provider: \"v8\", provider: 'v8', provider: \"istanbul\", etc.\n const providerMatch = content.match(/provider\\s*:\\s*[\"']?(v8|istanbul)[\"']?/);\n const coverageProvider = providerMatch\n ? (providerMatch[1] as \"v8\" | \"istanbul\")\n : null;\n\n return { hasCoverageConfig, coverageProvider };\n } catch {\n return { hasCoverageConfig: false, coverageProvider: null };\n }\n}\n\n/**\n * Check if coverage data file exists and get its age\n */\nfunction findCoverageData(projectPath: string): {\n path: string | null;\n age: number | null;\n} {\n const coverageDataPath = join(projectPath, \"coverage\", \"coverage-final.json\");\n if (existsSync(coverageDataPath)) {\n try {\n const stats = statSync(coverageDataPath);\n const age = Date.now() - stats.mtimeMs;\n return { path: coverageDataPath, age };\n } catch {\n return { path: coverageDataPath, age: null };\n }\n }\n return { path: null, age: null };\n}\n\n/**\n * Detect coverage setup in a project\n */\nexport function detectCoverageSetup(projectPath: string): CoverageSetupInfo {\n const { hasVitest, hasCoveragePackage } = checkPackageDeps(projectPath);\n const vitestConfigPath = findVitestConfig(projectPath);\n const hasVitestConfig = vitestConfigPath !== null;\n\n let hasCoverageConfig = false;\n let coverageProvider: \"v8\" | \"istanbul\" | null = null;\n\n if (vitestConfigPath) {\n const coverageInfo = parseCoverageConfig(vitestConfigPath);\n hasCoverageConfig = coverageInfo.hasCoverageConfig;\n coverageProvider = coverageInfo.coverageProvider;\n }\n\n const coverageData = findCoverageData(projectPath);\n const hasCoverageData = coverageData.path !== null;\n\n // Compute preparation flags\n const needsCoveragePackage = hasVitest && !hasCoveragePackage;\n const needsCoverageConfig = hasVitest && hasVitestConfig && !hasCoverageConfig;\n\n return {\n hasVitest,\n hasVitestConfig,\n vitestConfigPath,\n hasCoverageConfig,\n coverageProvider,\n hasCoverageData,\n coverageDataPath: coverageData.path,\n needsCoveragePackage,\n needsCoverageConfig,\n coverageDataAge: coverageData.age,\n };\n}\n"],"mappings":";AAMA,SAAS,YAAY,cAAc,gBAAgB;AACnD,SAAS,YAAY;AA2BrB,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUA,SAAS,iBAAiB,aAAsC;AAC9D,MAAI;AACF,UAAM,UAAU,KAAK,aAAa,cAAc;AAChD,QAAI,CAAC,WAAW,OAAO,EAAG,QAAO,EAAE,WAAW,OAAO,oBAAoB,MAAM;AAE/E,UAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAKrD,UAAM,OAAO,EAAE,GAAI,IAAI,gBAAgB,CAAC,GAAI,GAAI,IAAI,mBAAmB,CAAC,EAAG;AAC3E,UAAM,YAAY,YAAY;AAC9B,UAAM,qBACJ,yBAAyB,QAAQ,+BAA+B;AAElE,WAAO,EAAE,WAAW,mBAAmB;AAAA,EACzC,QAAQ;AACN,WAAO,EAAE,WAAW,OAAO,oBAAoB,MAAM;AAAA,EACvD;AACF;AAKA,SAAS,iBAAiB,aAAoC;AAC5D,aAAW,cAAc,qBAAqB;AAC5C,UAAM,aAAa,KAAK,aAAa,UAAU;AAC/C,QAAI,WAAW,UAAU,GAAG;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,oBAAoB,YAG3B;AACA,MAAI;AACF,UAAM,UAAU,aAAa,YAAY,OAAO;AAGhD,UAAM,oBAAoB,oBAAoB,KAAK,OAAO;AAE1D,QAAI,CAAC,mBAAmB;AACtB,aAAO,EAAE,mBAAmB,OAAO,kBAAkB,KAAK;AAAA,IAC5D;AAIA,UAAM,gBAAgB,QAAQ,MAAM,wCAAwC;AAC5E,UAAM,mBAAmB,gBACpB,cAAc,CAAC,IAChB;AAEJ,WAAO,EAAE,mBAAmB,iBAAiB;AAAA,EAC/C,QAAQ;AACN,WAAO,EAAE,mBAAmB,OAAO,kBAAkB,KAAK;AAAA,EAC5D;AACF;AAKA,SAAS,iBAAiB,aAGxB;AACA,QAAM,mBAAmB,KAAK,aAAa,YAAY,qBAAqB;AAC5E,MAAI,WAAW,gBAAgB,GAAG;AAChC,QAAI;AACF,YAAM,QAAQ,SAAS,gBAAgB;AACvC,YAAM,MAAM,KAAK,IAAI,IAAI,MAAM;AAC/B,aAAO,EAAE,MAAM,kBAAkB,IAAI;AAAA,IACvC,QAAQ;AACN,aAAO,EAAE,MAAM,kBAAkB,KAAK,KAAK;AAAA,IAC7C;AAAA,EACF;AACA,SAAO,EAAE,MAAM,MAAM,KAAK,KAAK;AACjC;AAKO,SAAS,oBAAoB,aAAwC;AAC1E,QAAM,EAAE,WAAW,mBAAmB,IAAI,iBAAiB,WAAW;AACtE,QAAM,mBAAmB,iBAAiB,WAAW;AACrD,QAAM,kBAAkB,qBAAqB;AAE7C,MAAI,oBAAoB;AACxB,MAAI,mBAA6C;AAEjD,MAAI,kBAAkB;AACpB,UAAM,eAAe,oBAAoB,gBAAgB;AACzD,wBAAoB,aAAa;AACjC,uBAAmB,aAAa;AAAA,EAClC;AAEA,QAAM,eAAe,iBAAiB,WAAW;AACjD,QAAM,kBAAkB,aAAa,SAAS;AAG9C,QAAM,uBAAuB,aAAa,CAAC;AAC3C,QAAM,sBAAsB,aAAa,mBAAmB,CAAC;AAE7D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,aAAa;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,iBAAiB,aAAa;AAAA,EAChC;AACF;","names":[]}
@@ -0,0 +1,24 @@
1
+ import { OperationState, PluginWithHandlers } from 'uilint-core';
2
+
3
+ interface CoveragePreparationStats {
4
+ packageAdded: boolean;
5
+ configModified: boolean;
6
+ testsRan: boolean;
7
+ coverageGenerated: boolean;
8
+ duration: number;
9
+ }
10
+ interface CoverageState {
11
+ preparation: OperationState<CoveragePreparationStats>;
12
+ coverageAvailable: boolean;
13
+ fileCount: number;
14
+ }
15
+
16
+ /**
17
+ * Coverage Plugin Definition
18
+ *
19
+ * Complete plugin export - NO REACT.
20
+ */
21
+
22
+ declare const coveragePlugin: PluginWithHandlers<CoverageState>;
23
+
24
+ export { type CoverageState, coveragePlugin, coveragePlugin as default };
@@ -0,0 +1,9 @@
1
+ import {
2
+ coveragePlugin,
3
+ plugin_default
4
+ } from "../chunk-TJZF52KU.js";
5
+ export {
6
+ coveragePlugin,
7
+ plugin_default as default
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "uilint-coverage",
3
+ "version": "0.2.150",
4
+ "description": "Test coverage analysis plugin for UILint",
5
+ "author": "Peter Suggate",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/peter-suggate/uilint.git",
9
+ "directory": "packages/uilint-coverage"
10
+ },
11
+ "homepage": "https://github.com/peter-suggate/uilint#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/peter-suggate/uilint/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "typesVersions": {
20
+ "*": {
21
+ "node": [
22
+ "./dist/node.d.ts"
23
+ ],
24
+ "*": [
25
+ "./dist/index.d.ts"
26
+ ]
27
+ }
28
+ },
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ },
34
+ "./node": {
35
+ "types": "./dist/node.d.ts",
36
+ "import": "./dist/node.js"
37
+ },
38
+ "./plugin": {
39
+ "types": "./dist/plugin/index.d.ts",
40
+ "import": "./dist/plugin/index.js"
41
+ },
42
+ "./eslint-rules": {
43
+ "types": "./dist/eslint-rules/index.d.ts",
44
+ "import": "./dist/eslint-rules/index.js"
45
+ },
46
+ "./eslint-rules/register": {
47
+ "types": "./dist/eslint-rules/register.d.ts",
48
+ "import": "./dist/eslint-rules/register.js"
49
+ },
50
+ "./eslint-rules/require-test-coverage": {
51
+ "types": "./dist/eslint-rules/require-test-coverage.d.ts",
52
+ "import": "./dist/eslint-rules/require-test-coverage.js"
53
+ },
54
+ "./cli-manifest": {
55
+ "types": "./dist/cli-manifest.d.ts",
56
+ "import": "./dist/cli-manifest.js"
57
+ }
58
+ },
59
+ "files": [
60
+ "dist",
61
+ "README.md"
62
+ ],
63
+ "engines": {
64
+ "node": ">=20.0.0"
65
+ },
66
+ "dependencies": {
67
+ "@typescript-eslint/utils": "^8.35.1",
68
+ "@typescript-eslint/typescript-estree": "^8.35.1",
69
+ "oxc-resolver": "^11.0.0"
70
+ },
71
+ "devDependencies": {
72
+ "@typescript-eslint/rule-tester": "^8.35.1",
73
+ "eslint": "^9.28.0",
74
+ "tsup": "^8.5.1",
75
+ "typescript": "^5.9.3",
76
+ "vitest": "^4.0.16"
77
+ },
78
+ "peerDependencies": {
79
+ "uilint-core": "0.2.152",
80
+ "uilint-eslint": "0.2.152"
81
+ },
82
+ "keywords": [
83
+ "test-coverage",
84
+ "code-analysis",
85
+ "react",
86
+ "typescript",
87
+ "lint",
88
+ "ui"
89
+ ],
90
+ "license": "MIT",
91
+ "publishConfig": {
92
+ "access": "public"
93
+ },
94
+ "scripts": {
95
+ "build": "tsup",
96
+ "dev": "tsup --watch",
97
+ "test": "vitest run",
98
+ "test:watch": "vitest",
99
+ "lint": "eslint src/",
100
+ "lint:strict": "eslint src/ --max-warnings 0",
101
+ "typecheck": "tsc --noEmit"
102
+ }
103
+ }