Skip to content

Commit 95d9f2c

Browse files
committed
Extract HttpBase class
Signed-off-by: Andrew Richardson <[email protected]>
1 parent 58f5077 commit 95d9f2c

File tree

6 files changed

+114
-106
lines changed

6 files changed

+114
-106
lines changed

lib/firefly.ts

Lines changed: 2 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { Stream, Readable } from 'stream';
2-
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
32
import * as FormData from 'form-data';
43
import {
5-
FireFlyOptions,
6-
FireFlyOptionsInput,
74
FireFlyStatusResponse,
85
FireFlyPrivateSendOptions,
96
FireFlyCreateOptions,
@@ -51,106 +48,10 @@ import {
5148
FireFlyContractAPIFilter,
5249
} from './interfaces';
5350
import { FireFlyWebSocket, FireFlyWebSocketCallback } from './websocket';
51+
import HttpBase, { mapConfig } from './http';
5452

55-
function isSuccess(status: number) {
56-
return status >= 200 && status < 300;
57-
}
58-
59-
function mapConfig(
60-
options: FireFlyGetOptions | FireFlyCreateOptions | undefined,
61-
params?: any,
62-
): AxiosRequestConfig {
63-
return {
64-
...options?.requestConfig,
65-
params: {
66-
...params,
67-
confirm: options?.confirm,
68-
},
69-
};
70-
}
71-
72-
export class FireFlyError extends Error {}
73-
74-
export default class FireFly {
75-
private options: FireFlyOptions;
76-
private rootHttp: AxiosInstance;
77-
private http: AxiosInstance;
53+
export default class FireFly extends HttpBase {
7854
private queue = Promise.resolve();
79-
private errorHandler?: (err: FireFlyError) => void;
80-
81-
constructor(options: FireFlyOptionsInput) {
82-
this.options = this.setDefaults(options);
83-
this.rootHttp = axios.create({
84-
...options.requestConfig,
85-
baseURL: `${options.host}/api/v1`,
86-
});
87-
this.http = axios.create({
88-
...options.requestConfig,
89-
baseURL: `${options.host}/api/v1/namespaces/${this.options.namespace}`,
90-
});
91-
}
92-
93-
private setDefaults(options: FireFlyOptionsInput): FireFlyOptions {
94-
return {
95-
...options,
96-
namespace: options.namespace ?? 'default',
97-
websocket: {
98-
...options.websocket,
99-
host: options.websocket?.host ?? options.host.replace('http', 'ws'),
100-
reconnectDelay: options.websocket?.reconnectDelay ?? 5000,
101-
heartbeatInterval: options.websocket?.heartbeatInterval ?? 30000,
102-
},
103-
};
104-
}
105-
106-
private async wrapError<T>(response: Promise<AxiosResponse<T>>) {
107-
return response.catch((err) => {
108-
if (axios.isAxiosError(err)) {
109-
const errorMessage = err.response?.data?.error;
110-
const ffError = new FireFlyError(errorMessage ?? err.message);
111-
if (this.errorHandler !== undefined) {
112-
this.errorHandler(ffError);
113-
}
114-
throw ffError;
115-
}
116-
throw err;
117-
});
118-
}
119-
120-
private async getMany<T>(url: string, params?: any, options?: FireFlyGetOptions, root = false) {
121-
const http = root ? this.rootHttp : this.http;
122-
const response = await this.wrapError(http.get<T>(url, mapConfig(options, params)));
123-
return response.data;
124-
}
125-
126-
private async getOne<T>(url: string, options?: FireFlyGetOptions, params?: any, root = false) {
127-
const http = root ? this.rootHttp : this.http;
128-
const response = await this.wrapError(
129-
http.get<T>(url, {
130-
...mapConfig(options, params),
131-
validateStatus: (status) => status === 404 || isSuccess(status),
132-
}),
133-
);
134-
return response.status === 404 ? undefined : response.data;
135-
}
136-
137-
private async createOne<T>(url: string, data: any, options?: FireFlyCreateOptions) {
138-
const response = await this.wrapError(this.http.post<T>(url, data, mapConfig(options)));
139-
return response.data;
140-
}
141-
142-
private async replaceOne<T>(url: string, data: any) {
143-
const response = await this.wrapError(this.http.put<T>(url, data));
144-
return response.data;
145-
}
146-
147-
private async deleteOne<T>(url: string) {
148-
await this.wrapError(this.http.delete<T>(url));
149-
}
150-
151-
onError(handler: (err: FireFlyError) => void) {
152-
this.errorHandler = handler;
153-
}
15455

15556
async getStatus(options?: FireFlyGetOptions): Promise<FireFlyStatusResponse> {
15657
const response = await this.rootHttp.get<FireFlyStatusResponse>('/status', mapConfig(options));

lib/http.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2+
import {
3+
FireFlyOptions,
4+
FireFlyOptionsInput,
5+
FireFlyCreateOptions,
6+
FireFlyGetOptions,
7+
FireFlyError,
8+
} from './interfaces';
9+
10+
function isSuccess(status: number) {
11+
return status >= 200 && status < 300;
12+
}
13+
14+
export function mapConfig(
15+
options: FireFlyGetOptions | FireFlyCreateOptions | undefined,
16+
params?: any,
17+
): AxiosRequestConfig {
18+
return {
19+
...options?.requestConfig,
20+
params: {
21+
...params,
22+
confirm: options?.confirm,
23+
},
24+
};
25+
}
26+
27+
export default class HttpBase {
28+
protected options: FireFlyOptions;
29+
protected rootHttp: AxiosInstance;
30+
protected http: AxiosInstance;
31+
32+
private errorHandler?: (err: FireFlyError) => void;
33+
34+
constructor(options: FireFlyOptionsInput) {
35+
this.options = this.setDefaults(options);
36+
this.rootHttp = axios.create({
37+
...options.requestConfig,
38+
baseURL: `${options.host}/api/v1`,
39+
});
40+
this.http = axios.create({
41+
...options.requestConfig,
42+
baseURL: `${options.host}/api/v1/namespaces/${this.options.namespace}`,
43+
});
44+
}
45+
46+
private setDefaults(options: FireFlyOptionsInput): FireFlyOptions {
47+
return {
48+
...options,
49+
namespace: options.namespace ?? 'default',
50+
websocket: {
51+
...options.websocket,
52+
host: options.websocket?.host ?? options.host.replace('http', 'ws'),
53+
reconnectDelay: options.websocket?.reconnectDelay ?? 5000,
54+
heartbeatInterval: options.websocket?.heartbeatInterval ?? 30000,
55+
},
56+
};
57+
}
58+
59+
protected async wrapError<T>(response: Promise<AxiosResponse<T>>) {
60+
return response.catch((err) => {
61+
if (axios.isAxiosError(err)) {
62+
const errorMessage = err.response?.data?.error;
63+
const ffError = new FireFlyError(errorMessage ?? err.message);
64+
if (this.errorHandler !== undefined) {
65+
this.errorHandler(ffError);
66+
}
67+
throw ffError;
68+
}
69+
throw err;
70+
});
71+
}
72+
73+
protected async getMany<T>(url: string, params?: any, options?: FireFlyGetOptions, root = false) {
74+
const http = root ? this.rootHttp : this.http;
75+
const response = await this.wrapError(http.get<T>(url, mapConfig(options, params)));
76+
return response.data;
77+
}
78+
79+
protected async getOne<T>(url: string, options?: FireFlyGetOptions, params?: any, root = false) {
80+
const http = root ? this.rootHttp : this.http;
81+
const response = await this.wrapError(
82+
http.get<T>(url, {
83+
...mapConfig(options, params),
84+
validateStatus: (status) => status === 404 || isSuccess(status),
85+
}),
86+
);
87+
return response.status === 404 ? undefined : response.data;
88+
}
89+
90+
protected async createOne<T>(url: string, data: any, options?: FireFlyCreateOptions) {
91+
const response = await this.wrapError(this.http.post<T>(url, data, mapConfig(options)));
92+
return response.data;
93+
}
94+
95+
protected async replaceOne<T>(url: string, data: any) {
96+
const response = await this.wrapError(this.http.put<T>(url, data));
97+
return response.data;
98+
}
99+
100+
protected async deleteOne<T>(url: string) {
101+
await this.wrapError(this.http.delete<T>(url));
102+
}
103+
104+
onError(handler: (err: FireFlyError) => void) {
105+
this.errorHandler = handler;
106+
}
107+
}

lib/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
import FireFly from './firefly';
2-
32
export default FireFly;
4-
export * from './firefly';
53
export * from './interfaces';

lib/interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { operations } from './schema';
1313

1414
// General
1515

16+
export class FireFlyError extends Error {}
17+
1618
export interface FireFlyGetOptions {
1719
confirm: undefined;
1820
requestConfig?: AxiosRequestConfig;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hyperledger/firefly-sdk",
3-
"version": "0.1.0-alpha.10",
3+
"version": "0.1.0-alpha.11",
44
"description": "Client SDK for Hyperledger FireFly",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

0 commit comments

Comments
 (0)