refactor: switch to using Bun (#718)

This commit is contained in:
Dan Ditomaso
2025-07-16 22:30:10 -04:00
committed by GitHub
parent acfd7ebd2d
commit 704d06cfe7
401 changed files with 35294 additions and 39107 deletions
@@ -1,10 +1,15 @@
import { createZodResolver } from "@components/Form/createZodResolver.ts";
import {
DynamicFormField,
type FieldProps,
} from "@components/Form/DynamicFormField.tsx";
import { FieldWrapper } from "@components/Form/FormWrapper.tsx";
import { Button } from "@components/UI/Button.tsx";
import { Heading } from "@components/UI/Typography/Heading.tsx";
import { Subtle } from "@components/UI/Typography/Subtle.tsx";
import { useAppStore } from "@core/stores/appStore.ts";
import { dotPaths } from "@core/utils/dotPath.ts";
import { useEffect } from "react";
import {
type Control,
type DefaultValues,
@@ -13,16 +18,11 @@ import {
get,
type Path,
type SubmitHandler,
useForm,
type UseFormReturn,
useForm,
} from "react-hook-form";
import { Heading } from "@components/UI/Typography/Heading.tsx";
import { ZodType } from "zod/v4";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { createZodResolver } from "@components/Form/createZodResolver.ts";
import { useAppStore } from "@core/stores/appStore.ts";
import { dotPaths } from "@core/utils/dotPath.ts";
import type { ZodType } from "zod/v4";
interface DisabledBy<T> {
fieldName: Path<T>;
@@ -86,41 +86,34 @@ export function DynamicForm<T extends FieldValues>({
formId,
}: DynamicFormProps<T>) {
const { t } = useTranslation();
const {
addError,
removeError,
} = useAppStore();
const { addError, removeError } = useAppStore();
const internalMethods = useForm<T>({
mode: "onChange",
defaultValues: defaultValues,
resolver: validationSchema
? createZodResolver(validationSchema)
: undefined,
shouldFocusError: false,
resetOptions: { keepDefaultValues: true },
values,
});
const methods = propMethods ?? internalMethods;
let methods = propMethods;
if (!methods) {
methods = useForm<
T
>({
mode: "onChange",
defaultValues: defaultValues,
resolver: validationSchema
? createZodResolver(validationSchema)
: undefined,
shouldFocusError: false,
resetOptions: { keepDefaultValues: true },
values,
});
}
const { handleSubmit, control, getValues, formState, getFieldState } =
methods;
useEffect(() => {
if (!propMethods) {
onFormInit?.(methods);
onFormInit?.(internalMethods);
}
}, [onFormInit, propMethods, methods]);
}, [onFormInit, propMethods, internalMethods]);
useEffect(() => {
const errorKeys = Object.keys(formState.errors);
if (formId) {
if (
errorKeys.length === 0
) {
if (errorKeys.length === 0) {
dotPaths(getValues()).forEach((key) => {
removeError(key);
});
@@ -132,19 +125,27 @@ export function DynamicForm<T extends FieldValues>({
addError(formId, "");
}
}
}, [formState.errors]);
}, [formState.errors, addError, formId, getValues, removeError]);
const isDisabled = (
disabledBy?: DisabledBy<T>[],
disabled?: boolean,
): boolean => {
if (disabled) return true;
if (!disabledBy) return false;
if (disabled) {
return true;
}
if (!disabledBy) {
return false;
}
return disabledBy.some((field) => {
const value = getValues(field.fieldName);
if (value === "always") return true;
if (typeof value === "boolean") return field.invert ? value : !value;
if (value === "always") {
return true;
}
if (typeof value === "boolean") {
return field.invert ? value : !value;
}
if (typeof value === "number") {
return field.invert
? field.selector !== value
@@ -181,14 +182,16 @@ export function DynamicForm<T extends FieldValues>({
fieldName={field.name}
description={field.description}
valid={!error}
validationText={error
? String(
t([`formValidation.${error.type}`, error.message], {
returnObjects: false,
...error.params,
}),
)
: ""}
validationText={
error
? String(
t([`formValidation.${error.type}`, error.message], {
returnObjects: false,
...error.params,
}),
)
: ""
}
>
<DynamicFormField
field={field}
@@ -203,11 +206,7 @@ export function DynamicForm<T extends FieldValues>({
</div>
))}
{hasSubmitButton && (
<Button
type="submit"
variant="outline"
disabled={!formState.isValid}
>
<Button type="submit" variant="outline" disabled={!formState.isValid}>
{t("button.submit")}
</Button>
)}
@@ -1,7 +1,3 @@
import {
type MultiSelectFieldProps,
MultiSelectInput,
} from "./FormMultiSelect.tsx";
import {
GenericInput,
type InputFieldProps,
@@ -19,6 +15,10 @@ import {
ToggleInput,
} from "@components/Form/FormToggle.tsx";
import type { Control, FieldValues } from "react-hook-form";
import {
type MultiSelectFieldProps,
MultiSelectInput,
} from "./FormMultiSelect.tsx";
export type FieldProps<T> =
| InputFieldProps<T>
+11 -6
View File
@@ -58,7 +58,9 @@ export function GenericInput<T extends FieldValues>({
return;
}
if (field.inputChange) field.inputChange(e);
if (field.inputChange) {
field.inputChange(e);
}
controllerField.onChange(
field.type === "number"
@@ -76,14 +78,17 @@ export function GenericInput<T extends FieldValues>({
<Input
type={field.type}
step={field.properties?.step}
value={field.type === "number"
? String(controllerField.value)
: controllerField.value}
value={
field.type === "number"
? String(controllerField.value)
: controllerField.value
}
id={field.name}
onChange={handleInputChange}
showCopyButton={field.properties?.showCopyButton}
showPasswordToggle={field.properties?.showPasswordToggle ||
field.type === "password"}
showPasswordToggle={
field.properties?.showPasswordToggle || field.type === "password"
}
className={field.properties?.className}
{...restProperties}
disabled={disabled}
@@ -2,11 +2,11 @@ import type {
BaseFormBuilderProps,
GenericFormElementProps,
} from "@components/Form/DynamicForm.tsx";
import type { FLAGS_CONFIG } from "@core/hooks/usePositionFlags.ts";
import { cn } from "@core/utils/cn.ts";
import type { FieldValues } from "react-hook-form";
import { useTranslation } from "react-i18next";
import type { FLAGS_CONFIG } from "@core/hooks/usePositionFlags.ts";
import { MultiSelect, MultiSelectItem } from "../UI/MultiSelect.tsx";
import { cn } from "@core/utils/cn.ts";
export interface MultiSelectFieldProps<T> extends BaseFormBuilderProps<T> {
type: "multiSelect";
@@ -15,9 +15,7 @@ export interface MultiSelectFieldProps<T> extends BaseFormBuilderProps<T> {
isChecked: (name: string) => boolean;
value: string[];
properties: BaseFormBuilderProps<T>["properties"] & {
enumValue:
| { [s: string]: string | number }
| typeof FLAGS_CONFIG;
enumValue: { [s: string]: string | number } | typeof FLAGS_CONFIG;
formatEnumName?: boolean;
};
}
@@ -39,7 +37,7 @@ export function MultiSelectInput<T extends FieldValues>({
([key, configOrValue]) => {
if (isNewConfigStructure) {
const config =
configOrValue as typeof FLAGS_CONFIG[keyof typeof FLAGS_CONFIG];
configOrValue as (typeof FLAGS_CONFIG)[keyof typeof FLAGS_CONFIG];
return {
key,
display: t(config.i18nKey),
@@ -2,11 +2,11 @@ import type {
BaseFormBuilderProps,
GenericFormElementProps,
} from "@components/Form/DynamicForm.tsx";
import type { ButtonVariant } from "../UI/Button.tsx";
import { Generator } from "@components/UI/Generator.tsx";
import { Controller, type FieldValues, useFormContext } from "react-hook-form";
import { usePasswordVisibilityToggle } from "@core/hooks/usePasswordVisibilityToggle.ts";
import { useEffect } from "react";
import { Controller, type FieldValues, useFormContext } from "react-hook-form";
import type { ButtonVariant } from "../UI/Button.tsx";
export interface PasswordGeneratorProps<T> extends BaseFormBuilderProps<T> {
type: "passwordGenerator";
@@ -38,24 +38,22 @@ export function PasswordGenerator<T extends FieldValues>({
useEffect(() => {
trigger(field.name);
}, [field.devicePSKBitCount, field.name, trigger]);
}, [field.name, trigger]);
return (
<Controller
name={field.name}
control={control}
render={(
{
field: { value, onChange, ...rest },
},
) => (
render={({ field: { value, onChange, ...rest } }) => (
<Generator
type={field.hide && !isVisible ? "password" : "text"}
id={field.id}
devicePSKBitCount={field.devicePSKBitCount}
bits={field.bits}
inputChange={(e) => {
if (field.inputChange) field.inputChange(e);
if (field.inputChange) {
field.inputChange(e);
}
onChange(e);
}}
selectChange={field.selectChange ?? (() => {})}
@@ -9,8 +9,8 @@ import {
SelectTrigger,
SelectValue,
} from "@components/UI/Select.tsx";
import { type FieldValues, useController } from "react-hook-form";
import { cn } from "@core/utils/cn.ts";
import { type FieldValues, useController } from "react-hook-form";
export interface SelectFieldProps<T> extends BaseFormBuilderProps<T> {
type: "select";
@@ -73,10 +73,14 @@ export function SelectInput<T extends FieldValues>({
if (field.validate) {
const isValid = await field.validate(selectedKey);
if (!isValid) return;
if (!isValid) {
return;
}
}
if (field.selectChange) field.selectChange(newValue, selectedKey);
if (field.selectChange) {
field.selectChange(newValue, selectedKey);
}
onChange(Number.parseInt(newValue));
};
@@ -3,8 +3,8 @@ import type {
GenericFormElementProps,
} from "@components/Form/DynamicForm.tsx";
import { Switch } from "@components/UI/Switch.tsx";
import { Controller, type FieldValues } from "react-hook-form";
import { cn } from "@core/utils/cn.ts";
import { Controller, type FieldValues } from "react-hook-form";
export interface ToggleFieldProps<T> extends BaseFormBuilderProps<T> {
type: "toggle";
@@ -22,9 +22,7 @@ export function ToggleInput<T extends FieldValues>({
<Controller
name={field.name}
control={control}
render={(
{ field: { value, onChange, ...rest } },
) => (
render={({ field: { value, onChange, ...rest } }) => (
<Switch
checked={value}
onCheckedChange={(v) => {
@@ -1,4 +1,3 @@
import type { ZodType } from "zod/v4";
import type {
FieldError,
FieldValues,
@@ -6,6 +5,7 @@ import type {
ResolverOptions,
ResolverResult,
} from "react-hook-form";
import type { ZodType } from "zod/v4";
export function createZodResolver<T extends FieldValues>(
schema: ZodType<T, unknown>,
@@ -32,18 +32,18 @@ export function createZodResolver<T extends FieldValues>(
const { path, code, message, ...params } = issue;
const key = path.join(".");
const suffix = "format" in params
? params.format
: "origin" in params
? params.origin
: "expected" in params
? params.expected
: "";
const suffix =
"format" in params
? params.format
: "origin" in params
? params.origin
: "expected" in params
? params.expected
: "";
const newCode = code.replace(
/_([a-z])/g,
(_, char) => char.toUpperCase(),
) + (suffix ? `.${suffix}` : "");
const newCode =
code.replace(/_([a-z])/g, (_, char) => char.toUpperCase()) +
(suffix ? `.${suffix}` : "");
const fieldError: FieldError & { params?: Record<string, unknown> } = {
type: newCode,