UNPKG

3.88 kBPlain TextView Raw
1import * as ts from 'typescript';
2import * as fs from 'fs-extra';
3import * as path from 'path';
4import * as util from 'util';
5
6import { logger } from './logger';
7
8const carriageReturnLineFeed = '\r\n';
9const lineFeed = '\n';
10
11export function detectIndent(str, count, indent?): string {
12 let stripIndent = function(str: string) {
13 const match = str.match(/^[ \t]*(?=\S)/gm);
14
15 if (!match) {
16 return str;
17 }
18
19 // TODO: use spread operator when targeting Node.js 6
20 const indent = Math.min.apply(Math, match.map(x => x.length)); // eslint-disable-line
21 const re = new RegExp(`^[ \\t]{${indent}}`, 'gm');
22
23 return indent > 0 ? str.replace(re, '') : str;
24 },
25 repeating = function(n, str) {
26 str = str === undefined ? ' ' : str;
27
28 if (typeof str !== 'string') {
29 throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``);
30 }
31
32 if (n < 0 || !Number.isFinite(n)) {
33 throw new TypeError(`Expected \`count\` to be a positive finite number, got \`${n}\``);
34 }
35
36 let ret = '';
37
38 do {
39 if (n & 1) {
40 ret += str;
41 }
42
43 str += str;
44 } while ((n >>= 1));
45
46 return ret;
47 },
48 indentString = function(str, count, indent) {
49 indent = indent === undefined ? ' ' : indent;
50 count = count === undefined ? 1 : count;
51
52 if (typeof str !== 'string') {
53 throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``);
54 }
55
56 if (typeof count !== 'number') {
57 throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
58 }
59
60 if (typeof indent !== 'string') {
61 throw new TypeError(`Expected \`indent\` to be a \`string\`, got \`${typeof indent}\``);
62 }
63
64 if (count === 0) {
65 return str;
66 }
67
68 indent = count > 1 ? repeating(count, indent) : indent;
69
70 return str.replace(/^(?!\s*$)/mg, indent);
71 }
72
73 return indentString(stripIndent(str), count || 0, indent);
74}
75
76// Create a compilerHost object to allow the compiler to read and write files
77export function compilerHost(transpileOptions: any): ts.CompilerHost {
78
79 const inputFileName = transpileOptions.fileName || (transpileOptions.jsx ? 'module.tsx' : 'module.ts');
80
81 const compilerHost: ts.CompilerHost = {
82 getSourceFile: (fileName) => {
83 if (fileName.lastIndexOf('.ts') !== -1) {
84 if (fileName === 'lib.d.ts') {
85 return undefined;
86 }
87 if (fileName.substr(-5) === '.d.ts') {
88 return undefined;
89 }
90
91 if (path.isAbsolute(fileName) === false) {
92 fileName = path.join(transpileOptions.tsconfigDirectory, fileName);
93 }
94 if (!fs.existsSync(fileName)) {
95 return undefined;
96 }
97
98 let libSource = '';
99
100 try {
101 libSource = fs.readFileSync(fileName).toString();
102 }
103 catch(e) {
104 logger.debug(e, fileName);
105 }
106
107 return ts.createSourceFile(fileName, libSource, transpileOptions.target, false);
108 }
109 return undefined;
110 },
111 writeFile: (name, text) => {},
112 getDefaultLibFileName: () => 'lib.d.ts',
113 useCaseSensitiveFileNames: () => false,
114 getCanonicalFileName: fileName => fileName,
115 getCurrentDirectory: () => '',
116 getNewLine: () => '\n',
117 fileExists: (fileName): boolean => fileName === inputFileName,
118 readFile: () => '',
119 directoryExists: () => true,
120 getDirectories: () => []
121 };
122 return compilerHost;
123}