diff --git a/src/components/widgets/filesystem/FileSystemGoToFileDialog.vue b/src/components/widgets/filesystem/FileSystemGoToFileDialog.vue index f92c0d55c6..d477c00d2e 100644 --- a/src/components/widgets/filesystem/FileSystemGoToFileDialog.vue +++ b/src/components/widgets/filesystem/FileSystemGoToFileDialog.vue @@ -65,7 +65,7 @@ export default class FileSystemGoToFileDialog extends Mixins(StateMixin) { search = '' loaded = false - get rootFiles (): Moonraker.Files.RootFile[] | undefined { + get rootFiles (): readonly Moonraker.Files.RootFile[] | undefined { return this.$typedGetters['files/getRootFiles'](this.root) } diff --git a/src/store/console/mutations.ts b/src/store/console/mutations.ts index 400e40b78d..5e28d1eba0 100644 --- a/src/store/console/mutations.ts +++ b/src/store/console/mutations.ts @@ -75,7 +75,7 @@ export const mutations = { * Defines the list of available commands */ setGcodeHelp (state, payload: Moonraker.KlippyApis.GcodeHelpResponse) { - state.gcodeHelp = payload + state.gcodeHelp = Object.freeze(payload) }, /** diff --git a/src/store/console/types.ts b/src/store/console/types.ts index 2eddc92581..e433e2a2d7 100644 --- a/src/store/console/types.ts +++ b/src/store/console/types.ts @@ -1,9 +1,8 @@ export interface ConsoleState { - // [key: string]: string; consoleCommand: string; consoleSearch: string; - console: ConsoleEntry[]; // console stream - gcodeHelp: Moonraker.KlippyApis.GcodeHelpResponse; // known commands + console: Readonly[]; // console stream + gcodeHelp: Readonly; // known commands consoleEntryCount: number; // give each console entry a unique id. commandHistory: string[]; autoScroll: boolean; diff --git a/src/store/files/mutations.ts b/src/store/files/mutations.ts index d966e69ecd..7d115de0fb 100644 --- a/src/store/files/mutations.ts +++ b/src/store/files/mutations.ts @@ -28,17 +28,25 @@ export const mutations = { setServerFilesGetDirectory (state, payload: { path: string, content: MoonrakerPathContent }) { const { path, content } = payload - Vue.set(state.pathContent, path, content) + const pathContent: MoonrakerPathContent = { + ...content, + files: content.files + .map(file => Object.freeze(file)), + dirs: content.dirs + .map(dir => Object.freeze(dir)) + } + + Vue.set(state.pathContent, path, pathContent) }, setServerFilesRoots (state, payload: Moonraker.Files.RootInfoWithPath[]) { - state.roots = payload + state.roots = Object.freeze(payload) }, setServerFilesListRoot (state, payload: { root: string, files: Moonraker.Files.RootFile[] }) { const { root, files } = payload - Vue.set(state.rootFiles, root, files) + Vue.set(state.rootFiles, root, Object.freeze(files)) }, setFileUpdate (state, payload: { paths: FilePaths, file: Moonraker.Files.File | Moonraker.Files.FileWithMeta }) { @@ -57,14 +65,14 @@ export const mutations = { const fileIndex = directory.files.findIndex(file => file.filename === paths.filename) if (fileIndex >= 0) { - Vue.set(directory.files, fileIndex, file) + Vue.set(directory.files, fileIndex, Object.freeze(file)) } else { - directory.files.push(file) + directory.files.push(Object.freeze(file)) } } else { const directory: MoonrakerPathContent = { partial: true, - files: [file], + files: [Object.freeze(file)], dirs: [] } @@ -89,9 +97,9 @@ export const mutations = { const dirIndex = directory.dirs.findIndex(dir => dir.dirname === paths.filename) if (dirIndex >= 0) { - Vue.set(directory.dirs, dirIndex, dir) + Vue.set(directory.dirs, dirIndex, Object.freeze(dir)) } else { - directory.dirs.push(dir) + directory.dirs.push(Object.freeze(dir)) } } } @@ -179,6 +187,6 @@ export const mutations = { }, setDiskUsage (state, payload: { root: string, disk_usage: Moonraker.Files.DiskUsage }) { - Vue.set(state.diskUsage, payload.root, payload.disk_usage) + Vue.set(state.diskUsage, payload.root, Object.freeze(payload.disk_usage)) } } satisfies MutationTree diff --git a/src/store/files/types.ts b/src/store/files/types.ts index 8d14c3a63d..eb1b3f16ef 100644 --- a/src/store/files/types.ts +++ b/src/store/files/types.ts @@ -6,10 +6,10 @@ export type { AppFileMeta } export interface FilesState { uploads: FileUpload[]; download: FileDownload | null; - roots: Moonraker.Files.RootInfoWithPath[] | null; + roots: readonly Moonraker.Files.RootInfoWithPath[] | null; currentPaths: Record; - diskUsage: Record; - rootFiles: Record; + diskUsage: Record | undefined>; + rootFiles: Record; pathContent: Record; } @@ -20,8 +20,8 @@ export interface AppDiskUsage extends Moonraker.Files.DiskUsage { export interface MoonrakerPathContent { partial?: boolean; - files: (Moonraker.Files.File | Moonraker.Files.FileWithMeta)[]; - dirs: Moonraker.Files.Dir[]; + files: (Readonly | Readonly)[]; + dirs: Readonly[]; } export interface AppFile extends Moonraker.Files.File, Pick { diff --git a/src/store/history/mutations.ts b/src/store/history/mutations.ts index 1ebab8b486..bddd3d1199 100644 --- a/src/store/history/mutations.ts +++ b/src/store/history/mutations.ts @@ -24,6 +24,7 @@ export const mutations = { setHistoryList (state, payload: Moonraker.History.ListResponse) { if (payload.jobs != null) { state.jobs = payload.jobs + .map(job => Object.freeze(job)) } if (payload.count != null) { state.count = payload.count @@ -35,7 +36,7 @@ export const mutations = { */ setAddHistory (state, payload: Moonraker.History.Job) { if (payload) { - state.jobs.push(payload) + state.jobs.push(Object.freeze(payload)) state.count++ } }, @@ -47,7 +48,7 @@ export const mutations = { if (payload) { const i = state.jobs.findIndex(job => job.job_id === payload.job_id) if (i >= 0) { - Vue.set(state.jobs, i, payload) + Vue.set(state.jobs, i, Object.freeze(payload)) } } }, @@ -57,13 +58,13 @@ export const mutations = { const i = state.jobs.findIndex(job => job.job_id === payload) if (i >= 0) { const job = state.jobs[i] - Vue.set(state.jobs, i, { + Vue.set(state.jobs, i, Object.freeze({ ...job, metadata: { ...job.metadata, thumbnails: [] } - }) + })) } } }, diff --git a/src/store/history/types.ts b/src/store/history/types.ts index 10341984b3..f3830ce9e7 100644 --- a/src/store/history/types.ts +++ b/src/store/history/types.ts @@ -2,7 +2,7 @@ import type { AppFileMeta } from '@/store/files/types.metadata' export interface HistoryState { count: number; - jobs: Moonraker.History.Job[]; + jobs: Readonly[]; job_totals: Moonraker.History.JobTotals; } diff --git a/src/store/jobQueue/mutations.ts b/src/store/jobQueue/mutations.ts index b1f94fc328..649cfa540a 100644 --- a/src/store/jobQueue/mutations.ts +++ b/src/store/jobQueue/mutations.ts @@ -12,6 +12,6 @@ export const mutations = { }, setQueuedJobs (state, payload: Moonraker.JobQueue.QueuedJob[]) { - state.queuedJobs = payload || [] + state.queuedJobs = Object.freeze(payload || []) } } satisfies MutationTree diff --git a/src/store/jobQueue/types.ts b/src/store/jobQueue/types.ts index 33582822bf..ca50451458 100644 --- a/src/store/jobQueue/types.ts +++ b/src/store/jobQueue/types.ts @@ -2,7 +2,7 @@ import type { AppFile, AppFileWithMeta } from '@/store/files/types' export interface JobQueueState { queueState: Moonraker.JobQueue.QueueState; - queuedJobs: Moonraker.JobQueue.QueuedJob[]; + queuedJobs: readonly Moonraker.JobQueue.QueuedJob[]; } export interface QueuedJobWithAppFile extends Moonraker.JobQueue.QueuedJob { diff --git a/src/store/spoolman/mutations.ts b/src/store/spoolman/mutations.ts index b712f417ed..b50858c6f8 100644 --- a/src/store/spoolman/mutations.ts +++ b/src/store/spoolman/mutations.ts @@ -20,7 +20,7 @@ export const mutations = { }, setSpools (state, payload: Moonraker.Spoolman.Spool[]) { - state.spools = payload + state.spools = Object.freeze(payload) }, setDialogState (state, payload: SpoolSelectionDialogState) { @@ -28,7 +28,7 @@ export const mutations = { }, setInfo (state, payload: Moonraker.Spoolman.Info) { - state.info = payload + state.info = Object.freeze(payload) }, setCurrency (state, payload: Moonraker.Spoolman.Currency) { diff --git a/src/store/spoolman/types.ts b/src/store/spoolman/types.ts index 1ffb1bb563..96344bfb44 100644 --- a/src/store/spoolman/types.ts +++ b/src/store/spoolman/types.ts @@ -1,6 +1,6 @@ export interface SpoolmanState { - info: Moonraker.Spoolman.Info | null; - spools: Moonraker.Spoolman.Spool[]; + info: Readonly | null; + spools: readonly Moonraker.Spoolman.Spool[]; activeSpool: number | null; currency: string | null; connected: boolean; diff --git a/src/typings/moonraker.spoolman.d.ts b/src/typings/moonraker.spoolman.d.ts index 9ac779daaf..a96c7aed15 100644 --- a/src/typings/moonraker.spoolman.d.ts +++ b/src/typings/moonraker.spoolman.d.ts @@ -57,6 +57,10 @@ declare namespace Moonraker.Spoolman { extra?: Record; } + export type FilamentMultiColorDirection = + | 'coaxial' + | 'longitudinal' + export interface Filament { id: number; registered: string; @@ -75,7 +79,7 @@ declare namespace Moonraker.Spoolman { settings_bed_temp?: number; color_hex?: string; multi_color_hexes?: string; - multi_color_direction?: string; + multi_color_direction?: FilamentMultiColorDirection; external_id?: string; extra?: Record; }