diff --git a/projects/frontend/src/utilities/fetch.ts b/projects/frontend/src/utilities/fetch.ts index 18362a8..6ccb4a6 100644 --- a/projects/frontend/src/utilities/fetch.ts +++ b/projects/frontend/src/utilities/fetch.ts @@ -114,15 +114,44 @@ export const fetchAndReturnText = async (path: string) => { * @returns the content of the YAML file after sanitizing then parsing */ export const fetchAndParseYaml = async <T>(path: string) => { + const text = await fetchAndReturnText(path) + return yaml.load(text) as T // do not catch exceptions +} + +/** + * Fetches, sanitizes, and parses JSON files + * @param path the path of the JSON file to load + * @returns the content of the JSON file after sanitizing then parsing + */ +export const fetchAndParseJson = async<T>(path: string) => { + const text = await fetchAndReturnText(path) + return JSON.parse(text) as T // do not catch exceptions +} + +/** + * Fetches, sanitizes, and parses a config file; + * valid config files are in YAML or JSON + * @param path the path of the config file to load + * @returns the content of the config file after sanitizing then parsing + */ +export const fetchAndParseConfig = async<T>(path: string) => { const store = useRouteStore() const existing = store.getFile<T>(path) if (!!existing) { return existing } else { - const text = await fetchAndReturnText(path) - const obj = yaml.load(text) as T - store.cacheFile(path, obj) - return obj + let parsed = {} + if (path.endsWith('.yml') || path.endsWith('.yaml')) { + parsed = await fetchAndParseYaml(path) + } else if (path.endsWith('.json')) { + parsed = await fetchAndParseJson(path) + } else { + // stop execution + throw new Error(`Invalid config specified at ${path}`) + } + + store.cacheFile(path, parsed) + return parsed as T } } @@ -159,7 +188,7 @@ export const fetchConfigsFromList = async <T>(list: ListWithEntries<T>): Promise if (!!list.entries) { ids = ids.concat(Object.keys(list.entries)) ids.forEach(id => { - entries[id] = fetchAndParseYaml<T>((list.entries!)[id]) + entries[id] = fetchAndParseConfig<T>((list.entries!)[id]) }) } if (!!list.embeddedEntries) { @@ -187,7 +216,7 @@ export const fetchConfigByIdFromList = async <T>(list: ListWithEntries<T>, id: s if (!!list.embeddedEntries && list.embeddedEntries[id]) { resolve(list.embeddedEntries[id]) } else if (!!list.entries && list.entries[id]) { - const config = await fetchAndParseYaml<T>(list.entries[id]) + const config = await fetchAndParseConfig<T>(list.entries[id]) resolve(config) } }) diff --git a/projects/frontend/src/views/article/article-view.vue b/projects/frontend/src/views/article/article-view.vue index 58dbd0f..bc0fc55 100644 --- a/projects/frontend/src/views/article/article-view.vue +++ b/projects/frontend/src/views/article/article-view.vue @@ -7,7 +7,7 @@ import type { RoutedWindow, } from '@goldenwere/mackenzii-types' -import { fetchAndParseMarkdown, fetchAndParseYaml, fetchConfigByIdFromList } from 'src/utilities/fetch' +import { fetchAndParseMarkdown, fetchAndParseConfig, fetchConfigByIdFromList } from 'src/utilities/fetch' import { getCurrentRoute } from 'src/utilities/vuetils' import { useRouteStore } from 'src/routes' @@ -28,7 +28,7 @@ const routeConfig = routeStore._routes[currentRoute.path.substring(0, currentRou const routeSubConfig = routeStore._routes[currentRoute.path] onMounted(async () => { - const config = await fetchAndParseYaml<ListWithEntries<ArticleEntry>>(routeConfig.config) + const config = await fetchAndParseConfig<ListWithEntries<ArticleEntry>>(routeConfig.config) resolved.value = await fetchConfigByIdFromList(config, currentRoute.query.id as string) const md = await fetchAndParseMarkdown(resolved.value.url) content.value = md diff --git a/projects/frontend/src/views/gallery/gallery-view.vue b/projects/frontend/src/views/gallery/gallery-view.vue index 49c5989..b72b203 100644 --- a/projects/frontend/src/views/gallery/gallery-view.vue +++ b/projects/frontend/src/views/gallery/gallery-view.vue @@ -10,7 +10,7 @@ import type { RoutedWindow, } from '@goldenwere/mackenzii-types' -import { fetchAndParseYaml, fetchConfigByIdFromList } from 'src/utilities/fetch' +import { fetchAndParseConfig, fetchConfigByIdFromList } from 'src/utilities/fetch' import { getCurrentRoute } from 'src/utilities/vuetils' import { useRouteStore } from 'src/routes' @@ -71,7 +71,7 @@ const onButtonClicked = (event: Event | null, direction: number, override?: numb } onMounted(async () => { - let config = await fetchAndParseYaml<ListWithEntries<GalleryEntry>>(routeConfig.config) + let config = await fetchAndParseConfig<ListWithEntries<GalleryEntry>>(routeConfig.config) resolved.value = await fetchConfigByIdFromList(config, currentRoute.query.id as string) document.title = routeSubConfig.fullTitle?.replace('$ENTRY', resolved.value.title || currentRoute.query.id as string) routeStore.setBreadcrumbs(currentRoute, resolved.value.title || currentRoute.query.id as string) diff --git a/projects/frontend/src/views/shared/media-list.vue b/projects/frontend/src/views/shared/media-list.vue index 6d55503..a39d211 100644 --- a/projects/frontend/src/views/shared/media-list.vue +++ b/projects/frontend/src/views/shared/media-list.vue @@ -7,7 +7,7 @@ import type { MediaEntry, ResolvedListEntries, } from '@goldenwere/mackenzii-types' -import { fetchAndParseYaml, fetchConfigsFromList, storage } from 'src/utilities/fetch' +import { fetchAndParseConfig, fetchConfigsFromList, storage } from 'src/utilities/fetch' import { getCurrentRoute } from 'src/utilities/vuetils' import { useRouteStore } from 'src/routes' @@ -84,7 +84,7 @@ const onHideWarningsToggled = (event: Event) => { } onMounted(async () => { - let listConfig = await fetchAndParseYaml<MediaList>(routeConfig.config) + let listConfig = await fetchAndParseConfig<MediaList>(routeConfig.config) const list = await fetchConfigsFromList<MediaEntry>(listConfig) config.value = listConfig entries.value = list.entries