-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathdts-creator.ts
113 lines (98 loc) · 3.27 KB
/
dts-creator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import * as process from 'process';
import * as path from'path';
import * as os from 'os';
import camelcase from "camelcase"
import FileSystemLoader from './file-system-loader';
import {DtsContent} from "./dts-content";
import {Plugin} from "postcss";
type CamelCaseOption = boolean | 'dashes' | undefined;
interface DtsCreatorOptions {
rootDir?: string;
searchDir?: string;
outDir?: string;
camelCase?: CamelCaseOption;
dropExtension?: boolean;
EOL?: string;
loaderPlugins?: Plugin<any>[];
extension?:string;
}
export class DtsCreator {
private rootDir: string;
private searchDir: string;
private outDir: string;
private loader: FileSystemLoader;
private inputDirectory: string;
private outputDirectory: string;
private camelCase: boolean | 'dashes' | undefined;
private dropExtension: boolean;
private EOL: string;
private extension:string;
constructor(options?: DtsCreatorOptions) {
if(!options) options = {};
this.rootDir = options.rootDir || process.cwd();
this.searchDir = options.searchDir || '';
this.outDir = options.outDir || this.searchDir;
this.loader = new FileSystemLoader(this.rootDir, options.loaderPlugins);
this.inputDirectory = path.join(this.rootDir, this.searchDir);
this.outputDirectory = path.join(this.rootDir, this.outDir);
this.camelCase = options.camelCase;
this.dropExtension = !!options.dropExtension;
this.extension = options.extension || '.d.ts';
this.EOL = options.EOL || os.EOL;
}
public async create(filePath: string, initialContents?: string, clearCache: boolean = false): Promise<DtsContent> {
let rInputPath: string;
if(path.isAbsolute(filePath)) {
rInputPath = path.relative(this.inputDirectory, filePath);
}else{
rInputPath = path.relative(this.inputDirectory, path.join(process.cwd(), filePath));
}
if(clearCache) {
this.loader.tokensByFile = {};
}
const res = await this.loader.fetch(filePath, "/", undefined, initialContents);
if(res) {
const tokens = res;
const keys = Object.keys(tokens);
const convertKey = this.getConvertKeyMethod(this.camelCase);
const result = keys
.map(k => convertKey(k))
.map(k => 'readonly "' + k + '": string;')
const content = new DtsContent({
dropExtension: this.dropExtension,
extension:this.extension,
rootDir: this.rootDir,
searchDir: this.searchDir,
outDir: this.outDir,
rInputPath,
rawTokenList: keys,
resultList: result,
EOL: this.EOL
});
return content;
}else{
throw res;
}
}
private getConvertKeyMethod(camelCaseOption: CamelCaseOption): (str: string) => string {
switch (camelCaseOption) {
case true:
return camelcase;
case 'dashes':
return this.dashesCamelCase;
default:
return (key) => key;
}
}
/**
* Replaces only the dashes and leaves the rest as-is.
*
* Mirrors the behaviour of the css-loader:
* https://github.com/webpack-contrib/css-loader/blob/1fee60147b9dba9480c9385e0f4e581928ab9af9/lib/compile-exports.js#L3-L7
*/
private dashesCamelCase(str: string): string {
return str.replace(/-+(\w)/g, function(match, firstLetter) {
return firstLetter.toUpperCase();
});
}
}