-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathjs2tsd.js
164 lines (117 loc) · 3.69 KB
/
js2tsd.js
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
'use strict';
var _ = require('lodash');
//////////////////// utility functions ////////////////////
function indent(str) {
var IND = " ";
return IND + str.replace(/\n(?!$)/mg, '\n' + IND);
}
function functionParams(propVal) {
if (propVal instanceof Function) {
var result = propVal.toString().replace(/^\s*function\s*\((.*?)\)[\S\s]*$/, '$1').split(/\,\s/);
if (result[0] === "") { result = []; }
return result;
} else {
return null;
}
}
function docOutput(propVal) {
var result = "/**\n *\n";
var params = functionParams(propVal);
if (!_(params).isEmpty()) {
result += " *\n";
_(params).forEach(function (param) {
result += " * @param " + param + " \n";
});
}
result += " */\n";
return result;
}
function propertyOutput(propVal, propName, anyEverything) {
var result = propName;
var params = functionParams(propVal);
if (params) {
result += '(' + _(params).map(function (param) {
if (anyEverything) {
return param + ": any";
} else {
return param;
}
}).join(', ') + ')';
}
if (anyEverything) {
result += ": any";
}
result += ";\n";
return result;
}
//////////////////// a typescript definition generator ////////////////////
function TsDGenerator(fileOptions) {
////////// declared symbols //////////
var _declaredSymbols = [];
////////// the header //////////
var _output =
"// Type definitions for " + fileOptions.libName + "\n" +
"// Project: " + fileOptions.projectURL + "\n" +
"// Definitions by: " + fileOptions.defAuthors + "\n" +
"// Definitions: " + fileOptions.defURL + "\n\n";
////////// how to add a class; can be chained //////////
this.addClass = function addClass(options) {
_declaredSymbols.push(options.name);
//// generate the class output
//
var classDef = "";
_(options.staticExpr).forOwn(function (propVal, propName) {
classDef += docOutput(propVal);
classDef += "static " + propertyOutput(propVal, propName, options.anyEverything) + "\n";
});
_(options.instanceExpr).forOwn(function (propVal, propName) {
classDef += docOutput(propVal);
classDef += propertyOutput(propVal, propName, options.anyEverything) + "\n";
});
//// add the class output to the full output
//
_output += "declare class " + options.name + " {\n\n" + indent(classDef) + "}\n\n";
//// return the generator to support chaining
//
return this;
};
////////// how to add an interface; can be chained //////////
this.addInterface = function addInterface(options) {
_declaredSymbols.push(options.name);
//// generate the interface output
//
var ifaceDef = "";
_(options.staticExpr).forOwn(function (propVal, propName) {
ifaceDef += docOutput(propVal);
ifaceDef += propertyOutput(propVal, propName, options.anyEverything) + "\n";
});
//// add the interface output to the full output
//
_output += "declare class " + options.name + " {\n\n" + indent(ifaceDef) + "}\n\n";
//// return the generator to support chaining
//
return this;
};
////////// how to declare the module //////////
this.addModule = function addModule(options) {
//// generate the module output
//
var moduleOutput = "";
if (options.singleExport) {
moduleOutput += "export = " + _declaredSymbols[0] + ";\n";
} else {
_(options.symbols || _declaredSymbols).forEach(function (symbol) {
moduleOutput += "export " + symbol + ";\n";
});
}
//// add the module output to the full output
//
_output += "declare module \"" + options.name + "\" {\n\n" + indent(moduleOutput) + "\n}\n\n";
//// return the generator to support chaining
//
return this;
};
////////// how to return the output //////////
this.output = function output() { return _output; }
}
exports.TsDGenerator = TsDGenerator;