Skip to content

Commit e904f8a

Browse files
Copilotfelickz
andcommitted
Fix TypeScript to JavaScript mapping in CodeQL analysis
Co-authored-by: felickz <[email protected]>
1 parent 974b6b3 commit e904f8a

File tree

6 files changed

+389
-0
lines changed

6 files changed

+389
-0
lines changed

src/services/codeqlService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ export class CodeQLService {
136136
);
137137
}
138138

139+
// Ensure languages are always mapped to CodeQL languages, even if manually configured
140+
// This prevents issues where users might manually configure "typescript" instead of "javascript"
141+
languages = this.mapLanguagesToCodeQL(languages);
142+
139143
this.logger.info(
140144
"CodeQLService",
141145
`Detected languages: [${languages.join(", ")}]`

test_comprehensive_fix.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Comprehensive test for the TypeScript to JavaScript mapping fix
2+
// This test simulates the full flow from language detection to query pack resolution
3+
4+
const languages = {
5+
javascript: ["javascript", "typescript", "js", "ts", "jsx", "tsx"],
6+
python: ["python", "py"],
7+
java: ["java"],
8+
csharp: ["csharp", "c#", "cs"],
9+
cpp: ["cpp", "c++", "c", "cc", "cxx"],
10+
go: ["go", "golang"],
11+
ruby: ["ruby", "rb"],
12+
swift: ["swift"],
13+
kotlin: ["kotlin", "kt"],
14+
scala: ["scala"],
15+
};
16+
17+
function mapLanguagesToCodeQL(inputLanguages) {
18+
const results = [];
19+
const addedLanguages = new Set();
20+
21+
for (const language of inputLanguages) {
22+
const lang = language.toLowerCase();
23+
24+
// Direct match with CodeQL language
25+
if (languages[lang] && !addedLanguages.has(lang)) {
26+
results.push(lang);
27+
addedLanguages.add(lang);
28+
continue;
29+
}
30+
31+
// Check if it's an alias for a CodeQL language
32+
for (const [codeqlLang, aliases] of Object.entries(languages)) {
33+
if (aliases.includes(lang) && !addedLanguages.has(codeqlLang)) {
34+
results.push(codeqlLang);
35+
addedLanguages.add(codeqlLang);
36+
break;
37+
}
38+
}
39+
}
40+
41+
return [...new Set(results)]; // Remove any duplicates just in case
42+
}
43+
44+
// Simulate runLocalScan logic with the fix
45+
function simulateRunLocalScan(configuredLanguages, githubLanguages) {
46+
console.log('\n--- Simulating runLocalScan ---');
47+
console.log('Configured languages:', configuredLanguages);
48+
console.log('GitHub languages:', githubLanguages);
49+
50+
// Simulate the original logic
51+
let languages = configuredLanguages || [];
52+
if (!languages || languages.length === 0) {
53+
languages = mapLanguagesToCodeQL(githubLanguages);
54+
console.log('Languages after GitHub mapping:', languages);
55+
}
56+
57+
// Apply the fix: ensure languages are always mapped
58+
languages = mapLanguagesToCodeQL(languages);
59+
console.log('Final languages after fix:', languages);
60+
61+
// Simulate the processing loop
62+
for (const language of languages) {
63+
console.log(`Processing language: ${language}`);
64+
65+
// Simulate database path generation
66+
const databasePath = `/path/to/databases/repo/${language}`;
67+
console.log(` Database path: ${databasePath}`);
68+
69+
// Simulate output path generation
70+
const outputPath = `/path/to/results/repo-${language}-abcd1234.sarif`;
71+
console.log(` Output path: ${outputPath}`);
72+
73+
// Simulate query pack resolution
74+
const queryPack = `codeql/${language}-queries`;
75+
console.log(` Query pack: ${queryPack}`);
76+
77+
// Simulate suite path
78+
const suitePath = `${queryPack}:codeql-suites/${language}-code-scanning.qls`;
79+
console.log(` Suite path: ${suitePath}`);
80+
}
81+
82+
return languages;
83+
}
84+
85+
console.log('=== Comprehensive Test for TypeScript to JavaScript Mapping Fix ===');
86+
87+
// Test case 1: The original problematic scenario
88+
console.log('\n🔍 Test Case 1: Original problematic scenario (auto-detection with TypeScript)');
89+
const result1 = simulateRunLocalScan([], ["TypeScript"]);
90+
console.log('✅ Expected: javascript-based paths');
91+
console.log('✅ Result:', result1.includes('javascript') && !result1.includes('typescript') ? 'PASS' : 'FAIL');
92+
93+
// Test case 2: Mixed languages from GitHub
94+
console.log('\n🔍 Test Case 2: Mixed GitHub languages');
95+
const result2 = simulateRunLocalScan([], ["TypeScript", "Python", "JavaScript"]);
96+
console.log('✅ Expected: javascript and python');
97+
console.log('✅ Result:', JSON.stringify(result2.sort()) === '["javascript","python"]' ? 'PASS' : 'FAIL');
98+
99+
// Test case 3: Manual configuration with typescript (edge case)
100+
console.log('\n🔍 Test Case 3: Manual typescript configuration');
101+
const result3 = simulateRunLocalScan(["typescript"], []);
102+
console.log('✅ Expected: javascript');
103+
console.log('✅ Result:', JSON.stringify(result3) === '["javascript"]' ? 'PASS' : 'FAIL');
104+
105+
// Test case 4: Manual configuration with javascript (should still work)
106+
console.log('\n🔍 Test Case 4: Manual javascript configuration');
107+
const result4 = simulateRunLocalScan(["javascript"], []);
108+
console.log('✅ Expected: javascript');
109+
console.log('✅ Result:', JSON.stringify(result4) === '["javascript"]' ? 'PASS' : 'FAIL');
110+
111+
// Test case 5: Mixed manual configuration
112+
console.log('\n🔍 Test Case 5: Mixed manual configuration');
113+
const result5 = simulateRunLocalScan(["typescript", "python", "javascript"], []);
114+
console.log('✅ Expected: javascript and python');
115+
console.log('✅ Result:', JSON.stringify(result5.sort()) === '["javascript","python"]' ? 'PASS' : 'FAIL');
116+
117+
console.log('\n📋 Summary:');
118+
console.log('- Fix ensures TypeScript always maps to JavaScript');
119+
console.log('- Database paths use correct language (javascript)');
120+
console.log('- Output files use correct language (javascript)');
121+
console.log('- Query packs use correct language (javascript-queries)');
122+
console.log('- Suite paths use correct language (javascript-code-scanning.qls)');
123+
console.log('- Fix works for both auto-detection and manual configuration');
124+
console.log('- Prevents the "codeql/typescript-queries" error');

test_fix_verification.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Test to verify the fix for the TypeScript to JavaScript mapping issue
2+
const languages = {
3+
javascript: ["javascript", "typescript", "js", "ts", "jsx", "tsx"],
4+
python: ["python", "py"],
5+
java: ["java"],
6+
csharp: ["csharp", "c#", "cs"],
7+
cpp: ["cpp", "c++", "c", "cc", "cxx"],
8+
go: ["go", "golang"],
9+
ruby: ["ruby", "rb"],
10+
swift: ["swift"],
11+
kotlin: ["kotlin", "kt"],
12+
scala: ["scala"],
13+
};
14+
15+
function mapLanguagesToCodeQL(inputLanguages) {
16+
const results = [];
17+
const addedLanguages = new Set();
18+
19+
for (const language of inputLanguages) {
20+
const lang = language.toLowerCase();
21+
22+
// Direct match with CodeQL language
23+
if (languages[lang] && !addedLanguages.has(lang)) {
24+
results.push(lang);
25+
addedLanguages.add(lang);
26+
continue;
27+
}
28+
29+
// Check if it's an alias for a CodeQL language
30+
for (const [codeqlLang, aliases] of Object.entries(languages)) {
31+
if (aliases.includes(lang) && !addedLanguages.has(codeqlLang)) {
32+
results.push(codeqlLang);
33+
addedLanguages.add(codeqlLang);
34+
break;
35+
}
36+
}
37+
}
38+
39+
return [...new Set(results)]; // Remove any duplicates just in case
40+
}
41+
42+
// Simulate the problematic scenarios and test the fix
43+
console.log('Testing fix for TypeScript to JavaScript mapping issue...');
44+
45+
// Test case 1: Languages from GitHub detection (auto-detection)
46+
console.log('\n1. Testing auto-detection scenario:');
47+
const githubDetected = ["TypeScript", "JavaScript"];
48+
let mappedFromGithub = mapLanguagesToCodeQL(githubDetected);
49+
console.log('GitHub detected:', githubDetected);
50+
console.log('First mapping:', mappedFromGithub);
51+
52+
// Apply the fix: ensure languages are always mapped even if already in config
53+
let finalLanguages = mapLanguagesToCodeQL(mappedFromGithub);
54+
console.log('Final languages after fix:', finalLanguages);
55+
console.log('Expected: ["javascript"]');
56+
console.log('Pass:', JSON.stringify(finalLanguages) === '["javascript"]');
57+
58+
// Test case 2: User manually configured "typescript" in settings
59+
console.log('\n2. Testing manual configuration with typescript:');
60+
const manuallyConfigured = ["typescript"];
61+
let mappedManual = mapLanguagesToCodeQL(manuallyConfigured);
62+
console.log('Manually configured:', manuallyConfigured);
63+
console.log('Mapped result:', mappedManual);
64+
console.log('Expected: ["javascript"]');
65+
console.log('Pass:', JSON.stringify(mappedManual) === '["javascript"]');
66+
67+
// Test case 3: Mixed configuration with both javascript and typescript
68+
console.log('\n3. Testing mixed configuration:');
69+
const mixedConfig = ["javascript", "typescript", "python"];
70+
let mappedMixed = mapLanguagesToCodeQL(mixedConfig);
71+
console.log('Mixed configuration:', mixedConfig);
72+
console.log('Mapped result:', mappedMixed);
73+
console.log('Expected: ["javascript", "python"]');
74+
console.log('Pass:', JSON.stringify(mappedMixed) === '["javascript","python"]');
75+
76+
// Test case 4: Edge case - typescript only (simulating the problematic scenario)
77+
console.log('\n4. Testing TypeScript-only scenario:');
78+
const typescriptOnly = ["TypeScript"];
79+
let mappedTSOnly = mapLanguagesToCodeQL(typescriptOnly);
80+
console.log('TypeScript only:', typescriptOnly);
81+
console.log('Mapped result:', mappedTSOnly);
82+
console.log('Expected: ["javascript"]');
83+
console.log('Pass:', JSON.stringify(mappedTSOnly) === '["javascript"]');
84+
85+
console.log('\nAll tests completed. The fix ensures that:');
86+
console.log('- TypeScript always maps to JavaScript for CodeQL analysis');
87+
console.log('- Both auto-detected and manually configured languages are properly mapped');
88+
console.log('- Duplicate languages are handled correctly');
89+
console.log('- The fix prevents the "typescript-queries" error');

test_issue_scenario.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Test to reproduce the language mapping issue
2+
// This simulates the flow in runLocalScan()
3+
4+
const languages = {
5+
javascript: ["javascript", "typescript", "js", "ts", "jsx", "tsx"],
6+
python: ["python", "py"],
7+
java: ["java"],
8+
csharp: ["csharp", "c#", "cs"],
9+
cpp: ["cpp", "c++", "c", "cc", "cxx"],
10+
go: ["go", "golang"],
11+
ruby: ["ruby", "rb"],
12+
swift: ["swift"],
13+
kotlin: ["kotlin", "kt"],
14+
scala: ["scala"],
15+
};
16+
17+
function mapLanguagesToCodeQL(inputLanguages) {
18+
const results = [];
19+
const addedLanguages = new Set();
20+
21+
for (const language of inputLanguages) {
22+
const lang = language.toLowerCase();
23+
24+
// Direct match with CodeQL language
25+
if (languages[lang] && !addedLanguages.has(lang)) {
26+
results.push(lang);
27+
addedLanguages.add(lang);
28+
continue;
29+
}
30+
31+
// Check if it's an alias for a CodeQL language
32+
for (const [codeqlLang, aliases] of Object.entries(languages)) {
33+
if (aliases.includes(lang) && !addedLanguages.has(codeqlLang)) {
34+
results.push(codeqlLang);
35+
addedLanguages.add(codeqlLang);
36+
break;
37+
}
38+
}
39+
}
40+
41+
return [...new Set(results)]; // Remove any duplicates just in case
42+
}
43+
44+
// Simulate the problematic scenario
45+
console.log('Simulating the issue scenario...');
46+
47+
// Simulate GitHub API returning TypeScript as a language
48+
const githubLanguages = ["TypeScript", "JavaScript"];
49+
console.log('GitHub languages detected:', githubLanguages);
50+
51+
// Simulate the mapping that should happen
52+
const mappedLanguages = mapLanguagesToCodeQL(githubLanguages);
53+
console.log('Mapped languages:', mappedLanguages);
54+
55+
// Expected result: should be ["javascript"] (only one entry since both TypeScript and JavaScript map to javascript)
56+
console.log('Expected: ["javascript"]');
57+
console.log('Test passes:', JSON.stringify(mappedLanguages) === '["javascript"]');
58+
59+
// Check if there's an issue with duplicate handling
60+
console.log('\nTesting duplicate handling...');
61+
const testDuplicates = mapLanguagesToCodeQL(["javascript", "typescript", "js", "ts"]);
62+
console.log('Input: ["javascript", "typescript", "js", "ts"]');
63+
console.log('Output:', testDuplicates);
64+
console.log('Expected: ["javascript"]');
65+
console.log('Test passes:', JSON.stringify(testDuplicates) === '["javascript"]');
66+
67+
// Test with only TypeScript
68+
console.log('\nTesting TypeScript only...');
69+
const testTypescriptOnly = mapLanguagesToCodeQL(["TypeScript"]);
70+
console.log('Input: ["TypeScript"]');
71+
console.log('Output:', testTypescriptOnly);
72+
console.log('Expected: ["javascript"]');
73+
console.log('Test passes:', JSON.stringify(testTypescriptOnly) === '["javascript"]');

test_language_mapping.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Test script to verify language mapping behavior
2+
const { CodeQLService } = require('./out/services/codeqlService');
3+
4+
// Mock GitHub service for testing
5+
const mockGitHubService = {
6+
getRepositoryInfo: () => Promise.resolve({ owner: 'test', repo: 'test' })
7+
};
8+
9+
// Create CodeQL service instance
10+
const codeqlService = new CodeQLService(mockGitHubService);
11+
12+
// Test cases to verify the mapping
13+
console.log('Testing language mapping...');
14+
15+
// Test 1: TypeScript should map to JavaScript
16+
const typescriptLanguages = ['typescript', 'ts'];
17+
const mappedTS = codeqlService.mapLanguagesToCodeQL(typescriptLanguages);
18+
console.log('TypeScript languages:', typescriptLanguages, '-> Mapped to:', mappedTS);
19+
20+
// Test 2: Mixed languages including TypeScript
21+
const mixedLanguages = ['javascript', 'typescript', 'python', 'java'];
22+
const mappedMixed = codeqlService.mapLanguagesToCodeQL(mixedLanguages);
23+
console.log('Mixed languages:', mixedLanguages, '-> Mapped to:', mappedMixed);
24+
25+
// Test 3: Direct JavaScript should still work
26+
const jsLanguages = ['javascript', 'js'];
27+
const mappedJS = codeqlService.mapLanguagesToCodeQL(jsLanguages);
28+
console.log('JavaScript languages:', jsLanguages, '-> Mapped to:', mappedJS);
29+
30+
// Test 4: Check all supported languages
31+
const supportedLanguages = codeqlService.getLanguages();
32+
console.log('All supported CodeQL languages:', supportedLanguages);

0 commit comments

Comments
 (0)