Skip to content

Commit 4c4ac81

Browse files
committed
JS: Add helper for doing path resolution with JS rules
1 parent b4cde7a commit 4c4ac81

File tree

1 file changed

+65
-0
lines changed
  • javascript/ql/lib/semmle/javascript/internal/paths

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Provides predicates for use in `Folder::ResolveSig` in order to resolve
3+
* paths using JavaScript semantics.
4+
*/
5+
6+
private import javascript
7+
private import semmle.javascript.TSConfig
8+
9+
/**
10+
* Gets a folder name that is a common source folder name.
11+
*/
12+
string getASrcFolderName() { result = ["ts", "js", "src", "lib"] }
13+
14+
/**
15+
* Gets a folder name that is a common build output folder name.
16+
*/
17+
string getABuildOutputFolderName() { result = ["dist", "build", "out", "lib"] }
18+
19+
/**
20+
* Provides predicates for use in a `Folder::ResolveSig` in order to resolve
21+
* paths using JavaScript semantics.
22+
*
23+
* This accounts for two things:
24+
* - automatic file extensions (e.g `./foo` may resolve to `./foo.js`)
25+
* - mapping compiled-generated files back to their original source files
26+
*/
27+
module JSPaths {
28+
/**
29+
* Gets an additional child of `base` to include when resolving JS paths.
30+
*/
31+
pragma[nomagic]
32+
Container getAnAdditionalChild(Container base, string name) {
33+
// Automatically fill in file extensions
34+
result = base.(Folder).getJavaScriptFileOrTypings(name)
35+
or
36+
// When importing a .js file, map to the original file that compiles to the .js file.
37+
exists(string stem |
38+
result = base.(Folder).getJavaScriptFileOrTypings(stem) and
39+
name = stem + ".js"
40+
)
41+
or
42+
// Redirect './bar' to 'foo' given a tsconfig like:
43+
//
44+
// { include: ["foo"], compilerOptions: { outDir: "./bar" }}
45+
//
46+
exists(TSConfig tsconfig |
47+
name =
48+
tsconfig.getCompilerOptions().getPropStringValue("outDir").regexpReplaceAll("^\\./", "") and
49+
base = tsconfig.getFolder() and
50+
result = tsconfig.getEffectiveRootDir()
51+
)
52+
or
53+
// Heuristic version of the above based on commonly used source and build folder names
54+
exists(Folder folder | base = folder |
55+
folder = any(PackageJson pkg).getFolder() and
56+
name = getABuildOutputFolderName() and
57+
not exists(folder.getChildContainer(name)) and
58+
(
59+
result = folder.getChildContainer(getASrcFolderName())
60+
or
61+
result = folder
62+
)
63+
)
64+
}
65+
}

0 commit comments

Comments
 (0)