Add extending by binding

This commit is contained in:
Endeavorance 2025-03-07 15:01:52 -05:00
parent beff321251
commit 49e82d0a13
12 changed files with 155 additions and 102 deletions

View file

@ -1,10 +1,17 @@
import path from "node:path";
import { Glob } from "bun";
import YAML from "yaml";
import z from "zod";
import {
getEmptyPlaybill,
type AnyResource,
type Playbill,
} from "@proscenium/playbill";
import { loadYAMLFileOrFail } from "./files";
import { loadResourceFile } from "./resource";
const BindingFileSchema = z.object({
$binding: z.literal("playbill"),
extends: z.string().optional(),
id: z.string(),
name: z.string().default("Unnamed playbill"),
author: z.string().optional(),
@ -17,25 +24,38 @@ type BindingFileContent = z.infer<typeof BindingFileSchema>;
export interface PlaybillBinding {
_raw: BindingFileContent;
// File information
bindingFilePath: string;
includedFiles: string[];
// Binding properties
id: string;
name: string;
author: string;
version: string;
description: string;
playbill: Playbill;
}
export function parseBindingFile(
text: string,
export async function loadFromBinding(
filePath: string,
): PlaybillBinding {
const parsed = YAML.parse(text);
const binding = BindingFileSchema.parse(parsed);
): Promise<PlaybillBinding> {
const yamlContent = await loadYAMLFileOrFail(filePath);
const binding = BindingFileSchema.parse(yamlContent);
const fileGlobs = binding.files;
const bindingFileDirname = filePath.split("/").slice(0, -1).join("/");
let basePlaybill: Playbill | null = null;
// If this is extending another binding, load that first
if (binding.extends) {
console.log(binding);
const extendBindingPath = path.resolve(bindingFileDirname, binding.extends);
basePlaybill = (await loadFromBinding(extendBindingPath)).playbill;
}
const allFilePaths: string[] = [];
for (const thisGlob of fileGlobs) {
@ -52,19 +72,68 @@ export function parseBindingFile(
}
const bindingFileAbsolutePath = path.resolve(filePath);
const filteredFilePaths = allFilePaths.filter((filePath) => {
const filePathsWithoutBindingFile = allFilePaths.filter((filePath) => {
return filePath !== bindingFileAbsolutePath;
});
// -- LOAD ASSOCIATED RESOURCE FILES -- //
const loadedResources: AnyResource[] = [];
for (const filepath of filePathsWithoutBindingFile) {
const loaded = await loadResourceFile(filepath);
loadedResources.push(...loaded);
}
// -- COMPILE PLAYBILL FROM RESOURCES --//
const playbill = basePlaybill ?? getEmptyPlaybill();
playbill.id = binding.id;
playbill.name = binding.name;
playbill.author = binding.author ?? "Anonymous";
playbill.version = binding.version;
playbill.description = binding.description ?? "";
for (const resource of loadedResources) {
switch (resource.$define) {
case "ability":
playbill.abilities.push(resource);
break;
case "species":
playbill.species.push(resource);
break;
case "entity":
playbill.entities.push(resource);
break;
case "item":
playbill.items.push(resource);
break;
case "tag":
playbill.tags.push(resource);
break;
case "method":
playbill.methods.push(resource);
break;
case "lore":
playbill.lore.push(resource);
break;
case "rule":
playbill.rules.push(resource);
break;
case "playbill":
throw new Error("Cannot load playbills rn dawg");
}
}
return {
_raw: binding,
bindingFilePath: filePath,
includedFiles: filteredFilePaths,
includedFiles: filePathsWithoutBindingFile,
id: binding.id,
name: binding.name,
author: binding.author ?? "Anonymous",
description: binding.description ?? "",
version: binding.version,
playbill,
};
}