Skip to content

Commit

Permalink
Improving CLI tooling - adding typedoc, jsdoc, better-docs, typescrip…
Browse files Browse the repository at this point in the history
…t-coverage-report, lighthouse cli & vite-bundle-analyzer. Adding test auth disabled mode for lighthouse scoring and playwright testing.
  • Loading branch information
bcd00 committed Jan 5, 2024
1 parent 66e6c3c commit 6f7543e
Show file tree
Hide file tree
Showing 37 changed files with 5,009 additions and 328 deletions.
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,21 @@ sandworm
/apps/ove-core/src/config/config.json

/tests/**/private.*

# typescript-coverage-report
/coverage-ts

# Lighthouse CLI
/.lighthouseci
!.lighthouseci/audit.js
!.lighthouseci/config.example.json

# vite-bundle-visualizer
/bundle-analysis

# better-docs & jsdoc
/docs/code

# typedoc
/docs/types

39 changes: 39 additions & 0 deletions .lighthouseci/audit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const z = require('zod').z;
const readFileSync = require('fs').readFileSync;
const writeFileSync = require('fs').writeFileSync;
const execSync = require('child_process').execSync;

const ConfigSchema = z.strictObject({
configFile: z.string(),
adminToken: z.string(),
buildToken: z.string(),
baseURL: z.string(),
serverBaseURL: z.string()
});

const config = ConfigSchema.parse(JSON.parse(readFileSync(process.argv.at(2)).toString()));

/** @type {() => string[]} */
const buildURLs = () => [
config.baseURL,
`${config.baseURL}/login`,
`${config.baseURL}/hardware`
];

const urls = buildURLs();
writeFileSync(config.configFile, JSON.stringify({
ci: {
collect: {
url: urls
},
upload: {
target: 'lhci',
serverBaseUrl: config.serverBaseURL,
token: config.buildToken
},
}
}, undefined, 2));

