Skip to content

Commit

Permalink
chore: cleanup API sender object
Browse files Browse the repository at this point in the history
replace any by unknown type and remove eslint/disable-no-explicit-any
make it consistent across all the packages and ensure it returns
a disposable object.

fixing also parts where callbacks can't be promises

Signed-off-by: Florent Benoit <fbenoit@redhat.com>
  • Loading branch information
benoitf committed Jan 18, 2024
1 parent 9d438cc commit ab0bd50
Show file tree
Hide file tree
Showing 22 changed files with 236 additions and 91 deletions.
9 changes: 4 additions & 5 deletions packages/main/src/plugin/api.ts
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,15 +17,14 @@
***********************************************************************/

import type { ContainerInfo } from './api/container-info.js';
import type { IDisposable } from './types/disposable.js';

export interface RemoteAPI {
// eslint-disable-next-line @typescript-eslint/ban-types
listContainers(options?: {}): Promise<ContainerInfo[]>;
}

export type ApiSenderType = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
send: (channel: string, data?: any) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
receive: (channel: string, func: any) => void;
send: (channel: string, data?: unknown) => void;
receive: (channel: string, func: (...args: unknown[]) => void) => IDisposable;
};
16 changes: 8 additions & 8 deletions packages/main/src/plugin/container-registry.ts
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022-2023 Red Hat, Inc.
* Copyright (C) 2022-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -200,24 +200,24 @@ export class ContainerProviderRegistry {
}

