Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Video-Downloader/web/src/lib/settings/validate.ts
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
87 lines (72 sloc)
2.61 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Optional } from '$lib/types/generic'; | |
import defaultSettings from './defaults' | |
import { | |
downloadModeOptions, | |
filenameStyleOptions, | |
savingMethodOptions, | |
themeOptions, | |
videoQualityOptions, | |
youtubeVideoCodecOptions, | |
type PartialSettings, | |
} from '$lib/types/settings'; | |
import { youtubeLanguages } from './youtube-lang'; | |
function validateTypes(input: unknown, reference = defaultSettings as unknown) { | |
if (typeof input === 'undefined') | |
return true; | |
if (typeof input !== typeof reference) | |
return false; | |
if (typeof reference !== 'object') | |
return true; | |
if (reference === null || input === null) | |
return input === reference; | |
if (Array.isArray(reference)) { | |
// TODO: we dont expect the reference array to hold any | |
// elements, but we should at maybe check whether | |
// the input array types are all matching. | |
return true; | |
} | |
// we know that `input` is an `object` based on the first | |
// two `if`s, but for some reason typescript doesn't. :) | |
if (typeof input !== 'object') | |
return false; | |
const keys = new Set([ | |
...Object.keys(input), | |
...Object.keys(reference) | |
]); | |
for (const key of keys) { | |
const _input = input as Record<string, unknown>; | |
const _reference = reference as Record<string, unknown>; | |
if (!validateTypes(_input[key], _reference[key])) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function validateLiteral(value: Optional<string>, allowed: readonly string[]) { | |
return value === undefined || allowed.includes(value); | |
} | |
function validateLiterals(literals: [Optional<string>, readonly string[]][]) { | |
for (const [ value, allowed ] of literals) { | |
if (!validateLiteral(value, allowed)) | |
return false; | |
} | |
return true; | |
} | |
// performs a basic check on an "untrusted" settings object. | |
export function validateSettings(settings: PartialSettings) { | |
if (!settings?.schemaVersion) { | |
return false; | |
} | |
return ( | |
validateTypes(settings) | |
&& validateLiterals([ | |
[ settings?.appearance?.theme , themeOptions ], | |
[ settings?.save?.downloadMode , downloadModeOptions ], | |
[ settings?.save?.filenameStyle , filenameStyleOptions ], | |
[ settings?.save?.videoQuality , videoQualityOptions ], | |
[ settings?.save?.youtubeVideoCodec, youtubeVideoCodecOptions ], | |
[ settings?.save?.savingMethod , savingMethodOptions ], | |
[ settings?.save?.youtubeDubLang , youtubeLanguages ] | |
]) | |
); | |
} |