mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 20:14:44 +08:00
Add rest client
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user