-
Notifications
You must be signed in to change notification settings - Fork 6
/
huntsman.js
122 lines (108 loc) · 3.06 KB
/
huntsman.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
var EventEmitter = require('events').EventEmitter;
var hottap = require('hottap').hottap;
var _ = require('underscore');
var Huntsman = function(config){
this.config = config || {};
this.root = config.root || 'http://localhost/';
this.readOnly = config.readOnly || true;
this.maxItems = config.maxItems || 10;
this.autoGET = config.autoGET || true;
this.stopOnError = config.stopOnError || true;
this.shouldStop = false;
this.debug = config.debug || true;
this.beenThere = []; // TODO populate this with places it's been
};
Huntsman.prototype = Object.create(EventEmitter.prototype);
Huntsman.prototype.capture = function(url, method, headers, body, cb){
var that = this;
method = method || "GET";
body = body || '';
headers = headers || {};
cb = cb || function(){};
if (this.debug){
console.log('<-- ', method, headers, body);
}
this.beenThere.push(method + "|" + url);
hottap(url).request(method, headers, body, function(err, response){
if (err){
that.emit('error', err);
if (that.stopOnError){
that.shouldStop = true;
}
cb(err);
} else {
if (that.debug){
console.log('--> ', response);
}
that.emit('response', response);
if (response.headers['content-type'] === 'application/json'){
console.log("harvesting");
that.harvest(response.body, function(){
cb(response);
});
} else {
if (that.debug){
console.log('--> (non-json response)');
}
cb('non-json response', response);
}
}
});
};
Huntsman.prototype.harvest = function(payload, cb){
var that = this;
var obj = {};
console.log("payload: ", payload);
if (_.isString(payload)){
try {
obj = JSON.parse(payload);
} catch(ex){
that.emit('parseError', ex);
}
} else {
obj = payload;
}
console.log("obj: ", obj);
console.log("links: ", obj._links);
_.each( obj._links, function(link, rel){
console.log('eachlink: ', link, rel);
that.emit('link', rel, link);
if (!!that.autoGET && !that.shouldStop){
console.log("about to follow... ", link);
if (!that.hasBeenTo('GET', link.href)){
that.capture(link.href, 'GET', {}, '', function(){
cb();
});
}
}
});
};
Huntsman.prototype.hasBeenTo = function(method, url){
return (this.beenThere.indexOf(method + '|' + url) !== -1);
};
Huntsman.prototype.hunt = function(url){
var that = this;
this.root = url || this.root;
this.shouldStop = false;
this.capture(this.root, 'GET', {}, '', function(){
that.emit('end');
});
};
var hunter = new Huntsman({ readOnly : false });
hunter.on('link', function(rel, linkObj){
console.log("link: ", rel, ' ', linkObj);
});
hunter.on('error', function(err){
console.log("error:", err);
});
hunter.on('parseError', function(err){
console.log("error:", err);
});
hunter.on('response', function(response){
console.log('response ', response);
});
hunter.on('end', function(){
console.log(hunter.beenThere);
console.log('done');
});
hunter.hunt("http://localhost:8080/api");