UNPKG

4.94 kBPlain TextView Raw
1import * as fs from 'fs-extra';
2import * as path from 'path';
3import { ts } from 'ts-simple-ast';
4import * as _ from 'lodash';
5
6import { logger } from './logger';
7
8import { stripBom, hasBom } from './utils/utils';
9
10export function cleanNameWithoutSpaceAndToLowerCase(name: string): string {
11 return name.toLowerCase().replace(/ /g, '-');
12}
13
14export function detectIndent(str, count, indent?): string {
15 let stripIndent = (str: string) => {
16 const match = str.match(/^[ \t]*(?=\S)/gm);
17
18 if (!match) {
19 return str;
20 }
21
22 // TODO: use spread operator when targeting Node.js 6
23 const indent = Math.min.apply(Math, match.map(x => x.length)); // eslint-disable-line
24 const re = new RegExp(`^[ \\t]{${indent}}`, 'gm');
25
26 return indent > 0 ? str.replace(re, '') : str;
27 };
28
29 let repeating = (n, str) => {
30 str = str === undefined ? ' ' : str;
31
32 if (typeof str !== 'string') {
33 throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``);
34 }
35
36 if (n < 0) {
37 throw new TypeError(`Expected \`count\` to be a positive finite number, got \`${n}\``);
38 }
39
40 let ret = '';
41
42 do {
43 if (n & 1) {
44 ret += str;
45 }
46
47 str += str;
48 } while ((n >>= 1));
49
50 return ret;
51 };
52
53 let indentString = (str, count, indent) => {
54 indent = indent === undefined ? ' ' : indent;
55 count = count === undefined ? 1 : count;
56
57 if (typeof str !== 'string') {
58 throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``);
59 }
60
61 if (typeof count !== 'number') {
62 throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
63 }
64
65 if (typeof indent !== 'string') {
66 throw new TypeError(`Expected \`indent\` to be a \`string\`, got \`${typeof indent}\``);
67 }
68
69 if (count === 0) {
70 return str;
71 }
72
73 indent = count > 1 ? repeating(count, indent) : indent;
74
75 return str.replace(/^(?!\s*$)/gm, indent);
76 };
77
78 return indentString(stripIndent(str), count || 0, indent);
79}
80
81// Create a compilerHost object to allow the compiler to read and write files
82export function compilerHost(transpileOptions: any): ts.CompilerHost {
83 const inputFileName =
84 transpileOptions.fileName || (transpileOptions.jsx ? 'module.tsx' : 'module.ts');
85
86 const toReturn: ts.CompilerHost = {
87 getSourceFile: (fileName: string) => {
88 if (fileName.lastIndexOf('.ts') !== -1 || fileName.lastIndexOf('.js') !== -1) {
89 if (fileName === 'lib.d.ts') {
90 return undefined;
91 }
92 if (fileName.substr(-5) === '.d.ts') {
93 return undefined;
94 }
95
96 if (path.isAbsolute(fileName) === false) {
97 fileName = path.join(transpileOptions.tsconfigDirectory, fileName);
98 }
99 if (!fs.existsSync(fileName)) {
100 return undefined;
101 }
102
103 let libSource = '';
104
105 try {
106 libSource = fs.readFileSync(fileName).toString();
107
108 if (hasBom(libSource)) {
109 libSource = stripBom(libSource);
110 }
111 } catch (e) {
112 logger.debug(e, fileName);
113 }
114
115 return ts.createSourceFile(fileName, libSource, transpileOptions.target, false);
116 }
117 return undefined;
118 },
119 writeFile: (name, text) => {},
120 getDefaultLibFileName: () => 'lib.d.ts',
121 useCaseSensitiveFileNames: () => false,
122 getCanonicalFileName: fileName => fileName,
123 getCurrentDirectory: () => '',
124 getNewLine: () => '\n',
125 fileExists: (fileName): boolean => fileName === inputFileName,
126 readFile: () => '',
127 directoryExists: () => true,
128 getDirectories: () => []
129 };
130
131 return toReturn;
132}
133
134export function findMainSourceFolder(files: string[]) {
135 let mainFolder = '';
136 let mainFolderCount = 0;
137 let rawFolders = files.map(filepath => {
138 let shortPath = filepath.replace(process.cwd() + path.sep, '');
139 return path.dirname(shortPath);
140 });
141 let folders = {};
142 rawFolders = _.uniq(rawFolders);
143
144 for (let i = 0; i < rawFolders.length; i++) {
145 let sep = rawFolders[i].split(path.sep);
146 sep.map(folder => {
147 if (folders[folder]) {
148 folders[folder] += 1;
149 } else {
150 folders[folder] = 1;
151 }
152 });
153 }
154 for (let f in folders) {
155 if (folders[f] > mainFolderCount) {
156 mainFolderCount = folders[f];
157 mainFolder = f;
158 }
159 }
160 return mainFolder;
161}