aboutsummaryrefslogtreecommitdiffstats
path: root/utils/loader.ts
diff options
context:
space:
mode:
Diffstat (limited to 'utils/loader.ts')
-rw-r--r--utils/loader.ts93
1 files changed, 93 insertions, 0 deletions
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<any[]> {
+ 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