An error occurred while loading the file. Please try again.
-
Guillaume Perréal authored01c23089
import { HttpRequest, HttpResponseBase } from '@angular/common/http';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Output,
} from '@angular/core';
// TODO injecter
import { Configuration } from '../configuration';
import { DebugStateService } from '../debug-state.service';
import { ApiDebugInterceptor, DebugEvent } from './api-debug.interceptor';
interface RequestInfo {
id: string;
url: string;
status: 'pending' | 'success' | 'error' | 'cancelled';
method: string;
response?: ResponseInfo;
}
interface ResponseInfo {
status: number;
statusText: string;
token?: string;
tokenLink?: string;
}
@Component({
selector: 'dbg-api-debug',
templateUrl: './api-debug.component.html',
styleUrls: ['./api-debug.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ApiDebugComponent {
private readonly requests = new Map<string, RequestInfo>();
private readonly unseen = new Set<string>();
private readonly ids: string[] = [];
private readonly apiPrefix: string;
@Output() public countChanged = new EventEmitter<number>();
constructor(
interceptor: ApiDebugInterceptor,
public readonly debug: DebugStateService,
private readonly cd: ChangeDetectorRef,
conf: Configuration
) {
this.apiPrefix = conf.apiBaseURL;
interceptor.events$.subscribe(ev => {
this.handle(ev);
});
}
public get unseenCount(): number {
return this.unseen.size;
}
public get totalCount(): number {
return this.ids.length;
}
public get last(): RequestInfo | null {
return this.ids.length ? this.requests.get(this.ids[0]) : null;
}
public get previous(): RequestInfo[] {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
return this.ids.slice(1).map(id => this.requests.get(id));
}
public get all(): RequestInfo[] {
return this.ids.map(id => this.requests.get(id));
}
public isUnseen({ id }: RequestInfo): boolean {
return this.unseen.has(id);
}
public seen({ id }: RequestInfo): void {
if (this.unseen.has(id)) {
this.unseen.delete(id);
this.cd.markForCheck();
}
}
private handle(ev: DebugEvent): void {
if (ev.type === 'request') {
this.addRequest(ev.id, ev.request);
this.countChanged.emit(this.ids.length);
this.cd.markForCheck();
return;
}
const request = this.requests.get(ev.id);
if (!request || request.status !== 'pending') {
return;
}
if (ev.type === 'response') {
this.setResponse(request, ev.response);
} else {
this.cancelRequest(request);
}
this.cd.markForCheck();
}
private addRequest(
id: string,
{ urlWithParams, method }: HttpRequest<any>
): void {
if (urlWithParams.startsWith(this.apiPrefix)) {
urlWithParams = new URL(urlWithParams).pathname;
}
const req: RequestInfo = {
id,
method,
url: urlWithParams,
status: 'pending',
};
this.requests.set(id, req);
this.unseen.add(id);
this.ids.unshift(id);
}
private setResponse(
request: RequestInfo,
{ status, statusText, headers }: HttpResponseBase
): void {
request.response = {
status,
statusText,
token: headers.get('X-Debug-Token'),
tokenLink: headers.get('X-Debug-Token-Link'),
};
if (status < 100 || status >= 400) {
request.status = 'error';
} else {
request.status = 'success';
141142143144145146147148
}
}
private cancelRequest(request: RequestInfo): void {
request.status = 'cancelled';
}
}