-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
101 lines (89 loc) · 3.03 KB
/
index.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
var IncomingMessage = require('http').IncomingMessage
// helpers
, merge = require('deeply')
// modules
, defaults = require('./defaults.js')
, normalize = require('./lib/normalize.js')
// adapters
, express = require('./adapters/express.js')
, hapi = require('./adapters/hapi.js')
, http = require('./adapters/http.js')
, restify = require('./adapters/restify.js')
;
// Public API
module.exports = agnostic;
agnostic.adapter = requestHandlerAdapter;
agnostic.defaults = defaults;
/**
* Wraps provided request handler with adapter function
*
* @param {function} requestHandler - http-server agnostic function to wrap
* @param {object} [options] - list of options to bake into request handler
* @returns {function} - wrapped function
*/
function agnostic(requestHandler, options)
{
options = merge(agnostic.defaults, options || {});
return requestHandlerAdapter.bind(options, requestHandler);
}
/**
* Selects proper adapter based on request object specific properties
*
* @this agnostic.options
* @param {function} requestHandler - original (server-agnostic) handler
* @param {object} rawRequest - server specific request object
* @param {object|function} rawResponse - server specific response object, or function in case of Hapi
*/
function requestHandlerAdapter(requestHandler, rawRequest, rawResponse)
{
var adapter;
// address the elephant in the room
// be normal
if (rawRequest instanceof IncomingMessage)
{
// `restify` being a good citizen, identifies itself
if (rawRequest.serverName == 'restify')
{
adapter = restify;
}
// express, or something pretending to be,
// it'd better be :)
else if (typeof rawRequest.next == 'function')
{
rawRequest.serverName = 'express';
adapter = express;
}
// assume everything else either native http.
// or something pretending to be it very hard
else
{
rawRequest.serverName = 'http';
adapter = http;
}
}
// or hapi-like
else if (typeof rawRequest.server == 'object' && typeof rawRequest.server.info == 'object')
{
rawRequest.serverName = 'hapi';
adapter = hapi;
}
if (!adapter)
{
// nothing found, booo
throw new TypeError('agnostic: Unsupported http server type. Please open new issue to add support for your server. https://github.com/alexindigo/agnostic/issues');
}
// invoke chosen adapter with normalized body
normalize.request.call(this, rawRequest, function(error, request)
{
var adaptedRequest, normalizedResponse;
if (error)
{
// terminate earlier – as input error
normalize.response.call(this, adapter.response, rawResponse, request)(error.statusCode || error.status || 400, error.message);
return;
}
adaptedRequest = adapter.request.call(this, request, rawRequest);
normalizedResponse = normalize.response.call(this, adapter.response, rawResponse, request);
requestHandler(adaptedRequest, normalizedResponse);
}.bind(this));
}