diff --git a/electron/package-lock.json b/electron/package-lock.json index 0495d9e1b..997ad9af6 100644 --- a/electron/package-lock.json +++ b/electron/package-lock.json @@ -27,7 +27,6 @@ "@tanstack/react-router": "^1.130.17", "@tanstack/react-table": "^8.21.2", "@tanstack/router-devtools": "^1.105.0", - "@tanstack/zod-adapter": "^1.116.0", "@vitejs/plugin-react": "^4.5.2", "babel-plugin-react-compiler": "^19.0.0-beta-714736e-20250131", "class-variance-authority": "^0.7.1", @@ -53,8 +52,8 @@ "tailwindcss-animate": "^1.0.7", "uplot": "^1.6.32", "xlsx": "^0.18.5", - "zod": "^3.24.2", - "zod-validation-error": "^3.4.0", + "zod": "^4.3.5", + "zod-validation-error": "^5.0.0", "zustand": "^5.0.8" }, "devDependencies": { @@ -3129,6 +3128,66 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.7.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.7.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.1.18", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", @@ -3408,23 +3467,6 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, - "node_modules/@tanstack/zod-adapter": { - "version": "1.141.1", - "resolved": "https://registry.npmjs.org/@tanstack/zod-adapter/-/zod-adapter-1.141.1.tgz", - "integrity": "sha512-ZsGxo+/AFZnVdut8g7VkDZ6+xZ94+bHUyXv6FnB5tSmuPVFXuVwRCZnVida7EYYd3SOWpyy222e4Qkpob1xwOw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-router": ">=1.43.2", - "zod": "^3.23.8" - } - }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -5964,6 +6006,29 @@ "eslint": ">=7" } }, + "node_modules/eslint-plugin-react-compiler/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/eslint-plugin-react-compiler/node_modules/zod-validation-error": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.4.tgz", + "integrity": "sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.24.4" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -12210,24 +12275,24 @@ } }, "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/zod-validation-error": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.4.tgz", - "integrity": "sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-5.0.0.tgz", + "integrity": "sha512-hmk+pkyKq7Q71PiWVSDUc3VfpzpvcRHZ3QPw9yEMVvmtCekaMeOHnbr3WbxfrgEnQTv6haGP4cmv0Ojmihzsxw==", "license": "MIT", "engines": { "node": ">=18.0.0" }, "peerDependencies": { - "zod": "^3.24.4" + "zod": "^3.25.0 || ^4.0.0" } }, "node_modules/zustand": { diff --git a/electron/package.json b/electron/package.json index f2b1eeadd..4c8df60c3 100644 --- a/electron/package.json +++ b/electron/package.json @@ -75,7 +75,6 @@ "@tanstack/react-router": "^1.130.17", "@tanstack/react-table": "^8.21.2", "@tanstack/router-devtools": "^1.105.0", - "@tanstack/zod-adapter": "^1.116.0", "@vitejs/plugin-react": "^4.5.2", "babel-plugin-react-compiler": "^19.0.0-beta-714736e-20250131", "class-variance-authority": "^0.7.1", @@ -101,8 +100,8 @@ "tailwindcss-animate": "^1.0.7", "uplot": "^1.6.32", "xlsx": "^0.18.5", - "zod": "^3.24.2", - "zod-validation-error": "^3.4.0", + "zod": "^4.3.5", + "zod-validation-error": "^5.0.0", "zustand": "^5.0.8" } } diff --git a/electron/src/components/preset/NewPresetDialog.tsx b/electron/src/components/preset/NewPresetDialog.tsx index 9771884d6..c5169d2ab 100644 --- a/electron/src/components/preset/NewPresetDialog.tsx +++ b/electron/src/components/preset/NewPresetDialog.tsx @@ -1,4 +1,3 @@ -import { PresetData, PresetSchema } from "@/lib/preset/preset"; import { Dialog, DialogContent, @@ -14,13 +13,13 @@ import { Separator } from "../ui/separator"; import { PresetPreviewEntries, PresetPreviewTable } from "./PresetPreviewTable"; import { Input } from "../ui/input"; -export type NewPresetDialogProps = { - currentState?: PresetData; +export type NewPresetDialogProps = { + currentState?: T; previewEntries: PresetPreviewEntries; onSave: (name: string) => void; }; -export function NewPresetDialog({ +export function NewPresetDialog({ currentState, onSave, previewEntries, diff --git a/electron/src/components/preset/PresetCard.tsx b/electron/src/components/preset/PresetCard.tsx index c1cfae270..103ca0cb0 100644 --- a/electron/src/components/preset/PresetCard.tsx +++ b/electron/src/components/preset/PresetCard.tsx @@ -60,7 +60,7 @@ export function PresetCardMenu({ ); } -export type PresetCardProps = { +export type PresetCardProps = { preset: Preset; onApply: (preset: Preset) => void; onOverwrite: (preset: Preset) => void; @@ -72,7 +72,7 @@ export type PresetCardProps = { isActive?: boolean; }; -export function PresetCard({ +export function PresetCard({ preset, onApply, onOverwrite, diff --git a/electron/src/components/preset/PresetPreviewTable.tsx b/electron/src/components/preset/PresetPreviewTable.tsx index e3df9b40f..9358dc5dd 100644 --- a/electron/src/components/preset/PresetPreviewTable.tsx +++ b/electron/src/components/preset/PresetPreviewTable.tsx @@ -1,28 +1,27 @@ import React, { Fragment } from "react"; -import { PresetData, PresetSchema } from "@/lib/preset/preset"; import { renderUnitSymbol, renderUnitSyntax, Unit } from "@/control/units"; export const previewSeparator = undefined; type PreviewSeparator = typeof previewSeparator; -type PresetPreviewEntry = { +type PresetPreviewEntry = { name: string; unit?: Unit; - renderValue: (data: PresetData) => string | undefined; + renderValue: (data: T) => string | undefined; }; -export type PresetPreviewEntries = ( +export type PresetPreviewEntries = ( | PresetPreviewEntry | PreviewSeparator )[]; -export type PresetPreviewTableProps = { - data: PresetData; +export type PresetPreviewTableProps = { + data?: T; entries: PresetPreviewEntries; }; -export function PresetPreviewTable({ +export function PresetPreviewTable({ data, entries, }: PresetPreviewTableProps) { @@ -39,7 +38,7 @@ export function PresetPreviewTable({ ); } - const value = entry.renderValue(data); + const value = data !== undefined ? entry.renderValue(data) : undefined; return (
{entry.name}
diff --git a/electron/src/components/preset/PresetShowDialog.tsx b/electron/src/components/preset/PresetShowDialog.tsx index e00a80ebe..cc418884e 100644 --- a/electron/src/components/preset/PresetShowDialog.tsx +++ b/electron/src/components/preset/PresetShowDialog.tsx @@ -1,4 +1,4 @@ -import { Preset, PresetSchema } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; import { Dialog, DialogContent, @@ -13,14 +13,14 @@ import { Icon } from "../Icon"; import { Separator } from "../ui/separator"; import { PresetPreviewEntries, PresetPreviewTable } from "./PresetPreviewTable"; -export type PresetShowDialogProps = { +export type PresetShowDialogProps = { preset: Preset; previewEntries: PresetPreviewEntries; onApply: (preset: Preset) => void; hideDate?: boolean; }; -export function PresetShowDialog({ +export function PresetShowDialog({ preset, onApply, previewEntries, diff --git a/electron/src/components/preset/PresetsPage.tsx b/electron/src/components/preset/PresetsPage.tsx index c4c954a14..4911ed60a 100644 --- a/electron/src/components/preset/PresetsPage.tsx +++ b/electron/src/components/preset/PresetsPage.tsx @@ -2,19 +2,19 @@ import React from "react"; import { ControlGrid } from "@/control/ControlGrid"; import { Page } from "@/components/Page"; import { usePresets, UsePresetsParams } from "@/lib/preset/usePresets"; -import { Preset, PresetSchema } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; import { PresetCard } from "./PresetCard"; import { PresetPreviewEntries } from "./PresetPreviewTable"; import { NewPresetDialog } from "./NewPresetDialog"; import { downloadJson } from "@/lib/download"; import { JsonFileInput } from "../FileInput"; -type PresetsPageProps = UsePresetsParams & { +type PresetsPageProps = UsePresetsParams & { applyPreset: (preset: Preset) => void; previewEntries: PresetPreviewEntries; }; -export function PresetsPage({ +export function PresetsPage({ applyPreset, machine_identification, currentState, diff --git a/electron/src/control/EditValue.tsx b/electron/src/control/EditValue.tsx index 5716ec016..940a98ee9 100644 --- a/electron/src/control/EditValue.tsx +++ b/electron/src/control/EditValue.tsx @@ -36,7 +36,6 @@ type Props = { maxSlider?: number; // Override the slider max value maxLabel?: string; step?: number; - valueSchema?: z.ZodType; inverted?: boolean; confirmation?: string; renderValue: (value: number) => string; @@ -89,7 +88,6 @@ export function EditValue({ description, defaultValue, step = 1, - valueSchema: schema, inverted, min, max, @@ -104,7 +102,7 @@ export function EditValue({ // Form setup const formSchema = z.object({ - value: schema ?? z.number(), + value: z.number(), }); type FormSchema = z.infer; @@ -191,7 +189,6 @@ export function EditValue({ const numericValue = parseFloat(normalizedInput); const hasValidationError = isNaN(numericValue) || - (schema && !schema.safeParse(numericValue).success) || (max !== undefined && numericValue > max) || (min !== undefined && numericValue < min); @@ -222,15 +219,7 @@ export function EditValue({ setValueStringError(false); preventFormSyncRef.current = false; } - }, [ - valueString, - valueStringDirty, - schema, - max, - min, - form, - roundToStepDecimals, - ]); + }, [valueString, valueStringDirty, max, min, form, roundToStepDecimals]); // Reset input state to clean form value const resetInput = React.useCallback(() => { diff --git a/electron/src/lib/objects.ts b/electron/src/lib/objects.ts index d538b96b1..fb878ff77 100644 --- a/electron/src/lib/objects.ts +++ b/electron/src/lib/objects.ts @@ -1,4 +1,7 @@ -export function deepEquals(a: T, b: T): boolean { +export function deepEquals( + a: object | undefined, + b: object | undefined, +): boolean { if (a === b) { return true; } diff --git a/electron/src/lib/preset/preset.ts b/electron/src/lib/preset/preset.ts index 39a0ef422..3c8b9f4c0 100644 --- a/electron/src/lib/preset/preset.ts +++ b/electron/src/lib/preset/preset.ts @@ -1,20 +1,16 @@ import { machineIdentification } from "@/machines/types"; import { z } from "zod"; -export type PresetSchema = z.ZodTypeAny; +export type PresetSchema = z.ZodType; -export const presetSchema = (dataSchema: S) => +export const presetSchema = (dataSchema: PresetSchema) => z.object({ id: z.number().int().nonnegative().optional(), name: z.string().nonempty(), lastModified: z.coerce.date(), machineIdentification, schemaVersion: z.number().int().positive(), - data: dataSchema, + data: dataSchema.optional(), }); -export type Preset = z.infer< - ReturnType> ->; - -export type PresetData = z.infer; +export type Preset = z.infer>>; diff --git a/electron/src/lib/preset/presetStore.ts b/electron/src/lib/preset/presetStore.ts index fad8f1d72..6ef9efa88 100644 --- a/electron/src/lib/preset/presetStore.ts +++ b/electron/src/lib/preset/presetStore.ts @@ -1,6 +1,6 @@ import { create } from "zustand"; import { persist, PersistStorage, StorageValue } from "zustand/middleware"; -import { Preset, PresetSchema, presetSchema } from "./preset"; +import { Preset, presetSchema } from "./preset"; import { MachineIdentification } from "@/machines/types"; import { z } from "zod"; import { toastError } from "@/components/Toast"; @@ -33,9 +33,9 @@ type PresetStoreData = { }; export type PresetStore = PresetStoreData & { - insert: (preset: Preset) => PersistedPreset; - update: (preset: Preset) => void; - remove: (preset: Preset) => void; + insert: (preset: Preset) => PersistedPreset; + update: (preset: Preset) => void; + remove: (preset: Preset) => void; getById: (id: number) => PersistedPreset | undefined; setLatestPresetId: ( @@ -100,7 +100,7 @@ export const usePresetStore = create()( presets: [], latestPresetIds: new Map(), - insert: (preset: Preset) => { + insert: (preset: Preset) => { const state = get(); const { presets } = state; const ids = presets.map((p: PersistedPreset) => p.id); @@ -115,7 +115,7 @@ export const usePresetStore = create()( return persistedPreset; }, - update: (preset: Preset) => { + update: (preset: Preset) => { const state = get(); const presets: PersistedPreset[] = state.presets.map( (p: PersistedPreset) => @@ -124,7 +124,7 @@ export const usePresetStore = create()( set({ ...state, presets }); }, - remove: (preset: Preset) => { + remove: (preset: Preset) => { const state = get(); const presets = state.presets.filter( (p: Preset) => p.id !== preset.id, diff --git a/electron/src/lib/preset/usePresets.ts b/electron/src/lib/preset/usePresets.ts index 11bc1c841..f9bf201d6 100644 --- a/electron/src/lib/preset/usePresets.ts +++ b/electron/src/lib/preset/usePresets.ts @@ -3,13 +3,13 @@ import { machineIdentificationEquals, } from "@/machines/types"; import { usePresetStore } from "./presetStore"; -import { Preset, PresetData, presetSchema, PresetSchema } from "./preset"; +import { Preset, presetSchema, PresetSchema } from "./preset"; import { deepEquals } from "@/lib/objects"; import { useEffect } from "react"; import { toastError } from "@/components/Toast"; import { z } from "zod"; -export type Presets = { +export type Presets = { get: () => Preset[]; createFromCurrentState: (name: string) => Preset; updateFromCurrentState: (preset: Preset) => Preset; @@ -20,15 +20,15 @@ export type Presets = { import: (json: any) => void; }; -export type UsePresetsParams = { +export type UsePresetsParams = { machine_identification: MachineIdentification; - schemas: Map; + schemas: Map>; schemaVersion: number; - currentState?: PresetData; - defaultState?: PresetData; + currentState?: T; + defaultState?: T; }; -export function usePresets({ +export function usePresets({ machine_identification, schemas, schemaVersion, @@ -49,7 +49,10 @@ export function usePresets({ } try { - const parsed = presetSchema(schema).parse(preset); + const parsed: Preset = { + ...preset, + data: schema.parse(preset.data), + }; if (parsed.schemaVersion < schemaVersion) { parsed.schemaVersion = schemaVersion; @@ -93,7 +96,11 @@ export function usePresets({ return { ...preset, data: currentState }; }; - const updateFromCurrentState = (preset: Preset) => { + const updateFromCurrentState = (preset: Preset): Preset => { + if (!currentState) { + return preset; + } + const data = currentState; const newPreset = { @@ -153,12 +160,16 @@ export function usePresets({ }; const isActive = (preset: Preset) => { - return deepEquals(currentState, preset.data); + if (!currentState) { + return false; + } + + return deepEquals(currentState, preset.data ?? {}); }; const importPreset = (json: any) => { try { - const anyPreset = presetSchema(z.any()).parse(json); + const anyPreset = presetSchema(z.object()).parse(json); if ( !machineIdentificationEquals( diff --git a/electron/src/lib/types.ts b/electron/src/lib/types.ts index 3329c6b70..cac7154bb 100644 --- a/electron/src/lib/types.ts +++ b/electron/src/lib/types.ts @@ -9,18 +9,18 @@ import { z } from "zod"; */ export function rustEnumSchema>( schemas: T, -): z.ZodType<{ [K in keyof T]?: z.infer }> { +) { // Create an object schema where all properties are optional const schemaEntries = Object.entries(schemas).map(([key, schema]) => [ key, schema.optional(), ]); - const objectSchema = z.object( - Object.fromEntries(schemaEntries) as { + const objectSchema = z.object({ + ...(schemaEntries as { [K in keyof T]: z.ZodOptional; - }, - ); + }), + }); // Add refinement to ensure exactly one property is defined return objectSchema.refine( diff --git a/electron/src/lib/validation.ts b/electron/src/lib/validation.ts deleted file mode 100644 index 955b47cb1..000000000 --- a/electron/src/lib/validation.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod"; - -// super refine function to validate if a string is a valid u16 number -export function validateU16(): (value: T, ctx: z.RefinementCtx) => boolean { - const refine = (value: T, ctx: z.RefinementCtx) => { - console.log("value", value); - if (typeof value === "string") { - const number = parseInt(value, 10); - if (number < 0 || number > 65535) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Wert muss u16 integer sein", - }); - } - } - return true; - }; - return refine; -} diff --git a/electron/src/machines/extruder/extruder2/Extruder2PresetsPage.tsx b/electron/src/machines/extruder/extruder2/Extruder2PresetsPage.tsx index a2830e94b..c96853f92 100644 --- a/electron/src/machines/extruder/extruder2/Extruder2PresetsPage.tsx +++ b/electron/src/machines/extruder/extruder2/Extruder2PresetsPage.tsx @@ -7,7 +7,7 @@ import { PresetPreviewEntries, previewSeparator, } from "@/components/preset/PresetPreviewTable"; -import { Preset, PresetData } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; const extruder1PresetDataSchema = z .object({ @@ -31,7 +31,7 @@ const extruder1PresetDataSchema = z }) .partial(); -type Extruder2 = typeof extruder1PresetDataSchema; +type Extruder2 = z.infer; const schemas = new Map([[1, extruder1PresetDataSchema]]); @@ -39,76 +39,69 @@ const previewEntries: PresetPreviewEntries = [ { name: "Target Front Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder2) => data.targetFrontHeatingTemperature?.toFixed(1), }, { name: "Target Middle Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder2) => data.targetMiddleHeatingTemperature?.toFixed(1), }, { name: "Target Back Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder2) => data.targetBackHeatingTemperature?.toFixed(1), }, { name: "Target Nozzle Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder2) => data.targetNozzleHeatingTemperature?.toFixed(1), }, previewSeparator, { name: "Inverter Regulation", - renderValue: (data: PresetData) => data.inverterRegulation, + renderValue: (data: Extruder2) => data.inverterRegulation, }, { name: "Target Inverter RPM", unit: "rpm", - renderValue: (data: PresetData) => - data.targetInverterRpm?.toFixed(2), + renderValue: (data: Extruder2) => data.targetInverterRpm?.toFixed(2), }, { name: "Target Inverter Pressure", unit: "bar", - renderValue: (data: PresetData) => - data.targetInverterPressure?.toFixed(1), + renderValue: (data: Extruder2) => data.targetInverterPressure?.toFixed(1), }, { name: "Inverter Direction", - renderValue: (data: PresetData) => - data.inverterRotationDirection, + renderValue: (data: Extruder2) => data.inverterRotationDirection, }, previewSeparator, { name: "Pressure Limit", unit: "bar", - renderValue: (data: PresetData) => - data.pressureLimit?.toFixed(1), + renderValue: (data: Extruder2) => data.pressureLimit?.toFixed(1), }, { name: "Enable Pressure Limit", - renderValue: (data: PresetData) => + renderValue: (data: Extruder2) => data.pressureLimitEnabled ? "on" : "off", }, previewSeparator, { name: "PID Pressue Kp", - renderValue: (data: PresetData) => - data.pidPressureKp?.toFixed(4), + renderValue: (data: Extruder2) => data.pidPressureKp?.toFixed(4), }, { name: "PID Pressue Ki", - renderValue: (data: PresetData) => - data.pidPressureKi?.toFixed(4), + renderValue: (data: Extruder2) => data.pidPressureKi?.toFixed(4), }, { name: "PID Pressue Kd", - renderValue: (data: PresetData) => - data.pidPressureKd?.toFixed(4), + renderValue: (data: Extruder2) => data.pidPressureKd?.toFixed(4), }, ]; @@ -135,7 +128,7 @@ export function Extruder2PresetsPage() { setPressurePidKp, } = useExtruder2(); - const toPresetData = (s?: typeof state): PresetData => ({ + const toPresetData = (s?: typeof state): Extruder2 => ({ targetFrontHeatingTemperature: s?.heating_states.front.target_temperature, targetMiddleHeatingTemperature: s?.heating_states.middle.target_temperature, targetBackHeatingTemperature: s?.heating_states.back.target_temperature, @@ -161,32 +154,32 @@ export function Extruder2PresetsPage() { const applyPreset = (preset: Preset) => { setFrontHeatingTemperature( - preset.data.targetFrontHeatingTemperature ?? 150.0, + preset?.data?.targetFrontHeatingTemperature ?? 150.0, ); setMiddleHeatingTemperature( - preset.data.targetMiddleHeatingTemperature ?? 150.0, + preset?.data?.targetMiddleHeatingTemperature ?? 150.0, ); setBackHeatingTemperature( - preset.data.targetBackHeatingTemperature ?? 150.0, + preset?.data?.targetBackHeatingTemperature ?? 150.0, ); setNozzleHeatingTemperature( - preset.data.targetNozzleHeatingTemperature ?? 150.0, + preset?.data?.targetNozzleHeatingTemperature ?? 150.0, ); - setInverterTargetRpm(preset.data.targetInverterRpm ?? 0); - setInverterTargetPressure(preset.data.targetInverterPressure ?? 0); - setInverterRegulation(preset.data.inverterRegulation === "RPM"); + setInverterTargetRpm(preset?.data?.targetInverterRpm ?? 0); + setInverterTargetPressure(preset?.data?.targetInverterPressure ?? 0); + setInverterRegulation(preset?.data?.inverterRegulation === "RPM"); setInverterRotationDirection( - preset.data.inverterRotationDirection === "Forward", + preset?.data?.inverterRotationDirection === "Forward", ); - setExtruderPressureLimit(preset.data.pressureLimit ?? 100.0); - setExtruderPressureLimitEnabled(preset.data.pressureLimitEnabled ?? true); + setExtruderPressureLimit(preset?.data?.pressureLimit ?? 100.0); + setExtruderPressureLimitEnabled(preset?.data?.pressureLimitEnabled ?? true); - setPressurePidKp(preset.data.pidPressureKp ?? 0.16); - setPressurePidKi(preset.data.pidPressureKi ?? 0.0); - setPressurePidKd(preset.data.pidPressureKd ?? 0.008); + setPressurePidKp(preset?.data?.pidPressureKp ?? 0.16); + setPressurePidKi(preset?.data?.pidPressureKi ?? 0.0); + setPressurePidKd(preset?.data?.pidPressureKd ?? 0.008); }; return ( diff --git a/electron/src/machines/extruder/extruder3/Extruder3PresetsPage.tsx b/electron/src/machines/extruder/extruder3/Extruder3PresetsPage.tsx index 64f83ff77..932b33646 100644 --- a/electron/src/machines/extruder/extruder3/Extruder3PresetsPage.tsx +++ b/electron/src/machines/extruder/extruder3/Extruder3PresetsPage.tsx @@ -7,7 +7,7 @@ import { PresetPreviewEntries, previewSeparator, } from "@/components/preset/PresetPreviewTable"; -import { Preset, PresetData } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; const extruder3PresetDataSchema = z .object({ @@ -31,7 +31,7 @@ const extruder3PresetDataSchema = z }) .partial(); -type Extruder3 = typeof extruder3PresetDataSchema; +type Extruder3 = z.infer; const schemas = new Map([[1, extruder3PresetDataSchema]]); @@ -39,76 +39,69 @@ const previewEntries: PresetPreviewEntries = [ { name: "Target Front Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder3) => data.targetFrontHeatingTemperature?.toFixed(1), }, { name: "Target Middle Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder3) => data.targetMiddleHeatingTemperature?.toFixed(1), }, { name: "Target Back Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder3) => data.targetBackHeatingTemperature?.toFixed(1), }, { name: "Target Nozzle Temperature", unit: "C", - renderValue: (data: PresetData) => + renderValue: (data: Extruder3) => data.targetNozzleHeatingTemperature?.toFixed(1), }, previewSeparator, { name: "Inverter Regulation", - renderValue: (data: PresetData) => data.inverterRegulation, + renderValue: (data: Extruder3) => data.inverterRegulation, }, { name: "Target Inverter RPM", unit: "rpm", - renderValue: (data: PresetData) => - data.targetInverterRpm?.toFixed(2), + renderValue: (data: Extruder3) => data.targetInverterRpm?.toFixed(2), }, { name: "Target Inverter Pressure", unit: "bar", - renderValue: (data: PresetData) => - data.targetInverterPressure?.toFixed(1), + renderValue: (data: Extruder3) => data.targetInverterPressure?.toFixed(1), }, { name: "Inverter Direction", - renderValue: (data: PresetData) => - data.inverterRotationDirection, + renderValue: (data: Extruder3) => data.inverterRotationDirection, }, previewSeparator, { name: "Pressure Limit", unit: "bar", - renderValue: (data: PresetData) => - data.pressureLimit?.toFixed(1), + renderValue: (data: Extruder3) => data.pressureLimit?.toFixed(1), }, { name: "Enable Pressure Limit", - renderValue: (data: PresetData) => + renderValue: (data: Extruder3) => data.pressureLimitEnabled ? "on" : "off", }, previewSeparator, { name: "PID Pressue Kp", - renderValue: (data: PresetData) => - data.pidPressureKp?.toFixed(4), + renderValue: (data: Extruder3) => data.pidPressureKp?.toFixed(4), }, { name: "PID Pressue Ki", - renderValue: (data: PresetData) => - data.pidPressureKi?.toFixed(4), + renderValue: (data: Extruder3) => data.pidPressureKi?.toFixed(4), }, { name: "PID Pressue Kd", - renderValue: (data: PresetData) => - data.pidPressureKd?.toFixed(4), + renderValue: (data: Extruder3) => data.pidPressureKd?.toFixed(4), }, ]; @@ -135,7 +128,7 @@ export function Extruder3PresetsPage() { setPressurePidKp, } = useExtruder3(); - const toPresetData = (s?: typeof state): PresetData => ({ + const toPresetData = (s?: typeof state): Extruder3 => ({ targetFrontHeatingTemperature: s?.heating_states.front.target_temperature, targetMiddleHeatingTemperature: s?.heating_states.middle.target_temperature, targetBackHeatingTemperature: s?.heating_states.back.target_temperature, @@ -161,32 +154,32 @@ export function Extruder3PresetsPage() { const applyPreset = (preset: Preset) => { setFrontHeatingTemperature( - preset.data.targetFrontHeatingTemperature ?? 150.0, + preset?.data?.targetFrontHeatingTemperature ?? 150.0, ); setMiddleHeatingTemperature( - preset.data.targetMiddleHeatingTemperature ?? 150.0, + preset?.data?.targetMiddleHeatingTemperature ?? 150.0, ); setBackHeatingTemperature( - preset.data.targetBackHeatingTemperature ?? 150.0, + preset?.data?.targetBackHeatingTemperature ?? 150.0, ); setNozzleHeatingTemperature( - preset.data.targetNozzleHeatingTemperature ?? 150.0, + preset?.data?.targetNozzleHeatingTemperature ?? 150.0, ); - setInverterTargetRpm(preset.data.targetInverterRpm ?? 0); - setInverterTargetPressure(preset.data.targetInverterPressure ?? 0); - setInverterRegulation(preset.data.inverterRegulation === "RPM"); + setInverterTargetRpm(preset?.data?.targetInverterRpm ?? 0); + setInverterTargetPressure(preset?.data?.targetInverterPressure ?? 0); + setInverterRegulation(preset?.data?.inverterRegulation === "RPM"); setInverterRotationDirection( - preset.data.inverterRotationDirection === "Forward", + preset?.data?.inverterRotationDirection === "Forward", ); - setExtruderPressureLimit(preset.data.pressureLimit ?? 100.0); - setExtruderPressureLimitEnabled(preset.data.pressureLimitEnabled ?? true); + setExtruderPressureLimit(preset?.data?.pressureLimit ?? 100.0); + setExtruderPressureLimitEnabled(preset?.data?.pressureLimitEnabled ?? true); - setPressurePidKp(preset.data.pidPressureKp ?? 0.16); - setPressurePidKi(preset.data.pidPressureKi ?? 0.0); - setPressurePidKd(preset.data.pidPressureKd ?? 0.008); + setPressurePidKp(preset?.data?.pidPressureKp ?? 0.16); + setPressurePidKi(preset?.data?.pidPressureKi ?? 0.0); + setPressurePidKd(preset?.data?.pidPressureKd ?? 0.008); }; return ( diff --git a/electron/src/machines/laser/laser1/Laser1PresetsPage.tsx b/electron/src/machines/laser/laser1/Laser1PresetsPage.tsx index ef4534b3a..4faa78132 100644 --- a/electron/src/machines/laser/laser1/Laser1PresetsPage.tsx +++ b/electron/src/machines/laser/laser1/Laser1PresetsPage.tsx @@ -1,7 +1,7 @@ import React from "react"; import { z } from "zod"; import { useLaser1 } from "./useLaser1"; -import { Preset, PresetData } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; import { laser1 } from "@/machines/properties"; import { PresetPreviewEntries } from "@/components/preset/PresetPreviewTable"; import { PresetsPage } from "@/components/preset/PresetsPage"; @@ -14,7 +14,7 @@ const laser1PresetDataSchema = z }) .partial(); -type Laser1 = typeof laser1PresetDataSchema; +type Laser1 = z.infer; const schemas = new Map([[1, laser1PresetDataSchema]]); @@ -22,18 +22,17 @@ const previewEntries: PresetPreviewEntries = [ { name: "Target Diameter", unit: "mm", - renderValue: (data: PresetData) => data?.targetDiameter?.toFixed(3), + renderValue: (data: Laser1) => data?.targetDiameter?.toFixed(3), }, { name: "Lower Tolerance", unit: "mm", - renderValue: (data: PresetData) => data?.lowerTolerance?.toFixed(3), + renderValue: (data: Laser1) => data?.lowerTolerance?.toFixed(3), }, { name: "Higher Tolerance", unit: "mm", - renderValue: (data: PresetData) => - data?.higherTolerance?.toFixed(3), + renderValue: (data: Laser1) => data?.higherTolerance?.toFixed(3), }, ]; @@ -47,16 +46,16 @@ export function Laser1PresetsPage() { } = useLaser1(); const applyPreset = (preset: Preset) => { - const targetDiameter = preset.data.targetDiameter ?? 1.75; - const lowerTolerance = preset.data?.lowerTolerance ?? 0.05; - const higherTolerance = preset.data?.higherTolerance ?? 0.05; + const targetDiameter = preset?.data?.targetDiameter ?? 1.75; + const lowerTolerance = preset?.data?.lowerTolerance ?? 0.05; + const higherTolerance = preset?.data?.higherTolerance ?? 0.05; setTargetDiameter(targetDiameter); setLowerTolerance(lowerTolerance); setHigherTolerance(higherTolerance); }; - const toPresetData = (s: typeof state): PresetData => ({ + const toPresetData = (s: typeof state): Laser1 => ({ targetDiameter: s?.laser_state.target_diameter, lowerTolerance: s?.laser_state.lower_tolerance, higherTolerance: s?.laser_state.higher_tolerance, diff --git a/electron/src/machines/mock/mock1/Mock1PresetsPage.tsx b/electron/src/machines/mock/mock1/Mock1PresetsPage.tsx index 748e5f5be..3e960d2c3 100644 --- a/electron/src/machines/mock/mock1/Mock1PresetsPage.tsx +++ b/electron/src/machines/mock/mock1/Mock1PresetsPage.tsx @@ -3,7 +3,7 @@ import { useMock1 } from "./useMock"; import { mock1 } from "@/machines/properties"; import { PresetsPage } from "@/components/preset/PresetsPage"; -import { Preset, PresetData } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; import { PresetPreviewEntries } from "@/components/preset/PresetPreviewTable"; import { z } from "zod"; @@ -15,7 +15,7 @@ const mock1PresetDataSchema = z }) .partial(); -type Mock1 = typeof mock1PresetDataSchema; +type Mock1 = z.infer; const schemas = new Map([[1, mock1PresetDataSchema]]); @@ -23,17 +23,17 @@ const previewEntries: PresetPreviewEntries = [ { name: "Frequency 1", unit: "mHz", - renderValue: (data: PresetData) => data?.frequency1?.toFixed(3), + renderValue: (data: Mock1) => data?.frequency1?.toFixed(3), }, { name: "Frequency 2", unit: "mHz", - renderValue: (data: PresetData) => data?.frequency2?.toFixed(3), + renderValue: (data: Mock1) => data?.frequency2?.toFixed(3), }, { name: "Frequency 3", unit: "mHz", - renderValue: (data: PresetData) => data?.frequency3?.toFixed(3), + renderValue: (data: Mock1) => data?.frequency3?.toFixed(3), }, ]; @@ -51,7 +51,7 @@ export function Mock1PresetsPage() { setFrequency3(frequency3); }; - const toPresetData = (s: typeof state): PresetData => ({ + const toPresetData = (s: typeof state): Mock1 => ({ frequency1: s?.frequency1 ?? defaultState?.frequency1, frequency2: s?.frequency2 ?? defaultState?.frequency2, frequency3: s?.frequency3 ?? defaultState?.frequency3, diff --git a/electron/src/machines/winder/winder2/Winder2PresetsPage.tsx b/electron/src/machines/winder/winder2/Winder2PresetsPage.tsx index 3513b7c64..f1ab761de 100644 --- a/electron/src/machines/winder/winder2/Winder2PresetsPage.tsx +++ b/electron/src/machines/winder/winder2/Winder2PresetsPage.tsx @@ -3,7 +3,7 @@ import { useWinder2 } from "./useWinder"; import { winder2 } from "@/machines/properties"; import { PresetsPage } from "@/components/preset/PresetsPage"; -import { Preset, PresetData } from "@/lib/preset/preset"; +import { Preset } from "@/lib/preset/preset"; import { pullerStateSchema, spoolSpeedControllerStateSchema, @@ -16,19 +16,21 @@ import { const winder2PresetDataSchema = z .object({ - traverse_state: z.object({ - limit_inner: z.number(), - limit_outer: z.number(), - step_size: z.number(), - padding: z.number(), - laserpointer: z.boolean(), - }), - puller_state: pullerStateSchema, - spool_speed_controller_state: spoolSpeedControllerStateSchema, + traverse_state: z + .object({ + limit_inner: z.number(), + limit_outer: z.number(), + step_size: z.number(), + padding: z.number(), + laserpointer: z.boolean(), + }) + .partial(), + puller_state: pullerStateSchema.partial(), + spool_speed_controller_state: spoolSpeedControllerStateSchema.partial(), }) - .deepPartial(); + .partial(); -type Winder2 = typeof winder2PresetDataSchema; +type Winder2 = z.infer; const schemas = new Map([[1, winder2PresetDataSchema]]); @@ -36,40 +38,39 @@ const previewEntries: PresetPreviewEntries = [ { name: "Inner Traverse Limit", unit: "mm", - renderValue: (data: PresetData) => - data?.traverse_state?.limit_inner?.toFixed(1) ?? "N/A", + renderValue: (data: Winder2) => + data.traverse_state?.limit_inner?.toFixed(1) ?? "N/A", }, { name: "Outer Traverse Limit", unit: "mm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data?.traverse_state?.limit_outer?.toFixed(1) ?? "N/A", }, { name: "Traverse Step Size", unit: "mm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data?.traverse_state?.step_size?.toFixed(1) ?? "N/A", }, { name: "Traverse Padding", unit: "mm", - renderValue: (data: PresetData) => - data?.traverse_state?.padding?.toFixed(1), + renderValue: (data: Winder2) => data?.traverse_state?.padding?.toFixed(1), }, previewSeparator, { name: "Puller Regulation", - renderValue: (data: PresetData) => data?.puller_state?.regulation, + renderValue: (data: Winder2) => data?.puller_state?.regulation, }, { name: "Puller Direction", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.puller_state?.forward ? "Forward" : "Backward", }, { name: "Puller Gear Ratio", - renderValue: (data: PresetData) => { + renderValue: (data: Winder2) => { const ratio = data.puller_state?.gear_ratio; if (ratio === "OneToOne") return "1:1"; if (ratio === "OneToFive") return "1:5"; @@ -80,74 +81,73 @@ const previewEntries: PresetPreviewEntries = [ { name: "Puller Target Speed", unit: "m/min", - renderValue: (data: PresetData) => - data.puller_state?.target_speed?.toFixed(2), + renderValue: (data: Winder2) => data.puller_state?.target_speed?.toFixed(2), }, { name: "Puller Target Diameter", unit: "mm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.puller_state?.target_diameter?.toFixed(1), }, { name: "Puller Target Diameter", unit: "mm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.puller_state?.target_diameter?.toFixed(1), }, previewSeparator, { name: "Spool Regulation", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.regulation_mode, }, { name: "Spool Direction", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.forward ? "Forward" : "Reverse", }, { name: "Spool Min Speed", unit: "rpm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.minmax_min_speed?.toFixed(2), }, { name: "Spool Max Speed", unit: "rpm", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.minmax_max_speed?.toFixed(2), }, previewSeparator, { name: "Adaptive Spool Tension Target", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.adaptive_tension_target?.toFixed(2), }, { name: "Adaptive Spool Learning Rate", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.adaptive_radius_learning_rate?.toFixed( 2, ), }, { name: "Adaptive Spool Max Speed Multiplier", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.adaptive_max_speed_multiplier?.toFixed( 1, ), }, { name: "Adaptive Spool Acceleration Factor", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.adaptive_acceleration_factor?.toFixed( 2, ), }, { name: "Adaptive Spool Deaccel. Urgency", - renderValue: (data: PresetData) => + renderValue: (data: Winder2) => data.spool_speed_controller_state?.adaptive_deacceleration_urgency_multiplier?.toFixed( 1, ), @@ -230,11 +230,11 @@ export function Winder2PresetsPage() { // ); enableTraverseLaserpointer( - preset.data.traverse_state?.laserpointer ?? false, + preset.data?.traverse_state?.laserpointer ?? false, ); }; - const toPresetData = (s: typeof state): PresetData => ({ + const toPresetData = (s: typeof state): Winder2 => ({ traverse_state: { limit_inner: s?.traverse_state?.limit_inner, limit_outer: s?.traverse_state?.limit_outer, diff --git a/electron/src/routes/routes.tsx b/electron/src/routes/routes.tsx index c3e678b70..5486f2bf4 100644 --- a/electron/src/routes/routes.tsx +++ b/electron/src/routes/routes.tsx @@ -4,7 +4,6 @@ import React from "react"; import { z } from "zod"; import { ChooseVersionPage } from "@/setup/ChooseVersionPage"; -import { fallback, zodValidator } from "@tanstack/zod-adapter"; import { githubSourceSchema } from "@/setup/GithubSourceDialog"; import { SidebarLayout } from "@/components/SidebarLayout"; import { SetupPage } from "@/setup/SetupPage"; @@ -381,9 +380,9 @@ export const metricsRoute = createRoute({ export const versionSearchSchema = z .object({ - branch: fallback(z.string().optional(), undefined), - commit: fallback(z.string().optional(), undefined), - tag: fallback(z.string().optional(), undefined), + branch: z.string().optional(), + commit: z.string().optional(), + tag: z.string().optional(), }) .merge(githubSourceSchema) .refine( @@ -405,14 +404,14 @@ export const updateChangelogRoute = createRoute({ getParentRoute: () => updateRoute, path: "changelog", component: () => , - validateSearch: zodValidator(versionSearchSchema), + validateSearch: versionSearchSchema, }); export const updateExecuteRoute = createRoute({ getParentRoute: () => updateRoute, path: "execute", component: () => , - validateSearch: zodValidator(versionSearchSchema), + validateSearch: versionSearchSchema, }); export const rootTree = RootRoute.addChildren([ diff --git a/electron/src/setup/DeviceEepromDialog.tsx b/electron/src/setup/DeviceEepromDialog.tsx index 55ff10347..354a7bc5c 100644 --- a/electron/src/setup/DeviceEepromDialog.tsx +++ b/electron/src/setup/DeviceEepromDialog.tsx @@ -37,7 +37,6 @@ import { SelectValue, } from "@/components/ui/select"; import { useFormValues } from "@/lib/useFormValues"; -import { validateU16 } from "@/lib/validation"; import { DeviceRoleComponent } from "@/components/DeviceRole"; import { Alert } from "@/components/Alert"; import { Separator } from "@/components/ui/separator"; @@ -54,9 +53,15 @@ type Props = { }; const formSchema = z.object({ - machine: z.string().superRefine(validateU16), - serial: z.string().superRefine(validateU16), - role: z.string().superRefine(validateU16), + machine: z + .string() + .refine((v) => parseInt(v) < 0xffff, { error: "Value too big" }), + serial: z + .string() + .refine((v) => parseInt(v) < 0xffff, { error: "Value too big" }), + role: z + .string() + .refine((v) => parseInt(v) < 0xffff, { error: "Value too big" }), }); type FormSchema = z.infer; diff --git a/electron/src/setup/GithubSourceDialog.tsx b/electron/src/setup/GithubSourceDialog.tsx index 27fb4f86d..3be0af008 100644 --- a/electron/src/setup/GithubSourceDialog.tsx +++ b/electron/src/setup/GithubSourceDialog.tsx @@ -24,7 +24,6 @@ import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { Icon } from "@/components/Icon"; import { TouchButton } from "@/components/touch/TouchButton"; -import { fallback } from "@tanstack/zod-adapter"; type Props = { value: GithubSource; @@ -32,9 +31,9 @@ type Props = { }; export const githubSourceSchema = z.object({ - githubRepoOwner: fallback(z.string(), "qitechgmbh"), - githubRepoName: fallback(z.string(), "control"), - githubToken: fallback(z.string().optional().nullable(), undefined), + githubRepoOwner: z.string().catch("qitechgmbh"), + githubRepoName: z.string().catch("control"), + githubToken: z.string().optional(), }); export type GithubSource = z.infer; @@ -91,7 +90,7 @@ export function GithubSourceDialogContent({ const onSubmit = (values: GithubSource) => { onChange({ ...values, - githubToken: values.githubToken === "" ? null : values.githubToken, + githubToken: values.githubToken === "" ? undefined : values.githubToken, }); setOpen(false); }; diff --git a/nixos/packages/electron.nix b/nixos/packages/electron.nix index fa952ef4b..26798a518 100644 --- a/nixos/packages/electron.nix +++ b/nixos/packages/electron.nix @@ -10,7 +10,7 @@ buildNpmPackage rec { ELECTRON_SKIP_BINARY_DOWNLOAD = 1; makeCacheWritable = true; - npmDepsHash = "sha256-gk/YC3+gc5DVvPS4ght9WmFcuc2FAX/UB+lIuQn436U="; + npmDepsHash = "sha256-+3dM745XNntgu6M5DQxb5Bsda8z/Q+55CRll+mIrN+k="; npmFlags = [ "--no-audit" "--no-fund" ]; installPhase = ''