mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add more injectables
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
a733641f62
commit
1b700491f9
@ -8,6 +8,8 @@ import hostedClusterIdInjectable from "../cluster-frame-context/hosted-cluster-i
|
|||||||
import getShellAuthTokenInjectable from "../../common/shell-authentication/get-auth-token.injectable";
|
import getShellAuthTokenInjectable from "../../common/shell-authentication/get-auth-token.injectable";
|
||||||
import type { TerminalApiQuery } from "./terminal-api";
|
import type { TerminalApiQuery } from "./terminal-api";
|
||||||
import { TerminalApi } from "./terminal-api";
|
import { TerminalApi } from "./terminal-api";
|
||||||
|
import createWebsocketInjectable from "./create-websocket.injectable";
|
||||||
|
import defaultWebsocketParamsInjectable from "./default-websocket-params.injectable";
|
||||||
|
|
||||||
export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
|
export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
|
||||||
|
|
||||||
@ -16,6 +18,8 @@ const createTerminalApiInjectable = getInjectable({
|
|||||||
instantiate: (di): CreateTerminalApi => {
|
instantiate: (di): CreateTerminalApi => {
|
||||||
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
||||||
const getShellAuthToken = di.inject(getShellAuthTokenInjectable);
|
const getShellAuthToken = di.inject(getShellAuthTokenInjectable);
|
||||||
|
const createWebsocket = di.inject(createWebsocketInjectable);
|
||||||
|
const defaultParams = di.inject(defaultWebsocketParamsInjectable);
|
||||||
|
|
||||||
return (query) => {
|
return (query) => {
|
||||||
assert(hostedClusterId, "Can only create terminal APIs within a cluster frame");
|
assert(hostedClusterId, "Can only create terminal APIs within a cluster frame");
|
||||||
@ -23,6 +27,8 @@ const createTerminalApiInjectable = getInjectable({
|
|||||||
return new TerminalApi({
|
return new TerminalApi({
|
||||||
hostedClusterId,
|
hostedClusterId,
|
||||||
getShellAuthToken,
|
getShellAuthToken,
|
||||||
|
createWebsocket,
|
||||||
|
defaultParams,
|
||||||
}, query);
|
}, query);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
14
src/renderer/api/create-websocket.injectable.ts
Normal file
14
src/renderer/api/create-websocket.injectable.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
export type CreateWebsocket = (url: string) => WebSocket;
|
||||||
|
|
||||||
|
const createWebsocketInjectable = getInjectable({
|
||||||
|
id: "create-websocket",
|
||||||
|
instantiate: (): CreateWebsocket => (url) => new WebSocket(url),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createWebsocketInjectable;
|
||||||
22
src/renderer/api/default-websocket-params.injectable.ts
Normal file
22
src/renderer/api/default-websocket-params.injectable.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { Injectable } from "@ogre-tools/injectable";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { TerminalChannels, type TerminalMessage } from "../../common/terminal/channels";
|
||||||
|
import isDevelopmentInjectable from "../../common/vars/is-development.injectable";
|
||||||
|
|
||||||
|
export type DefaultWebsocketParams = typeof defaultWebsocketParamsInjectable extends Injectable<infer T, any, any> ? T : never;
|
||||||
|
|
||||||
|
const defaultWebsocketParamsInjectable = getInjectable({
|
||||||
|
id: "default-websocket-params",
|
||||||
|
instantiate: (di) => ({
|
||||||
|
logging: di.inject(isDevelopmentInjectable),
|
||||||
|
reconnectDelay: 10,
|
||||||
|
flushOnOpen: true,
|
||||||
|
pingMessage: JSON.stringify({ type: TerminalChannels.PING } as TerminalMessage),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defaultWebsocketParamsInjectable;
|
||||||
@ -3,7 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { WebSocketEvents } from "./websocket-api";
|
import type { WebSocketApiDependencies, WebSocketEvents } from "./websocket-api";
|
||||||
import { WebSocketApi } from "./websocket-api";
|
import { WebSocketApi } from "./websocket-api";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
@ -36,7 +36,7 @@ export interface TerminalEvents extends WebSocketEvents {
|
|||||||
connected: () => void;
|
connected: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TerminalApiDependencies {
|
export interface TerminalApiDependencies extends WebSocketApiDependencies {
|
||||||
readonly hostedClusterId: string;
|
readonly hostedClusterId: string;
|
||||||
getShellAuthToken: GetShellAuthToken;
|
getShellAuthToken: GetShellAuthToken;
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
|||||||
@observable public isReady = false;
|
@observable public isReady = false;
|
||||||
|
|
||||||
constructor(protected readonly dependencies: TerminalApiDependencies, protected readonly query: TerminalApiQuery) {
|
constructor(protected readonly dependencies: TerminalApiDependencies, protected readonly query: TerminalApiQuery) {
|
||||||
super({
|
super(dependencies, {
|
||||||
flushOnOpen: false,
|
flushOnOpen: false,
|
||||||
pingInterval: 30,
|
pingInterval: 30,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,9 +7,9 @@ import { observable, makeObservable } from "mobx";
|
|||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
import type TypedEventEmitter from "typed-emitter";
|
import type TypedEventEmitter from "typed-emitter";
|
||||||
import type { Arguments } from "typed-emitter";
|
import type { Arguments } from "typed-emitter";
|
||||||
import { isDevelopment } from "../../common/vars";
|
|
||||||
import type { Defaulted } from "../utils";
|
import type { Defaulted } from "../utils";
|
||||||
import { TerminalChannels, type TerminalMessage } from "../../common/terminal/channels";
|
import type { CreateWebsocket } from "./create-websocket.injectable";
|
||||||
|
import type { DefaultWebsocketParams } from "./default-websocket-params.injectable";
|
||||||
|
|
||||||
interface WebsocketApiParams {
|
interface WebsocketApiParams {
|
||||||
/**
|
/**
|
||||||
@ -64,27 +64,25 @@ export interface WebSocketEvents {
|
|||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WebSocketApiDependencies {
|
||||||
|
createWebsocket: CreateWebsocket;
|
||||||
|
readonly defaultParams: DefaultWebsocketParams;
|
||||||
|
}
|
||||||
|
|
||||||
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
|
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
|
||||||
protected socket: WebSocket | null = null;
|
protected socket: WebSocket | null = null;
|
||||||
protected pendingCommands: string[] = [];
|
protected pendingCommands: string[] = [];
|
||||||
protected reconnectTimer?: number;
|
protected reconnectTimer?: number;
|
||||||
protected pingTimer?: number;
|
protected pingTimer?: number;
|
||||||
protected params: Defaulted<WebsocketApiParams, keyof typeof WebSocketApi["defaultParams"]>;
|
protected readonly params: Defaulted<WebsocketApiParams, keyof DefaultWebsocketParams>;
|
||||||
|
|
||||||
@observable readyState = WebSocketApiState.PENDING;
|
@observable readyState = WebSocketApiState.PENDING;
|
||||||
|
|
||||||
private static readonly defaultParams = {
|
constructor(protected readonly dependencies: WebSocketApiDependencies, params: WebsocketApiParams) {
|
||||||
logging: isDevelopment,
|
|
||||||
reconnectDelay: 10,
|
|
||||||
flushOnOpen: true,
|
|
||||||
pingMessage: JSON.stringify({ type: TerminalChannels.PING } as TerminalMessage),
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(params: WebsocketApiParams) {
|
|
||||||
super();
|
super();
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
this.params = {
|
this.params = {
|
||||||
...WebSocketApi.defaultParams,
|
...this.dependencies.defaultParams,
|
||||||
...params,
|
...params,
|
||||||
};
|
};
|
||||||
const { pingInterval } = this.params;
|
const { pingInterval } = this.params;
|
||||||
@ -111,7 +109,7 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
|||||||
this.socket?.close();
|
this.socket?.close();
|
||||||
|
|
||||||
// start new connection
|
// start new connection
|
||||||
this.socket = new WebSocket(url);
|
this.socket = this.dependencies.createWebsocket(url);
|
||||||
this.socket.addEventListener("open", ev => this._onOpen(ev));
|
this.socket.addEventListener("open", ev => this._onOpen(ev));
|
||||||
this.socket.addEventListener("message", ev => this._onMessage(ev));
|
this.socket.addEventListener("message", ev => this._onMessage(ev));
|
||||||
this.socket.addEventListener("error", ev => this._onError(ev));
|
this.socket.addEventListener("error", ev => this._onError(ev));
|
||||||
|
|||||||
@ -4,43 +4,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { RenderResult } from "@testing-library/react";
|
import type { RenderResult } from "@testing-library/react";
|
||||||
import { waitFor } from "@testing-library/react";
|
|
||||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import getShellAuthTokenChannelHandlerInjectable from "../../main/lens-proxy/proxy-functions/shell/auth-token-channel-handler.injectable";
|
import getShellAuthTokenChannelHandlerInjectable from "../../main/lens-proxy/proxy-functions/shell/auth-token-channel-handler.injectable";
|
||||||
import type { GetShellAuthToken } from "../../common/shell-authentication/get-auth-token.injectable";
|
import type { GetShellAuthToken } from "../../common/shell-authentication/get-auth-token.injectable";
|
||||||
import type { SpawnPty } from "../../main/shell-session/spawn-pty.injectable";
|
|
||||||
import spawnPtyInjectable from "../../main/shell-session/spawn-pty.injectable";
|
import spawnPtyInjectable from "../../main/shell-session/spawn-pty.injectable";
|
||||||
import type { IPty } from "node-pty";
|
|
||||||
|
|
||||||
describe("local shell session techincal tests", () => {
|
describe("local shell session techincal tests", () => {
|
||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
let result: RenderResult;
|
let result: RenderResult;
|
||||||
let authenticationSpy: jest.SpyInstance<Uint8Array | Promise<Uint8Array>, Parameters<GetShellAuthToken>>;
|
let authenticationSpy: jest.SpyInstance<Uint8Array | Promise<Uint8Array>, Parameters<GetShellAuthToken>>;
|
||||||
let spawnPtyMock: jest.MockedFunction<SpawnPty>;
|
|
||||||
let ptyMock: jest.MockedObject<IPty>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
builder = getApplicationBuilder()
|
builder = getApplicationBuilder()
|
||||||
.beforeApplicationStart(() => {
|
.beforeApplicationStart(() => {
|
||||||
spawnPtyMock = jest.fn();
|
builder.dis.mainDi.override(spawnPtyInjectable, () => jest.fn());
|
||||||
builder.dis.mainDi.override(spawnPtyInjectable, () => spawnPtyMock);
|
|
||||||
|
|
||||||
spawnPtyMock.mockImplementation(() => ptyMock = {
|
|
||||||
cols: 80,
|
|
||||||
rows: 40,
|
|
||||||
pid: 12346,
|
|
||||||
process: "my-mocked-shell",
|
|
||||||
handleFlowControl: true,
|
|
||||||
kill: jest.fn(),
|
|
||||||
onData: jest.fn(),
|
|
||||||
onExit: jest.fn(),
|
|
||||||
on: jest.fn(),
|
|
||||||
resize: jest.fn(),
|
|
||||||
write: jest.fn(),
|
|
||||||
pause: jest.fn(),
|
|
||||||
resume: jest.fn(),
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.beforeRender(() => {
|
.beforeRender(() => {
|
||||||
const shellAuthentication = builder.dis.mainDi.inject(getShellAuthTokenChannelHandlerInjectable);
|
const shellAuthentication = builder.dis.mainDi.inject(getShellAuthTokenChannelHandlerInjectable);
|
||||||
@ -60,9 +38,4 @@ describe("local shell session techincal tests", () => {
|
|||||||
it("should call the authentication function", () => {
|
it("should call the authentication function", () => {
|
||||||
expect(authenticationSpy).toBeCalled();
|
expect(authenticationSpy).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create a pty instance", async () => {
|
|
||||||
await waitFor(() => expect(spawnPtyMock).toBeCalled());
|
|
||||||
void ptyMock;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user