Revert "Progress"

This reverts commit e38a4b40b5.
This commit is contained in:
lucas lelievre
2025-10-10 19:02:50 +02:00
parent e38a4b40b5
commit 25c659ba03
16 changed files with 1372 additions and 962 deletions

View File

@@ -1,8 +1,8 @@
# VITE_FIRMWARE_TOOL_URL=https://fw-tool-api.slimevr.io
# VITE_FIRMWARE_TOOL_S3_URL=https://fw-tool-bucket.slimevr.io
# FIRMWARE_TOOL_SCHEMA_URL=https://fw-tool-api.slimevr.io/api-json
VITE_FIRMWARE_TOOL_URL=https://fw-tool-api.slimevr.io
VITE_FIRMWARE_TOOL_S3_URL=https://fw-tool-bucket.slimevr.io
FIRMWARE_TOOL_SCHEMA_URL=https://fw-tool-api.slimevr.io/api-json
VITE_FIRMWARE_TOOL_URL=http://localhost:3000
VITE_FIRMWARE_TOOL_S3_URL=http://localhost:9099
FIRMWARE_TOOL_SCHEMA_URL=http://localhost:3000/api-json
# VITE_FIRMWARE_TOOL_URL=http://localhost:3000
# VITE_FIRMWARE_TOOL_S3_URL=http://localhost:9000
# FIRMWARE_TOOL_SCHEMA_URL=http://localhost:3000/api-json

View File

@@ -25,7 +25,6 @@
"@tauri-apps/plugin-store": "^2.0.0",
"@tweenjs/tween.js": "^25.0.0",
"@twemoji/svg": "^15.0.0",
"ajv": "^8.17.1",
"browser-fs-access": "^0.35.0",
"classnames": "^2.5.1",
"flatbuffers": "22.10.26",

View File

@@ -89,7 +89,6 @@ board_type-WEMOSD1MINI = Wemos D1 Mini
board_type-TTGO_TBASE = TTGO T-Base
board_type-ESP01 = ESP-01
board_type-SLIMEVR = SlimeVR
board_type-SLIMEVR_V1_2 = SlimeVR v1.2
board_type-LOLIN_C3_MINI = Lolin C3 Mini
board_type-BEETLE32C3 = Beetle ESP32-C3
board_type-ESP32C3DEVKITM1 = Espressif ESP32-C3 DevKitM-1
@@ -384,8 +383,7 @@ tracker-settings-name_section-label = Tracker name
tracker-settings-forget = Forget tracker
tracker-settings-forget-description = Removes the tracker from the SlimeVR Server and prevents it from connecting until the server is restarted. The configuration of the tracker won't be lost.
tracker-settings-forget-label = Forget tracker
tracker-settings-update-unavailable-v2 = No releases found
tracker-settings-update-incompatible = Cannot update. Incompatible board
tracker-settings-update-unavailable = Cannot be updated (DIY)
tracker-settings-update-low-battery = Cannot update. Battery lower than 50%
tracker-settings-update-up_to_date = Up to date
tracker-settings-update-blocked = Update not available. No other releases available

View File

