ts-reconf 0.4.0 → 0.4.1

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
+ export {};
@@ -0,0 +1,76 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { analyze } from '../analyzer.js';
3
+ describe('Analyzer', () => {
4
+ it('should return empty findings for clean config', () => {
5
+ const config = {
6
+ compilerOptions: {
7
+ target: 99,
8
+ module: 99,
9
+ },
10
+ rawConfig: {},
11
+ };
12
+ const findings = analyze(config);
13
+ expect(Array.isArray(findings)).toBe(true);
14
+ });
15
+ it('should detect redundant options when strict is enabled', () => {
16
+ const config = {
17
+ compilerOptions: {
18
+ strict: true,
19
+ noImplicitAny: true,
20
+ strictNullChecks: true,
21
+ },
22
+ rawConfig: {},
23
+ };
24
+ const findings = analyze(config);
25
+ const redundantFindings = findings.filter(f => f.category === 'redundant');
26
+ expect(redundantFindings.length).toBeGreaterThan(0);
27
+ expect(redundantFindings.some(f => f.message.includes('noImplicitAny'))).toBe(true);
28
+ });
29
+ it('should provide explanations for skipLibCheck', () => {
30
+ const config = {
31
+ compilerOptions: {
32
+ skipLibCheck: true,
33
+ },
34
+ rawConfig: {},
35
+ };
36
+ const findings = analyze(config);
37
+ const explanations = findings.filter(f => f.category === 'explanation' && f.message.includes('skipLibCheck'));
38
+ expect(explanations.length).toBeGreaterThan(0);
39
+ });
40
+ it('should handle empty compiler options', () => {
41
+ const config = {
42
+ compilerOptions: {},
43
+ rawConfig: {},
44
+ };
45
+ const findings = analyze(config);
46
+ expect(Array.isArray(findings)).toBe(true);
47
+ });
48
+ it('should categorize findings with correct severity levels', () => {
49
+ const config = {
50
+ compilerOptions: {
51
+ strict: true,
52
+ noImplicitAny: true,
53
+ },
54
+ rawConfig: {},
55
+ };
56
+ const findings = analyze(config);
57
+ const severities = findings.map(f => f.severity);
58
+ severities.forEach(severity => {
59
+ expect(['info', 'warn', 'error']).toContain(severity);
60
+ });
61
+ });
62
+ it('should detect module resolution mismatches', () => {
63
+ const config = {
64
+ compilerOptions: {
65
+ module: 7, // ESNext
66
+ moduleResolution: 1, // Classic
67
+ },
68
+ rawConfig: {},
69
+ };
70
+ const findings = analyze(config);
71
+ const mismatches = findings.filter(f => f.message.includes('moduleResolution'));
72
+ // May or may not have mismatches depending on rules, but should not error
73
+ expect(Array.isArray(findings)).toBe(true);
74
+ });
75
+ });
76
+ //# sourceMappingURL=analyzer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.test.js","sourceRoot":"","sources":["../../src/__tests__/analyzer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,111 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { loadTsConfig } from '../loadTsConfig.js';
3
+ import { analyze } from '../analyzer.js';
4
+ import { toMarkdown, toPrettyOutput } from '../reporter.js';
5
+ import { writeFileSync, mkdirSync, rmSync } from 'fs';
6
+ import { join } from 'path';
7
+ describe('Integration Tests', () => {
8
+ const testDir = join(process.cwd(), '.test-integration');
9
+ beforeEach(() => {
10
+ mkdirSync(testDir, { recursive: true });
11
+ });
12
+ afterEach(() => {
13
+ rmSync(testDir, { recursive: true, force: true });
14
+ });
15
+ it('should complete full analysis pipeline', () => {
16
+ const configPath = join(testDir, 'tsconfig.json');
17
+ writeFileSync(configPath, JSON.stringify({
18
+ compilerOptions: {
19
+ target: 'ES2020',
20
+ module: 'commonjs',
21
+ strict: true,
22
+ noImplicitAny: true,
23
+ skipLibCheck: true,
24
+ },
25
+ include: ['src'],
26
+ }));
27
+ // Load config
28
+ const config = loadTsConfig(configPath);
29
+ expect(config).toBeDefined();
30
+ // Analyze
31
+ const findings = analyze(config);
32
+ expect(Array.isArray(findings)).toBe(true);
33
+ // Report - markdown
34
+ const markdown = toMarkdown(findings, 'tsconfig.json');
35
+ expect(markdown).toContain('tsconfig findings');
36
+ // Report - pretty
37
+ const pretty = toPrettyOutput(findings, 'tsconfig.json');
38
+ expect(pretty).toContain('Analyzing');
39
+ });
40
+ it('should analyze realistic tsconfig with multiple issues', () => {
41
+ const configPath = join(testDir, 'tsconfig.json');
42
+ writeFileSync(configPath, JSON.stringify({
43
+ compilerOptions: {
44
+ target: 'ES2020',
45
+ module: 'ES2020',
46
+ moduleResolution: 'node',
47
+ strict: true,
48
+ noImplicitAny: true,
49
+ noImplicitThis: true,
50
+ strictNullChecks: true,
51
+ skipLibCheck: true,
52
+ esModuleInterop: true,
53
+ declaration: true,
54
+ declarationMap: true,
55
+ sourceMap: true,
56
+ outDir: 'dist',
57
+ },
58
+ include: ['src'],
59
+ exclude: ['node_modules', 'dist'],
60
+ }));
61
+ const config = loadTsConfig(configPath);
62
+ const findings = analyze(config);
63
+ const report = toPrettyOutput(findings, 'tsconfig.json');
64
+ // Should find redundant strict options
65
+ const redundantFindings = findings.filter(f => f.category === 'redundant');
66
+ expect(redundantFindings.length).toBeGreaterThan(0);
67
+ // Report should be generated successfully
68
+ expect(report).toContain('Done');
69
+ });
70
+ it('should handle clean config gracefully', () => {
71
+ const configPath = join(testDir, 'tsconfig.json');
72
+ writeFileSync(configPath, JSON.stringify({
73
+ compilerOptions: {
74
+ target: 'ES2020',
75
+ module: 'commonjs',
76
+ },
77
+ include: ['src'],
78
+ }));
79
+ const config = loadTsConfig(configPath);
80
+ const findings = analyze(config);
81
+ // Even if there are no issues, the pipeline should work
82
+ expect(Array.isArray(findings)).toBe(true);
83
+ const report = toPrettyOutput(findings);
84
+ expect(report).toBeDefined();
85
+ });
86
+ it('should preserve all information through pipeline', () => {
87
+ const configPath = join(testDir, 'tsconfig.json');
88
+ const testConfig = {
89
+ compilerOptions: {
90
+ strict: true,
91
+ noImplicitAny: true,
92
+ target: 'ES2020',
93
+ },
94
+ include: ['src', 'tests'],
95
+ exclude: ['node_modules'],
96
+ files: ['index.ts'],
97
+ };
98
+ writeFileSync(configPath, JSON.stringify(testConfig));
99
+ const config = loadTsConfig(configPath);
100
+ // Raw config should be preserved
101
+ expect(config.rawConfig.include).toEqual(['src', 'tests']);
102
+ expect(config.rawConfig.exclude).toEqual(['node_modules']);
103
+ expect(config.rawConfig.files).toEqual(['index.ts']);
104
+ // Compiler options should be set
105
+ expect(config.compilerOptions.strict).toBe(true);
106
+ // Analysis should work on preserved data
107
+ const findings = analyze(config);
108
+ expect(findings).toBeDefined();
109
+ });
110
+ });
111
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,79 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { loadTsConfig } from '../loadTsConfig.js';
3
+ import { writeFileSync, mkdirSync, rmSync } from 'fs';
4
+ import { join } from 'path';
5
+ describe('loadTsConfig', () => {
6
+ const testDir = join(process.cwd(), '.test-tsconfig');
7
+ beforeEach(() => {
8
+ mkdirSync(testDir, { recursive: true });
9
+ });
10
+ afterEach(() => {
11
+ rmSync(testDir, { recursive: true, force: true });
12
+ });
13
+ it('should load valid tsconfig.json', () => {
14
+ const configPath = join(testDir, 'tsconfig.json');
15
+ writeFileSync(configPath, JSON.stringify({
16
+ compilerOptions: {
17
+ target: 'ES2020',
18
+ module: 'commonjs',
19
+ },
20
+ include: ['src'],
21
+ }));
22
+ const config = loadTsConfig(configPath);
23
+ expect(config).toHaveProperty('compilerOptions');
24
+ expect(config).toHaveProperty('rawConfig');
25
+ expect(config.compilerOptions).toBeDefined();
26
+ });
27
+ it('should parse compiler options correctly', () => {
28
+ const configPath = join(testDir, 'tsconfig.json');
29
+ writeFileSync(configPath, JSON.stringify({
30
+ compilerOptions: {
31
+ target: 'ES2022',
32
+ strict: true,
33
+ declaration: true,
34
+ },
35
+ }));
36
+ const config = loadTsConfig(configPath);
37
+ expect(config.compilerOptions.strict).toBe(true);
38
+ expect(config.compilerOptions.declaration).toBe(true);
39
+ });
40
+ it('should preserve raw config include/exclude/files', () => {
41
+ const configPath = join(testDir, 'tsconfig.json');
42
+ writeFileSync(configPath, JSON.stringify({
43
+ compilerOptions: { target: 'ES2020' },
44
+ include: ['src'],
45
+ exclude: ['node_modules', 'dist'],
46
+ files: ['index.ts'],
47
+ }));
48
+ const config = loadTsConfig(configPath);
49
+ expect(config.rawConfig.include).toEqual(['src']);
50
+ expect(config.rawConfig.exclude).toEqual(['node_modules', 'dist']);
51
+ expect(config.rawConfig.files).toEqual(['index.ts']);
52
+ });
53
+ it('should throw error for invalid JSON', () => {
54
+ const configPath = join(testDir, 'tsconfig.json');
55
+ writeFileSync(configPath, '{invalid json}');
56
+ expect(() => loadTsConfig(configPath)).toThrow();
57
+ });
58
+ it('should throw error for missing file', () => {
59
+ const configPath = join(testDir, 'nonexistent.json');
60
+ expect(() => loadTsConfig(configPath)).toThrow();
61
+ });
62
+ it('should handle extends property in raw config', () => {
63
+ const configPath = join(testDir, 'tsconfig.json');
64
+ writeFileSync(configPath, JSON.stringify({
65
+ extends: './tsconfig.base.json',
66
+ compilerOptions: { strict: true },
67
+ }));
68
+ const config = loadTsConfig(configPath);
69
+ expect(config.rawConfig.extends).toBe('./tsconfig.base.json');
70
+ });
71
+ it('should handle empty config file', () => {
72
+ const configPath = join(testDir, 'tsconfig.json');
73
+ writeFileSync(configPath, JSON.stringify({}));
74
+ const config = loadTsConfig(configPath);
75
+ expect(config.compilerOptions).toBeDefined();
76
+ expect(config.rawConfig).toBeDefined();
77
+ });
78
+ });
79
+ //# sourceMappingURL=loadTsConfig.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadTsConfig.test.js","sourceRoot":"","sources":["../../src/__tests__/loadTsConfig.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,95 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { toMarkdown, toPrettyOutput } from '../reporter.js';
3
+ describe('Reporter', () => {
4
+ const mockFindings = [
5
+ {
6
+ ruleId: 'test.redundant',
7
+ message: 'noImplicitAny is redundant',
8
+ severity: 'info',
9
+ category: 'redundant',
10
+ },
11
+ {
12
+ ruleId: 'test.explanation',
13
+ message: 'skipLibCheck improves build speed',
14
+ severity: 'info',
15
+ category: 'explanation',
16
+ },
17
+ {
18
+ ruleId: 'test.conflict',
19
+ message: 'Module and moduleResolution conflict',
20
+ severity: 'warn',
21
+ category: 'conflict',
22
+ },
23
+ ];
24
+ describe('toMarkdown', () => {
25
+ it('should return success message for empty findings', () => {
26
+ const output = toMarkdown([], 'tsconfig.json');
27
+ expect(output).toContain('Looks good!');
28
+ expect(output).toContain('No issues found');
29
+ });
30
+ it('should list findings in markdown format', () => {
31
+ const output = toMarkdown(mockFindings, 'tsconfig.json');
32
+ expect(output).toContain('tsconfig findings');
33
+ expect(output).toContain('noImplicitAny is redundant');
34
+ expect(output).toContain('skipLibCheck improves build speed');
35
+ expect(output).toContain('Module and moduleResolution conflict');
36
+ });
37
+ it('should format findings as markdown list items', () => {
38
+ const output = toMarkdown(mockFindings);
39
+ expect(output).toMatch(/- .+/); // Should have list items
40
+ });
41
+ it('should handle undefined file parameter', () => {
42
+ const output = toMarkdown(mockFindings);
43
+ expect(output).toContain('tsconfig findings');
44
+ });
45
+ });
46
+ describe('toPrettyOutput', () => {
47
+ it('should return success message for empty findings', () => {
48
+ const output = toPrettyOutput([], 'tsconfig.json');
49
+ expect(output).toContain('Looks good!');
50
+ expect(output).toContain('No issues found');
51
+ //expect(output).toContain('Done');
52
+ });
53
+ it('should group findings by category', () => {
54
+ const output = toPrettyOutput(mockFindings);
55
+ expect(output).toContain('Conflict');
56
+ expect(output).toContain('Redundant');
57
+ expect(output).toContain('Explanation');
58
+ });
59
+ it('should display category counts', () => {
60
+ const output = toPrettyOutput(mockFindings);
61
+ expect(output).toMatch(/Redundant \(\d+\)/);
62
+ expect(output).toMatch(/Explanation \(\d+\)/);
63
+ expect(output).toMatch(/Conflict \(\d+\)/);
64
+ });
65
+ it('should format findings with bullet points', () => {
66
+ const output = toPrettyOutput(mockFindings);
67
+ expect(output).toContain('•');
68
+ });
69
+ it('should include file name in output', () => {
70
+ const output = toPrettyOutput(mockFindings, 'my-tsconfig.json');
71
+ expect(output).toContain('my-tsconfig.json');
72
+ });
73
+ it('should have visual separators', () => {
74
+ const output = toPrettyOutput(mockFindings);
75
+ expect(output).toContain('────────────');
76
+ });
77
+ });
78
+ describe('Output consistency', () => {
79
+ it('markdown output should be compact', () => {
80
+ const markdown = toMarkdown(mockFindings);
81
+ const pretty = toPrettyOutput(mockFindings);
82
+ // Markdown should generally be shorter (no formatting)
83
+ expect(markdown.length).toBeLessThanOrEqual(pretty.length);
84
+ });
85
+ it('both formats should include all findings', () => {
86
+ const markdown = toMarkdown(mockFindings);
87
+ const pretty = toPrettyOutput(mockFindings);
88
+ mockFindings.forEach(finding => {
89
+ expect(markdown).toContain(finding.message);
90
+ expect(pretty).toContain(finding.message);
91
+ });
92
+ });
93
+ });
94
+ });
95
+ //# sourceMappingURL=reporter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.test.js","sourceRoot":"","sources":["../../src/__tests__/reporter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ describe('Type Definitions', () => {
3
+ it('should create valid Finding objects', () => {
4
+ const finding = {
5
+ ruleId: 'test.rule',
6
+ message: 'Test message',
7
+ severity: 'info',
8
+ category: 'redundant',
9
+ };
10
+ expect(finding.ruleId).toBe('test.rule');
11
+ expect(finding.message).toBe('Test message');
12
+ expect(['info', 'warn', 'error']).toContain(finding.severity);
13
+ });
14
+ it('should accept all valid severity levels', () => {
15
+ const severities = ['info', 'warn', 'error'];
16
+ severities.forEach(severity => {
17
+ const finding = {
18
+ ruleId: 'test',
19
+ message: 'test',
20
+ severity,
21
+ category: 'redundant',
22
+ };
23
+ expect(finding.severity).toBe(severity);
24
+ });
25
+ });
26
+ it('should accept all valid categories', () => {
27
+ const categories = [
28
+ 'conflict',
29
+ 'legacy',
30
+ 'redundant',
31
+ 'suggestion',
32
+ 'explanation',
33
+ ];
34
+ categories.forEach(category => {
35
+ const finding = {
36
+ ruleId: 'test',
37
+ message: 'test',
38
+ severity: 'info',
39
+ category,
40
+ };
41
+ expect(finding.category).toBe(category);
42
+ });
43
+ });
44
+ it('should create valid AnalysisContext objects', () => {
45
+ const context = {
46
+ compilerOptions: {
47
+ strict: true,
48
+ target: 99,
49
+ },
50
+ rawConfig: {
51
+ include: ['src'],
52
+ exclude: ['node_modules'],
53
+ },
54
+ };
55
+ expect(context.compilerOptions).toBeDefined();
56
+ expect(context.rawConfig).toBeDefined();
57
+ });
58
+ it('should enforce Rule interface contract', () => {
59
+ const rule = {
60
+ id: 'test.rule',
61
+ analyze: (config) => {
62
+ return [];
63
+ },
64
+ };
65
+ expect(rule.id).toBe('test.rule');
66
+ expect(typeof rule.analyze).toBe('function');
67
+ const findings = rule.analyze({
68
+ compilerOptions: {},
69
+ rawConfig: {},
70
+ });
71
+ expect(Array.isArray(findings)).toBe(true);
72
+ });
73
+ });
74
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"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"}
package/dist/analyzer.js CHANGED
@@ -1,4 +1,4 @@
1
- import { legacyOptionRule, strictRedundantRule, skipLibCheckRule, defaultRedundantRule, targetLibConflictRule, moduleKindCheckRule, allowJsCheckRule, noEmitOutDirCheckRule, noIncludeOrFilesCheckRule, moduleResolutionMismatchRule, declarationNoEmitCheckRule, verbatimModuleIsolatedModulesRule, verbatimModuleSyntaxCheckRule, allowSyntheticDefaultImportsRule, noUncheckedIndexedAccessRule, forceConsistentCasingInFileNamesRule, moduleResolutionOutdatedRule, emitDeclarationOnlyRule, legacyJsxTransformCheckRule, } from "./rules/index.js";
1
+ import { legacyOptionRule, strictRedundantRule, skipLibCheckRule, defaultRedundantRule, targetLibConflictRule, moduleKindCheckRule, allowJsCheckRule, noEmitOutDirCheckRule, noIncludeOrFilesCheckRule, moduleResolutionMismatchRule, declarationNoEmitCheckRule, verbatimModuleIsolatedModulesRule, verbatimModuleSyntaxCheckRule, allowSyntheticDefaultImportsRule, noUncheckedIndexedAccessRule, forceConsistentCasingInFileNamesRule, moduleResolutionOutdatedRule, emitDeclarationOnlyRule, legacyJsxTransformCheckRule, declarationMapCheckRule, } from "./rules/index.js";
2
2
  const rules = [
3
3
  legacyOptionRule,
4
4
  strictRedundantRule,
@@ -19,6 +19,7 @@ const rules = [
19
19
  moduleResolutionOutdatedRule,
20
20
  emitDeclarationOnlyRule,
21
21
  legacyJsxTransformCheckRule,
22
+ declarationMapCheckRule,
22
23
  ];
23
24
  export function analyze(config) {
24
25
  return rules.flatMap(rule => rule.analyze(config));
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,iCAAiC,EACjC,6BAA6B,EAC7B,gCAAgC,EAChC,4BAA4B,EAC5B,oCAAoC,EACpC,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,GAC9B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,KAAK,GAAW;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,gBAAgB;IAChB,qBAAqB;IACrB,yBAAyB;IACzB,4BAA4B;IAC5B,0BAA0B;IAC1B,iCAAiC;IACjC,6BAA6B;IAC7B,gCAAgC;IAChC,4BAA4B;IAC5B,oCAAoC;IACpC,4BAA4B;IAC5B,uBAAuB;IACvB,2BAA2B;CAC9B,CAAC;AAEF,MAAM,UAAU,OAAO,CAAC,MAAuB;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,iCAAiC,EACjC,6BAA6B,EAC7B,gCAAgC,EAChC,4BAA4B,EAC5B,oCAAoC,EACpC,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,KAAK,GAAW;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,gBAAgB;IAChB,qBAAqB;IACrB,yBAAyB;IACzB,4BAA4B;IAC5B,0BAA0B;IAC1B,iCAAiC;IACjC,6BAA6B;IAC7B,gCAAgC;IAChC,4BAA4B;IAC5B,oCAAoC;IACpC,4BAA4B;IAC5B,uBAAuB;IACvB,2BAA2B;IAC3B,uBAAuB;CAC1B,CAAC;AAEF,MAAM,UAAU,OAAO,CAAC,MAAuB;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC"}
package/dist/reporter.js CHANGED
@@ -1,4 +1,9 @@
1
1
  const NO_ISSUES_FOUND_MSG = "## Looks good! 🎉 No issues found ✔\n";
2
+ const SeverityIcons = new Map([
3
+ ["info", "ℹ"],
4
+ ["warn", "⚠"],
5
+ ["error", "✖"]
6
+ ]);
2
7
  export function toMarkdown(findings, file) {
3
8
  const lines = [`## tsconfig findings for ${file ?? ""}:\n`];
4
9
  if (findings.length === 0) {
@@ -35,7 +40,7 @@ export function toPrettyOutput(findings, file) {
35
40
  category.slice(1);
36
41
  lines.push(`${title} (${items.length})`);
37
42
  for (const item of items) {
38
- lines.push(` • ${item.message}`);
43
+ lines.push(` • ${SeverityIcons.get(item.severity)} ${item.message}`);
39
44
  }
40
45
  lines.push("");
41
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAG,uCAAuC,CAAC;AAEpE,MAAM,UAAU,UAAU,CAAC,QAAmB,EAAE,IAAa;IACzD,MAAM,KAAK,GAAG,CAAC,4BAA4B,IAAI,IAAI,EAAE,KAAK,CAAC,CAAC;IAE5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,eAAe,CAAC,QAAmB;IACxC,MAAM,MAAM,GAA8B,EAAE,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QAClC,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAmB,EAAE,IAAa;IAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,+BAA+B,IAAI,IAAI,eAAe,KAAK,CAAC,CAAC;IAExE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1B,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEzC,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,MAAM,KAAK,GACP,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YAChC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEvB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Rule } from "../types.js";
2
+ export declare const declarationMapCheckRule: Rule;
@@ -0,0 +1,18 @@
1
+ const ruleId = "ts.declarationMap.noDeclaration";
2
+ export const declarationMapCheckRule = {
3
+ id: ruleId,
4
+ analyze(config) {
5
+ const compilerOptions = config.compilerOptions ?? {};
6
+ const findings = [];
7
+ if (compilerOptions.declarationMap && !compilerOptions.declaration) {
8
+ findings.push({
9
+ ruleId: ruleId,
10
+ category: "redundant",
11
+ severity: "warn",
12
+ message: `"declarationMap" emits ".d.ts.map" files but has no effect if "declaration" is not set to "true"`
13
+ });
14
+ }
15
+ return findings;
16
+ }
17
+ };
18
+ //# sourceMappingURL=declarationMapCheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarationMapCheck.js","sourceRoot":"","sources":["../../src/rules/declarationMapCheck.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,iCAAiC,CAAC;AAEjD,MAAM,CAAC,MAAM,uBAAuB,GAAS;IACzC,EAAE,EAAE,MAAM;IACV,OAAO,CAAC,MAAuB;QAC3B,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,IAAI,eAAe,CAAC,cAAc,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC;YACjE,QAAQ,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,WAAW;gBACrB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,kGAAkG;aAC9G,CAAC,CAAC;QACP,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;CAEJ,CAAA"}
@@ -17,3 +17,4 @@ export { forceConsistentCasingInFileNamesRule } from "./forceConsistentCasing.js
17
17
  export { moduleResolutionOutdatedRule } from "./moduleResolutionOutdated.js";
18
18
  export { emitDeclarationOnlyRule } from "./emitDeclarationOnly.js";
19
19
  export { legacyJsxTransformCheckRule } from "./legacyJsxTransformCheck.js";
20
+ export { declarationMapCheckRule } from "./declarationMapCheck.js";
@@ -17,4 +17,5 @@ export { forceConsistentCasingInFileNamesRule } from "./forceConsistentCasing.js
17
17
  export { moduleResolutionOutdatedRule } from "./moduleResolutionOutdated.js";
18
18
  export { emitDeclarationOnlyRule } from "./emitDeclarationOnly.js";
19
19
  export { legacyJsxTransformCheckRule } from "./legacyJsxTransformCheck.js";
20
+ export { declarationMapCheckRule } from "./declarationMapCheck.js";
20
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -1,4 +1,4 @@
1
- import { ModuleResolutionKind } from "typescript";
1
+ import { ModuleResolutionKind, ScriptTarget } from "typescript";
2
2
  const ruleId = "ts.moduleResolution.outdated";
3
3
  export const moduleResolutionOutdatedRule = {
4
4
  id: ruleId,
@@ -14,6 +14,15 @@ export const moduleResolutionOutdatedRule = {
14
14
  message: `"moduleResolution" is set to "node" (Node10), which is the legacy CommonJS resolution algorithm. It does not support package.json "exports", self-references via "imports", or ESM resolution rules. Consider upgrading to "node16", "nodenext" (for Node.js), or "bundler" (for Vite/Webpack/esbuild).`
15
15
  });
16
16
  }
17
+ const target = options.target;
18
+ if (target !== undefined && target < ScriptTarget.ES2017) {
19
+ findings.push({
20
+ ruleId: ruleId,
21
+ category: "suggestion",
22
+ severity: "warn",
23
+ message: `"target" is outdated. Consider upgrading to at least "ES2017" or "ES2020". See "https://github.com/tsconfig/bases#centralized-recommendations-for-tsconfig-bases" for more details`
24
+ });
25
+ }
17
26
  return findings;
18
27
  }
19
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"moduleResolutionOutdated.js","sourceRoot":"","sources":["../../src/rules/moduleResolutionOutdated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,GAAG,8BAA8B,CAAC;AAE9C,MAAM,CAAC,MAAM,4BAA4B,GAAS;IAC9C,EAAE,EAAE,MAAM;IAEV,OAAO,CAAC,MAAuB;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;QAE7C,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAElD,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,IAAI,gBAAgB,KAAK,oBAAoB,CAAC,MAAM,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,ySAAyS;aACrT,CAAC,CAAC;QACP,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ,CAAC"}
1
+ {"version":3,"file":"moduleResolutionOutdated.js","sourceRoot":"","sources":["../../src/rules/moduleResolutionOutdated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGhE,MAAM,MAAM,GAAG,8BAA8B,CAAC;AAE9C,MAAM,CAAC,MAAM,4BAA4B,GAAS;IAC9C,EAAE,EAAE,MAAM;IAEV,OAAO,CAAC,MAAuB;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;QAE7C,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QAElD,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,IAAI,gBAAgB,KAAK,oBAAoB,CAAC,MAAM,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,ySAAyS;aACrT,CAAC,CAAC;QACP,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC7B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,YAAY;gBACtB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,oLAAoL;aAChM,CAAC,CAAC;QACP,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -14,6 +14,7 @@ export interface AnalysisContext {
14
14
  exclude?: string[];
15
15
  files?: string[];
16
16
  extends?: string;
17
+ compileOnSave?: boolean;
17
18
  };
18
19
  }
19
20
  export interface Rule {
package/package.json CHANGED
@@ -1,45 +1,49 @@
1
- {
2
- "name": "ts-reconf",
3
- "version": "0.4.0",
4
- "description": "Understand and simplify (re-conf) your tsconfig.json",
5
- "main": "index.js",
6
- "type": "module",
7
- "bin": {
8
- "ts-reconf": "./dist/cli.js"
9
- },
10
- "files": [
11
- "dist",
12
- "README.md",
13
- "LICENSE"
14
- ],
15
- "repository": {
16
- "type": "git",
17
- "url": "https://github.com/rockcoder/ts-reconf.git"
18
- },
19
- "scripts": {
20
- "build": "tsc",
21
- "dev": "tsx src/cli.ts",
22
- "clean": "rm -rf dist",
23
- "start": "node dist/cli.js",
24
- "test": "echo \"Todo: write tests\" && exit 1",
25
- "prepublishOnly": "npm run clean && npm run build"
26
- },
27
- "engines": {
28
- "node": ">=18"
29
- },
30
- "keywords": [
31
- "typescript",
32
- "tsconfig",
33
- "cli",
34
- "developer-tools"
35
- ],
36
- "author": "rockcoder",
37
- "license": "MIT",
38
- "dependencies": {
39
- "typescript": "6.0.3"
40
- },
41
- "devDependencies": {
42
- "@types/node": "25.9.1",
43
- "tsx": "4.22.3"
44
- }
45
- }
1
+ {
2
+ "name": "ts-reconf",
3
+ "version": "0.4.1",
4
+ "description": "Understand and simplify (re-conf) your tsconfig.json",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "ts-reconf": "./dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/rockcoder/ts-reconf.git"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsx src/cli.ts",
22
+ "clean": "rm -rf dist",
23
+ "start": "node dist/cli.js",
24
+ "test": "vitest",
25
+ "test:run": "vitest run",
26
+ "test:coverage": "vitest run --coverage",
27
+ "prepublishOnly": "npm run clean && npm run build"
28
+ },
29
+ "engines": {
30
+ "node": ">=20"
31
+ },
32
+ "keywords": [
33
+ "typescript",
34
+ "tsconfig",
35
+ "cli",
36
+ "developer-tools"
37
+ ],
38
+ "author": "rockcoder",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "typescript": "6.0.3"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "25.9.1",
45
+ "@vitest/coverage-v8": "4.1.8",
46
+ "tsx": "4.22.4",
47
+ "vitest": "4.1.8"
48
+ }
49
+ }