Continued work

This commit is contained in:
Endeavorance 2025-03-14 15:41:20 -04:00
parent 10c84d2dce
commit 3e2ab6ec73
3 changed files with 38 additions and 57 deletions

View file

@ -1,6 +1,6 @@
import { watch } from "node:fs/promises"; import { watch } from "node:fs/promises";
import { import {
ValidatedPlaybillSchema, PlaybillSchema,
renderPlaybillToHTML, renderPlaybillToHTML,
renderPlaybillToJSON, renderPlaybillToJSON,
} from "@proscenium/playbill"; } from "@proscenium/playbill";
@ -40,7 +40,7 @@ async function processBinding({ inputFilePath, options }: CLIArguments) {
const binding = await loadFromBinding(bindingPath); const binding = await loadFromBinding(bindingPath);
// -- VALDATE PLAYBILL -- // // -- VALDATE PLAYBILL -- //
const validatedPlaybill = ValidatedPlaybillSchema.safeParse(binding.playbill); const validatedPlaybill = PlaybillSchema.safeParse(binding.playbill);
if (!validatedPlaybill.success) { if (!validatedPlaybill.success) {
console.error("Error validating playbill"); console.error("Error validating playbill");
@ -56,8 +56,8 @@ async function processBinding({ inputFilePath, options }: CLIArguments) {
let css = ""; let css = "";
if (binding.html?.styles) { if (binding.styles && binding.styles.length > 0) {
for (const style of binding.html.styles) { for (const style of binding.styles) {
const cssFilePath = path.resolve(binding.bindingFileDirname, style); const cssFilePath = path.resolve(binding.bindingFileDirname, style);
const cssFile = Bun.file(cssFilePath); const cssFile = Bun.file(cssFilePath);
const cssFileExists = await cssFile.exists(); const cssFileExists = await cssFile.exists();

View file

@ -1,9 +1,8 @@
import path from "node:path"; import path from "node:path";
import { import {
IDSchema, UnvalidatedPlaybillSchema,
PlaybillSchema, type UnknownComponent,
type Playbill, type UnvalidatedPlaybill,
type UnknownResource,
} from "@proscenium/playbill"; } from "@proscenium/playbill";
import { Glob } from "bun"; import { Glob } from "bun";
import z from "zod"; import z from "zod";
@ -11,29 +10,17 @@ import { FileNotFoundError } from "#lib/errors";
import { loadYAMLFileOrFail } from "#util/files"; import { loadYAMLFileOrFail } from "#util/files";
import { loadResourceFile } from "./resource"; import { loadResourceFile } from "./resource";
const HTMLRenderOptionsSchema = z.object({
styles: z.array(z.string()).optional(),
});
const PageDefinitionSchema = z.object({
id: z.string(),
title: z.string(),
resources: z.array(IDSchema),
});
const BindingFileSchema = z.object({ const BindingFileSchema = z.object({
$binding: z.literal("playbill"), extend: z.string().optional(),
extends: z.string().optional(),
id: z.string(), id: z.string(),
name: z.string().default("Unnamed playbill"), name: z.string().default("Unnamed playbill"),
author: z.string().optional(), author: z.string().optional(),
description: z.string().optional(), description: z.string().optional(),
version: z.string(), version: z.string().default("0.0.0"),
files: z.array(z.string()).default(["**/*.yaml", "**/*.md"]), files: z.array(z.string()).default(["**/*.yaml", "**/*.md"]),
styles: z.array(z.string()).optional(),
html: HTMLRenderOptionsSchema.optional(),
pages: PageDefinitionSchema.array().optional(),
}); });
type BindingFileContent = z.infer<typeof BindingFileSchema>; type BindingFileContent = z.infer<typeof BindingFileSchema>;
@ -53,14 +40,13 @@ export interface PlaybillBinding {
version: string; version: string;
description: string; description: string;
html?: z.infer<typeof HTMLRenderOptionsSchema>; styles?: string[];
pages?: z.infer<typeof PageDefinitionSchema>[];
playbill: Playbill; playbill: UnvalidatedPlaybill;
} }
export async function resolveBindingPath(bindingPath: string): Promise<string> { export async function resolveBindingPath(bindingPath: string): Promise<string> {
// If the path does not specify a filename, use binding.yamk // If the path does not specify a filename, use binding.yaml
const inputLocation = Bun.file(bindingPath); const inputLocation = Bun.file(bindingPath);
// If it is a directory, try again seeking a binding.yaml inside // If it is a directory, try again seeking a binding.yaml inside
@ -85,16 +71,22 @@ export async function loadFromBinding(
const yamlContent = await loadYAMLFileOrFail(resolvedBindingPath); const yamlContent = await loadYAMLFileOrFail(resolvedBindingPath);
const binding = BindingFileSchema.parse(yamlContent); const binding = BindingFileSchema.parse(yamlContent);
const fileGlobs = binding.files; const fileGlobs = binding.files;
const bindingFileDirname = bindingPath.split("/").slice(0, -1).join("/"); const bindingFileDirname = path.dirname(resolvedBindingPath);
let basePlaybill: Playbill | null = null; let playbill: UnvalidatedPlaybill = UnvalidatedPlaybillSchema.parse({
$define: "playbill",
id: "blank",
name: "Unnamed playbill",
description: "Unnamed Playbill",
version: "0.0.1",
});
// If this is extending another binding, load that first // If this is extending another binding, load that first
if (binding.extends) { if (binding.extend) {
const pathFromHere = path.resolve(bindingFileDirname, binding.extends); const pathFromHere = path.resolve(bindingFileDirname, binding.extend);
const extendBindingPath = await resolveBindingPath(pathFromHere); const extendBindingPath = await resolveBindingPath(pathFromHere);
const loadedBinding = await loadFromBinding(extendBindingPath); const loadedBinding = await loadFromBinding(extendBindingPath);
basePlaybill = loadedBinding.playbill; playbill = loadedBinding.playbill;
} }
const allFilePaths: string[] = []; const allFilePaths: string[] = [];
@ -118,23 +110,12 @@ export async function loadFromBinding(
}); });
// -- LOAD ASSOCIATED RESOURCE FILES -- // // -- LOAD ASSOCIATED RESOURCE FILES -- //
const loadedResources: UnknownResource[] = []; const loadedResources: UnknownComponent[] = [];
for (const filepath of filePathsWithoutBindingFile) { for (const filepath of filePathsWithoutBindingFile) {
const loaded = await loadResourceFile(filepath); const loaded = await loadResourceFile(filepath);
loadedResources.push(...loaded); loadedResources.push(...loaded);
} }
// -- COMPILE PLAYBILL FROM RESOURCES --//
const playbill =
basePlaybill ??
PlaybillSchema.parse({
$define: "playbill",
id: "blank",
name: "Unnamed playbill",
description: "Unnamed Playbill",
version: "0.0.1",
});
playbill.id = binding.id; playbill.id = binding.id;
playbill.name = binding.name; playbill.name = binding.name;
playbill.author = binding.author ?? "Anonymous"; playbill.author = binding.author ?? "Anonymous";
@ -162,7 +143,7 @@ export async function loadFromBinding(
description: binding.description ?? "", description: binding.description ?? "",
version: binding.version, version: binding.version,
html: binding.html, styles: binding.styles,
playbill, playbill,
}; };

View file

@ -1,7 +1,7 @@
import { import {
ResourceMap, ComponentMap,
type UnknownResource, type UnknownComponent,
UnknownResourceSchema, UnknownComponentSchema,
} from "@proscenium/playbill"; } from "@proscenium/playbill";
import YAML, { YAMLParseError } from "yaml"; import YAML, { YAMLParseError } from "yaml";
import { ZodError } from "zod"; import { ZodError } from "zod";
@ -18,7 +18,7 @@ function determineFileFormat(filePath: string): FileFormat {
function loadYamlResourceFile( function loadYamlResourceFile(
filePath: string, filePath: string,
text: string, text: string,
): UnknownResource[] { ): UnknownComponent[] {
const parsedDocs = YAML.parseAllDocuments(text); const parsedDocs = YAML.parseAllDocuments(text);
if (parsedDocs.some((doc) => doc.toJS() === null)) { if (parsedDocs.some((doc) => doc.toJS() === null)) {
@ -35,11 +35,11 @@ function loadYamlResourceFile(
); );
} }
const collection: UnknownResource[] = []; const collection: UnknownComponent[] = [];
for (const doc of parsedDocs) { for (const doc of parsedDocs) {
const raw = doc.toJS(); const raw = doc.toJS();
const parsed = UnknownResourceSchema.safeParse(raw); const parsed = UnknownComponentSchema.safeParse(raw);
if (!parsed.success) { if (!parsed.success) {
throw new MalformedResourceFileError( throw new MalformedResourceFileError(
@ -51,7 +51,7 @@ function loadYamlResourceFile(
const parsedResource = parsed.data; const parsedResource = parsed.data;
const type = parsedResource.$define; const type = parsedResource.$define;
const schemaToUse = ResourceMap[type]; const schemaToUse = ComponentMap[type];
const validated = schemaToUse.parse(parsedResource); const validated = schemaToUse.parse(parsedResource);
collection.push(validated); collection.push(validated);
} }
@ -62,7 +62,7 @@ function loadYamlResourceFile(
function loadMarkdownResourceFile( function loadMarkdownResourceFile(
filePath: string, filePath: string,
text: string, text: string,
): UnknownResource[] { ): UnknownComponent[] {
try { try {
const frontmatter = extractFrontmatter(text); const frontmatter = extractFrontmatter(text);
const markdown = extractMarkdown(text); const markdown = extractMarkdown(text);
@ -72,7 +72,7 @@ function loadMarkdownResourceFile(
description: markdown, description: markdown,
}; };
const parsed = UnknownResourceSchema.parse(together); const parsed = UnknownComponentSchema.parse(together);
return [parsed]; return [parsed];
} catch (e) { } catch (e) {
if (e instanceof YAMLParseError) { if (e instanceof YAMLParseError) {
@ -105,7 +105,7 @@ function loadMarkdownResourceFile(
*/ */
export async function loadResourceFile( export async function loadResourceFile(
filePath: string, filePath: string,
): Promise<UnknownResource[]> { ): Promise<UnknownComponent[]> {
const text = await loadFileOrFail(filePath); const text = await loadFileOrFail(filePath);
const format = determineFileFormat(filePath); const format = determineFileFormat(filePath);