@@ -3,7 +3,7 @@ import { Typography } from '@/components/commons/Typography';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
FirmwareToolContextC,
provideFirmwareTool,
useFirmwareToolContext,
} from '@/hooks/firmware-tool';
import { AddImusStep } from './AddImusStep';
import { SelectBoardStep } from './SelectBoardStep';
@@ -15,87 +15,63 @@ import { SelectFirmwareStep } from './SelectFirmwareStep';
import { BuildStep } from './BuildStep';
import { FlashingMethodStep } from './FlashingMethodStep';
import { FlashingStep } from './FlashingStep';
import { FlashBtnStep } from './FlashBtnStep';
import { FirmwareUpdateMethod } from 'solarxr-protocol';
import { useMemo } from 'react';
import {
useGetHealth,
useGetIsCompatibleVersion,
} from '@/firmware-tool-api/firmwareToolComponents';
import { SelectSourceSetep } from './steps/SelectSourceStep';
import { BoardDefaultsStep } from './steps/BoardDefaultsStep';
function FirmwareToolContent() {
const { l10n } = useLocalization();
const context = provideFirmwareTool();
const { isError, isLoading: isInitialLoading, refetch } = useGetHealth({});
const compatibilityCheckEnabled = !!__VERSION_TAG__;
const { isLoading: isCompatibilityLoading, data: compatibilityData } =
useGetIsCompatibleVersion(
{ pathParams: { version: __VERSION_TAG__ } },
{ enabled: compatibilityCheckEnabled }
);
const isLoading = isInitialLoading || isCompatibilityLoading;
const isCompatible =
!compatibilityCheckEnabled || (compatibilityData?.success ?? false);
const context = useFirmwareToolContext();
const { isError, isGlobalLoading: isLoading, retry, isCompatible } = context;
const steps = useMemo(() => {
const steps = [
{
id: 'SelectSource',
component: SelectSourceSetep,
title: l10n.getString('firmware_tool-step-select_source'),
id: 'SelectBoard',
component: SelectBoardStep,
title: l10n.getString('firmware_tool-board_step'),
},
{
component: BoardDefaultsStep,
title: l10n.getString('firmware_tool-step-board_defaults'),
component: BoardPinsStep,
title: l10n.getString('firmware_tool-board_pins_step'),
},
{
component: AddImusStep,
title: l10n.getString('firmware_tool-add_imus_step'),
},
{
id: 'SelectFirmware',
component: SelectFirmwareStep,
title: l10n.getString('firmware_tool-select_firmware_step'),
},
{
component: FlashingMethodStep,
id: 'FlashingMethod',
title: l10n.getString('firmware_tool-flash_method_step'),
},
{
component: BuildStep,
title: l10n.getString('firmware_tool-build_step'),
},
{
component: FlashingStep,
title: l10n.getString('firmware_tool-flashing_step'),
},
// {
// component: BoardPinsStep,
// title: l10n.getString('firmware_tool-board_pins_step'),
// },
// {
// component: AddImusStep,
// title: l10n.getString('firmware_tool-add_imus_step'),
// },
// {
// id: 'SelectFirmware',
// component: SelectFirmwareStep,
// title: l10n.getString('firmware_tool-select_firmware_step'),
// },
// {
// component: FlashingMethodStep,
// id: 'FlashingMethod',
// title: l10n.getString('firmware_tool-flash_method_step'),
// },
// {
// component: BuildStep,
// title: l10n.getString('firmware_tool-build_step'),
// },
// {
// component: FlashingStep,
// title: l10n.getString('firmware_tool-flashing_step'),
// },
];
// if (
// context.defaultConfig?.needBootPress &&
// context.selectedDevices?.find(
// ({ type }) => type === FirmwareUpdateMethod.SerialFirmwareUpdate
// )
// ) {
// steps.splice(5, 0, {
// component: FlashBtnStep,
// title: l10n.getString('firmware_tool-flashbtn_step'),
// });
// }
if (
context.defaultConfig?.needBootPress &&
context.selectedDevices?.find(
({ type }) => type === FirmwareUpdateMethod.SerialFirmwareUpdate
)
) {
steps.splice(5, 0, {
component: FlashBtnStep,
title: l10n.getString('firmware_tool-flashbtn_step'),
});
}
return steps;
}, [
/* context.defaultConfig?.needBootPress, context.selectedDevices */ l10n,
]);
const retry = async () => {
await refetch();
};
}, [context.defaultConfig?.needBootPress, context.selectedDevices, l10n]);
return (
<FirmwareToolContextC.Provider value={context}>

View File

@@ -26,9 +26,7 @@ export function FlashBtnStep({
{l10n.getString('firmware_tool-flashbtn_step-description')}
</Typography>
{defaultConfig?.boardConfig.type ===
boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR] ||
defaultConfig?.boardConfig.type ===
boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR_V1_2] ? (
boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR] ? (
<>
<Typography variant="standard" whitespace="whitespace-pre">
{l10n.getString('firmware_tool-flashbtn_step-board_SLIMEVR')}

View File

@@ -1,173 +0,0 @@
import { useLocalization } from '@fluent/react';
import { Typography } from '@/components/commons/Typography';
import { useFirmwareTool } from '@/hooks/firmware-tool';
import {} from '@/firmware-tool-api/firmwareToolComponents';
import { SomeJSONSchema } from 'ajv/dist/types/json-schema';
import { useEffect } from 'react';
const refToKey = (ref: string) => ref.substring('#/$defs/'.length);
type ComponentNode = { label: string } & (
| {
type: 'checkbox';
value: boolean;
}
| {
type: 'dropdown';
items: string[];
value: string;
}
| {
type: 'text';
value: string;
}
| {
type: 'group';
name: string;
childrens: ComponentNode[];
}
| {
type: 'list';
childrens: ComponentNode[];
}
);
const handleNode = (
defs: SomeJSONSchema['$defs'],
node: SomeJSONSchema,
data: any,
parentNode: SomeJSONSchema | null = null
): ComponentNode[] => {
const components: ComponentNode[] = [];
if (!node) return [];
if (node.$ref) {
return handleNode(defs, defs![refToKey(node.$ref)], data, node);
}
if (node.type === 'object') {
if (
node.oneOf &&
Array.isArray(node.oneOf) &&
node.discriminator?.propertyName
) {
const discriminator = node.discriminator.propertyName;
const selected = node.oneOf.find((o) => {
if (
o.$ref &&
defs![refToKey(o.$ref)].properties[discriminator].const ===
data[discriminator]
) {
return true;
}
if (
o.type === 'object' &&
o.properties[discriminator].const === data[discriminator]
) {
console.log(data);
return true;
}
return false;
});
components.push(...handleNode(defs, selected, data, node));
} else if (node.properties) {
const childs: ComponentNode[] = [];
for (const property of Object.keys(node.properties)) {
childs.push(
...handleNode(defs, node.properties[property], data[property], node)
);
}
components.push({
type: 'group',
name: node.description,
childrens: childs,
label: node.description ?? parentNode?.description ?? 'nothing o',
});
} else {
throw 'unknown object';
}
}
if (node.type === 'boolean') {
components.push({
type: 'checkbox',
label: node.description ?? parentNode?.description ?? 'nothing b',
value: data,
});
}
if (node.type === 'array') {
if (!Array.isArray(data)) throw 'not an array';
const childs: ComponentNode[] = [];
data.forEach((d) => {
childs.push(...handleNode(defs, node.items, d, node));
});
components.push({
type: 'list',
childrens: childs,
label: node.description ?? parentNode?.description ?? 'nothing a',
});
}
if (node.type === 'string') {
if (node.enum) {
components.push({
type: 'dropdown',
label: node.description ?? parentNode?.description ?? 'nothing e',
items: node.enum,
value: data,
});
} else {
components.push({
type: 'text',
label: node.description ?? parentNode?.description ?? 'nothing s',
value: data,
});
}
}
if (node.type === 'number') {
components.push({
type: 'text',
label: node.description ?? parentNode?.description ?? 'nothing n',
value: data,
});
}
return components;
};
export function BoardDefaultsStep({
nextStep,
goTo,
}: {
nextStep: () => void;
prevStep: () => void;
goTo: (id: string) => void;
}) {
const { l10n } = useLocalization();
const { selectedSource } = useFirmwareTool();
useEffect(() => {
if (!selectedSource) return;
const d = selectedSource?.default?.schema as any as SomeJSONSchema;
if (!d.$defs) throw 'no defs';
const t = refToKey(d.properties.defaults.additionalProperties.$ref);
if (!t) throw 'unable to get defaults ref';
const boardConfig = d.$defs[t];
const boardValues = d.$defs[refToKey(boardConfig.properties.values.$ref)];
const data = selectedSource.default?.defaults.values as any;
console.log(
// selectedSource.default?.defaults.values
JSON.stringify(handleNode(d.$defs, boardValues, data), null, 2)
);
}, [selectedSource]);
return (
<>
<div className="flex flex-col w-full">
<div className="flex flex-grow flex-col gap-4">
<Typography>
{l10n.getString('firmware_tool-board_step-description')}
</Typography>
</div>
<div className="my-4"></div>
</div>
</>
);
}

View File

@@ -1,234 +0,0 @@
import { Localized, useLocalization } from '@fluent/react';
import { Typography } from '@/components/commons/Typography';
import { LoaderIcon, SlimeState } from '@/components/commons/icon/LoaderIcon';
import { useFirmwareTool } from '@/hooks/firmware-tool';
import classNames from 'classnames';
import { Button } from '@/components/commons/Button';
import {
fetchGetFirmwareBoardDefaults,
useGetFirmwareSources,
} from '@/firmware-tool-api/firmwareToolComponents';
import { useEffect, useMemo, useState } from 'react';
function Selector({
text,
active,
disabled,
official,
onClick,
}: {
text: string;
active: boolean;
official?: boolean;
disabled?: boolean;
onClick: () => void;
}) {
return (
<div
className={classNames(
'p-3 rounded-md hover:bg-background-50 w-full cursor-pointer relative',
{
'bg-background-50 text-background-10': active, // FIXME: use selected source
'bg-background-60': !active,
'bg-background-80 text-background-50': disabled,
}
)}
onClick={() => {
if (!disabled) onClick();
}}
>
{official && (
<div className="absolute px-2 py-0.5 rounded-md bg-accent-background-20 -top-2 -right-2">
<Typography>Official</Typography>
</div>
)}
{text}
</div>
);
}
export function SelectSourceSetep({
nextStep,
goTo,
}: {
nextStep: () => void;
prevStep: () => void;
goTo: (id: string) => void;
}) {
const { l10n } = useLocalization();
const { setSelectedSource, selectedSource } = useFirmwareTool();
const [partialBoard, setPartialBoard] = useState<{
source?: string;
version?: string;
board?: string;
}>();
const { isFetching, data: sources } = useGetFirmwareSources({});
const { possibleBoards, possibleVersions, sourcesGroupped } = useMemo(() => {
return {
sourcesGroupped: sources?.reduce(
(curr, source) => {
if (!curr.find(({ name }) => source.source === name))
curr.push({
name: source.source,
official: source.official,
disabled:
!partialBoard?.board ||
!source.availableBoards.includes(partialBoard.board),
});
return curr;
},
[] as { name: string; official: boolean; disabled: boolean }[]
),
possibleBoards: sources?.reduce((curr, source) => {
const unknownBoards = source.availableBoards.filter(
(b) => !curr.includes(b)
);
curr.push(...unknownBoards);
return curr;
}, [] as string[]),
possibleVersions: sources?.reduce(
(curr, source) => {
if (!curr.find(({ name }) => source.version === name))
curr.push({
disabled:
!partialBoard?.board ||
!source.availableBoards.includes(partialBoard.board) ||
source.source !== partialBoard.source,
name: source.version,
});
return curr;
},
[] as { name: string; disabled: boolean }[]
),
};
}, [sources, partialBoard]);
useEffect(() => {
if (partialBoard?.source && partialBoard.board && partialBoard.version) {
const params = {
board: partialBoard.board,
source: partialBoard.source,
version: partialBoard.version,
};
fetchGetFirmwareBoardDefaults({
queryParams: params,
}).then((board) =>
setSelectedSource({
source: params,
default: board,
})
);
}
}, [partialBoard]);
const formatSource = (name: string, official: boolean) => {
return !official ? name : name.substring(name.indexOf('/') + 1);
};
return (
<>
<div className="flex flex-col w-full">
<div className="flex flex-grow flex-col gap-4">
<Typography>
{l10n.getString('firmware_tool-board_step-description')}
</Typography>
</div>
<div className="my-4">
{!isFetching && (
<>
<div className="grid grid-cols-3 gap-4">
<div className="flex flex-col gap-2 w-full">
<Typography variant="section-title">Board Type</Typography>
<div className="flex flex-col gap-2">
{possibleBoards?.map((board) => (
<Selector
active={partialBoard?.board === board}
key={`${board}`}
onClick={() => {
setPartialBoard({ board });
}}
text={board}
></Selector>
))}
</div>
</div>
<div className="flex flex-col gap-2 w-full">
<Typography variant="section-title">
Firmware Source
</Typography>
<div className="flex flex-col gap-2">
{sourcesGroupped?.map(({ name, official, disabled }) => (
<Selector
active={partialBoard?.source === name}
disabled={disabled}
key={`${name}`}
official={official}
onClick={() => {
setPartialBoard((curr) => ({
...curr,
source: name,
}));
}}
text={formatSource(name, official)}
></Selector>
))}
</div>
</div>
<div className="flex flex-col gap-2 w-full">
<Typography variant="section-title">
Firmware Version
</Typography>
<div className="flex flex-col gap-2">
{possibleVersions?.map(({ name, disabled }) => (
<Selector
active={partialBoard?.version === name}
disabled={disabled}
key={`${name}`}
onClick={() => {
setPartialBoard((curr) => ({
...curr,
version: name,
}));
}}
text={name}
></Selector>
))}
</div>
</div>
</div>
<div className="flex justify-end">
<Localized id="firmware_tool-next_step">
<Button
variant="primary"
disabled={!selectedSource}
onClick={() => {
// if (
// selectedSource?.default?.defaults.flashingRules
// .shouldOnlyUseDefaults
// ) {
// goTo('SelectFirmware');
// } else {
nextStep();
// }
}}
></Button>
</Localized>
</div>
</>
)}
{isFetching && (
<div className="flex justify-center flex-col items-center gap-3 h-44">
<LoaderIcon slimeState={SlimeState.JUMPY}></LoaderIcon>
<Localized id="firmware_tool-loading">
<Typography></Typography>
</Localized>
</div>
)}
</div>
</div>
</>
);
}

View File

@@ -3,7 +3,6 @@ import { Typography } from '@/components/commons/Typography';
import { getTrackerName } from '@/hooks/tracker';
import { ComponentProps, useEffect, useMemo, useRef, useState } from 'react';
import {
BoardType,
DeviceDataT,
DeviceIdTableT,
FirmwareUpdateMethod,
@@ -40,8 +39,6 @@ interface FirmwareUpdateForm {
selectedDevices: { [key: string]: boolean };
}
type SelectedDeviceWithBoard = SelectedDevice & { board: BoardType };
interface UpdateStatus {
status: FirmwareUpdateStatus;
type: FirmwareUpdateMethod;
@@ -199,34 +196,21 @@ export function FirmwareUpdate() {
};
}, []);
const queueFlashing = (selectedDevices: SelectedDeviceWithBoard[]) => {
const queueFlashing = (selectedDevices: SelectedDevice[]) => {
clear();
pendingDevicesRef.current = selectedDevices;
const firmwareFile = currentFirmwareRelease?.firmwareFile;
if (!firmwareFile) throw new Error('invalid state - no firmware file');
const requests = getFlashingRequests(
selectedDevices,
[{ isFirmware: true, firmwareId: '', url: firmwareFile, offset: 0 }],
{ wifi: undefined, alonePage: false, progress: 0 }, // we do not use serial
null // we do not use serial
);
if (!currentFirmwareRelease)
throw new Error('invalid state - no fw release');
const groupedByBoard = selectedDevices.reduce((curr, device) => {
const boards = curr.get(device.board) ?? [];
boards.push(device);
curr.set(device.board, boards);
return curr;
}, new Map<BoardType, SelectedDeviceWithBoard[]>());
for (const [board, devices] of groupedByBoard) {
if (board === BoardType.UNKNOWN) continue;
const firmwareFile = currentFirmwareRelease.firmwareFiles[board];
if (!firmwareFile) continue;
const requests = getFlashingRequests(
devices,
[{ isFirmware: true, firmwareId: '', url: firmwareFile, offset: 0 }],
{ wifi: undefined, alonePage: false, progress: 0 }, // we do not use serial
null // we do not use serial
);
requests.forEach((req) => {
sendRPCPacket(RpcMessage.FirmwareUpdateRequest, req);
});
}
requests.forEach((req) => {
sendRPCPacket(RpcMessage.FirmwareUpdateRequest, req);
});
};
const trackerWithErrors = useMemo(
@@ -297,12 +281,11 @@ export function FirmwareUpdate() {
{
type: FirmwareUpdateMethod.OTAFirmwareUpdate,
deviceId: id,
board: device.hardwareInfo?.officialBoardType ?? BoardType.UNKNOWN,
deviceNames: deviceNames(device, l10n),
},
];
},
[] as SelectedDeviceWithBoard[]
[] as SelectedDevice[]
);
if (!selectedDevices)
throw new Error('invalid state - no selected devices');

View File

@@ -170,7 +170,11 @@ export function TrackerSettingsPage() {
currentFirmwareRelease &&
tracker?.device?.hardwareInfo &&
checkForUpdate(currentFirmwareRelease, tracker?.device);
const updateUnavailable = needUpdate === null;
const updateUnavailable =
tracker?.device?.hardwareInfo?.officialBoardType !== BoardType.SLIMEVR ||
!semver.valid(
tracker?.device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none'
);
return (
<form
@@ -212,19 +216,12 @@ export function TrackerSettingsPage() {
</Typography>
<Typography>-</Typography>
{updateUnavailable && (
<Localized id="tracker-settings-update-unavailable-v2">
<Typography>No releases found</Typography>
<Localized id="tracker-settings-update-unavailable">
<Typography>Cannot be updated (DIY)</Typography>
</Localized>
)}
{!updateUnavailable && (
<>
{needUpdate === 'unavailable' && (
<Localized id="tracker-settings-update-incompatible">
<Typography>
Cannot be updated, Incompatible board
</Typography>
</Localized>
)}
{needUpdate === 'blocked' && (
// This happens only if no update is available and or the user is not in the current stagged
<Localized id="tracker-settings-update-blocked">

View File

@@ -4,10 +4,7 @@
* @version 0.0.1
*/
import * as reactQuery from '@tanstack/react-query';
import {
useFirmwareToolContext,
FirmwareToolContext,
} from './firmwareToolContext';
import { useFirmwareToolContext, FirmwareToolContext } from './firmwareToolContext';
import type * as Fetcher from './firmwareToolFetcher';
import { firmwareToolFetch } from './firmwareToolFetcher';
import type * as Schemas from './firmwareToolSchemas';
@@ -30,16 +27,7 @@ export const fetchGetIsCompatibleVersion = (
signal?: AbortSignal
) =>
firmwareToolFetch<
| {
success: true;
}
| {
success: false;
reason: {
message: string;
versions: string;
};
},
Schemas.VerionCheckResponse,
GetIsCompatibleVersionError,
undefined,
{},
@@ -50,51 +38,20 @@ export const fetchGetIsCompatibleVersion = (
/**
* Is this api compatible with the server version given
*/
export const useGetIsCompatibleVersion = <
TData =
| {
success: true;
}
| {
success: false;
reason: {
message: string;
versions: string;
};
},
>(
export const useGetIsCompatibleVersion = <TData = Schemas.VerionCheckResponse>(
variables: GetIsCompatibleVersionVariables,
options?: Omit<
reactQuery.UseQueryOptions<
| {
success: true;
}
| {
success: false;
reason: {
message: string;
versions: string;
};
},
Schemas.VerionCheckResponse,
GetIsCompatibleVersionError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useFirmwareToolContext(options);
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
| {
success: true;
}
| {
success: false;
reason: {
message: string;
versions: string;
};
},
Schemas.VerionCheckResponse,
GetIsCompatibleVersionError,
TData
>({
@@ -110,6 +67,504 @@ export const useGetIsCompatibleVersion = <
});
};
export type GetFirmwaresError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresResponse = Schemas.FirmwareDTO[];
export type GetFirmwaresVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the built firmwares
*/
export const fetchGetFirmwares = (
variables: GetFirmwaresVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<GetFirmwaresResponse, GetFirmwaresError, undefined, {}, {}, {}>({
url: '/firmwares',
method: 'get',
...variables,
signal,
});
/**
* List all the built firmwares
*/
export const useGetFirmwares = <TData = GetFirmwaresResponse>(
variables: GetFirmwaresVariables,
options?: Omit<
reactQuery.UseQueryOptions<GetFirmwaresResponse, GetFirmwaresError, TData>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<GetFirmwaresResponse, GetFirmwaresError, TData>({
queryKey: queryKeyFn({
path: '/firmwares',
operationId: 'getFirmwares',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwares({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type PostFirmwaresBuildError = Fetcher.ErrorWrapper<{
status: 400;
payload: Schemas.VersionNotFoundExeption;
}>;
export type PostFirmwaresBuildVariables = {
body: Schemas.CreateBuildFirmwareDTO;
} & FirmwareToolContext['fetcherOptions'];
/**
* Build a firmware from the requested configuration
*/
export const fetchPostFirmwaresBuild = (
variables: PostFirmwaresBuildVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.BuildResponseDTO,
PostFirmwaresBuildError,
Schemas.CreateBuildFirmwareDTO,
{},
{},
{}
>({ url: '/firmwares/build', method: 'post', ...variables, signal });
/**
* Build a firmware from the requested configuration
*/
export const usePostFirmwaresBuild = (
options?: Omit<
reactQuery.UseMutationOptions<
Schemas.BuildResponseDTO,
PostFirmwaresBuildError,
PostFirmwaresBuildVariables
>,
'mutationFn'
>
) => {
const { fetcherOptions } = useFirmwareToolContext();
return reactQuery.useMutation<
Schemas.BuildResponseDTO,
PostFirmwaresBuildError,
PostFirmwaresBuildVariables
>({
mutationFn: (variables: PostFirmwaresBuildVariables) =>
fetchPostFirmwaresBuild({ ...fetcherOptions, ...variables }),
...options,
});
};
export type GetFirmwaresBuildStatusIdPathParams = {
id: string;
};
export type GetFirmwaresBuildStatusIdError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresBuildStatusIdVariables = {
pathParams: GetFirmwaresBuildStatusIdPathParams;
} & FirmwareToolContext['fetcherOptions'];
/**
* Get the build status of a firmware
* This is a SSE (Server Sent Event)
* you can use the web browser api to check for the build status and update the ui in real time
*/
export const fetchGetFirmwaresBuildStatusId = (
variables: GetFirmwaresBuildStatusIdVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.ObservableType,
GetFirmwaresBuildStatusIdError,
undefined,
{},
{},
GetFirmwaresBuildStatusIdPathParams
>({
url: '/firmwares/build-status/{id}',
method: 'get',
...variables,
signal,
});
/**
* Get the build status of a firmware
* This is a SSE (Server Sent Event)
* you can use the web browser api to check for the build status and update the ui in real time
*/
export const useGetFirmwaresBuildStatusId = <TData = Schemas.ObservableType>(
variables: GetFirmwaresBuildStatusIdVariables,
options?: Omit<
reactQuery.UseQueryOptions<
Schemas.ObservableType,
GetFirmwaresBuildStatusIdError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
Schemas.ObservableType,
GetFirmwaresBuildStatusIdError,
TData
>({
queryKey: queryKeyFn({
path: '/firmwares/build-status/{id}',
operationId: 'getFirmwaresBuildStatusId',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresBuildStatusId({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresBoardsError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresBoardsResponse = string[];
export type GetFirmwaresBoardsVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the possible board types
*/
export const fetchGetFirmwaresBoards = (
variables: GetFirmwaresBoardsVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
GetFirmwaresBoardsResponse,
GetFirmwaresBoardsError,
undefined,
{},
{},
{}
>({ url: '/firmwares/boards', method: 'get', ...variables, signal });
/**
* List all the possible board types
*/
export const useGetFirmwaresBoards = <TData = GetFirmwaresBoardsResponse>(
variables: GetFirmwaresBoardsVariables,
options?: Omit<
reactQuery.UseQueryOptions<
GetFirmwaresBoardsResponse,
GetFirmwaresBoardsError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
GetFirmwaresBoardsResponse,
GetFirmwaresBoardsError,
TData
>({
queryKey: queryKeyFn({
path: '/firmwares/boards',
operationId: 'getFirmwaresBoards',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresBoards({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresVersionsError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresVersionsResponse = Schemas.ReleaseDTO[];
export type GetFirmwaresVersionsVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the possible versions to build a firmware from
*/
export const fetchGetFirmwaresVersions = (
variables: GetFirmwaresVersionsVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
GetFirmwaresVersionsResponse,
GetFirmwaresVersionsError,
undefined,
{},
{},
{}
>({ url: '/firmwares/versions', method: 'get', ...variables, signal });
/**
* List all the possible versions to build a firmware from
*/
export const useGetFirmwaresVersions = <TData = GetFirmwaresVersionsResponse>(
variables: GetFirmwaresVersionsVariables,
options?: Omit<
reactQuery.UseQueryOptions<
GetFirmwaresVersionsResponse,
GetFirmwaresVersionsError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
GetFirmwaresVersionsResponse,
GetFirmwaresVersionsError,
TData
>({
queryKey: queryKeyFn({
path: '/firmwares/versions',
operationId: 'getFirmwaresVersions',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresVersions({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresImusError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresImusResponse = Schemas.Imudto[];
export type GetFirmwaresImusVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the possible imus to use
*/
export const fetchGetFirmwaresImus = (
variables: GetFirmwaresImusVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
GetFirmwaresImusResponse,
GetFirmwaresImusError,
undefined,
{},
{},
{}
>({ url: '/firmwares/imus', method: 'get', ...variables, signal });
/**
* List all the possible imus to use
*/
export const useGetFirmwaresImus = <TData = GetFirmwaresImusResponse>(
variables: GetFirmwaresImusVariables,
options?: Omit<
reactQuery.UseQueryOptions<GetFirmwaresImusResponse, GetFirmwaresImusError, TData>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<GetFirmwaresImusResponse, GetFirmwaresImusError, TData>({
queryKey: queryKeyFn({
path: '/firmwares/imus',
operationId: 'getFirmwaresImus',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresImus({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresBatteriesError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresBatteriesResponse = string[];
export type GetFirmwaresBatteriesVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the battery types
*/
export const fetchGetFirmwaresBatteries = (
variables: GetFirmwaresBatteriesVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
GetFirmwaresBatteriesResponse,
GetFirmwaresBatteriesError,
undefined,
{},
{},
{}
>({ url: '/firmwares/batteries', method: 'get', ...variables, signal });
/**
* List all the battery types
*/
export const useGetFirmwaresBatteries = <TData = GetFirmwaresBatteriesResponse>(
variables: GetFirmwaresBatteriesVariables,
options?: Omit<
reactQuery.UseQueryOptions<
GetFirmwaresBatteriesResponse,
GetFirmwaresBatteriesError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
GetFirmwaresBatteriesResponse,
GetFirmwaresBatteriesError,
TData
>({
queryKey: queryKeyFn({
path: '/firmwares/batteries',
operationId: 'getFirmwaresBatteries',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresBatteries({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresDefaultConfigBoardPathParams = {
board:
| 'BOARD_SLIMEVR'
| 'BOARD_NODEMCU'
| 'BOARD_WROOM32'
| 'BOARD_WEMOSD1MINI'
| 'BOARD_TTGO_TBASE'
| 'BOARD_ESP01'
| 'BOARD_LOLIN_C3_MINI'
| 'BOARD_BEETLE32C3'
| 'BOARD_ES32C3DEVKITM1';
};
export type GetFirmwaresDefaultConfigBoardError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwaresDefaultConfigBoardVariables = {
pathParams: GetFirmwaresDefaultConfigBoardPathParams;
} & FirmwareToolContext['fetcherOptions'];
/**
* Gives the default pins / configuration of a given board
*/
export const fetchGetFirmwaresDefaultConfigBoard = (
variables: GetFirmwaresDefaultConfigBoardVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.DefaultBuildConfigDTO,
GetFirmwaresDefaultConfigBoardError,
undefined,
{},
{},
GetFirmwaresDefaultConfigBoardPathParams
>({
url: '/firmwares/default-config/{board}',
method: 'get',
...variables,
signal,
});
/**
* Gives the default pins / configuration of a given board
*/
export const useGetFirmwaresDefaultConfigBoard = <
TData = Schemas.DefaultBuildConfigDTO,
>(
variables: GetFirmwaresDefaultConfigBoardVariables,
options?: Omit<
reactQuery.UseQueryOptions<
Schemas.DefaultBuildConfigDTO,
GetFirmwaresDefaultConfigBoardError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<
Schemas.DefaultBuildConfigDTO,
GetFirmwaresDefaultConfigBoardError,
TData
>({
queryKey: queryKeyFn({
path: '/firmwares/default-config/{board}',
operationId: 'getFirmwaresDefaultConfigBoard',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresDefaultConfigBoard({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwaresIdPathParams = {
id: string;
};
export type GetFirmwaresIdError = Fetcher.ErrorWrapper<{
status: 404;
payload: Schemas.HttpException;
}>;
export type GetFirmwaresIdVariables = {
pathParams: GetFirmwaresIdPathParams;
} & FirmwareToolContext['fetcherOptions'];
/**
* Get the inforamtions about a firmware from its id
* also provide more informations than the simple list, like pins and imus and files
*/
export const fetchGetFirmwaresId = (
variables: GetFirmwaresIdVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.FirmwareDetailDTO,
GetFirmwaresIdError,
undefined,
{},
{},
GetFirmwaresIdPathParams
>({ url: '/firmwares/{id}', method: 'get', ...variables, signal });
/**
* Get the inforamtions about a firmware from its id
* also provide more informations than the simple list, like pins and imus and files
*/
export const useGetFirmwaresId = <TData = Schemas.FirmwareDetailDTO>(
variables: GetFirmwaresIdVariables,
options?: Omit<
reactQuery.UseQueryOptions<Schemas.FirmwareDetailDTO, GetFirmwaresIdError, TData>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<Schemas.FirmwareDetailDTO, GetFirmwaresIdError, TData>({
queryKey: queryKeyFn({
path: '/firmwares/{id}',
operationId: 'getFirmwaresId',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwaresId({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetHealthError = Fetcher.ErrorWrapper<undefined>;
export type GetHealthVariables = FirmwareToolContext['fetcherOptions'];
@@ -118,10 +573,7 @@ export type GetHealthVariables = FirmwareToolContext['fetcherOptions'];
* Gives the status of the api
* this endpoint will always return true
*/
export const fetchGetHealth = (
variables: GetHealthVariables,
signal?: AbortSignal
) =>
export const fetchGetHealth = (variables: GetHealthVariables, signal?: AbortSignal) =>
firmwareToolFetch<boolean, GetHealthError, undefined, {}, {}, {}>({
url: '/health',
method: 'get',
@@ -133,15 +585,14 @@ export const fetchGetHealth = (
* Gives the status of the api
* this endpoint will always return true
*/
export const useGetHealth = <TData = boolean,>(
export const useGetHealth = <TData = boolean>(
variables: GetHealthVariables,
options?: Omit<
reactQuery.UseQueryOptions<boolean, GetHealthError, TData>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useFirmwareToolContext(options);
const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options);
return reactQuery.useQuery<boolean, GetHealthError, TData>({
queryKey: queryKeyFn({
path: '/health',
@@ -155,252 +606,54 @@ export const useGetHealth = <TData = boolean,>(
});
};
export type GetFirmwareSourcesError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwareSourcesResponse = Schemas.FirmwareSource[];
export type GetFirmwareSourcesVariables = FirmwareToolContext['fetcherOptions'];
/**
* List all the sources you can build a firmware from
*/
export const fetchGetFirmwareSources = (
variables: GetFirmwareSourcesVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
GetFirmwareSourcesResponse,
GetFirmwareSourcesError,
undefined,
{},
{},
{}
>({ url: '/firmware/sources', method: 'get', ...variables, signal });
/**
* List all the sources you can build a firmware from
*/
export const useGetFirmwareSources = <TData = GetFirmwareSourcesResponse,>(
variables: GetFirmwareSourcesVariables,
options?: Omit<
reactQuery.UseQueryOptions<
GetFirmwareSourcesResponse,
GetFirmwareSourcesError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useFirmwareToolContext(options);
return reactQuery.useQuery<
GetFirmwareSourcesResponse,
GetFirmwareSourcesError,
TData
>({
queryKey: queryKeyFn({
path: '/firmware/sources',
operationId: 'getFirmwareSources',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwareSources({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type GetFirmwareBoardDefaultsQueryParams = {
source: string;
board: string;
version: string;
};
export type GetFirmwareBoardDefaultsError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwareBoardDefaultsVariables = {
queryParams: GetFirmwareBoardDefaultsQueryParams;
} & FirmwareToolContext['fetcherOptions'];
/**
* Fet the defaults of a specific board on a specific firmware
*/
export const fetchGetFirmwareBoardDefaults = (
variables: GetFirmwareBoardDefaultsVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.FirmwareBoardDefaultsNullable,
GetFirmwareBoardDefaultsError,
undefined,
{},
GetFirmwareBoardDefaultsQueryParams,
{}
>({ url: '/firmware/board-defaults', method: 'get', ...variables, signal });
/**
* Fet the defaults of a specific board on a specific firmware
*/
export const useGetFirmwareBoardDefaults = <
TData = Schemas.FirmwareBoardDefaultsNullable,
>(
variables: GetFirmwareBoardDefaultsVariables,
options?: Omit<
reactQuery.UseQueryOptions<
Schemas.FirmwareBoardDefaultsNullable,
GetFirmwareBoardDefaultsError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useFirmwareToolContext(options);
return reactQuery.useQuery<
Schemas.FirmwareBoardDefaultsNullable,
GetFirmwareBoardDefaultsError,
TData
>({
queryKey: queryKeyFn({
path: '/firmware/board-defaults',
operationId: 'getFirmwareBoardDefaults',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwareBoardDefaults(
{ ...fetcherOptions, ...variables },
signal
),
...options,
...queryOptions,
});
};
export type PostFirmwareBuildError = Fetcher.ErrorWrapper<undefined>;
export type PostFirmwareBuildVariables = {
body: Schemas.BuildFirmwareBody;
} & FirmwareToolContext['fetcherOptions'];
export const fetchPostFirmwareBuild = (
variables: PostFirmwareBuildVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.BuildStatusBasic | Schemas.BuildStatusDone,
PostFirmwareBuildError,
Schemas.BuildFirmwareBody,
{},
{},
{}
>({ url: '/firmware/build', method: 'post', ...variables, signal });
export const usePostFirmwareBuild = (
options?: Omit<
reactQuery.UseMutationOptions<
Schemas.BuildStatusBasic | Schemas.BuildStatusDone,
PostFirmwareBuildError,
PostFirmwareBuildVariables
>,
'mutationFn'
>
) => {
const { fetcherOptions } = useFirmwareToolContext();
return reactQuery.useMutation<
Schemas.BuildStatusBasic | Schemas.BuildStatusDone,
PostFirmwareBuildError,
PostFirmwareBuildVariables
>({
mutationFn: (variables: PostFirmwareBuildVariables) =>
fetchPostFirmwareBuild({ ...fetcherOptions, ...variables }),
...options,
});
};
export type GetFirmwareIdPathParams = {
id: string;
};
export type GetFirmwareIdError = Fetcher.ErrorWrapper<undefined>;
export type GetFirmwareIdVariables = {
pathParams: GetFirmwareIdPathParams;
} & FirmwareToolContext['fetcherOptions'];
/**
* Get the inforamtions about a firmware from its id
* also provide more informations than the simple list, like pins and imus and files
*/
export const fetchGetFirmwareId = (
variables: GetFirmwareIdVariables,
signal?: AbortSignal
) =>
firmwareToolFetch<
Schemas.FirmwareWithFiles,
GetFirmwareIdError,
undefined,
{},
{},
GetFirmwareIdPathParams
>({ url: '/firmware/{id}', method: 'get', ...variables, signal });
/**
* Get the inforamtions about a firmware from its id
* also provide more informations than the simple list, like pins and imus and files
*/
export const useGetFirmwareId = <TData = Schemas.FirmwareWithFiles,>(
variables: GetFirmwareIdVariables,
options?: Omit<
reactQuery.UseQueryOptions<
Schemas.FirmwareWithFiles,
GetFirmwareIdError,
TData
>,
'queryKey' | 'queryFn' | 'initialData'
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useFirmwareToolContext(options);
return reactQuery.useQuery<
Schemas.FirmwareWithFiles,
GetFirmwareIdError,
TData
>({
queryKey: queryKeyFn({
path: '/firmware/{id}',
operationId: 'getFirmwareId',
variables,
}),
queryFn: ({ signal }) =>
fetchGetFirmwareId({ ...fetcherOptions, ...variables }, signal),
...options,
...queryOptions,
});
};
export type QueryOperation =
| {
path: '/is-compatible/{version}';
operationId: 'getIsCompatibleVersion';
variables: GetIsCompatibleVersionVariables;
}
| {
path: '/firmwares';
operationId: 'getFirmwares';
variables: GetFirmwaresVariables;
}
| {
path: '/firmwares/build-status/{id}';
operationId: 'getFirmwaresBuildStatusId';
variables: GetFirmwaresBuildStatusIdVariables;
}
| {
path: '/firmwares/boards';
operationId: 'getFirmwaresBoards';
variables: GetFirmwaresBoardsVariables;
}
| {
path: '/firmwares/versions';
operationId: 'getFirmwaresVersions';
variables: GetFirmwaresVersionsVariables;
}
| {
path: '/firmwares/imus';
operationId: 'getFirmwaresImus';
variables: GetFirmwaresImusVariables;
}
| {
path: '/firmwares/batteries';
operationId: 'getFirmwaresBatteries';
variables: GetFirmwaresBatteriesVariables;
}
| {
path: '/firmwares/default-config/{board}';
operationId: 'getFirmwaresDefaultConfigBoard';
variables: GetFirmwaresDefaultConfigBoardVariables;
}
| {
path: '/firmwares/{id}';
operationId: 'getFirmwaresId';
variables: GetFirmwaresIdVariables;
}
| {
path: '/health';
operationId: 'getHealth';
variables: GetHealthVariables;
}
| {
path: '/firmware/sources';
operationId: 'getFirmwareSources';
variables: GetFirmwareSourcesVariables;
}
| {
path: '/firmware/board-defaults';
operationId: 'getFirmwareBoardDefaults';
variables: GetFirmwareBoardDefaultsVariables;
}
| {
path: '/firmware/{id}';
operationId: 'getFirmwareId';
variables: GetFirmwareIdVariables;
};

View File

@@ -3,96 +3,606 @@
*
* @version 0.0.1
*/
export type FirmwareSource = {
version: string;
source: string;
branch?: string;
official: boolean;
prerelease: boolean;
availableBoards: string[];
};
export type FirmwareBoardDefaults = {
schema: void;
defaults: BoardDefaults;
};
export type BoardDefaults = {
values: void;
editable: string[];
flashingRules: {
applicationOffset: number;
needBootPress: boolean;
needManualReboot: boolean;
shouldOnlyUseDefaults: boolean;
export type VerionCheckResponse = {
success: boolean;
reason?: {
message: string;
versions: string;
};
};
export type BoardDefaultsQuery = {
source: string;
board: string;
version: string;
};
export type BuildStatusBasic = {
/**
* Root object declaring a built firmware
* this object contains:
* - the status of the build
* - the the repository and commit used as source
*/
export type FirmwareDTO = {
/**
* UUID of the firmware
*
* @format uuid
*/
id: string;
status:
| 'QUEUED'
/**
* Id of the firmware version used.
* Usually the commit id of the source
* used to build the firmware
*/
releaseId: string;
/**
* Current status of the build
* this value will change during the build
* process
*
* BUILDING -> DONE \\ the firmwrare is build and ready
* -> FAILED \\ the build failled and will be garbage collected
*/
buildStatus:
| 'CREATING_BUILD_FOLDER'
| 'DOWNLOADING_SOURCE'
| 'EXTRACTING_SOURCE'
| 'BUILDING'
| 'SAVING'
| 'ERROR';
};
export type BuildStatusDone = {
id: string;
status: 'DONE';
files: {
filePath: string;
offset: number;
isFirmware: boolean;
firmwareId: string;
}[];
};
export type BuildFirmwareBody = {
source: string;
board: string;
version: string;
values: void;
};
export type FirmwareWithFiles = {
id: string;
release_id: string;
status:
| 'QUEUED'
| 'CREATING_BUILD_FOLDER'
| 'DOWNLOADING_SOURCE'
| 'EXTRACTING_SOURCE'
| 'DOWNLOADING_FIRMWARE'
| 'EXTRACTING_FIRMWARE'
| 'SETTING_UP_DEFINES'
| 'BUILDING'
| 'SAVING'
| 'DONE'
| 'ERROR';
/**
* The repository and branch used as source of the firmware
*/
buildVersion: string;
/**
* The date of creation of this firmware build
*
* @format date-time
*/
createdAt: string;
/**
* @format date-time
*/
updatedAt: string;
files: {
filePath: string;
offset: number;
isFirmware: boolean;
firmwareId: string;
}[];
};
export type FirmwareBoardDefaultsNullable = {
schema: void;
defaults: BoardDefaults;
} | null;
export type BuildResponseDTO = {
/**
* Id of the firmware
*
* @format uuid
*/
id: string;
/**
* Build status of the firmware
*/
status:
| 'CREATING_BUILD_FOLDER'
| 'DOWNLOADING_FIRMWARE'
| 'EXTRACTING_FIRMWARE'
| 'SETTING_UP_DEFINES'
| 'BUILDING'
| 'SAVING'
| 'DONE'
| 'ERROR';
/**
* List of built firmware files, only set if the build succeeded
*/
firmwareFiles?: FirmwareFileDTO[];
};
export type FirmwareFileDTO = {
/**
* Url to the file
*/
url: string;
/**
* Address of the partition
*/
offset: number;
/**
* Is this file the main firmware
*/
isFirmware: boolean;
/**
* Id of the linked firmware
*
* @format uuid
*/
firmwareId: string;
};
export type CreateBuildFirmwareDTO = {
/**
* Repository of the firmware used
*/
version: string;
/**
* Board config, used to declare the pins used by the board
*/
boardConfig: CreateBoardConfigDTO;
/**
* Imu config, list of all the imus used and their pins
*
* @minItems 1
*/
imusConfig: CreateImuConfigDTO[];
};
export type CreateBoardConfigDTO = {
/**
* Type of the board
*/
type:
| 'BOARD_SLIMEVR'
| 'BOARD_NODEMCU'
| 'BOARD_WROOM32'
| 'BOARD_WEMOSD1MINI'
| 'BOARD_TTGO_TBASE'
| 'BOARD_ESP01'
| 'BOARD_LOLIN_C3_MINI'
| 'BOARD_BEETLE32C3'
| 'BOARD_ES32C3DEVKITM1';
/**
* Pin address of the indicator LED
*/
ledPin: string;
/**
* Is the indicator LED enabled
*/
enableLed: boolean;
/**
* Is the led inverted
*/
ledInverted: boolean;
/**
* Pin address of the battery indicator
*/
batteryPin: string;
/**
* Type of battery
*/
batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021';
/**
* Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2]
*
* @minItems 3
* @maxItems 3
*/
batteryResistances: number[];
};
export type CreateImuConfigDTO = {
/**
* Type of the imu
*/
type:
| 'IMU_BNO085'
| 'IMU_MPU9250'
| 'IMU_MPU6500'
| 'IMU_BNO080'
| 'IMU_BNO055'
| 'IMU_BNO086'
| 'IMU_MPU6050'
| 'IMU_BMI160'
| 'IMU_ICM20948'
| 'IMU_BMI270';
/**
* Pin address of the imu int pin
* not all imus use it
*/
intPin: string | null;
/**
* Rotation of the imu in degrees
*/
rotation: number;
/**
* Pin address of the scl pin
*/
sclPin: string;
/**
* Pin address of the sda pin
*/
sdaPin: string;
/**
* Is this imu optionnal
* Allows for extensions to be unplugged
*/
optional: boolean;
};
export type VersionNotFoundExeption = {
cause: void;
name: string;
message: string;
stack?: string;
};
/**
* A representation of any set of values over any amount of time. This is the most basic building block
* of RxJS.
*/
export type ObservableType = {
/**
* @deprecated true
*/
source?: Observableany;
/**
* @deprecated true
*/
operator?: OperatoranyType;
};
/**
* A representation of any set of values over any amount of time. This is the most basic building block
* of RxJS.
*/
export type Observableany = {
/**
* @deprecated true
*/
source?: Observableany;
/**
* @deprecated true
*/
operator?: Operatoranyany;
};
/**
* *
*/
export type Operatoranyany = {};
/**
* *
*/
export type OperatoranyType = {};
export type ReleaseDTO = {
/**
* id of the release, usually the commit id
*/
id: string;
/**
* url of the release
*/
url: string;
/**
* name of the release
*/
name: string;
/**
* url of the source archive
*/
zipball_url: string;
/**
* Is this release a pre release
*/
prerelease: boolean;
/**
* Is this release a draft
*/
draft: boolean;
};
export type Imudto = {
/**
* Type of the imu
*/
type:
| 'IMU_BNO085'
| 'IMU_MPU9250'
| 'IMU_MPU6500'
| 'IMU_BNO080'
| 'IMU_BNO055'
| 'IMU_BNO086'
| 'IMU_MPU6050'
| 'IMU_BMI160'
| 'IMU_ICM20948'
| 'IMU_BMI270';
/**
* Does that imu type require a int pin
*/
hasIntPin: boolean;
/**
* First address of the imu
*/
imuStartAddress: number;
/**
* Increment of the address for each new imus
*/
addressIncrement: number;
};
export type DefaultBuildConfigDTO = {
/**
* Default config of the selected board
* contains all the default pins information about the selected board
*/
boardConfig: CreateBoardConfigDTO;
/**
* Inform the flashing utility that the user need to press the boot (or Flash) button
* on the tracker
*/
needBootPress?: boolean;
/**
* Inform the flashing utility that the board will need a reboot after
* being flashed
*/
needManualReboot?: boolean;
/**
* Will use the default values and skip the customisation options
*/
shouldOnlyUseDefaults?: boolean;
/**
* List of the possible imus pins, usually only two items will be sent
*
* @minItems 1
*/
imuDefaults: IMUDefaultDTO[];
/**
* Gives the offset of the firmare file in the eeprom. Used for flashing
*/
application_offset: number;
};
export type IMUDefaultDTO = {
/**
* Type of the imu
*/
type?:
| 'IMU_BNO085'
| 'IMU_MPU9250'
| 'IMU_MPU6500'
| 'IMU_BNO080'
| 'IMU_BNO055'
| 'IMU_BNO086'
| 'IMU_MPU6050'
| 'IMU_BMI160'
| 'IMU_ICM20948'
| 'IMU_BMI270';
/**
* Pin address of the imu int pin
* not all imus use it
*/
intPin: string | null;
/**
* Rotation of the imu in degrees
*/
rotation?: number;
/**
* Pin address of the scl pin
*/
sclPin: string;
/**
* Pin address of the sda pin
*/
sdaPin: string;
/**
* Is this imu optionnal
* Allows for extensions to be unplugged
*/
optional: boolean;
};
export type BoardConfigDTONullable = {
/**
* Unique id of the board config, used for relations
*
* @format uuid
*/
id: string;
/**
* Type of the board
*/
type:
| 'BOARD_SLIMEVR'
| 'BOARD_NODEMCU'
| 'BOARD_WROOM32'
| 'BOARD_WEMOSD1MINI'
| 'BOARD_TTGO_TBASE'
| 'BOARD_ESP01'
| 'BOARD_LOLIN_C3_MINI'
| 'BOARD_BEETLE32C3'
| 'BOARD_ES32C3DEVKITM1';
/**
* Pin address of the indicator LED
*/
ledPin: string;
/**
* Is the indicator LED enabled
*/
enableLed: boolean;
/**
* Is the led inverted
*/
ledInverted: boolean;
/**
* Pin address of the battery indicator
*/
batteryPin: string;
/**
* Type of battery
*/
batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021';
/**
* Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2]
*
* @minItems 3
* @maxItems 3
*/
batteryResistances: number[];
/**
* Id of the linked firmware, used for relations
*
* @format uuid
*/
firmwareId: string;
};
export type FirmwareDetailDTO = {
/**
* Pins informations about the board
*/
boardConfig: BoardConfigDTONullable;
/**
* List of the declared imus, and their pin configuration
*
* @minItems 1
*/
imusConfig: ImuConfigDTO[];
/**
* List of the built files / partitions with their url and offsets
*/
firmwareFiles: FirmwareFileDTO[];
/**
* UUID of the firmware
*
* @format uuid
*/
id: string;
/**
* Id of the firmware version used.
* Usually the commit id of the source
* used to build the firmware
*/
releaseId: string;
/**
* Current status of the build
* this value will change during the build
* process
*
* BUILDING -> DONE \\ the firmwrare is build and ready
* -> FAILED \\ the build failled and will be garbage collected
*/
buildStatus:
| 'CREATING_BUILD_FOLDER'
| 'DOWNLOADING_FIRMWARE'
| 'EXTRACTING_FIRMWARE'
| 'SETTING_UP_DEFINES'
| 'BUILDING'
| 'SAVING'
| 'DONE'
| 'ERROR';
/**
* The repository and branch used as source of the firmware
*/
buildVersion: string;
/**
* The date of creation of this firmware build
*
* @format date-time
*/
createdAt: string;
};
export type BoardConfigDTO = {
/**
* Unique id of the board config, used for relations
*
* @format uuid
*/
id: string;
/**
* Type of the board
*/
type:
| 'BOARD_SLIMEVR'
| 'BOARD_NODEMCU'
| 'BOARD_WROOM32'
| 'BOARD_WEMOSD1MINI'
| 'BOARD_TTGO_TBASE'
| 'BOARD_ESP01'
| 'BOARD_LOLIN_C3_MINI'
| 'BOARD_BEETLE32C3'
| 'BOARD_ES32C3DEVKITM1';
/**
* Pin address of the indicator LED
*/
ledPin: string;
/**
* Is the indicator LED enabled
*/
enableLed: boolean;
/**
* Is the led inverted
*/
ledInverted: boolean;
/**
* Pin address of the battery indicator
*/
batteryPin: string;
/**
* Type of battery
*/
batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021';
/**
* Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2]
*
* @minItems 3
* @maxItems 3
*/
batteryResistances: number[];
/**
* Id of the linked firmware, used for relations
*
* @format uuid
*/
firmwareId: string;
};
export type ImuConfigDTO = {
/**
* Unique id of the config
* this probably will never be shown to the user as it is moslty use for relations
*
* @format uuid
*/
id: string;
/**
* Type of the imu
*/
type:
| 'IMU_BNO085'
| 'IMU_MPU9250'
| 'IMU_MPU6500'
| 'IMU_BNO080'
| 'IMU_BNO055'
| 'IMU_BNO086'
| 'IMU_MPU6050'
| 'IMU_BMI160'
| 'IMU_ICM20948'
| 'IMU_BMI270';
/**
* Rotation of the imu in degrees
*/
rotation: number;
/**
* Pin address of the imu int pin
* not all imus use it
*/
intPin: string | null;
/**
* Pin address of the scl pin
*/
sclPin: string;
/**
* Pin address of the sda pin
*/
sdaPin: string;
/**
* Is this imu optionnal
* Allows for extensions to be unplugged
*/
optional: boolean;
/**
* id of the linked firmware, used for relations
*
* @format uuid
*/
firmwareId: string;
};
/**
* Defines the base Nest HTTP exception, which is handled by the default
* Exceptions Handler.
*/
export type HttpException = {
cause: void;
name: string;
message: string;
stack?: string;
};

View File

@@ -1,5 +1,20 @@
import { createContext, useContext, useState } from 'react';
import {
fetchGetFirmwaresDefaultConfigBoard,
useGetHealth,
useGetIsCompatibleVersion,
} from '@/firmware-tool-api/firmwareToolComponents';
import {
BuildResponseDTO,
CreateBoardConfigDTO,
CreateBuildFirmwareDTO,
DefaultBuildConfigDTO,
FirmwareFileDTO,
} from '@/firmware-tool-api/firmwareToolSchemas';
import { BoardPinsForm } from '@/components/firmware-tool/BoardPinsStep';
import { DeepPartial } from 'react-hook-form';
import {
BoardType,
DeviceIdT,
FirmwarePartT,
FirmwareUpdateMethod,
@@ -10,20 +25,53 @@ import {
SerialFirmwareUpdateT,
} from 'solarxr-protocol';
import { OnboardingContext } from './onboarding';
import {
BoardDefaults,
FirmwareBoardDefaultsNullable,
FirmwareSource,
FirmwareWithFiles,
} from '@/firmware-tool-api/firmwareToolSchemas';
import { GetFirmwareBoardDefaultsQueryParams } from '@/firmware-tool-api/firmwareToolComponents';
export type PartialBuildFirmware = DeepPartial<CreateBuildFirmwareDTO>;
export type FirmwareBuildStatus = BuildResponseDTO;
export type SelectedDevice = {
type: FirmwareUpdateMethod;
deviceId: string | number;
deviceNames: string[];
};
export const boardTypeToFirmwareToolBoardType: Record<
Exclude<
BoardType,
// This boards will not be handled by the firmware tool.
// These are either impossible to compile automatically or deprecated
| BoardType.CUSTOM
| BoardType.SLIMEVR_DEV
| BoardType.SLIMEVR_LEGACY
| BoardType.OWOTRACK
| BoardType.WRANGLER
| BoardType.MOCOPI
| BoardType.HARITORA
| BoardType.DEV_RESERVED
>,
CreateBoardConfigDTO['type'] | null
> = {
[BoardType.UNKNOWN]: null,
[BoardType.NODEMCU]: 'BOARD_NODEMCU',
[BoardType.WROOM32]: 'BOARD_WROOM32',
[BoardType.WEMOSD1MINI]: 'BOARD_WEMOSD1MINI',
[BoardType.TTGO_TBASE]: 'BOARD_TTGO_TBASE',
[BoardType.ESP01]: 'BOARD_ESP01',
[BoardType.SLIMEVR]: 'BOARD_SLIMEVR',
[BoardType.LOLIN_C3_MINI]: 'BOARD_LOLIN_C3_MINI',
[BoardType.BEETLE32C3]: 'BOARD_BEETLE32C3',
[BoardType.ESP32C3DEVKITM1]: 'BOARD_ES32C3DEVKITM1',
[BoardType.WEMOSWROOM02]: null,
[BoardType.XIAO_ESP32C3]: null,
[BoardType.ESP32C6DEVKITC1]: null,
[BoardType.GLOVE_IMU_SLIMEVR_DEV]: null,
[BoardType.GESTURES]: null,
};
export const firmwareToolToBoardType: Record<CreateBoardConfigDTO['type'], BoardType> =
Object.fromEntries(
Object.entries(boardTypeToFirmwareToolBoardType).map((a) => a.reverse())
);
export const firmwareUpdateErrorStatus = [
FirmwareUpdateStatus.ERROR_AUTHENTICATION_FAILED,
FirmwareUpdateStatus.ERROR_DEVICE_NOT_FOUND,
@@ -61,7 +109,24 @@ export const firmwareUpdateStatusLabel: Record<FirmwareUpdateStatus, string> = {
[FirmwareUpdateStatus.ERROR_UNKNOWN]: 'firmware_update-status-ERROR_UNKNOWN',
};
export type FirmwareToolContext = ReturnType<typeof provideFirmwareTool>;
export interface FirmwareToolContext {
selectBoard: (boardType: CreateBoardConfigDTO['type']) => Promise<void>;
selectVersion: (version: CreateBuildFirmwareDTO['version']) => void;
updatePins: (form: BoardPinsForm) => void;
updateImus: (imus: CreateBuildFirmwareDTO['imusConfig']) => void;
setBuildStatus: (buildStatus: FirmwareBuildStatus) => void;
selectDevices: (device: SelectedDevice[] | null) => void;
retry: () => void;
buildStatus: FirmwareBuildStatus;
defaultConfig: DefaultBuildConfigDTO | null;
newConfig: PartialBuildFirmware | null;
selectedDevices: SelectedDevice[] | null;
isStepLoading: boolean;
isGlobalLoading: boolean;
isCompatible: boolean;
isError: boolean;
}
export const FirmwareToolContextC = createContext<FirmwareToolContext>(
undefined as any
);
@@ -74,23 +139,97 @@ export function useFirmwareTool() {
return context;
}
export function provideFirmwareTool() {
const [selectedSource, setSelectedSource] = useState<{
source: GetFirmwareBoardDefaultsQueryParams;
default: FirmwareBoardDefaultsNullable;
}>();
export function useFirmwareToolContext(): FirmwareToolContext {
const [defaultConfig, setDefaultConfig] = useState<DefaultBuildConfigDTO | null>(
null
);
const [selectedDevices, selectDevices] = useState<SelectedDevice[] | null>(null);
const [newConfig, setNewConfig] = useState<PartialBuildFirmware>({});
const [isLoading, setLoading] = useState(false);
const { isError, isLoading: isInitialLoading, refetch } = useGetHealth({});
const compatibilityCheckEnabled = !!__VERSION_TAG__;
const { isLoading: isCompatibilityLoading, data: compatibilityData } =
useGetIsCompatibleVersion(
{ pathParams: { version: __VERSION_TAG__ } },
{ enabled: compatibilityCheckEnabled }
);
const [buildStatus, setBuildStatus] = useState<FirmwareBuildStatus>({
status: 'CREATING_BUILD_FOLDER',
id: '',
});
return {
selectedSource,
setSelectedSource,
selectBoard: async (boardType: CreateBoardConfigDTO['type']) => {
setLoading(true);
const boardDefaults = await fetchGetFirmwaresDefaultConfigBoard({
pathParams: { board: boardType },
});
setDefaultConfig(boardDefaults);
if (boardDefaults.shouldOnlyUseDefaults) {
setNewConfig((currConfig) => ({
...currConfig,
...boardDefaults,
imusConfig: boardDefaults.imuDefaults,
}));
} else {
setNewConfig((currConfig) => ({
...currConfig,
boardConfig: { ...currConfig.boardConfig, type: boardType },
imusConfig: [],
}));
}
setLoading(false);
},
updatePins: (form: BoardPinsForm) => {
setNewConfig((currConfig) => {
return {
...currConfig,
imusConfig: [...(currConfig?.imusConfig || [])],
boardConfig: {
...currConfig.boardConfig,
...form,
batteryResistances: form.batteryResistances.map((r) => Number(r)),
},
};
});
},
updateImus: (imus: CreateBuildFirmwareDTO['imusConfig']) => {
setNewConfig((currConfig) => {
return {
...currConfig,
imusConfig: imus.map(({ rotation, ...fields }) => ({
...fields,
rotation: Number(rotation),
})), // Make sure that the rotation is handled as number
};
});
},
retry: async () => {
setLoading(true);
await refetch();
setLoading(false);
},
selectVersion: (version: CreateBuildFirmwareDTO['version']) => {
setNewConfig((currConfig) => ({ ...currConfig, version }));
},
setBuildStatus,
selectDevices,
selectedDevices,
buildStatus,
defaultConfig,
newConfig,
isStepLoading: isLoading,
isGlobalLoading: isInitialLoading || isCompatibilityLoading,
isCompatible: !compatibilityCheckEnabled || (compatibilityData?.success ?? false),
isError: isError || (!compatibilityData?.success && compatibilityCheckEnabled),
};
}
export const getFlashingRequests = (
devices: SelectedDevice[],
firmwareFiles: FirmwareWithFiles['files'],
firmwareFiles: FirmwareFileDTO[],
onboardingState: OnboardingContext['state'],
defaultConfig: BoardDefaults | null
defaultConfig: DefaultBuildConfigDTO | null
) => {
const firmware = firmwareFiles.find(({ isFirmware }) => isFirmware);
if (!firmware) throw new Error('invalid state - no firmware to find');
@@ -105,7 +244,7 @@ export const getFlashingRequests = (
const part = new FirmwarePartT();
part.offset = 0;
part.url = firmware.filePath;
part.url = firmware.url;
const method = new OTAFirmwareUpdateT();
method.deviceId = dId;
@@ -128,13 +267,12 @@ export const getFlashingRequests = (
method.deviceId = id;
method.ssid = onboardingState.wifi.ssid;
method.password = onboardingState.wifi.password;
method.needManualReboot =
defaultConfig?.flashingRules.needManualReboot ?? false;
method.needManualReboot = defaultConfig?.needManualReboot ?? false;
method.firmwarePart = firmwareFiles.map(({ offset, filePath }) => {
method.firmwarePart = firmwareFiles.map(({ offset, url }) => {
const part = new FirmwarePartT();
part.offset = offset;
part.url = filePath;
part.url = url;
return part;
});

View File

@@ -8,7 +8,7 @@ export interface FirmwareRelease {
name: string;
version: string;
changelog: string;
firmwareFiles: Partial<Record<BoardType, string>>;
firmwareFile: string;
userCanUpdate: boolean;
}
@@ -89,9 +89,7 @@ export async function fetchCurrentFirmwareRelease(): Promise<FirmwareRelease | n
const processedReleses = [];
for (const release of releases) {
const fwAsset = firstAsset(release.assets, 'BOARD_SLIMEVR-firmware.bin');
const fw12Asset = firstAsset(release.assets, 'BOARD_SLIMEVR_V1_2-firmware.bin');
if (!release.assets || (!fwAsset && !fw12Asset) /* || release.prerelease */)
continue;
if (!release.assets || !fwAsset /* || release.prerelease */) continue;
let version = release.tag_name;
if (version.charAt(0) === 'v') {
@@ -107,10 +105,7 @@ export async function fetchCurrentFirmwareRelease(): Promise<FirmwareRelease | n
name: release.name,
version,
changelog: release.body,
firmwareFiles: {
[BoardType.SLIMEVR]: fwAsset.browser_download_url,
[BoardType.SLIMEVR_V1_2]: fw12Asset.browser_download_url,
},
firmwareFile: fwAsset.browser_download_url,
userCanUpdate,
});
@@ -128,10 +123,7 @@ export function checkForUpdate(
if (!currentFirmwareRelease.userCanUpdate) return 'blocked';
if (
!device.hardwareInfo?.officialBoardType ||
![BoardType.SLIMEVR, BoardType.SLIMEVR_V1_2].includes(
device.hardwareInfo.officialBoardType
) ||
device.hardwareInfo?.officialBoardType !== BoardType.SLIMEVR ||
!semver.valid(currentFirmwareRelease.version) ||
!semver.valid(device.hardwareInfo.firmwareVersion?.toString() ?? 'none')
) {

23
pnpm-lock.yaml generated
View File

@@ -80,9 +80,6 @@ importers:
'@twemoji/svg':
specifier: ^15.0.0
version: 15.0.0
ajv:
specifier: ^8.17.1
version: 8.17.1
browser-fs-access:
specifier: ^0.35.0
version: 0.35.0
@@ -1543,9 +1540,6 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
ansi-escapes@4.3.2:
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
engines: {node: '>=8'}
@@ -2311,9 +2305,6 @@ packages:
fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
fast-uri@3.1.0:
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
@@ -2870,9 +2861,6 @@ packages:
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -5828,13 +5816,6 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ajv@8.17.1:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.0
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
ansi-escapes@4.3.2:
dependencies:
type-fest: 0.21.3
@@ -6760,8 +6741,6 @@ snapshots:
fast-safe-stringify@2.1.1: {}
fast-uri@3.1.0: {}
fastq@1.17.1:
dependencies:
reusify: 1.0.4
@@ -7316,8 +7295,6 @@ snapshots:
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
json-stable-stringify-without-jsonify@1.0.1: {}
json5@1.0.2:

View File

@@ -56,8 +56,6 @@ enum class BoardType(val id: UInt) {
ESP32C6DEVKITC1(19u),
GLOVE_IMU_SLIMEVR_DEV(20u),
GESTURES(21u),
SLIMEVR_V1_2(22u),
ESP32S3_SUPERMINI(23u),
DEV_RESERVED(250u),
;
@@ -86,8 +84,6 @@ enum class BoardType(val id: UInt) {
HARITORA -> "Haritora"
ESP32C6DEVKITC1 -> "Espressif ESP32-C6 DevKitC-1"
GLOVE_IMU_SLIMEVR_DEV -> "SlimeVR Dev IMU Glove"
SLIMEVR_V1_2 -> "SlimeVR v1.2"
ESP32S3_SUPERMINI -> "ESP32-S3 SuperMini"
DEV_RESERVED -> "Prototype"
}