Add sdnr wt odlux
[ccsdk/features.git] / sdnr / wt / odlux / framework / src / services / restAccessorService.ts
1 import * as $ from 'jquery'; 
2 import { Action, IActionHandler } from '../flux/action';
3 import { MiddlewareArg } from '../flux/middleware';
4 import { Dispatch } from '../flux/store';
5
6 import { IApplicationStoreState } from '../store/applicationStore';
7 import { AddErrorInfoAction, ErrorInfo } from '../actions/errorActions';
8 import { PlainObject, AjaxParameter } from 'models/restService';
9
10 export const absoluteUri = /^(https?:\/\/|blob:)/i;
11 export const baseUrl = `${ window.location.origin }${ window.location.pathname }`;
12
13 class RestBaseAction extends Action { }
14
15 export const createRestApiAccessor = <TResult extends PlainObject>(urlOrPath: string, initialValue: TResult) => {
16   const isLocalRequest = !absoluteUri.test(urlOrPath);
17   const uri = isLocalRequest ? `${ baseUrl }/${ urlOrPath }`.replace(/\/{2,}/, '/') : urlOrPath ;
18  
19   class RestRequestAction extends RestBaseAction { constructor(public settings?: AjaxParameter) { super(); } }
20
21   class RestResponseAction extends RestBaseAction { constructor(public result: TResult) { super(); } }
22
23   class RestErrorAction extends RestBaseAction { constructor(public error?: Error | string) { super(); } }
24   
25   type RestAction = RestRequestAction | RestResponseAction | RestErrorAction;
26
27   /** Represents our middleware to handle rest backend requests */
28   const restMiddleware = (api: MiddlewareArg<IApplicationStoreState>) =>
29     (next: Dispatch) => (action: RestAction): RestAction => {
30       
31       // pass all actions through by default
32       next(action);
33       // handle the RestRequestAction
34       if (action instanceof RestRequestAction) {
35         const state = api.getState();
36         const authHeader = isLocalRequest && state && state.framework.authenticationState.user && state.framework.authenticationState.user.token
37           ? { "Authentication": "Bearer " + state.framework.authenticationState.user.token } : { };
38         $.ajax({
39           url: uri,
40           method: (action.settings && action.settings.method) || "GET",
41           headers: { ...authHeader, ...action.settings && action.settings.headers ? action.settings.headers : { } },
42         }).then((data: TResult) => {
43            next(new RestResponseAction(data));
44         }).catch((err: any) => {
45           next(new RestErrorAction());
46           next(new AddErrorInfoAction((err instanceof Error) ? { error: err } : { message: err.toString() }));
47         });
48       }
49       // allways return action
50       return action;
51   };
52   
53   /** Represents our action handler to handle our actions */
54   const restActionHandler: IActionHandler<TResult> = (state = initialValue, action) => {
55     if (action instanceof RestRequestAction) {
56       return {
57         ...(state as any),
58         busy: true
59       };
60     } else if (action instanceof RestResponseAction) {
61       return action.result;
62     } else if (action instanceof RestErrorAction) {
63       return initialValue;
64     }
65     return state;
66   };
67
68   return {
69     requestAction: RestRequestAction,
70     actionHandler: restActionHandler,
71     middleware: restMiddleware,
72   };
73 }
74
75
76