Add extending by binding
This commit is contained in:
parent
beff321251
commit
49e82d0a13
12 changed files with 155 additions and 102 deletions
4
bun.lock
4
bun.lock
|
@ -4,7 +4,7 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "@proscenium/muse",
|
"name": "@proscenium/muse",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@proscenium/playbill": "0.0.4",
|
"@proscenium/playbill": "0.0.9",
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"yaml": "^2.7.0",
|
"yaml": "^2.7.0",
|
||||||
"zod": "^3.24.1",
|
"zod": "^3.24.1",
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
|
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
|
||||||
|
|
||||||
"@proscenium/playbill": ["@proscenium/playbill@0.0.4", "https://git.astral.camp/api/packages/proscenium/npm/%40proscenium%2Fplaybill/-/0.0.4/playbill-0.0.4.tgz", { "peerDependencies": { "typescript": "^5" } }, "sha512-wLH04ac77LdCcYgkFmJwRDmRJ4W1I3W+KrbQ1oYQoTDY81Rrv+//ndx9HUMtXEDjM4oTcmhP3q4SxOLZgE744Q=="],
|
"@proscenium/playbill": ["@proscenium/playbill@0.0.9", "https://git.astral.camp/api/packages/proscenium/npm/%40proscenium%2Fplaybill/-/0.0.9/playbill-0.0.9.tgz", { "peerDependencies": { "typescript": "^5" } }, "sha512-Wx8q/1AM5LOSaFjwoRagU/J6lAGNZz2yorLrY0TrqHyuWKwkpzzPx0EAY9bBuq/+BDiebw2n84Mp+gHFJ5JyeQ=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.3", "", { "dependencies": { "bun-types": "1.2.3" } }, "sha512-054h79ipETRfjtsCW9qJK8Ipof67Pw9bodFWmkfkaUaRiIQ1dIV2VTlheshlBx3mpKr0KeK8VqnMMCtgN9rQtw=="],
|
"@types/bun": ["@types/bun@1.2.3", "", { "dependencies": { "bun-types": "1.2.3" } }, "sha512-054h79ipETRfjtsCW9qJK8Ipof67Pw9bodFWmkfkaUaRiIQ1dIV2VTlheshlBx3mpKr0KeK8VqnMMCtgN9rQtw=="],
|
||||||
|
|
||||||
|
|
5
extend-me/binding.yaml
Normal file
5
extend-me/binding.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
$binding: playbill
|
||||||
|
id: root
|
||||||
|
name: Root Playbill
|
||||||
|
author: "Endeavorance <hello@endeavorance.camp>"
|
||||||
|
version: 0.0.1
|
7
extend-me/spires/lore/mortals.md
Normal file
7
extend-me/spires/lore/mortals.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
$define: lore
|
||||||
|
id: mortals
|
||||||
|
name: Mortals
|
||||||
|
---
|
||||||
|
|
||||||
|
Fleshy af
|
|
@ -14,7 +14,7 @@
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"yaml": "^2.7.0",
|
"yaml": "^2.7.0",
|
||||||
"zod": "^3.24.1",
|
"zod": "^3.24.1",
|
||||||
"@proscenium/playbill": "0.0.4"
|
"@proscenium/playbill": "0.0.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"fmt": "bunx --bun biome check --fix",
|
"fmt": "bunx --bun biome check --fix",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
$binding: playbill
|
$binding: playbill
|
||||||
|
extends: ../extend-me/binding.yaml
|
||||||
id: the-great-spires
|
id: the-great-spires
|
||||||
name: The Great Spires
|
name: The Great Spires
|
||||||
author: "Endeavorance <hello@endeavorance.camp>"
|
author: "Endeavorance <hello@endeavorance.camp>"
|
||||||
|
|
|
@ -11,8 +11,7 @@ $define: ability
|
||||||
id: identify-poison
|
id: identify-poison
|
||||||
name: Identify Poison
|
name: Identify Poison
|
||||||
type: action
|
type: action
|
||||||
costs:
|
ap: 1
|
||||||
ap: 1
|
|
||||||
roll: focus
|
roll: focus
|
||||||
boons:
|
boons:
|
||||||
- You know the antidote to the detected poison
|
- You know the antidote to the detected poison
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { Glob } from "bun";
|
import { Glob } from "bun";
|
||||||
import YAML from "yaml";
|
|
||||||
import z from "zod";
|
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({
|
const BindingFileSchema = z.object({
|
||||||
$binding: z.literal("playbill"),
|
$binding: z.literal("playbill"),
|
||||||
|
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(),
|
||||||
|
@ -17,25 +24,38 @@ type BindingFileContent = z.infer<typeof BindingFileSchema>;
|
||||||
|
|
||||||
export interface PlaybillBinding {
|
export interface PlaybillBinding {
|
||||||
_raw: BindingFileContent;
|
_raw: BindingFileContent;
|
||||||
|
|
||||||
|
// File information
|
||||||
bindingFilePath: string;
|
bindingFilePath: string;
|
||||||
includedFiles: string[];
|
includedFiles: string[];
|
||||||
|
|
||||||
|
// Binding properties
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
author: string;
|
author: string;
|
||||||
version: string;
|
version: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
|
playbill: Playbill;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseBindingFile(
|
export async function loadFromBinding(
|
||||||
text: string,
|
|
||||||
filePath: string,
|
filePath: string,
|
||||||
): PlaybillBinding {
|
): Promise<PlaybillBinding> {
|
||||||
const parsed = YAML.parse(text);
|
const yamlContent = await loadYAMLFileOrFail(filePath);
|
||||||
const binding = BindingFileSchema.parse(parsed);
|
const binding = BindingFileSchema.parse(yamlContent);
|
||||||
const fileGlobs = binding.files;
|
const fileGlobs = binding.files;
|
||||||
const bindingFileDirname = filePath.split("/").slice(0, -1).join("/");
|
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[] = [];
|
const allFilePaths: string[] = [];
|
||||||
|
|
||||||
for (const thisGlob of fileGlobs) {
|
for (const thisGlob of fileGlobs) {
|
||||||
|
@ -52,19 +72,68 @@ export function parseBindingFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
const bindingFileAbsolutePath = path.resolve(filePath);
|
const bindingFileAbsolutePath = path.resolve(filePath);
|
||||||
const filteredFilePaths = allFilePaths.filter((filePath) => {
|
const filePathsWithoutBindingFile = allFilePaths.filter((filePath) => {
|
||||||
return filePath !== bindingFileAbsolutePath;
|
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 {
|
return {
|
||||||
_raw: binding,
|
_raw: binding,
|
||||||
bindingFilePath: filePath,
|
bindingFilePath: filePath,
|
||||||
includedFiles: filteredFilePaths,
|
includedFiles: filePathsWithoutBindingFile,
|
||||||
|
|
||||||
id: binding.id,
|
id: binding.id,
|
||||||
name: binding.name,
|
name: binding.name,
|
||||||
author: binding.author ?? "Anonymous",
|
author: binding.author ?? "Anonymous",
|
||||||
description: binding.description ?? "",
|
description: binding.description ?? "",
|
||||||
version: binding.version,
|
version: binding.version,
|
||||||
|
|
||||||
|
playbill,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ export class MuseError extends Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResourceFileError extends MuseError {
|
export class FileError extends MuseError {
|
||||||
filePath: string;
|
filePath: string;
|
||||||
details?: string;
|
details?: string;
|
||||||
|
|
||||||
|
@ -18,3 +18,15 @@ export class ResourceFileError extends MuseError {
|
||||||
return `-- ${this.message} --\nFile Path: ${this.filePath}\nDetails: ${this.details}`;
|
return `-- ${this.message} --\nFile Path: ${this.filePath}\nDetails: ${this.details}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MalformedResourceFileError extends FileError { }
|
||||||
|
|
||||||
|
export class FileNotFoundError extends FileError {
|
||||||
|
constructor(filePath: string) {
|
||||||
|
super("File not found", filePath);
|
||||||
|
this.message = "File not found";
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CLIError extends MuseError { }
|
||||||
|
|
21
src/files.ts
Normal file
21
src/files.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import YAML from "yaml";
|
||||||
|
import { FileError, FileNotFoundError } from "./errors";
|
||||||
|
|
||||||
|
export async function loadFileOrFail(filePath: string): Promise<string> {
|
||||||
|
const fileToLoad = Bun.file(filePath);
|
||||||
|
const fileExists = await fileToLoad.exists();
|
||||||
|
|
||||||
|
if (!fileExists) {
|
||||||
|
throw new FileNotFoundError(`File not found: ${filePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fileToLoad.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadYAMLFileOrFail(filePath: string): Promise<unknown> {
|
||||||
|
try {
|
||||||
|
return YAML.parse(await loadFileOrFail(filePath));
|
||||||
|
} catch (error) {
|
||||||
|
throw new FileError("Failed to parse YAML file", filePath, `${error}`);
|
||||||
|
}
|
||||||
|
}
|
84
src/index.ts
84
src/index.ts
|
@ -1,34 +1,15 @@
|
||||||
import { parseArgs } from "node:util";
|
import { parseArgs } from "node:util";
|
||||||
import {
|
import { ValidatedPlaybillSchema, checkDirectives } from "@proscenium/playbill";
|
||||||
type AnyResource,
|
|
||||||
ValidatedPlaybillSchema,
|
|
||||||
checkDirectives,
|
|
||||||
getEmptyPlaybill,
|
|
||||||
} from "@proscenium/playbill";
|
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { parseBindingFile } from "./binding";
|
import { loadFromBinding } from "./binding";
|
||||||
import { loadResourceFile } from "./resource";
|
|
||||||
import { usage } from "./usage";
|
import { usage } from "./usage";
|
||||||
import { ResourceFileError } from "./errors";
|
import { CLIError, MuseError } from "./errors";
|
||||||
|
|
||||||
enum ExitCode {
|
enum ExitCode {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
Error = 1,
|
Error = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
class CLIError extends Error { }
|
|
||||||
|
|
||||||
async function loadFileOrFail(filePath: string): Promise<string> {
|
|
||||||
const fileToLoad = Bun.file(filePath);
|
|
||||||
const fileExists = await fileToLoad.exists();
|
|
||||||
|
|
||||||
if (!fileExists) {
|
|
||||||
throw new Error(`File not found: ${filePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fileToLoad.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main(): Promise<number> {
|
async function main(): Promise<number> {
|
||||||
// -- ARGUMENT PARSING -- //
|
// -- ARGUMENT PARSING -- //
|
||||||
const { values: options, positionals: args } = parseArgs({
|
const { values: options, positionals: args } = parseArgs({
|
||||||
|
@ -97,68 +78,15 @@ async function main(): Promise<number> {
|
||||||
|
|
||||||
verboseLog(`Building Playbill with binding: ${bindingPath}`);
|
verboseLog(`Building Playbill with binding: ${bindingPath}`);
|
||||||
|
|
||||||
const bindingFileContent = await loadFileOrFail(bindingPath);
|
const binding = await loadFromBinding(bindingPath);
|
||||||
const binding = parseBindingFile(bindingFileContent, bindingPath);
|
|
||||||
|
|
||||||
verboseLog(
|
verboseLog(
|
||||||
`↳ Binding loaded with ${binding.includedFiles.length} associated resources`,
|
`↳ Binding loaded with ${binding.includedFiles.length} associated resources`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// -- RESOURCE FILES -- //
|
|
||||||
verboseLog("Loading resources");
|
|
||||||
const loadedResources: AnyResource[] = [];
|
|
||||||
for (const filepath of binding.includedFiles) {
|
|
||||||
verboseLog(`↳ Loading ${filepath}`);
|
|
||||||
const loaded = await loadResourceFile(filepath);
|
|
||||||
verboseLog(` ↳ Loaded ${loaded.length} resources`);
|
|
||||||
loadedResources.push(...loaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
verboseLog("Constructing playbill");
|
|
||||||
|
|
||||||
// -- COMPILE RESOURCES --//
|
|
||||||
const playbill = getEmptyPlaybill();
|
|
||||||
|
|
||||||
playbill.id = binding.id;
|
|
||||||
playbill.name = binding.name;
|
|
||||||
playbill.author = binding.author;
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- VALDATE PLAYBILL -- //
|
// -- VALDATE PLAYBILL -- //
|
||||||
verboseLog("Validating playbill");
|
verboseLog("Validating playbill");
|
||||||
const validatedPlaybill = ValidatedPlaybillSchema.safeParse(playbill);
|
const validatedPlaybill = ValidatedPlaybillSchema.safeParse(binding.playbill);
|
||||||
|
|
||||||
if (!validatedPlaybill.success) {
|
if (!validatedPlaybill.success) {
|
||||||
console.error("Error validating playbill");
|
console.error("Error validating playbill");
|
||||||
|
@ -202,7 +130,7 @@ try {
|
||||||
const exitCode = await main();
|
const exitCode = await main();
|
||||||
process.exit(exitCode);
|
process.exit(exitCode);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof ResourceFileError) {
|
if (error instanceof MuseError) {
|
||||||
console.error(chalk.red(error.fmt()));
|
console.error(chalk.red(error.fmt()));
|
||||||
} else {
|
} else {
|
||||||
console.error("An unexpected error occurred");
|
console.error("An unexpected error occurred");
|
||||||
|
|
|
@ -5,8 +5,9 @@ import {
|
||||||
} from "@proscenium/playbill";
|
} from "@proscenium/playbill";
|
||||||
import YAML, { YAMLParseError } from "yaml";
|
import YAML, { YAMLParseError } from "yaml";
|
||||||
import { ZodError } from "zod";
|
import { ZodError } from "zod";
|
||||||
import { ResourceFileError } from "./errors";
|
import { MalformedResourceFileError } from "./errors";
|
||||||
import { extractFrontmatter, extractMarkdown } from "./markdown";
|
import { extractFrontmatter, extractMarkdown } from "./markdown";
|
||||||
|
import { loadFileOrFail } from "./files";
|
||||||
|
|
||||||
type FileFormat = "yaml" | "markdown";
|
type FileFormat = "yaml" | "markdown";
|
||||||
|
|
||||||
|
@ -18,13 +19,13 @@ function loadYamlResourceFile(filePath: string, text: string): AnyResource[] {
|
||||||
const parsedDocs = YAML.parseAllDocuments(text);
|
const parsedDocs = YAML.parseAllDocuments(text);
|
||||||
|
|
||||||
if (parsedDocs.some((doc) => doc.toJS() === null)) {
|
if (parsedDocs.some((doc) => doc.toJS() === null)) {
|
||||||
throw new ResourceFileError("Encountered NULL resource", filePath);
|
throw new MalformedResourceFileError("Encountered NULL resource", filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const errors = parsedDocs.flatMap((doc) => doc.errors);
|
const errors = parsedDocs.flatMap((doc) => doc.errors);
|
||||||
|
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
throw new ResourceFileError(
|
throw new MalformedResourceFileError(
|
||||||
"Error parsing YAML resource",
|
"Error parsing YAML resource",
|
||||||
filePath,
|
filePath,
|
||||||
errors.map((e) => e.message).join(", "),
|
errors.map((e) => e.message).join(", "),
|
||||||
|
@ -35,10 +36,20 @@ function loadYamlResourceFile(filePath: string, text: string): AnyResource[] {
|
||||||
|
|
||||||
for (const doc of parsedDocs) {
|
for (const doc of parsedDocs) {
|
||||||
const raw = doc.toJS();
|
const raw = doc.toJS();
|
||||||
const parsed = AnyResourceSchema.parse(raw);
|
const parsed = AnyResourceSchema.safeParse(raw);
|
||||||
const type = parsed.$define;
|
|
||||||
|
if (!parsed.success) {
|
||||||
|
throw new MalformedResourceFileError(
|
||||||
|
"Failed to parse resource",
|
||||||
|
filePath,
|
||||||
|
`Schema validation failed: ${parsed.error.message}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedResource = parsed.data;
|
||||||
|
const type = parsedResource.$define;
|
||||||
const schemaToUse = ResourceMap[type];
|
const schemaToUse = ResourceMap[type];
|
||||||
const validated = schemaToUse.parse(parsed);
|
const validated = schemaToUse.parse(parsedResource);
|
||||||
collection.push(validated);
|
collection.push(validated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +73,7 @@ function loadMarkdownResourceFile(
|
||||||
return [parsed];
|
return [parsed];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof YAMLParseError) {
|
if (e instanceof YAMLParseError) {
|
||||||
throw new ResourceFileError(
|
throw new MalformedResourceFileError(
|
||||||
"Error parsing Markdown frontmatter",
|
"Error parsing Markdown frontmatter",
|
||||||
filePath,
|
filePath,
|
||||||
e.message,
|
e.message,
|
||||||
|
@ -70,7 +81,7 @@ function loadMarkdownResourceFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof ZodError) {
|
if (e instanceof ZodError) {
|
||||||
throw new ResourceFileError(
|
throw new MalformedResourceFileError(
|
||||||
"Error parsing resource file",
|
"Error parsing resource file",
|
||||||
filePath,
|
filePath,
|
||||||
e.message,
|
e.message,
|
||||||
|
@ -92,8 +103,7 @@ function loadMarkdownResourceFile(
|
||||||
export async function loadResourceFile(
|
export async function loadResourceFile(
|
||||||
filePath: string,
|
filePath: string,
|
||||||
): Promise<AnyResource[]> {
|
): Promise<AnyResource[]> {
|
||||||
const file = Bun.file(filePath);
|
const text = await loadFileOrFail(filePath);
|
||||||
const text = await file.text();
|
|
||||||
const format = determineFileFormat(filePath);
|
const format = determineFileFormat(filePath);
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|
|
@ -13,5 +13,6 @@ Options:
|
||||||
--write Write the output to a file. If not specified, outputs to stdout
|
--write Write the output to a file. If not specified, outputs to stdout
|
||||||
--outfile Specify the output file path [default: playbill.json]
|
--outfile Specify the output file path [default: playbill.json]
|
||||||
--verbose, -v Verbose output
|
--verbose, -v Verbose output
|
||||||
|
--minify, -m Minify the output JSON
|
||||||
--help, -h Show this help message
|
--help, -h Show this help message
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue