UNPKG

5.7 kBJavaScriptView Raw
1/*jslint plusplus: true, devel: true, nomen: true, vars: true, node: true, indent: 4, maxerr: 50 */
2/*global require, exports, module */
3
4var fs = require("fs"),
5 url = require("url"),
6 path = require("path"),
7 send = require("../node_modules/connect/node_modules/send"),
8 mustach = require("../brackets-src/src/thirdparty/mustache");
9
10var index,
11 env,
12 namespaces = {
13 fs : fs
14 };
15
16// add some stuff to fs because the return types are sometimes complicated objects that don't jsonify
17fs.statBrackets = function (path, callback) {
18 "use strict";
19
20 fs.stat(path, function (err, stats) {
21 if (err) {
22 callback(err, null);
23 } else {
24 var result = {};
25 result.isFile = stats.isFile();
26 result.isDirectory = stats.isDirectory();
27 result.mtime = stats.mtime;
28 result.filesize = stats.size;
29 callback(0, result); // TODO: hack, need handling of error being null in callbacks on client side
30 }
31 });
32};
33
34function handleError(res, message, statusCode, reasonPhrase) {
35 "use strict";
36
37 message = "Error: " + message + "\n";
38 console.log(message);
39 res.writeHead(statusCode || 500, reasonPhrase || "Internal server error", {"Content-Type": "text/plain"});
40 res.write(message);
41 res.end();
42}
43
44function createCallback(id, res) {
45 "use strict";
46
47 return function () {
48 var args = Array.prototype.slice.call(arguments),
49 result = args[0];
50 if (result === null) { // Brackets expects 0 response code on successful write but Node fs returns null
51 args[0] = 0;
52 } else if (result.code) {
53 switch (result.code) {
54 case "ENOENT": // Not found, Brackets expects response code 3
55 args[0] = 3;
56 break;
57 }
58 }
59
60 res.writeHead(200, {"Content-Type": "application/json"});
61 res.write(JSON.stringify({id: id, result: args}));
62 res.end();
63 };
64}
65
66function doCommand(id, namespace, command, args, res) {
67 "use strict";
68
69 var filePath = args[0];
70 if (filePath === "/.git/HEAD") {
71 args[0] = path.normalize(__dirname + "/../brackets-src" + filePath);
72 } else if (filePath.indexOf(env.bracketsRoot) === 0) {
73 args[0] = path.normalize(__dirname + "/../brackets-src/src" + filePath.substr(env.bracketsRoot.length));
74 } else {
75 args[0] = path.resolve(filePath);
76 }
77
78 try {
79 var f = namespaces[namespace][command],
80 callback = createCallback(id, res);
81
82 args.push(callback);
83 f.apply(global, args);
84 } catch (e) {
85 handleError(res, "Couldn't run the command " + namespace + "." + command + " with args " + JSON.stringify(args));
86 }
87}
88
89function sendIndex(res) {
90 "use strict";
91
92 res.writeHead(200, {"Content-Type": "text/html; charset=UTF-8"});
93 res.write(mustach.render(index, { data: JSON.stringify(env) }));
94 res.end();
95}
96
97function processFilesRequest(req, res) {
98 "use strict";
99
100 if (req.method === "POST") {
101 var body = "";
102 req.setEncoding("utf8");
103 req.on("data", function (chunk) {
104 body += chunk;
105 }).on("end", function () {
106 var m = JSON.parse(body);
107 doCommand(m.id, m.namespace, m.command, m.args, res);
108 });
109 return;
110 }
111
112 handleError(res, "405 - Method not supported", 405, "Method not supported");
113}
114
115function initialize(workDirectories) {
116 "use strict";
117
118 var folders, argType = typeof workDirectories;
119
120 switch (argType) {
121 case "string":
122 if (workDirectories === "") {
123 workDirectories = "./";
124 }
125 folders = [workDirectories];
126 break;
127 case "undefined":
128 folders = ["./"];
129 break;
130 case "object":
131 if (workDirectories instanceof Array) {
132 folders = workDirectories;
133 if (folders.length === 0) {
134 folders[0] = "./";
135 }
136 break;
137 }
138 // fall through
139 default:
140 throw "Invalid argument for node-brackets module initialization.";
141 }
142
143 env = {
144 currentRootFolder: folders[0],
145 rootFolders: folders,
146 fileService: "",
147 bracketsRoot: ""
148 };
149
150 return function (req, res, next) {
151 var idx = req.originalUrl.length - 1;
152 if (req.url === "/" && req.originalUrl[idx] !== "/") {
153 res.writeHead(302, {Location: req.originalUrl + "/"});
154 res.end();
155 } else if (req.url === "/" || req.url === "/index.html") {
156 if (!index) {
157 fs.readFile(__dirname + "/../brackets-src/src/index.html", function (err, data) {
158 if (err) {
159 handleError(res, err);
160 return;
161 }
162
163 var pathname = req.originalUrl;
164 index = data.toString();
165 env.fileService = url.resolve(pathname, "files.svc");
166 env.bracketsRoot = pathname.substr(0, pathname.lastIndexOf("/"));
167 sendIndex(res);
168 });
169 return;
170 }
171 sendIndex(res);
172 } else if (req.url.indexOf("/files.svc") === 0) {
173 processFilesRequest(req, res);
174 } else {
175 send(req, req.url)
176 .root(__dirname + "/../brackets-src/src")
177 .pipe(res);
178 }
179 };
180}
181
182exports = module.exports = initialize;