1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | var EventEmitter = require("events").EventEmitter
|
8 | , os = require("os")
|
9 | , _ = require("lodash")
|
10 | ;
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function Session(options) {
|
21 | options = options || {};
|
22 | this.id = options.id || this._guid();
|
23 | this.parent = options.parent || void 0;
|
24 | this.authenticating = options.authenticating || false;
|
25 | this.authenticated = options.authenticated || void 0;
|
26 | this.user = options.user || "guest";
|
27 | this.host = options.host;
|
28 | this.address = options.address || void 0;
|
29 | this._isLocal = options.local || void 0;
|
30 | this._delimiter = options.delimiter || String(os.hostname()).split(".")[0] + "~$";
|
31 | this._modeDelimiter = void 0;
|
32 |
|
33 |
|
34 |
|
35 | this._tabCtr = 0;
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | this._hist = [];
|
42 | this._histCtr = 0;
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | this._histCache = [];
|
49 | this._histCtrCache = 0;
|
50 |
|
51 |
|
52 |
|
53 | this._mode = void 0;
|
54 |
|
55 | return this;
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | var session = Session.prototype;
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | module.exports = exports = Session;
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | Session.prototype.__proto__ = EventEmitter.prototype;
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | session.log = function() {
|
86 | var self = this;
|
87 | if (this.isLocal()) {
|
88 | this.parent.ui.log.apply(this.parent.ui, arguments);
|
89 | } else {
|
90 |
|
91 |
|
92 | var args = [];
|
93 | for (var i = 0; i < arguments.length; ++i) {
|
94 | var str = arguments[i];
|
95 | str = (str && str.stack) ? "Error: " + str.message : str;
|
96 | args.push(str);
|
97 | }
|
98 | self.parent._send("vantage-ssn-stdout-downstream", "downstream", { sessionId: self.id, value: args });
|
99 | }
|
100 | return this;
|
101 | };
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | session.isLocal = function() {
|
112 | return this._isLocal;
|
113 | };
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | session.prompt = function(options, cb) {
|
125 | options = options || {};
|
126 | options.sessionId = this.id;
|
127 | return this.parent.prompt(options, cb);
|
128 | };
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | session.fullDelimiter = function() {
|
139 | var result = this._delimiter
|
140 | + ((this._modeDelimiter !== undefined) ? this._modeDelimiter : "");
|
141 | return result;
|
142 | };
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | session.delimiter = function(str) {
|
153 | if (str === undefined) {
|
154 | return this._delimiter;
|
155 | } else {
|
156 | this._delimiter = String(str).trim() + " ";
|
157 | if (this.isLocal()) {
|
158 | this.parent.ui.refresh();
|
159 | } else {
|
160 | this.parent._send("vantage-delimiter-downstream", "downstream", { value: str, sessionId: this.id });
|
161 | }
|
162 | return this;
|
163 | }
|
164 | };
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | session.modeDelimiter = function(str) {
|
175 | var self = this;
|
176 | if (str === undefined) {
|
177 | return this._modeDelimiter;
|
178 | } else {
|
179 | if (!this.isLocal()) {
|
180 | self.parent._send("vantage-mode-delimiter-downstream", "downstream", { value: str, sessionId: self.id });
|
181 | } else {
|
182 | if (str === false || str === "false") {
|
183 | this._modeDelimiter = void 0;
|
184 | } else {
|
185 | this._modeDelimiter = String(str).trim() + " ";
|
186 | }
|
187 | this.parent.ui.refresh();
|
188 | }
|
189 | return this;
|
190 | }
|
191 | };
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | session.getKeypressResult = function(key, value, cb) {
|
204 | cb = cb || function() {}
|
205 | var keyMatch = (["up", "down", "tab"].indexOf(key) > -1);
|
206 | if (key !== "tab") {
|
207 | this._tabCtr = 0;
|
208 | }
|
209 | if (keyMatch) {
|
210 | if (["up", "down"].indexOf(key) > -1) {
|
211 | cb(void 0, this.getHistory(key));
|
212 | } else if (key === "tab") {
|
213 | this.getAutocomplete(value, function(err, data) {
|
214 | cb(err, data);
|
215 | });
|
216 | }
|
217 | } else {
|
218 | this._histCtr = 0;
|
219 | }
|
220 | };
|
221 |
|
222 | session.history = function(str) {
|
223 | var exceptions = [];
|
224 | if (str && exceptions.indexOf(String(str).toLowerCase()) === -1) {
|
225 | this._hist.push(str);
|
226 | }
|
227 | };
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | session.getAutocomplete = function(str, cb) {
|
246 | cb = cb || function() {}
|
247 | var typed = String(str);
|
248 | var names = _.pluck(this.parent.commands, "_name");
|
249 |
|
250 | var match = void 0;
|
251 | var extra = void 0;
|
252 | names.forEach(function(name){
|
253 | if (typed.substr(0, name.length) === name) {
|
254 | match = name;
|
255 | extra = typed.substr(name.length, typed.length);
|
256 | }
|
257 | });
|
258 |
|
259 | var command = (match)
|
260 | ? _.findWhere(this.parent.commands, { _name: match })
|
261 | : void 0;
|
262 |
|
263 | if (!command) {
|
264 | command = _.findWhere(this.parent.commands, { _catch: true });
|
265 | }
|
266 |
|
267 | if (command && _.isFunction(command._autocompletion)) {
|
268 | this._tabCtr++;
|
269 | command._autocompletion.call(this, extra, this._tabCtr, cb);
|
270 | } else {
|
271 | cb(void 0, this._autocomplete(str, names));
|
272 | }
|
273 | };
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 | session._autocomplete = function(str, arr) {
|
286 | arr.sort();
|
287 | var arrX = _.clone(arr);
|
288 | var strX = String(str);
|
289 |
|
290 | var go = function() {
|
291 | var matches = [];
|
292 | for (var i = 0; i < arrX.length; i++) {
|
293 | if (arrX[i].slice(0, strX.length).toLowerCase() === strX.toLowerCase()) {
|
294 | matches.push(arrX[i]);
|
295 | }
|
296 | }
|
297 | if (matches.length === 1) {
|
298 | return matches[0] + " ";
|
299 | } else if (matches.length === 0) {
|
300 | return void 0;
|
301 | } else {
|
302 | var furthest = strX;
|
303 | for (var k = strX.length; k < matches[0].length; ++k) {
|
304 | var curr = String(matches[0].slice(0, k)).toLowerCase();
|
305 | var same = 0;
|
306 | for (var j = 0; j < matches.length; ++j) {
|
307 | var sliced = String(matches[j].slice(0, curr.length)).toLowerCase();
|
308 | if (sliced === curr) {
|
309 | same++;
|
310 | }
|
311 | }
|
312 | if (same === matches.length) {
|
313 | furthest = curr;
|
314 | continue;
|
315 | } else {
|
316 | break;
|
317 | }
|
318 | }
|
319 | if (furthest !== strX) {
|
320 | return furthest;
|
321 | } else {
|
322 | return void 0;
|
323 | }
|
324 | }
|
325 | };
|
326 |
|
327 | return go();
|
328 | };
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 |
|
339 | session.help = function(command) {
|
340 | this.log(this.parent._commandHelp(command || ''))
|
341 | };
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 | session.match = function(str, arr) {
|
353 | return this._autocomplete(str, arr);
|
354 | };
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 | session.getHistory = function(direction) {
|
367 | if (direction === "up") {
|
368 | this._histCtr++;
|
369 | this._histCtr = (this._histCtr > this._hist.length) ? this._hist.length : this._histCtr;
|
370 | } else if (direction === "down") {
|
371 | this._histCtr--;
|
372 | this._histCtr = (this._histCtr < 1) ? 1 : this._histCtr;
|
373 | }
|
374 | return this._hist[this._hist.length - (this._histCtr)];
|
375 | };
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 | session._guid = function() {
|
385 | function s4() {
|
386 | return Math.floor((1 + Math.random()) * 0x10000)
|
387 | .toString(16)
|
388 | .substring(1);
|
389 | }
|
390 | return s4() + s4() + "-" + s4() + "-" + s4() + "-" +
|
391 | s4() + "-" + s4() + s4() + s4();
|
392 | };
|