UNPKG

2.1 kBPlain TextView Raw
1// tslint:disable ban-types
2import Ast, { SourceFile, ts } from 'ts-simple-ast';
3
4import appRootDir from 'app-root-dir';
5import * as fs from 'fs-extra';
6import * as path from 'path';
7
8const findRoot = async (
9 dir: string | string[],
10 filename: string,
11): Promise<string> => {
12 let start = dir;
13
14 if (typeof start === 'string') {
15 if (start[start.length - 1] !== path.sep) {
16 start += path.sep;
17 }
18 start = start.split(path.sep);
19 }
20 if (!start.length) {
21 throw new Error('tsconfig.json not found in path');
22 }
23
24 start.pop();
25 const currentDir = start.join(path.sep);
26 const file = path.join(currentDir, filename);
27 const exists = await fs.pathExists(file);
28 if (exists) {
29 return file;
30 }
31
32 return findRoot(start, filename);
33};
34
35export const makeAst = async (dir: string): Promise<Ast> => {
36 const tsConfigFilePath = await findRoot(dir, 'tsconfig.json');
37 const res = ts.readConfigFile(tsConfigFilePath, (value) =>
38 fs.readFileSync(value, 'utf8'),
39 );
40 const parseConfigHost = {
41 fileExists: fs.existsSync,
42 readDirectory: ts.sys.readDirectory,
43 readFile: ts.sys.readFile,
44 useCaseSensitiveFileNames: true,
45 };
46 const parsed = ts.parseJsonConfigFileContent(
47 res.config,
48 parseConfigHost,
49 path.dirname(tsConfigFilePath),
50 );
51
52 return new Ast({ compilerOptions: parsed.options });
53};
54
55export const getAst = async (dir: string): Promise<Ast> => {
56 const ast = await makeAst(dir);
57 ast.addExistingSourceFiles(path.join(dir, '**', '*.ts'));
58 // For some reason this forces Ast to resolve references. Do not remove.
59 ast.getPreEmitDiagnostics();
60 return ast;
61};
62
63export const getAstForSnippet = async (
64 code: string,
65): Promise<{ ast: Ast; sourceFile: SourceFile }> => {
66 const ast = await makeAst(appRootDir.get());
67 const sourceFile = ast.createSourceFile('code.ts', code);
68 // For some reason this forces Ast to resolve references. Do not remove.
69 ast.getPreEmitDiagnostics();
70 return { ast, sourceFile };
71};
72
73export function notNull<TValue>(
74 value: TValue | null | undefined,
75): value is TValue {
76 return value != null;
77}