This repository has been archived by the owner on Jan 19, 2024. It is now read-only.
forked from mulesoft-labs/osprey-mock-service
-
Notifications
You must be signed in to change notification settings - Fork 1
/
raml-mock-service.js
155 lines (136 loc) · 3.51 KB
/
raml-mock-service.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
var Negotiator = require('negotiator')
var resources = require('osprey-resources')
var osprey = require('osprey')
/**
* Export the mock server.
*/
module.exports = ospreyMockServer
module.exports.createServer = createServer
module.exports.createServerFromBaseUri = createServerFromBaseUri
module.exports.loadFile = loadFile
/**
* Create an Osprey server instance.
*
* @param {Object} raml
* @return {Function}
*/
function ospreyMockServer (raml) {
return resources(raml.resources, handler)
}
/**
* Create a server with Osprey and the mock service.
*
* @param {Object} raml
* @param {Object} options
* @return {Function}
*/
function createServer (raml, options) {
var app = osprey.Router()
app.use(osprey.server(raml, options))
app.use(ospreyMockServer(raml))
app.use(osprey.errorHandler())
return app
}
/**
* Create a mock service using the base uri path.
*
* @param {Object} raml
* @param {Object} options
* @return {Function}
*/
function createServerFromBaseUri (raml, options) {
var app = osprey.Router()
var path = (raml.baseUri || '').replace(/^(\w+:)?\/\/[^/]+/, '') || '/'
app.use(path, raml.baseUriParameters, createServer(raml, options))
return app
}
/**
* Create a mock service from a filename.
*
* @param {String} filename
* @param {Object} options
* @return {Function}
*/
function loadFile (filename, options) {
return require('raml-1-parser')
.loadRAML(filename, { rejectOnErrors: true })
.then(function (ramlApi) {
var raml = ramlApi.expand(true).toJSON({
serializeMetadata: false
})
options['RAMLVersion'] = ramlApi.RAMLVersion()
return createServerFromBaseUri(raml, options)
})
}
/**
* Returns either a random example from examples or the single example.
*
* @param {Object} obj
*/
function getSingleExample (obj) {
if (obj.examples) {
var randomIndex = Math.floor(Math.random() * obj.examples.length)
return obj.examples[randomIndex].value
} else {
return obj.example
}
}
/**
* Create a RAML example method handler.
*
* @param {Object} method
* @return {Function}
*/
function handler (method) {
var statusCode = getStatusCode(method)
var response = (method.responses || {})[statusCode] || {}
var bodies = response.body || {}
var headers = {}
var types = Object.keys(bodies)
// Set up the default response headers.
if (response.headers) {
response.headers.forEach(function (header) {
if (header.default) {
headers[header.name] = header.default
} else if (header.example || header.examples) {
var example = getSingleExample(header)
headers[header.name] = example
}
})
}
return function (req, res) {
var negotiator = new Negotiator(req)
var type = negotiator.mediaType(types)
var body = bodies[type]
res.statusCode = statusCode
setHeaders(res, headers)
if (type) {
res.setHeader('Content-Type', type)
var example = getSingleExample(body)
if (example) {
res.write(typeof example === 'object' ? JSON.stringify(example) : example)
}
}
res.end()
}
}
/**
* Get an appropriate HTTP response code.
*
* @param {Object} method
* @return {Number}
*/
function getStatusCode (method) {
return Object.keys(method.responses || {})[0] || 200
}
/**
* Set a map of headers on the response.
*
* @param {HTTP.Response} res
* @param {Object} headers
*/
function setHeaders (res, headers) {
Object.keys(headers).forEach(function (key) {
res.setHeader(key, headers[key])
})
}