UNPKG

8.65 kBJavaScriptView Raw
1import PromiseHttpResourceExecutor from 'api/PromiseHttpResourceExecutor'
2import { HttpMethod, Protocol } from 'api/const'
3import async from 'async'
4import querystring from 'querystring'
5
6if (global.__RESOURCE_GROUP_REGISTRY__ == null || typeof global.__RESOURCE_GROUP_REGISTRY__ === 'undefined') {
7 global.__RESOURCE_GROUP_REGISTRY__ = {}
8}
9
10class RemoteResourceExecution {
11 constructor (resource, resourceGroup, apiCaller) {
12 this._resource = resource
13 this._resourceGroup = resourceGroup
14 this._data = null
15 this._onProgressListener = null
16 this._attachments = null
17 this._configuration = {
18 context: {},
19 trackingContext: {},
20 http: {
21 headers: {},
22 method: HttpMethod.POST,
23 contentType: 'application/json'
24 },
25 protocol: Protocol.HTTP
26 }
27 this._apiCaller = apiCaller
28 this._successHandler = null
29 this._errorHandler = null
30 this._offlineHandler = null
31 }
32
33 data (data) {
34 this._data = data
35 return this
36 }
37
38 onProgress (fn) {
39 this._onProgressListener = fn
40 return this
41 }
42
43 attach (attachments) {
44 this._attachments = attachments
45 return this
46 }
47
48 contentType (contentType) {
49 this._configuration.http.contentType = contentType
50 return this
51 }
52
53 context (key, value) {
54 this._configuration.context[key] = value
55 return this
56 }
57
58 trackingContext(key, value){
59 this._configuration.trackingContext[key] = value
60 return this
61 }
62
63 setTrackingContext(trackingContext){
64 let combinedTrackingContext = {
65 ...this._configuration.trackingContext,
66 ...trackingContext
67 }
68 try{
69 // TODO this is hack
70 let fiz = global.__CONFIG__.fiz
71 combinedTrackingContext['ipAddress'] = fiz.ip('https://concierge-api.airyrooms.com/getIp')
72 } catch(e){
73
74 }
75
76 this._configuration.trackingContext = combinedTrackingContext
77 return this
78 }
79
80
81 method (method) {
82 this._configuration.http.method = method
83 return this
84 }
85
86 header (key, value) {
87 this._configuration.http.headers[key] = value
88 return this
89 }
90
91 protocol (protocol) {
92 this._configuration.protocol = protocol
93 return this
94 }
95
96 timeout (timeout) {
97 this._configuration.http.timeout = timeout
98 return this
99 }
100
101 _createHttpAPIExecutionSpec (data, context, trackingContext) {
102 let url = this._resource.getUrl()
103 if (this._resource._query) {
104 url += this._resource._query
105 }
106 return {
107 uri: url,
108 body: {
109 data: data,
110 context: context,
111 trackingContext: trackingContext
112 },
113 headers: this._configuration.http.headers,
114 method: this._configuration.http.method,
115 contentType: this._configuration.http.contentType,
116 timeout: this._configuration.http.timeout
117 }
118 }
119
120 _executeHttpAPI () {
121 let resourceGroupContext = this._resourceGroup.getContext()
122 let resourceContext = this._resource.getContext()
123 let resourceExecutionContext = this._configuration.context
124 let resourceExecutionTrackingContext = this._configuration.trackingContext
125
126 let finalContext = {}
127 let finalTrackingContext = {}
128
129 finalTrackingContext = {
130 ...finalTrackingContext,
131 ...resourceExecutionTrackingContext
132 }
133 finalContext = {
134 ...finalContext,
135 ...resourceGroupContext
136 }
137
138 finalContext = {
139 ...finalContext,
140 ...resourceContext
141 }
142
143 finalContext = {
144 ...finalContext,
145 ...resourceExecutionContext
146 }
147
148 let apiSpec = this._createHttpAPIExecutionSpec(this._data, finalContext, finalTrackingContext)
149 this._apiCaller.execute(apiSpec, this._offlineHandler, this._errorHandler, this._successHandler, this._attachments, this._onProgressListener)
150 }
151
152 execute () {
153 let beforeExecuteFilterFn = []
154 if (this._resourceGroup.getOnBeforeExecuteFilters() != null) {
155 if (this._resourceGroup.getOnBeforeExecuteFilters().length > 0) {
156 this._resourceGroup.getOnBeforeExecuteFilters().forEach((f) => {
157 beforeExecuteFilterFn.push(f)
158 })
159 }
160 }
161
162 if (this._resource.getOnBeforeExecuteFilters() != null) {
163 if (this._resource.getOnBeforeExecuteFilters().length > 0) {
164 this._resource.getOnBeforeExecuteFilters().forEach((f) => {
165 beforeExecuteFilterFn.push(f)
166 })
167 }
168 }
169
170 if (beforeExecuteFilterFn.length > 0) {
171 let beforeExecuteFilterFnCallQueue = []
172 let idx = 0
173 beforeExecuteFilterFn.forEach((beff) => {
174 if (idx === 0) {
175 beforeExecuteFilterFnCallQueue.push(
176 (callback) => {
177 // TODO handle short circuit
178 return beff(this, callback)
179 }
180 )
181 } else {
182 beforeExecuteFilterFnCallQueue.push(
183 (result, callback) => {
184 // TODO handle short circuit
185 console.log(arguments, result)
186 return beff(this, callback)
187 }
188 )
189 }
190 idx += 1
191 })
192
193 async.waterfall(beforeExecuteFilterFnCallQueue, (err, results) => {
194 if (err) {
195 // TODO handle error
196 } else {
197 if (this._configuration.protocol === Protocol.HTTP) {
198 this._executeHttpAPI()
199 } else {
200 // TODO should we call / handle additional protocol?
201 }
202 }
203 })
204 } else {
205 if (this._configuration.protocol === Protocol.HTTP) {
206 this._executeHttpAPI()
207 } else {
208 // TODO should we call / handle additional protocol?
209 }
210 }
211 }
212
213 success (fn) {
214 this._successHandler = fn
215 return this
216 }
217
218 error (fn) {
219 this._errorHandler = fn
220 return this
221 }
222
223 offline (fn) {
224 this._offlineHandler = fn
225 return this
226 }
227}
228
229class RemoteResource {
230 constructor (resourceGroup, url) {
231 this._resourceGroup = resourceGroup
232 this._url = url
233 this._originalUrl = url
234 this._query = ''
235 this._configuration = {
236 context: {}
237 }
238 this._onBeforeExecuteFilters = []
239 this._onAfterExecuteFilters = []
240 this._resourceExecutor = resourceGroup.getResourceExecutor()
241 }
242
243 onBeforeExecute (filterFn) {
244 this._onBeforeExecuteFilters.push(filterFn)
245 }
246
247 onAfterExecute (filterFn) {
248 this._onAfterExecuteFilters.push(filterFn)
249 }
250
251 context (key, value) {
252 this._configuration.context[key] = value
253 }
254
255 prepare () {
256 return new RemoteResourceExecution(
257 this,
258 this._resourceGroup,
259 this._resourceExecutor
260 )
261 }
262
263 param (param) {
264 if (param) {
265 Object.keys(param).forEach((key) => {
266 let value = param[key]
267 this._url = this._originalUrl.replace(':' + key, value)
268 })
269 }
270 return this
271 }
272
273 use (resourceExecutor) {
274 this._resourceExecutor = resourceExecutor
275 }
276
277 getContext () {
278 return this._configuration.context
279 }
280
281 getOnBeforeExecuteFilters () {
282 return this._onBeforeExecuteFilters
283 }
284
285 getOnAfterExecuteFilters () {
286 return this._onAfterExecuteFilters
287 }
288
289 getUrl () {
290 return this._url
291 }
292
293 getQuery () {
294 return this._query
295 }
296
297 setQuery (q) {
298 this._query = q
299 }
300}
301
302class RemoteResourceGroup {
303 constructor (name) {
304 this._name = name
305 this._configuration = {
306 context: {}
307 }
308 this._onBeforeExecuteFilters = []
309 this._onAfterExecuteFilters = []
310 this._resourceExecutor = new PromiseHttpResourceExecutor()
311 }
312
313 use (resourceExecutor) {
314 this._resourceExecutor = resourceExecutor
315 }
316
317 create (url) {
318 return new RemoteResource(this, url)
319 }
320
321 createWithQuery (url, query) {
322 let q = "?" + querystring.stringify(query)
323 this._query = q
324 let remoteResource = new RemoteResource(this, url)
325 remoteResource.setQuery(q)
326 return remoteResource
327 }
328
329 context (key, value) {
330 this._configuration.context[key] = value
331 }
332
333 onBeforeExecute (filterFn) {
334 this._onBeforeExecuteFilters.push(filterFn)
335 }
336
337 onAfterExecute (filterFn) {
338 this._onAfterExecuteFilters.push(filterFn)
339 }
340
341 getContext () {
342 return this._configuration.context
343 }
344
345 getOnBeforeExecuteFilters () {
346 return this._onBeforeExecuteFilters
347 }
348
349 getOnAfterExecuteFilters () {
350 return this._onAfterExecuteFilters
351 }
352
353 getResourceExecutor () {
354 return this._resourceExecutor
355 }
356}
357
358RemoteResource.group = function (groupName) {
359 if (global.__RESOURCE_GROUP_REGISTRY__[groupName] == null || typeof global.__RESOURCE_GROUP_REGISTRY__[groupName] === 'undefined') {
360 global.__RESOURCE_GROUP_REGISTRY__[groupName] = new RemoteResourceGroup(groupName)
361 }
362 return global.__RESOURCE_GROUP_REGISTRY__[groupName]
363}
364
365export default {
366 RemoteResource: RemoteResource
367}