setupListeners() {
const cleanStreamMap = (containerId: string) => {
this.streamsPerContainerId.delete(containerId);
this.streamsOutputPerContainerId.delete(containerId);
const cleanStreamMap = (containerId: unknown) => {
this.streamsPerContainerId.delete(String(containerId));
this.streamsOutputPerContainerId.delete(String(containerId));
};

this.apiSender.receive('container-stopped-event', (containerId: string) => {
this.apiSender.receive('container-stopped-event', (containerId: unknown) => {
cleanStreamMap(containerId);
});

this.apiSender.receive('container-die-event', (containerId: string) => {
this.apiSender.receive('container-die-event', (containerId: unknown) => {
cleanStreamMap(containerId);
});

this.apiSender.receive('container-kill-event', (containerId: string) => {
this.apiSender.receive('container-kill-event', (containerId: unknown) => {
cleanStreamMap(containerId);
});

this.apiSender.receive('container-removed-event', (containerId: string) => {
this.apiSender.receive('container-removed-event', (containerId: unknown) => {
cleanStreamMap(containerId);
});
}
Expand Down
16 changes: 10 additions & 6 deletions packages/main/src/plugin/contribution-manager.spec.ts
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
* Copyright (C) 2023-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,6 +32,7 @@ import type { RunResult } from '@podman-desktop/api';
import { EventEmitter } from 'stream-json/Assembler.js';
import type { ContributionInfo } from './api/contribution-info.js';
import type { Proxy } from './proxy.js';
import type { IDisposable } from './types/disposable.js';
let contributionManager: TestContributionManager;

let composeFileExample: any;
Expand All @@ -42,14 +43,17 @@ const portNumber = 10000;

const eventEmitter = new EventEmitter();

const send = (channel: string, data?: any) => {
const send = (channel: string, data?: unknown) => {
eventEmitter.emit(channel, data);
};

const receive = (channel: string, func: any) => {
eventEmitter.on(channel, data => {
func(data);
});
const receive = (channel: string, func: any): IDisposable => {
eventEmitter.on(channel, func);
return {
dispose: () => {
eventEmitter.off(channel, func);
},
} as unknown as IDisposable;
};

const apiSender: ApiSenderType = {
Expand Down
20 changes: 11 additions & 9 deletions packages/main/src/plugin/index.ts
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022-2023 Red Hat, Inc.
* Copyright (C) 2022-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -149,6 +149,7 @@ import type { KubeContext } from './kubernetes-context.js';
import { KubernetesInformerManager } from './kubernetes-informer-registry.js';
import type { KubernetesInformerResourcesType } from './api/kubernetes-informer-info.js';
import { OpenDevToolsInit } from './open-devtools-init.js';
import type { IDisposable } from './types/disposable.js';

type LogType = 'log' | 'warn' | 'trace' | 'debug' | 'error';

Expand Down Expand Up @@ -286,7 +287,7 @@ export class PluginSystem {
}

getApiSender(webContents: WebContents): ApiSenderType {
const queuedEvents: { channel: string; data: string }[] = [];
const queuedEvents: { channel: string; data: unknown }[] = [];

const flushQueuedEvents = () => {
// flush queued events ?
Expand All @@ -307,8 +308,7 @@ export class PluginSystem {

const eventEmitter = new EventEmitter();
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
send: (channel: string, data: any) => {
send: (channel: string, data: unknown) => {
// send only when the UI is ready
if (this.uiReady && this.isReady) {
flushQueuedEvents();
Expand All @@ -319,11 +319,13 @@ export class PluginSystem {
}
eventEmitter.emit(channel, data);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
receive: (channel: string, func: any) => {
eventEmitter.on(channel, data => {
func(data);
});
receive: (channel: string, func: (...args: unknown[]) => void): IDisposable => {
eventEmitter.on(channel, func);
return {
dispose: () => {
eventEmitter.removeListener(channel, func);
},
};
},
};
}
Expand Down
20 changes: 19 additions & 1 deletion packages/main/src/plugin/kubernetes-client-kubeconfig.spec.ts
@@ -1,3 +1,21 @@
/**********************************************************************
* Copyright (C) 2023-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import type { Cluster, Context, User, KubeConfig } from '@kubernetes/client-node';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import type { ConfigurationRegistry } from './configuration-registry.js';
Expand Down Expand Up @@ -52,7 +70,7 @@ describe('context tests', () => {
} as unknown as Telemetry;
const apiSender: ApiSenderType = {
send: apiSendMock,
receive: () => {},
receive: vi.fn(),
};

const client = new TestKubernetesClient(
Expand Down
71 changes: 71 additions & 0 deletions packages/preload/src/index.spec.ts
@@ -0,0 +1,71 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import { beforeEach, expect, test, vi } from 'vitest';
import { buildApiSender } from '.';

vi.mock('electron', async () => {
return {
contextBridge: {
exposeInMainWorld: vi.fn(),
},
ipcRenderer: {
on: vi.fn(),
emit: vi.fn(),
handle: vi.fn(),
},
ipcMain: {
on: vi.fn(),
emit: vi.fn(),
handle: vi.fn(),
},
};
});

beforeEach(() => {
vi.resetAllMocks();
});

test('build Api Sender', () => {
const apiSender = buildApiSender();

expect(apiSender).toBeDefined();

// add a receiver
const received: string[] = [];
const disposable = apiSender.receive('channel', (...val: unknown[]) => {
received.push(String(val));
});

// send a message
apiSender.send('channel', 'message');
expect(received.length).toBe(1);
expect(received[0]).toBe('message');

// send another message
apiSender.send('channel', 'message2');
expect(received.length).toBe(2);
expect(received[1]).toBe('message2');

// dispose the receiver
disposable.dispose();

// send another message
apiSender.send('channel', 'message3');
// should not be received anymore as we disposed the listener
expect(received.length).toBe(2);
});
30 changes: 19 additions & 11 deletions packages/preload/src/index.ts
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022-2023 Red Hat, Inc.
* Copyright (C) 2022-2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -90,6 +90,8 @@ import type { KubeContext } from '../../main/src/plugin/kubernetes-context';

import type { KubernetesGeneratorInfo } from '../../main/src/plugin/api/KubernetesGeneratorInfo';
import type { NotificationCard, NotificationCardOptions } from '../../main/src/plugin/api/notification';
import type { ApiSenderType } from '../../main/src/plugin/api';
import type { IDisposable } from '../../main/src/plugin/types/disposable';

export type DialogResultCallback = (openDialogReturnValue: Electron.OpenDialogReturnValue) => void;

Expand All @@ -112,21 +114,27 @@ export interface KeyLogger {
warn(key: symbol, ...data: any[]): void;
}

// initialize extension loader mechanism
function initExposure(): void {
export const buildApiSender = (): ApiSenderType => {
const eventEmitter = new EventEmitter();
const apiSender = {
send: (channel: string, data: string) => {

return {
send: (channel: string, data: unknown) => {
eventEmitter.emit(channel, data);
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-explicit-any
receive: (channel: string, func: any) => {
eventEmitter.on(channel, data => {
func(data);
});
receive: (channel: string, func: (...args: unknown[]) => void): IDisposable => {
eventEmitter.on(channel, func);
return {
dispose: () => {
eventEmitter.removeListener(channel, func);
},
};
},
};
};

// initialize extension loader mechanism
function initExposure(): void {
const apiSender = buildApiSender();

interface ErrorMessage {
name: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/renderer/src/Loader.svelte
Expand Up @@ -72,7 +72,7 @@ window.events?.receive('install-extension:from-id', (extensionId: any) => {
});
// Wait that the server-side is ready
window.events.receive('starting-extensions', (value: string) => {
window.events.receive('starting-extensions', (value: unknown) => {
systemReady = value === 'true';
if (systemReady) {
window.dispatchEvent(new CustomEvent('system-ready', {}));
Expand Down
3 changes: 2 additions & 1 deletion packages/renderer/src/lib/dialogs/CustomPick.svelte
Expand Up @@ -29,7 +29,8 @@ onMount(() => {
window.events?.receive('showCustomPick:add', showCustomPickCallback);
});
async function showCustomPickCallback(options?: CustomPickOptions) {
function showCustomPickCallback(customQuickPickParameter: unknown) {
const options: CustomPickOptions | undefined = customQuickPickParameter as CustomPickOptions;
id = options?.id || 0;
title = options?.title || '';
description = options?.description || '';
Expand Down
17 changes: 11 additions & 6 deletions packages/renderer/src/lib/dialogs/MessageBox.svelte
Expand Up @@ -23,7 +23,8 @@ let display = false;
let inputElement: HTMLInputElement | undefined = undefined;
let messageBox: HTMLDivElement;
const showMessageBoxCallback = async (options?: MessageBoxOptions) => {
const showMessageBoxCallback = (messageBoxParameter: unknown) => {
const options: MessageBoxOptions | undefined = messageBoxParameter as MessageBoxOptions;
currentId = options?.id || 0;
title = options?.title || '';
message = options?.message || '';
Expand Down Expand Up @@ -74,11 +75,15 @@ const showMessageBoxCallback = async (options?: MessageBoxOptions) => {
display = true;
await tick();
if (display && inputElement) {
inputElement.focus();
}
tick()
.then(() => {
if (display && inputElement) {
inputElement.focus();
}
})
.catch((error: unknown) => {
console.error('Unable to focus on input element', error);
});
};
onMount(() => {
Expand Down

0 comments on commit ab0bd50

Please sign in to comment.