events & initialize
This commit is contained in:
parent
3f7fc8a147
commit
afbcae4add
5 changed files with 73 additions and 9 deletions
23
README.md
23
README.md
|
@ -6,7 +6,7 @@ Zur Verfügung gestellt werden Requests mit den benötigten Models, Types und En
|
||||||
|
|
||||||
Der WebApiClient realisiert den automatischen refresh von Zugangs-Tokens.
|
Der WebApiClient realisiert den automatischen refresh von Zugangs-Tokens.
|
||||||
|
|
||||||
Beispiele:\
|
Beispiele:
|
||||||
1. Verwendung des Clients:
|
1. Verwendung des Clients:
|
||||||
``` ts
|
``` ts
|
||||||
import { WebApiClient, AdminRequests } from "@ff-admin/webapi-client"
|
import { WebApiClient, AdminRequests } from "@ff-admin/webapi-client"
|
||||||
|
@ -15,7 +15,10 @@ let myClient = new WebApiClient({
|
||||||
serverAdress: "",
|
serverAdress: "",
|
||||||
webapiToken: ""
|
webapiToken: ""
|
||||||
});
|
});
|
||||||
|
myClient.initialize() // asynchrone Funktion - muss vollständig ausgeführt sein, bevor irgendwelche Anfragen gestellt werden
|
||||||
|
```
|
||||||
|
2. Nutzung der Requests
|
||||||
|
```ts
|
||||||
let data = AdminRequests.MemberRequests.getAllMembers(myClient)
|
let data = AdminRequests.MemberRequests.getAllMembers(myClient)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log(res)
|
console.log(res)
|
||||||
|
@ -49,12 +52,24 @@ AdminRequests.MemberRequests.updateMember(myClient, {
|
||||||
.then(() => {})
|
.then(() => {})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
```
|
```
|
||||||
|
3. Zugriff auf Typen, Models und Enums:
|
||||||
2. Zugriff auf Typen, Models und Enums:
|
|
||||||
``` ts
|
``` ts
|
||||||
import { AdminModels, AdminTypes, AdminEnums } from "@ff-admin/webapi-client"
|
import { AdminModels, AdminTypes, AdminEnums } from "@ff-admin/webapi-client"
|
||||||
|
|
||||||
let model: AdminModels.MemberModels.CreateMemberViewModel;
|
let model: AdminModels.MemberModels.CreateMemberViewModel;
|
||||||
let type: AdminTypes.DynamicQueries.DynamicQueryStructure
|
let type: AdminTypes.DynamicQueries.DynamicQueryStructure
|
||||||
let enum = AdminEnums.NewsletterType.NewsletterConfigType.mail
|
let enum = AdminEnums.NewsletterType.NewsletterConfigType.mail
|
||||||
|
```
|
||||||
|
4. http Events:
|
||||||
|
Es können Events wie Fehler oder Informationen direkt aus der Middleware des Clients angezapft werden.
|
||||||
|
``` ts
|
||||||
|
import { WebApiClient, AdminRequests } from "@ff-admin/webapi-client"
|
||||||
|
|
||||||
|
let myClient = new WebApiClient({
|
||||||
|
serverAdress: "",
|
||||||
|
webapiToken: ""
|
||||||
|
});
|
||||||
|
myClient.initialize()
|
||||||
|
|
||||||
|
client.httpEvents.on(<"error" | "info">, (data) => {})
|
||||||
```
|
```
|
|
@ -12,6 +12,12 @@ export class BaseClient extends Config {
|
||||||
return this.httpInstance.http;
|
return this.httpInstance.http;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get httpEvents() {
|
||||||
|
return this.httpInstance.httpEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async initialize(): Promise<void> {}
|
||||||
|
|
||||||
public refreshToken(): Promise<void> {
|
public refreshToken(): Promise<void> {
|
||||||
return new Promise<void>(async (resolve, reject) => {
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
reject("api token refresh not implemented");
|
reject("api token refresh not implemented");
|
||||||
|
|
|
@ -5,8 +5,8 @@ export class WebApiClient extends BaseClient {
|
||||||
super({ serverAdress, webapiToken });
|
super({ serverAdress, webapiToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
get http() {
|
public async initialize(): Promise<void> {
|
||||||
return this.httpInstance.http;
|
await this.refreshToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
public refreshToken(): Promise<void> {
|
public refreshToken(): Promise<void> {
|
||||||
|
|
23
src/http.ts
23
src/http.ts
|
@ -1,9 +1,16 @@
|
||||||
import axios, { AxiosInstance } from "axios";
|
import axios, { AxiosInstance } from "axios";
|
||||||
import { BaseClient } from "./clients/clientBase";
|
import { BaseClient } from "./clients/clientBase";
|
||||||
|
import { EventEmitterReadonly, TypedEventEmitter } from "./utils/typedEmitter";
|
||||||
|
|
||||||
|
type HttpEvents = {
|
||||||
|
info: [arg1: string];
|
||||||
|
error: [arg1: { code: string; message: string }];
|
||||||
|
};
|
||||||
|
|
||||||
export default class HTTP {
|
export default class HTTP {
|
||||||
public http: AxiosInstance;
|
public readonly http: AxiosInstance;
|
||||||
private client: BaseClient;
|
protected readonly httpEmitter: TypedEventEmitter<HttpEvents>;
|
||||||
|
protected client: BaseClient;
|
||||||
|
|
||||||
constructor(client: BaseClient) {
|
constructor(client: BaseClient) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
@ -15,15 +22,20 @@ export default class HTTP {
|
||||||
Expires: "0",
|
Expires: "0",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
this.httpEmitter = new TypedEventEmitter<HttpEvents>();
|
||||||
|
|
||||||
this.setRequestInterceptor();
|
this.setRequestInterceptor();
|
||||||
this.setResponseInterceptor();
|
this.setResponseInterceptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get httpEvents(): EventEmitterReadonly<HttpEvents> {
|
||||||
|
return this.httpEmitter;
|
||||||
|
}
|
||||||
|
|
||||||
private setRequestInterceptor() {
|
private setRequestInterceptor() {
|
||||||
this.http.interceptors.request.use(
|
this.http.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
if (config.headers && config.headers.Authorization == "") {
|
if (config.headers && !config.headers.Authorization) {
|
||||||
config.headers.Authorization = `Bearer ${this.client.accessToken}`;
|
config.headers.Authorization = `Bearer ${this.client.accessToken}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +65,16 @@ export default class HTTP {
|
||||||
return await this.client
|
return await this.client
|
||||||
.refreshToken()
|
.refreshToken()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
this.httpEmitter.emit("info", "successfully refreshed token");
|
||||||
return this.http(originalRequest);
|
return this.http(originalRequest);
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.httpEmitter.emit("error", {
|
||||||
|
code: error.code,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
26
src/utils/typedEmitter.ts
Normal file
26
src/utils/typedEmitter.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import EventEmitter = require("node:events");
|
||||||
|
|
||||||
|
export interface EventEmitterReadonly<TEvents extends Record<string, any>> {
|
||||||
|
on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void;
|
||||||
|
off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventEmitterFull<TEvents extends Record<string, any>> extends EventEmitterReadonly<TEvents> {
|
||||||
|
emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArg: TEvents[TEventName]): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TypedEventEmitter<TEvents extends Record<string, any>> implements EventEmitterFull<TEvents> {
|
||||||
|
private emitter = new EventEmitter();
|
||||||
|
|
||||||
|
emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArg: TEvents[TEventName]) {
|
||||||
|
this.emitter.emit(eventName, ...(eventArg as []));
|
||||||
|
}
|
||||||
|
|
||||||
|
on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void) {
|
||||||
|
this.emitter.on(eventName, handler as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void) {
|
||||||
|
this.emitter.off(eventName, handler as any);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue