-
Notifications
You must be signed in to change notification settings - Fork 2
processors/typescript: depend on files listed in includes
in nearest tsconfig.json
#17
base: main
Are you sure you want to change the base?
Changes from all commits
07a8772
8641356
9f8339d
1eb792c
302539c
c160a94
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../project/tsconfig.json", | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["../decls/*.d.ts", "./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"include": ["../decls/one.d.ts", "./**/*.*"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -499,4 +499,39 @@ describe('dependencyTree', () => { | |
).rejects.toThrowErrorMatchingSnapshot(); | ||
}); | ||
}); | ||
|
||
describe('tsconfig', () => { | ||
beforeEach(() => { | ||
dependencyTree = new DependencyTree([fixture('tsconfigs')]); | ||
}); | ||
|
||
it('adds files in `include` from nearest tsconfig.json', async () => { | ||
expect.hasAssertions(); | ||
const result = await dependencyTree.gather(); | ||
const decl1 = fixture('tsconfigs', 'decls', 'one.d.ts'); | ||
const decl2 = fixture('tsconfigs', 'decls', 'two.d.ts'); | ||
expect(result).toStrictEqual({ | ||
missing: new Map(), | ||
resolved: new Map([ | ||
[fixture('tsconfigs', 'project', 'project.ts'), new Set([decl1])], | ||
[ | ||
fixture('tsconfigs', 'project', 'nested', 'nested.ts'), | ||
new Set([decl1]), | ||
], | ||
[fixture('tsconfigs', 'glob', 'glob.ts'), new Set([decl1, decl2])], | ||
// "includes" is overwritten in the child config | ||
[fixture('tsconfigs', 'extends', 'extends.ts'), new Set([])], | ||
// decls in the same dir that includes './**.*.*' depend on one another | ||
[fixture('tsconfigs', 'decls', 'one.d.ts'), new Set([decl2])], | ||
[fixture('tsconfigs', 'decls', 'two.d.ts'), new Set([decl1])], | ||
Comment on lines
+525
to
+526
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seemed a little odd to me at first but it makes sense. If I have |
||
// files can depend on decls in the same dir | ||
[ | ||
fixture('tsconfigs', 'mixed', 'source.ts'), | ||
new Set([fixture('tsconfigs', 'mixed', 'decl.d.ts')]), | ||
], | ||
[fixture('tsconfigs', 'mixed', 'decl.d.ts'), new Set([])], | ||
]), | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,6 +104,16 @@ export class TypeScriptFileProcessor implements FileProcessor { | |
dependencyTree: DependencyTree, | ||
): Promise<Set<Path>> { | ||
const importedFiles = new Set<Path>(); | ||
|
||
// TypeScript files can *implicitly* depend on .d.ts files. We discover | ||
// these files by extracting them from the nearest tsconfig.json file. | ||
// These do not need to be processed further since they have already been fully | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are sure these are absolute paths at all times? |
||
// resolved by the typescript compiler. | ||
const includes = await this.includesFromNearestTsconfigFile(file); | ||
for (const include of includes) { | ||
importedFiles.add(include); | ||
} | ||
|
||
const filesList = ts | ||
.preProcessFile(contents, true, true) | ||
.importedFiles.map(({ fileName }) => fileName); | ||
|
@@ -189,6 +199,51 @@ export class TypeScriptFileProcessor implements FileProcessor { | |
}, | ||
); | ||
|
||
private async includesFromNearestTsconfigFile(file: Path): Promise<string[]> { | ||
const tsconfigPath = ts.findConfigFile( | ||
path.dirname(file), | ||
ts.sys.fileExists, | ||
); | ||
if (!tsconfigPath) { | ||
throw new Error( | ||
`could not find a tsconfig file for '${path.relative( | ||
this.rootDir, | ||
file, | ||
)}'`, | ||
); | ||
} | ||
if (!tsconfigPath.startsWith(this.rootDir)) { | ||
throw new Error( | ||
`invalid tsconfig file '${path.relative( | ||
this.rootDir, | ||
tsconfigPath, | ||
)}' found for '${path.relative( | ||
this.rootDir, | ||
file, | ||
)}'. expected a tsconfig file inside the project root '${ | ||
this.rootDir | ||
}'`, | ||
); | ||
} | ||
|
||
const json = ts.parseJsonText( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. much nicer :) |
||
tsconfigPath, | ||
await fs.promises.readFile(tsconfigPath, 'utf-8'), | ||
); | ||
const parsed = ts.parseJsonSourceFileConfigFileContent( | ||
json, | ||
ts.sys, | ||
path.dirname(tsconfigPath), | ||
); | ||
return parsed.fileNames.filter( | ||
(fileName) => | ||
// only include .d.ts files. all other references should be made using `import` or `require`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think standard ts(x) files can be referenced with types in them? Can you check? Maybe it makes sense for us to not filter this at all and just take the references verbatim? |
||
fileName.endsWith('.d.ts') && | ||
// files do not depend on themselves | ||
fileName !== file, | ||
); | ||
} | ||
|
||
// Finds an implicit 'import' in the entry point object literal, like: | ||
// | ||
// export const entryPoint: DynamicEntryPoint = { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@WearyMonkey 🎉