This repository has been archived by the owner on Jun 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 146
/
Copy pathresponsePromise.js
137 lines (124 loc) · 3.25 KB
/
responsePromise.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
/*
* Copyright 2014-2016 the original author or authors
* @license MIT, see LICENSE.txt for details
*
* @author Scott Andrews
*/
'use strict'
var normalizeHeaderName = require('./normalizeHeaderName')
function property (promise, name) {
return promise.then(
function (value) {
return value && value[name]
},
function (value) {
return Promise.reject(value && value[name])
}
)
}
/**
* Obtain the response entity
*
* @returns {Promise} for the response entity
*/
function entity () {
return property(this, 'entity')
}
/**
* Obtain the response status
*
* @returns {Promise} for the response status
*/
function status () {
return property(property(this, 'status'), 'code')
}
/**
* Obtain the response headers map
*
* @returns {Promise} for the response headers map
*/
function headers () {
return property(this, 'headers')
}
/**
* Obtain a specific response header
*
* @param {String} headerName the header to retrieve
* @returns {Promise} for the response header's value
*/
function header (headerName) {
headerName = normalizeHeaderName(headerName)
return property(this.headers(), headerName)
}
/**
* Follow a related resource
*
* The relationship to follow may be define as a plain string, an object
* with the rel and params, or an array containing one or more entries
* with the previous forms.
*
* Examples:
* response.follow('next')
*
* response.follow({ rel: 'next', params: { pageSize: 100 } })
*
* response.follow([
* { rel: 'items', params: { projection: 'noImages' } },
* 'search',
* { rel: 'findByGalleryIsNull', params: { projection: 'noImages' } },
* 'items'
* ])
*
* @param {String|Object|Array} rels one, or more, relationships to follow
* @returns ResponsePromise<Response> related resource
*/
function follow (rels) {
rels = [].concat(rels)
return make(rels.reduce(function (response, rel) {
return response.then(function (response) {
if (typeof rel === 'string') {
rel = { rel: rel }
}
if (typeof response.entity.clientFor !== 'function') {
throw new Error('Hypermedia response expected')
}
var client = response.entity.clientFor(rel.rel)
return client({ params: rel.params })
})
}, this))
}
/**
* Wrap a Promise as an ResponsePromise
*
* @param {Promise<Response>} promise the promise for an HTTP Response
* @param {Request} request the HTTP Request
* @returns {ResponsePromise<Response>} wrapped promise for Response with additional helper methods
*/
function make (promise, request) {
promise.status = status
promise.headers = headers
promise.header = header
promise.entity = entity
promise.follow = follow
promise.cancel = function () {
if (!request) { return }
if (request.cancel) {
request.cancel()
} else {
request.canceled = true
}
return this
}
return promise
}
function responsePromise (obj, callback, errback, request) {
return make(Promise.resolve(obj).then(callback, errback), request)
}
responsePromise.make = make
responsePromise.reject = function (val, request) {
return make(Promise.reject(val), request)
}
responsePromise.promise = function (func, request) {
return make(new Promise(func), request)
}
module.exports = responsePromise