UNPKG

2.63 kBJavaScriptView Raw
1// State machine representing URI's
2//
3// Cleans up the logic of connecting via ports,
4// urls or file sockets.
5
6var state = require('state');
7var isUrl = require('is-url');
8var _ = require('lodash');
9var norma = require('norma');
10var url = require('url');
11var path = require('path');
12var temp = require('temp').track();
13
14var Uri = function(options) {
15 this.initialize();
16 return this;
17};
18
19Uri.prototype.initialize = function() {
20 state(this, {
21 // Possible states for the URI
22 Initial: state('initial', {
23
24 // Change state based on input.
25 set: function(input) {
26 this.input = input;
27
28 // attempt each state in order.
29 // guards will stop them.
30 this.state().go('Port');
31 this.state().go('Url');
32 this.state().go('File');
33 }
34 }),
35
36 Port: state({
37 admit: { // format: 3000
38 Initial: function() { return _.isNumber(this.owner.input); }
39 },
40 arrive: function() {
41 this.setPort(this.input);
42 },
43 setPort: function(port) {
44 this.url = url.parse('http://0.0.0.0:'+port);
45 },
46 listenUrl: function() {
47 return [this.input];
48 }
49 }),
50
51 Url: state({
52 admit: { // format: 'http://api.example.com'
53 Initial: function() { return isUrl(this.owner.input); }
54 },
55 arrive: function() {
56 this.url = url.parse(this.input + '/');
57 }
58 }),
59
60 File: state({
61 admit: { // format: '/filename.sock' or undefined
62 Initial: function() { return true; }
63 },
64 arrive: function() {
65 this.filename = this.input || temp.path();
66 this.url = 'http://unix:' + this.filename+':/';
67 },
68 getFilename: function() {
69 return this.filename;
70 },
71 requestUrl: function(_path) {
72 var noslash = (_path||'').replace(/^\//, '');
73 return 'http://unix:' + this.filename + ":/" + noslash;
74 },
75 listenUrl: function() {
76 return [this.filename];
77 }
78 }),
79
80 // default for all
81 get: function() {
82 return this.url;
83 },
84
85 // append the request path.
86 requestUrl: function() {
87 var args = norma('path:s?', arguments);
88 var _url = url.format(_.clone(this.url));
89 var _path = (args.path || '').replace(/^\//, '');
90 return url.resolve(_url, _path);
91 },
92 // always returns an array
93 // due to http.listen(3000, '10.0.0.1');
94 listenUrl: function() {
95 var results = [parseInt(this.url.port, 10)];
96 this.url.hostname && results.push(this.url.hostname);
97 return results;
98 },
99
100 setPort: function() {}
101 });
102};
103
104
105module.exports = Uri;