-
Notifications
You must be signed in to change notification settings - Fork 0
/
rt-loader.js
73 lines (66 loc) · 3.12 KB
/
rt-loader.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
var reactTemplates = require('react-templates/src/reactTemplates');
var url = require('url');
var queryString = require('querystring');
var fs = require("fs");
var path = require("path");
function addStateInterfaceRequire(js, rtPath) {
var rtPathParsed = path.parse(rtPath),
componentName = rtPathParsed.name.replace(".rt", ""),
componentPath = path.join(rtPathParsed.dir, componentName + ".tsx"),
stateInterfaceModuleName = "I" + componentName + "State.ts",
stateInterfaceModulePath = path.join(rtPathParsed.dir, stateInterfaceModuleName);
if (!fileExists(componentPath)) {
throw new Error("Naming mismatch.\n\
Please, give component's template (.rt.html file) the same name as the component.\n\
For example, if you have component \"Calculator.tsx\", create \"Calculator.rt.html\" template for it at the same folder.\n\
Searched for file: \"" + componentPath + "\"");
}
if (!fileExists(stateInterfaceModulePath)) {
throw new Error('Module not found.\n\
File "' + stateInterfaceModulePath + '" not found.\n\
Create this file and place interface for component state there.');
}
var insertAfter = "import _ = require('lodash');",
index = js.indexOf(insertAfter) === -1 ? 0 : js.indexOf(insertAfter) + insertAfter.length;
return js.substring(0, index) + '\n\nimport IState from "./' + stateInterfaceModuleName + '";\n\n' + js.substring(index);
}
function addTestTemplateTypingClass(js) {
var classStart = '\n\
class TemplateTypingCheck extends React.Component<{}, IState> {\n\
render(): React.ReactElement<{}> {\n\
',
classEnd = '\n\
}\n\
}\n\
export = new TemplateTypingCheck().render();\n',
fn = js.substring(js.indexOf("var fn = function() {") + 21, js.lastIndexOf("}")) + ";",
classCode = classStart + fn + classEnd,
insertIndex = js.indexOf("var fn = function() {") - 2;
return js.substring(0, insertIndex) + "\n" + classCode;
}
function fileExists(path) {
try {
fs.accessSync(path, fs.F_OK);
return true;
} catch (e) {
return false;
}
}
module.exports = function(source) {
//console.log("=====> convertRT:", reactTemplates.convertRT);
//console.log("=====> convertJSRTToJS:", reactTemplates.convertJSRTToJS);
//console.log("=====> this:", this.resourcePath);
var options = queryString.parse(url.parse(this.query).query);
this.cacheable && this.cacheable();
//console.log("===> emitting");
var js = reactTemplates.convertRT(source, {}, { modules: "typescript" });
js = js.replace("import React = require('react/addons');", "import React = require(\"react\");");
//js = js.replace("var fn = function()", "var fn: () => React.ReactElement<{}> = () => ");
js = addStateInterfaceRequire(js, this.resourcePath);
js = addTestTemplateTypingClass(js);
var jsrtPath = this.resourcePath + ".jsrt.ts";
fs.writeFileSync(jsrtPath, js);
//console.log("===> emit complete");
this.resourcePath = jsrtPath;
return js;
};