Add rest client

This commit is contained in:
Chi Vinh Le
2018-08-10 17:19:01 +02:00
parent 4e493ad1da
commit bb39b4e8fa
3 changed files with 63 additions and 0 deletions
@@ -6,6 +6,7 @@ import { MediaQueryMatchers } from "react-responsive";
import { Formatter } from "react-timeago";
import { Environment } from "relay-runtime";
import { RestClient } from "talk-framework/lib/rest";
import { UIContext } from "talk-ui/components";
import { ClickFarAwayRegister } from "talk-ui/components/ClickOutside";
@@ -22,6 +23,9 @@ export interface TalkContext {
/** media query values for testing purposes */
mediaQueryValues?: MediaQueryMatchers;
/** Rest client */
rest: RestClient;
/**
* A way to listen for clicks that are e.g. outside of the
* current frame for `ClickOutside`
@@ -6,6 +6,7 @@ import React from "react";
import { Formatter } from "react-timeago";
import { Environment, Network, RecordSource, Store } from "relay-runtime";
import { RestClient } from "talk-framework/lib/rest";
import { ClickFarAwayRegister } from "talk-ui/components/ClickOutside";
import { generateMessages, LocalesData, negotiateLanguages } from "../i18n";
@@ -99,6 +100,7 @@ export default async function createContext({
pym,
eventEmitter,
registerClickFarAway,
rest: new RestClient("/api"),
};
// Run custom initializations.
+57
View File
@@ -0,0 +1,57 @@
import merge from "lodash/merge";
import { Overwrite } from "talk-framework/types";
const buildOptions = (inputOptions: RequestInit = {}) => {
const defaultOptions: RequestInit = {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
credentials: "same-origin",
};
const options = merge({}, defaultOptions, inputOptions);
if (options.method!.toLowerCase() !== "get") {
options.body = JSON.stringify(options.body);
}
return options;
};
const handleResp = (res: Response) => {
if (res.status > 399) {
return res.json().then((err: any) => {
// TODO: sync error handling with server.
const message = err.message || res.status;
const error = new Error(message);
throw error;
});
} else if (res.status === 204) {
return res.text();
} else {
return res.json();
}
};
type PartialRequestInit = Overwrite<Partial<RequestInit>, { body: any }>;
export class RestClient {
public readonly uri: string;
private tokenGetter?: () => string;
constructor(uri: string, tokenGetter?: () => string) {
this.uri = uri;
this.tokenGetter = tokenGetter;
}
public fetch(path: string, options: PartialRequestInit): Promise<Response> {
let opts = options;
if (this.tokenGetter) {
opts = merge({}, options, {
headers: {
Authorization: `Bearer ${this.tokenGetter()}`,
},
});
}
return fetch(`${this.uri}${path}`, buildOptions(opts)).then(handleResp);
}
}