/** @type {Buffer} */
const res = execSync(`lhci autorun --config=${config.configFile} --disable-storage-reset`);
console.log(res.toString());
7 changes: 7 additions & 0 deletions .lighthouseci/config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"configFile": "",
"adminToken": "",
"buildToken": "",
"serverBaseURL": "",
"baseURL": ""
}
2 changes: 1 addition & 1 deletion apps/ove-bridge-ui/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { type InboundAPI } from "@ove/ove-types";
declare global {
// noinspection JSUnusedGlobalSymbols
interface Window {
electron: InboundAPI & {
bridge: InboundAPI & {
receive: <Key extends keyof OutboundAPI>(
event: OutboundAPIChannels[Key],
listener: (args: Parameters<OutboundAPI[Key]>[0]) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const Auth = forwardRef<HTMLDialogElement, AuthProps>(({
const handleAuth = async ({pin}: {pin: string}) => {
if (device === null) throw new Error("Cannot ID null device");
const registered =
await window.electron.registerAuth({ id: device.id, pin });
await window.bridge.registerAuth({ id: device.id, pin });
setStatus(typeof "registered" !== "object");

if (!registered) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const Devices = () => {
const close = useCallback(() => setMode("overview"), []);

useEffect(() => {
window.electron.getDevices({}).then(devices => {
window.bridge.getDevices({}).then(devices => {
if ("oveError" in devices) return;
setDevices(devices);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const saveDevice_ = (device: Device | null, setMode: (mode: Mode) => void, type:

if (id === "" || id.length < 1) return false;
if ((e?.nativeEvent as unknown as NativeEvent)?.submitter?.name === "delete") {
window.electron.removeDevice({deviceId: assert(device).id})
window.bridge.removeDevice({deviceId: assert(device).id})
.catch(console.error).then(() => setMode("overview"));
return;
}
Expand All @@ -63,7 +63,7 @@ const saveDevice_ = (device: Device | null, setMode: (mode: Mode) => void, type:
if (JSON.stringify(updatedDevice) === JSON.stringify(device)) {
setMode("overview");
} else {
window.electron.addDevice({ device: updatedDevice })
window.bridge.addDevice({ device: updatedDevice })
.catch(console.error)
.then(() => setMode("overview"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const AutoModeConfiguration = ({ closeDialog }: AutoModeConfigurationProps) => {
const { register, setValue, handleSubmit } = useForm<Form>();

useEffect(() => {
window.electron.getAutoSchedule({}).then(autoSchedule => {
window.bridge.getAutoSchedule({}).then(autoSchedule => {
if (autoSchedule !== undefined && "oveError" in autoSchedule) return;
setValue("start" as const, autoSchedule?.wake ?? undefined);
setValue("end" as const, autoSchedule?.sleep ?? undefined);
Expand All @@ -28,7 +28,7 @@ const AutoModeConfiguration = ({ closeDialog }: AutoModeConfigurationProps) => {
}, []);

const onSubmit = ({ start, end, days }: Form) => {
window.electron.setAutoSchedule({
window.bridge.setAutoSchedule({
autoSchedule: {
wake: start ?? null,
sleep: end ?? null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ import { logger } from "../../../../env";

export const useEnv = (setValue: (k: "coreURL" | "calendarURL" | "bridgeName", v: string | undefined) => void) => {
useEffect(() => {
window.electron.getEnv({}).then(env => {
window.bridge.getEnv({}).then(env => {
if ("oveError" in env) return;
setValue("coreURL", env.coreURL);
setValue("bridgeName", env.bridgeName);
setValue("calendarURL", env.calendarURL);
});
}, []);

return (env: { bridgeName?: string, coreURL?: string, calendarURL?: string }) => window.electron.updateEnv(env).catch(logger.error);
return (env: { bridgeName?: string, coreURL?: string, calendarURL?: string }) => window.bridge.updateEnv(env).catch(logger.error);
};

export const useSocket = () => {
const [connected, setConnected] = useState(false);

useEffect(() => {
window.electron.getSocketStatus({}).then(status => setConnected(typeof status === "boolean" && status));
window.electron.receive("socket-connect", () => {
window.bridge.getSocketStatus({}).then(status => setConnected(typeof status === "boolean" && status));
window.bridge.receive("socket-connect", () => {
setConnected(true);
});
window.electron.receive("socket-disconnect", () => {
window.bridge.receive("socket-disconnect", () => {
setConnected(false);
});
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const KeyPass = () => {
const [isCopied, setIsCopied] = useState(false);

useEffect(() => {
window.electron.getPublicKey({}).then(key => {
window.bridge.getPublicKey({}).then(key => {
if (typeof key !== "string") return;
setDisplayPublicKey(key);
});
Expand Down
20 changes: 16 additions & 4 deletions apps/ove-bridge-ui/src/pages/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ import KeyPass from "./components/key-pass/key-pass";
import Configuration from "./components/configuration/configuration";
import AutoModeConfiguration
from "./components/auto-mode-configuration/auto-mode-configuration";
import { type OVEException, type Calendar as TCalendar } from "@ove/ove-types";
import {
type OVEException,
type Calendar as TCalendar,
isError
} from "@ove/ove-types";

import styles from "./home.module.scss";

const useFetchCalendar = (controller: typeof window["electron"]["getCalendar"]) => {
const useFetchCalendar = (controller: typeof window["bridge"]["getCalendar"]) => {
const [response, setResponse] = useState<TCalendar | OVEException | undefined>(undefined);
const x = useCalendar(response);

Expand All @@ -27,9 +31,17 @@ const useFetchCalendar = (controller: typeof window["electron"]["getCalendar"])
};

const Home = () => {
const { calendar, lastUpdated, refresh: refreshCalendar } = useFetchCalendar(window.electron.getCalendar);
const [mode, setMode] = useState<"manual" | "auto" | "eco" | null>("manual");
const { calendar, lastUpdated, refresh: refreshCalendar } = useFetchCalendar(window.bridge.getCalendar);
const { ref, openDialog, closeDialog } = useDialog();

useEffect(() => {
window.bridge.getMode({}).then(mode => {
if (isError(mode)) return;
setMode(mode);
});
}, []);

useEffect(() => {
console.log(JSON.stringify(calendar));
}, [calendar]);
Expand All @@ -45,7 +57,7 @@ const Home = () => {
<div className={styles.power}>
<LastUpdated lastUpdated={lastUpdated}
refreshCalendar={refreshCalendar} />
<PowerMode calendar={calendar} controller={window.electron} />
<PowerMode mode={mode} setMode={setMode} calendar={calendar} controller={window.bridge} />
</div>
{calendar !== null ? <Calendar calendar={calendar} /> : null}
</section>
Expand Down
6 changes: 3 additions & 3 deletions apps/ove-bridge-ui/src/pages/live-view/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ export const useVideoStreams = () => {
const [streams, setStreams] = useState<string[] | undefined>(undefined);

useEffect(() => {
window.electron.startStreams({}).catch(logger.error);
window.electron.getStreams({}).then(streams => {
window.bridge.startStreams({}).catch(logger.error);
window.bridge.getStreams({}).then(streams => {
if (!Array.isArray(streams)) return;
setStreams(streams);
});

return () => {
window.electron.stopStreams({}).catch(logger.error);
window.bridge.stopStreams({}).catch(logger.error);
}
}, []);

Expand Down
4 changes: 4 additions & 0 deletions apps/ove-bridge-ui/src/svg.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "*.svg" {
const content: string;
export default content;
}
2 changes: 1 addition & 1 deletion apps/ove-bridge-ui/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"types": ["vite/client", "vitest"]
"types": ["vite/client", "vitest", "./src/svg.d.ts"]
},
"files": [],
"include": [],
Expand Down
1 change: 1 addition & 0 deletions apps/ove-bridge/src/app/api/features/bridge/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const service: TBridgeService = {
}
},
getStreams: () => env.VIDEO_STREAMS,
// @ts-expect-error - TODO: fix typing
getCalendar: async () => {
// TODO: add full production integration with email service, Azure auth etc.
if (env.CALENDAR_URL === undefined) return undefined;
Expand Down
3 changes: 2 additions & 1 deletion apps/ove-bridge/src/ipc-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const inboundChannels: InboundAPIChannels = {
getAutoSchedule: "get-auto-schedule",
getStreams: "get-video-streams",
startStreams: "start-videos",
stopStreams: "stop-videos"
stopStreams: "stop-videos",
getGeometry: "get-geometry"
};

export type InboundAPIChannels = {
Expand Down
5 changes: 2 additions & 3 deletions apps/ove-client-ui/src/app/app-controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { useEffect, useState } from "react";

export const usePin = () => {
const [pin, setPin] =
useState<string>("");
const [pin, setPin] = useState("");

useEffect(() => {
window.electron.receive("update-pin", setPin);
window.client.receive("update-pin", setPin);
}, []);

return pin;
Expand Down
4 changes: 2 additions & 2 deletions apps/ove-client-ui/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { usePin } from "./app-controller";
declare global {
// noinspection JSUnusedGlobalSymbols
interface Window {
electron: InboundAPI & {
client: InboundAPI & {
receive: <Key extends keyof OutboundAPI>(
event: OutboundAPIChannels[Key],
listener: (...args: Parameters<OutboundAPI[Key]>) =>
listener: (args: Parameters<OutboundAPI[Key]>[0]) =>
ReturnType<OutboundAPI[Key]>
) => void
};
Expand Down
4 changes: 3 additions & 1 deletion apps/ove-core-ui/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
VITE_CORE_URL="http://localhost:3333/api/1/trpc"
VITE_LOG_LEVEL=1
VITE_LOGGING_SERVER=""
VITE_VIDEO_STREAM_URL=""
VITE_VIDEO_STREAM_URL=""
VITE_MODE="production"
VITE_DISABLE_AUTH=false
6 changes: 3 additions & 3 deletions apps/ove-core-ui/src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { env } from "../env";
import Router from "./router";
import { useEffect, useState } from "react";
import superjson from "superjson";
import { useAuth } from "../hooks";
import { trpc } from "../utils/api";
import { httpLink } from "@trpc/client";
import { Nav } from "@ove/ui-components";
import { HddStack } from "react-bootstrap-icons";
import { useEffect, useState, useMemo } from "react";
import { NavigationMenuLink, Toaster } from "@ove/ui-base-components";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

Expand Down Expand Up @@ -116,12 +116,12 @@ export const App = () => {
setTrpcClient(createTrpcClient);
}, [loggedIn]);

const [queryClient] = useState<QueryClient>(() => new QueryClient({
const queryClient = useMemo<QueryClient>(() => new QueryClient({
defaultOptions: {
queries: {},
mutations: {}
}
}));
}), []);

return <trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
Expand Down
4 changes: 2 additions & 2 deletions apps/ove-core-ui/src/components/protected-route.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Navigate } from "react-router-dom";
import { type ReactNode } from "react";
import { Navigate } from "react-router-dom";

/**
* Only allows navigation to a route if a condition is met.
Expand All @@ -10,7 +10,7 @@ const ProtectedRoute = ({
redirectTo,
children
}: ConditionalRouteProps): JSX.Element => condition ? <>{children}</> :
<Navigate to={redirectTo} replace />
<Navigate to={redirectTo} replace />;

export type ConditionalRouteProps = {
/**
Expand Down
Loading

0 comments on commit 6f7543e

Please sign in to comment.