From a072c91cc0dc26e417c51f666e8547e08ef40942 Mon Sep 17 00:00:00 2001 From: Leonardo Bishop Date: Tue, 12 Mar 2024 23:18:23 +0000 Subject: Add import from file system --- utils/loader.ts | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 utils/loader.ts (limited to 'utils/loader.ts') diff --git a/utils/loader.ts b/utils/loader.ts new file mode 100644 index 0000000..56e29fa --- /dev/null +++ b/utils/loader.ts @@ -0,0 +1,93 @@ +import { parse } from "yaml"; +import { loadCategoriesFromJson, loadItemsFromJson, loadQuestsFromJson } from "~/lib/questsLoader"; + +export async function openFileSystem() { + try { + return await (window as any).showDirectoryPicker(); + } catch (e) { + return undefined; + } +} + +export async function enumerateQuestDirectory(dirHandle: any) { + let configFile: any = null; + let categoryFile: any = null; + let questsDirectory: any = null; + let itemsDirectory: any = null; + + for await (const [name, handle] of dirHandle) { + if (name === 'quests' && handle.kind === 'directory') { + questsDirectory = handle; + } else if (name === 'items' && handle.kind === 'directory') { + itemsDirectory = handle; + } else if (name === 'config.yml' && handle.kind === 'file') { + configFile = handle; + } else if (name === 'categories.yml' && handle.kind === 'file') { + categoryFile = handle; + } + } + + if (!configFile) { + throw Error('invalid quest directory'); + } + + const [questFiles, itemFiles] = await Promise.all([questsDirectory ? listAllFilesAndDirs(questsDirectory) : [], itemsDirectory ? listAllFilesAndDirs(itemsDirectory) : []]); + const [categories, quests, items] = await Promise.all([(async () => { + if (!categoryFile) { + return []; + } + + const file: any = await categoryFile.getFile(); + const text: string = await file.text(); + const parsedYaml: any = parse(text); + + return loadCategoriesFromJson(parsedYaml.categories); + })(), + (async () => { + if (!questFiles) { + return []; + } + + const allQuests = await Promise.all(questFiles.filter(({ name, handle, kind }) => name.endsWith('.yml')).map(async ({ name, handle, kind }) => { + const file: any = await handle.getFile(); + const text: string = await file.text(); + return [ + name.replace('.yml', ''), + parse(text) + ]; + })) + + return loadQuestsFromJson(Object.fromEntries(allQuests)); + })(), + (async () => { + if (!itemFiles) { + return []; + } + + const allItems = await Promise.all(itemFiles.filter(({ name, handle, kind }) => name.endsWith('.yml')).map(async ({ name, handle, kind }) => { + const file: any = await handle.getFile(); + const text: string = await file.text(); + return [ + name.replace('.yml', ''), + parse(text) + ]; + })) + + return loadItemsFromJson(Object.fromEntries(allItems)); + })()]); + + return { categories, quests, items }; +} + +async function listAllFilesAndDirs(dirHandle: any): Promise { + const files = []; + for await (const [name, handle] of dirHandle) { + const { kind } = handle; + if (handle.kind === 'directory') { + files.push(...await listAllFilesAndDirs(handle)); + } else { + files.push({ name, handle, kind }); + } + } + return files; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2