Skip to content

Commit d2e646b

Browse files
committed
feat: improve requirements typing
1 parent ae1abe2 commit d2e646b

File tree

11 files changed

+101
-45
lines changed

11 files changed

+101
-45
lines changed

src/app/config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,5 @@ export function getConfig(cleanCache = false): Config {
6565
};
6666

6767
config = { ...defaultConfig, ...packageConfig, ...argsConfig };
68-
6968
return config;
7069
}

src/app/core/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { getRequirements } from './requirements';

src/app/core/requirements.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { exec } from 'child_process';
2+
import { BrowserWindow, IpcMainEvent, IpcMainInvokeEvent } from 'electron';
3+
import { promisify } from 'util';
4+
import {
5+
Requirement,
6+
RequirementsResource,
7+
} from '../../shared/types/requirements';
8+
9+
const requirements = [
10+
'node -v',
11+
'npm -v',
12+
'mvn --version',
13+
'java -version',
14+
'git --version',
15+
];
16+
const execPromise = promisify(exec);
17+
18+
export default class RequirementsFacade implements RequirementsResource {
19+
async getRequirements(): Promise<Requirement[]> {
20+
return Promise.all(
21+
requirements.map(requirement =>
22+
execPromise(requirement).then(({ stdout, stderr }) => ({
23+
name: requirement,
24+
cmd: requirement,
25+
state: stdout ? ('ok' as const) : ('error' as const),
26+
message: stdout || stderr,
27+
}))
28+
)
29+
);
30+
}
31+
}
32+
33+
const cache: {
34+
[windowId: string]: RequirementsFacade;
35+
} = {};
36+
37+
export const getRequirements = (
38+
e: IpcMainEvent | IpcMainInvokeEvent
39+
): RequirementsFacade => {
40+
const sourceWindow = BrowserWindow.fromWebContents(e.sender);
41+
if (!sourceWindow) {
42+
throw new Error('Could not resolve current window');
43+
}
44+
45+
const windowId = sourceWindow.id;
46+
47+
let instance = cache[windowId];
48+
if (!instance) {
49+
instance = new RequirementsFacade();
50+
cache[windowId] = instance;
51+
}
52+
53+
return new RequirementsFacade();
54+
};

src/app/ipc-main.ts

+6-25
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,13 @@
1-
import { exec } from 'child_process';
2-
import { ipcMain } from 'electron';
3-
import { promisify } from 'util';
1+
import { IpcMainInvokeEvent, ipcMain } from 'electron';
42
import * as events from '../shared/events';
5-
import createLogger from './logger';
3+
import { getRequirements } from './core';
64

7-
const logger = createLogger('app');
8-
9-
const requirements = [
10-
'node -v',
11-
'npm -v',
12-
'mvn --version',
13-
'java -version',
14-
'git --version',
15-
];
16-
const execPromise = promisify(exec);
17-
18-
async function getRequirements(): Promise<
19-
{ stdout: string; stderr: string }[]
20-
> {
21-
return Promise.all(
22-
requirements.map(requirement => {
23-
return execPromise(requirement);
24-
})
5+
function registerRequirementsIPCMainHandlers() {
6+
ipcMain.handle(events.TIP_GET_REQUIREMENTS, (e: IpcMainInvokeEvent) =>
7+
getRequirements(e).getRequirements()
258
);
269
}
2710

2811
export const registerIPCMainHandlers = (): void => {
29-
logger.info('registerIPCMainHandlers');
30-
31-
ipcMain.handle(events.TIP_GET_REQUIREMENTS, getRequirements);
12+
registerRequirementsIPCMainHandlers();
3213
};

src/app/preload.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { contextBridge, ipcRenderer } from 'electron';
2-
import { TipManagerAPI } from '../shared/api';
2+
import { TipManagerResource } from '../shared/api';
33
import * as events from '../shared/events';
44

5-
const tipManagerAPI: TipManagerAPI = {
6-
getRequirements: () => ipcRenderer.invoke(events.TIP_GET_REQUIREMENTS),
5+
const tipManagerResource: TipManagerResource = {
6+
requirements: {
7+
getRequirements: () => ipcRenderer.invoke(events.TIP_GET_REQUIREMENTS),
8+
},
79
};
810

9-
contextBridge.exposeInMainWorld('tipmanager', tipManagerAPI);
11+
contextBridge.exposeInMainWorld('tipmanager', tipManagerResource);

src/shared/api.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export interface TipManagerAPI {
2-
getRequirements(): Promise<{ stdout: string; stderr: string }[]>;
1+
import { RequirementsResource } from './types/requirements';
2+
3+
export interface TipManagerResource {
4+
requirements: RequirementsResource;
35
}

src/shared/types/requirements.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface Requirement {
2+
name: string;
3+
cmd: string;
4+
state: 'ok' | 'error';
5+
message: string;
6+
}
7+
8+
export interface RequirementsResource {
9+
getRequirements(): Promise<Requirement[]>;
10+
}

src/ui/electron-api/common.ts

-7
This file was deleted.

src/ui/modules/requirements/requirements.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import Button from '@mui/material/Button';
22
import { useState } from 'react';
3-
import { CommonAPI } from '../../electron-api/common';
3+
import { RequirementsResourceImpl } from '../../tip-manager-api/requirements';
44

55
export default function Requirements() {
66
const getRequirements = async () => {
7-
const requirements = await new CommonAPI().getRequirements();
8-
setRequirements(requirements.map(requirement => requirement.stdout));
7+
const requirements = await new RequirementsResourceImpl().getRequirements();
8+
setRequirements(requirements.map(requirement => requirement.message));
99
};
1010

1111
const [requirements, setRequirements] = useState<string[]>([]);

src/ui/electron-api/base.ts src/ui/tip-manager-api/base.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { TipManagerAPI } from '../../shared/api';
1+
import { TipManagerResource } from '../../shared/api';
22

33
declare global {
44
interface Window {
5-
tipmanager: TipManagerAPI;
5+
tipmanager: TipManagerResource;
66
}
77
}
88

99
export class BaseAPI {
10-
private _base: TipManagerAPI;
10+
private _base: TipManagerResource;
1111

1212
get base() {
1313
return this._base;
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type {
2+
Requirement,
3+
RequirementsResource,
4+
} from '../../shared/types/requirements';
5+
import { BaseAPI } from './base';
6+
7+
export class RequirementsResourceImpl
8+
extends BaseAPI
9+
implements RequirementsResource
10+
{
11+
async getRequirements(): Promise<Requirement[]> {
12+
return this.base.requirements.getRequirements();
13+
}
14+
}

0 commit comments

Comments
 (0)