@poleski/quality-tools 0.1.3

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.
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@poleski/quality-tools",
3
+ "version": "0.1.3",
4
+ "type": "module",
5
+ "description": "Portable TypeScript quality checks for project structure, complexity, mutation, and test health",
6
+ "license": "MIT",
7
+ "bin": {
8
+ "quality-tools": "./dist/cli/main.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "stryker/",
13
+ "stryker.config.cjs",
14
+ "README.md",
15
+ "CHANGELOG.md",
16
+ "LICENSE"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "engines": {
22
+ "node": ">=22.22.0"
23
+ },
24
+ "dependencies": {
25
+ "@stryker-mutator/api": "^9.6.1",
26
+ "@stryker-mutator/core": "^9.6.1",
27
+ "@stryker-mutator/vitest-runner": "^9.6.1",
28
+ "glob": "^13.0.6",
29
+ "semver": "^7.7.4",
30
+ "typescript": "^5.3.3"
31
+ },
32
+ "devDependencies": {
33
+ "@changesets/cli": "^2.30.0",
34
+ "@eslint/js": "^9.0.0",
35
+ "@types/node": "^20.11.0",
36
+ "@vitest/coverage-istanbul": "^3.2.4",
37
+ "esbuild": "^0.25.0",
38
+ "eslint": "^9.0.0",
39
+ "tsx": "^4.21.0",
40
+ "vitest": "^3.0.0",
41
+ "typescript-eslint": "^8.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "esbuild src/cli/main.ts --bundle --platform=node --format=esm --packages=external --outfile=dist/cli/main.js",
45
+ "ci": "pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build",
46
+ "release": "pnpm run ci && pnpm publish --access public",
47
+ "changeset": "changeset",
48
+ "cli": "tsx src/cli/main.ts",
49
+ "quality-tools": "pnpm run cli",
50
+ "boundaries": "tsx src/cli/boundaries.ts",
51
+ "reachability": "tsx src/cli/reachability.ts",
52
+ "crap": "tsx src/cli/crap.ts",
53
+ "mutate": "tsx src/cli/mutate.ts",
54
+ "scrap": "tsx src/cli/scrap.ts",
55
+ "organize": "tsx src/cli/organize.ts",
56
+ "test": "vitest run --config vitest.config.ts",
57
+ "test:watch": "vitest --config vitest.config.ts",
58
+ "lint": "eslint src tests",
59
+ "typecheck": "tsc --noEmit -p tsconfig.json",
60
+ "version-packages": "changeset version"
61
+ }
62
+ }
@@ -0,0 +1,83 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import semver from 'semver';
4
+ import { createRequire } from 'node:module';
5
+ import { INSTRUMENTER_CONSTANTS } from '@stryker-mutator/api/core';
6
+ import { declareFactoryPlugin, PluginKind, commonTokens, tokens } from '@stryker-mutator/api/plugin';
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const vitestRunnerRoot = path.dirname(require.resolve('@stryker-mutator/vitest-runner/package.json'));
10
+ const { VitestTestRunner } = await import(path.join(vitestRunnerRoot, 'dist/src/vitest-test-runner.js'));
11
+ const { vitestWrapper } = await import(path.join(vitestRunnerRoot, 'dist/src/vitest-wrapper.js'));
12
+
13
+ const STRYKER_SETUP = path.join(vitestRunnerRoot, 'dist/src/stryker-setup.js');
14
+ const STRYKER_SETUP_SOURCE_MAP = 'stryker-setup.js.map';
15
+
16
+ function createStrykerSetupSourceMap(setupFilePath) {
17
+ return JSON.stringify({
18
+ version: 3,
19
+ file: path.basename(setupFilePath),
20
+ sources: [],
21
+ names: [],
22
+ mappings: '',
23
+ });
24
+ }
25
+
26
+ class QualityToolsVitestTestRunner extends VitestTestRunner {
27
+ async init() {
28
+ this.setEnv();
29
+ await fs.promises.copyFile(STRYKER_SETUP, this.localSetupFile);
30
+ await fs.promises.writeFile(
31
+ path.resolve(path.dirname(this.localSetupFile), STRYKER_SETUP_SOURCE_MAP),
32
+ createStrykerSetupSourceMap(this.localSetupFile),
33
+ );
34
+
35
+ this.ctx = await vitestWrapper.createVitest('test', {
36
+ config: this.options.vitest?.configFile,
37
+ pool: 'forks',
38
+ coverage: { enabled: false },
39
+ watch: false,
40
+ dir: this.options.vitest?.dir,
41
+ bail: this.options.disableBail ? 0 : 1,
42
+ onConsoleLog: () => false,
43
+ });
44
+ this.ctx.provide('globalNamespace', this.globalNamespace);
45
+ this.ctx.provide(
46
+ 'isGreaterThanVitest4Point1',
47
+ semver.satisfies(vitestWrapper.version, '>=4.1.0'),
48
+ );
49
+ this.ctx.config.browser.screenshotFailures = false;
50
+ this.ctx.projects.forEach((project) => {
51
+ project.config.setupFiles = [
52
+ this.localSetupFile,
53
+ ...project.config.setupFiles,
54
+ ];
55
+ project.config.browser.screenshotFailures = false;
56
+ });
57
+ if (this.log.isDebugEnabled()) {
58
+ this.log.debug(`vitest final config: ${JSON.stringify(this.ctx.config, null, 2)}`);
59
+ }
60
+ }
61
+ }
62
+
63
+ function createQualityToolsVitestTestRunnerFactory(
64
+ namespace = INSTRUMENTER_CONSTANTS.NAMESPACE,
65
+ ) {
66
+ createQualityToolsVitestTestRunner.inject = tokens(commonTokens.injector);
67
+ function createQualityToolsVitestTestRunner(injector) {
68
+ return injector
69
+ .provideValue('globalNamespace', namespace)
70
+ .injectClass(QualityToolsVitestTestRunner);
71
+ }
72
+ return createQualityToolsVitestTestRunner;
73
+ }
74
+
75
+ export const qualityToolsVitestTestRunnerFactory = createQualityToolsVitestTestRunnerFactory();
76
+
77
+ export const strykerPlugins = [
78
+ declareFactoryPlugin(
79
+ PluginKind.TestRunner,
80
+ 'quality-tools-vitest',
81
+ qualityToolsVitestTestRunnerFactory,
82
+ ),
83
+ ];
@@ -0,0 +1,65 @@
1
+ const path = require('node:path');
2
+
3
+ const packageRoot = __dirname;
4
+ const hostRoot = process.cwd();
5
+ const vitestConfig = process.env.QUALITY_TOOLS_VITEST_CONFIG ?? 'vitest.config.ts';
6
+ const vitestDir = process.env.QUALITY_TOOLS_VITEST_DIR;
7
+ const reportsDir = process.env.QUALITY_TOOLS_REPORTS_DIR ?? 'reports/quality-tools';
8
+ const mutationReportsDir = path.join(reportsDir, 'mutation');
9
+ const numberFromEnv = (name, fallback) => {
10
+ const rawValue = process.env[name];
11
+ if (!rawValue) {
12
+ return fallback;
13
+ }
14
+ const parsed = Number(rawValue);
15
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
16
+ };
17
+
18
+ module.exports = {
19
+ $schema: 'https://raw.githubusercontent.com/stryker-mutator/stryker-js/master/packages/core/schema/stryker-core.schema.json',
20
+ packageManager: process.env.QUALITY_TOOLS_PACKAGE_MANAGER ?? 'pnpm',
21
+ testRunner: 'quality-tools-vitest',
22
+ plugins: [
23
+ path.join(packageRoot, 'stryker/quality-tools-vitest-runner.mjs'),
24
+ '@stryker-mutator/vitest-runner',
25
+ ],
26
+ vitest: {
27
+ configFile: path.isAbsolute(vitestConfig) ? vitestConfig : path.join(hostRoot, vitestConfig),
28
+ dir: vitestDir,
29
+ related: false,
30
+ },
31
+ reporters: [
32
+ 'progress',
33
+ 'clear-text',
34
+ 'json',
35
+ 'html',
36
+ ],
37
+ jsonReporter: {
38
+ fileName: path.join(mutationReportsDir, 'mutation.json'),
39
+ },
40
+ htmlReporter: {
41
+ fileName: path.join(mutationReportsDir, 'mutation.html'),
42
+ },
43
+ concurrency: numberFromEnv('QUALITY_TOOLS_STRYKER_CONCURRENCY', 2),
44
+ coverageAnalysis: 'perTest',
45
+ maxTestRunnerReuse: numberFromEnv('QUALITY_TOOLS_STRYKER_MAX_TEST_RUNNER_REUSE', 0),
46
+ testRunnerNodeArgs: [
47
+ '--max-old-space-size=8192',
48
+ ],
49
+ dryRunTimeoutMinutes: 30,
50
+ incremental: true,
51
+ incrementalFile: path.join(mutationReportsDir, 'stryker-incremental.json'),
52
+ ignorePatterns: [
53
+ '/coverage',
54
+ '/.vscode-test',
55
+ '/.vscode-test/**',
56
+ '/.stryker-tmp',
57
+ '/.stryker-tmp/**',
58
+ ],
59
+ ignoreStatic: true,
60
+ thresholds: {
61
+ high: 90,
62
+ low: 80,
63
+ break: null,
64
+ },
65
+ };