mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
use browser fetch on renderer
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
070fc1bb44
commit
7e20856641
@ -48,25 +48,17 @@ if (typeof window === "undefined") {
|
||||
});
|
||||
} else {
|
||||
apiBase = new JsonApi({
|
||||
serverAddress: `http://127.0.0.1:${window.location.port}`,
|
||||
serverAddress: `http://localhost:${window.location.port}`,
|
||||
apiBase: apiPrefix,
|
||||
debug: isDevelopment || isDebugging,
|
||||
}, {
|
||||
headers: {
|
||||
"Host": window.location.host
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isClusterPageContext()) {
|
||||
apiKube = new KubeJsonApi({
|
||||
serverAddress: `http://127.0.0.1:${window.location.port}`,
|
||||
serverAddress: `http://${window.location.host}:${window.location.port}`,
|
||||
apiBase: apiKubePrefix,
|
||||
debug: isDevelopment
|
||||
}, {
|
||||
headers: {
|
||||
"Host": window.location.host
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -21,8 +21,9 @@
|
||||
|
||||
// Base http-service / json-api class
|
||||
|
||||
import { randomBytes } from "crypto";
|
||||
import { merge } from "lodash";
|
||||
import fetch, { Response, RequestInit } from "node-fetch";
|
||||
import nodeFetch, { Response as NodeResponse, RequestInit as NodeRequestInit } from "node-fetch";
|
||||
import { stringify } from "querystring";
|
||||
import { EventEmitter } from "../../common/event-emitter";
|
||||
import logger from "../../common/logger";
|
||||
@ -44,11 +45,14 @@ export interface JsonApiParams<D = any> {
|
||||
export interface JsonApiLog {
|
||||
method: string;
|
||||
reqUrl: string;
|
||||
reqInit: RequestInit;
|
||||
reqInit: RequestInit | NodeRequestInit;
|
||||
data?: any;
|
||||
error?: any;
|
||||
}
|
||||
|
||||
export type JsonRequestInit = RequestInit | NodeRequestInit;
|
||||
export type JsonResponse = Response | NodeResponse;
|
||||
|
||||
export interface JsonApiConfig {
|
||||
apiBase: string;
|
||||
serverAddress: string;
|
||||
@ -65,22 +69,22 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
debug: false
|
||||
};
|
||||
|
||||
constructor(public readonly config: JsonApiConfig, protected reqInit?: RequestInit) {
|
||||
constructor(public readonly config: JsonApiConfig, protected reqInit?: JsonRequestInit) {
|
||||
this.config = Object.assign({}, JsonApi.configDefault, config);
|
||||
this.reqInit = merge({}, JsonApi.reqInitDefault, reqInit);
|
||||
this.parseResponse = this.parseResponse.bind(this);
|
||||
}
|
||||
|
||||
public onData = new EventEmitter<[D, Response]>();
|
||||
public onError = new EventEmitter<[JsonApiErrorParsed, Response]>();
|
||||
public onData = new EventEmitter<[D, JsonResponse]>();
|
||||
public onError = new EventEmitter<[JsonApiErrorParsed, JsonResponse]>();
|
||||
|
||||
get<T = D>(path: string, params?: P, reqInit: RequestInit = {}) {
|
||||
get<T = D>(path: string, params?: P, reqInit: RequestInit | NodeRequestInit = {}) {
|
||||
return this.request<T>(path, params, { ...reqInit, method: "get" });
|
||||
}
|
||||
|
||||
getResponse(path: string, params?: P, init: RequestInit = {}): Promise<Response> {
|
||||
let reqUrl = `${this.config.serverAddress}${this.config.apiBase}${path}`;
|
||||
const reqInit: RequestInit = merge({}, this.reqInit, init);
|
||||
getResponse(path: string, params?: P, init: JsonRequestInit = {}): Promise<JsonResponse> {
|
||||
let reqUrl = this.buildRequestUrl(path, true);
|
||||
const reqInit = merge({}, this.reqInit, init);
|
||||
const { query } = params || {} as P;
|
||||
|
||||
if (!reqInit.method) {
|
||||
@ -93,28 +97,42 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
reqUrl += (reqUrl.includes("?") ? "&" : "?") + queryString;
|
||||
}
|
||||
|
||||
return fetch(reqUrl, reqInit);
|
||||
if (window) {
|
||||
return fetch(reqUrl, reqInit as RequestInit);
|
||||
} else {
|
||||
return nodeFetch(reqUrl, reqInit as NodeRequestInit);
|
||||
}
|
||||
}
|
||||
|
||||
post<T = D>(path: string, params?: P, reqInit: RequestInit = {}) {
|
||||
post<T = D>(path: string, params?: P, reqInit: JsonRequestInit = {}) {
|
||||
return this.request<T>(path, params, { ...reqInit, method: "post" });
|
||||
}
|
||||
|
||||
put<T = D>(path: string, params?: P, reqInit: RequestInit = {}) {
|
||||
put<T = D>(path: string, params?: P, reqInit: JsonRequestInit = {}) {
|
||||
return this.request<T>(path, params, { ...reqInit, method: "put" });
|
||||
}
|
||||
|
||||
patch<T = D>(path: string, params?: P, reqInit: RequestInit = {}) {
|
||||
patch<T = D>(path: string, params?: P, reqInit: JsonRequestInit = {}) {
|
||||
return this.request<T>(path, params, { ...reqInit, method: "PATCH" });
|
||||
}
|
||||
|
||||
del<T = D>(path: string, params?: P, reqInit: RequestInit = {}) {
|
||||
del<T = D>(path: string, params?: P, reqInit: JsonRequestInit = {}) {
|
||||
return this.request<T>(path, params, { ...reqInit, method: "delete" });
|
||||
}
|
||||
|
||||
protected async request<D>(path: string, params?: P, init: RequestInit = {}) {
|
||||
let reqUrl = `${this.config.serverAddress}${this.config.apiBase}${path}`;
|
||||
const reqInit: RequestInit = merge({}, this.reqInit, init);
|
||||
protected buildRequestUrl(path: string, useSubdomain = false) {
|
||||
if (window) {
|
||||
const subdomain = useSubdomain ? `${randomBytes(2).toString("hex")}.` : "";
|
||||
|
||||
return `http://${subdomain}${window.location.host}${this.config.apiBase}${path}`;
|
||||
} else {
|
||||
return `${this.config.serverAddress}${this.config.apiBase}${path}`;
|
||||
}
|
||||
}
|
||||
|
||||
protected async request<D>(path: string, params?: P, init: JsonRequestInit = {}) {
|
||||
let reqUrl = this.buildRequestUrl(path);
|
||||
const reqInit = merge({}, this.reqInit, init);
|
||||
const { data, query } = params || {} as P;
|
||||
|
||||
if (data && !reqInit.body) {
|
||||
@ -132,12 +150,20 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
reqInit,
|
||||
};
|
||||
|
||||
const res = await fetch(reqUrl, reqInit);
|
||||
const res = await this.fetch(reqUrl, reqInit);
|
||||
|
||||
return this.parseResponse<D>(res, infoLog);
|
||||
}
|
||||
|
||||
protected async parseResponse<D>(res: Response, log: JsonApiLog): Promise<D> {
|
||||
protected fetch(reqUrl: string, reqInit: JsonRequestInit) {
|
||||
if (window) {
|
||||
return fetch(reqUrl, reqInit as RequestInit);
|
||||
} else {
|
||||
return nodeFetch(reqUrl, reqInit as NodeRequestInit);
|
||||
}
|
||||
}
|
||||
|
||||
protected async parseResponse<D>(res: JsonResponse, log: JsonApiLog): Promise<D> {
|
||||
const { status } = res;
|
||||
|
||||
const text = await res.text();
|
||||
@ -169,7 +195,7 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
throw error;
|
||||
}
|
||||
|
||||
protected parseError(error: JsonApiError | string, res: Response): string[] {
|
||||
protected parseError(error: JsonApiError | string, res: JsonResponse): string[] {
|
||||
if (typeof error === "string") {
|
||||
return [error];
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import { noop } from "../utils";
|
||||
import type { RequestInit } from "node-fetch";
|
||||
import AbortController from "abort-controller";
|
||||
import { Agent, AgentOptions } from "https";
|
||||
import { ReadableWebToNodeStream } from "readable-web-to-node-stream";
|
||||
|
||||
export interface IKubeApiOptions<T extends KubeObject> {
|
||||
/**
|
||||
@ -117,7 +118,7 @@ export interface IRemoteKubeApiConfig {
|
||||
export function forCluster<T extends KubeObject>(cluster: ILocalKubeApiConfig, kubeClass: KubeObjectConstructor<T>): KubeApi<T> {
|
||||
const url = new URL(apiBase.config.serverAddress);
|
||||
const request = new KubeJsonApi({
|
||||
serverAddress: apiBase.config.serverAddress,
|
||||
serverAddress: window ? `${cluster.metadata.uid}.localhost:${url.port}` : apiBase.config.serverAddress,
|
||||
apiBase: apiKubePrefix,
|
||||
debug: isDevelopment,
|
||||
}, {
|
||||
@ -507,21 +508,24 @@ export class KubeApi<T extends KubeObject> {
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
const body = window ? new ReadableWebToNodeStream(response.body as ReadableStream): response.body as NodeJS.ReadableStream;
|
||||
|
||||
["end", "close", "error"].forEach((eventName) => {
|
||||
response.body.on(eventName, () => {
|
||||
body.on(eventName, () => {
|
||||
clearTimeout(timedRetry);
|
||||
|
||||
if (errorReceived) return; // kubernetes errors should be handled in a callback
|
||||
if (signal.aborted) return;
|
||||
|
||||
logger.info(`[KUBE-API] watch (${watchId}) ${eventName} ${watchUrl}`);
|
||||
|
||||
clearTimeout(timedRetry);
|
||||
timedRetry = setTimeout(() => { // we did not get any kubernetes errors so let's retry
|
||||
this.watch({ ...opts, namespace, callback, watchId, retry: true });
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
byline(response.body).on("data", (line) => {
|
||||
byline(body).on("data", (line) => {
|
||||
try {
|
||||
const event: IKubeWatchEvent<KubeJsonApiData> = JSON.parse(line);
|
||||
|
||||
|
||||
@ -348,7 +348,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
const { signal } = abortController;
|
||||
|
||||
const callback = (data: IKubeWatchEvent<T>, error: any) => {
|
||||
if (!this.isLoaded || error?.type === "aborted") return;
|
||||
if (!this.isLoaded || error instanceof DOMException || error?.type === "aborted") return;
|
||||
|
||||
if (error instanceof Response) {
|
||||
if (error.status === 404 || error.status === 401) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user