105 lines
2.3 KiB
TypeScript
105 lines
2.3 KiB
TypeScript
import { normalize, extname } from "node:path";
|
|
import YAML from "yaml";
|
|
import TOML from "smol-toml";
|
|
import EMDY from "@endeavorance/emdy";
|
|
import type { MuseEntry, UnknownRecord } from "./types";
|
|
|
|
function parseYAMLEntries(text: string): UnknownRecord[] {
|
|
const parsedDocs = YAML.parseAllDocuments(text);
|
|
|
|
if (parsedDocs.some((doc) => doc.toJS() === null)) {
|
|
throw new Error("Encountered NULL resource");
|
|
}
|
|
|
|
const errors = parsedDocs.flatMap((doc) => doc.errors);
|
|
|
|
if (errors.length > 0) {
|
|
throw new Error(
|
|
`Error parsing YAML resource: ${errors.map((e) => e.message).join(", ")}`,
|
|
);
|
|
}
|
|
|
|
const collection: UnknownRecord[] = parsedDocs.map((doc) => doc.toJS());
|
|
return collection;
|
|
}
|
|
|
|
function parseJSONEntries(text: string): UnknownRecord[] {
|
|
const parsed = JSON.parse(text);
|
|
|
|
if (Array.isArray(parsed)) {
|
|
return parsed;
|
|
}
|
|
|
|
if (typeof parsed === "object") {
|
|
return [parsed];
|
|
}
|
|
|
|
throw new Error("JSON resource must be an object or an array of objects");
|
|
}
|
|
|
|
function parseTOMLEntries(text: string): UnknownRecord[] {
|
|
const parsed = TOML.parse(text);
|
|
|
|
if (Array.isArray(parsed)) {
|
|
return parsed;
|
|
}
|
|
|
|
if (typeof parsed === "object") {
|
|
return [parsed];
|
|
}
|
|
|
|
throw new Error("TOML resource must be an object or an array of objects");
|
|
}
|
|
|
|
interface ParseMuseFileOptions {
|
|
contentKey?: string;
|
|
}
|
|
|
|
export async function parseMuseFile(
|
|
rawFilePath: string,
|
|
{ contentKey = "content" }: ParseMuseFileOptions = {},
|
|
): Promise<MuseEntry[]> {
|
|
const filePath = normalize(rawFilePath);
|
|
const file = Bun.file(filePath);
|
|
const fileType = extname(filePath).slice(1);
|
|
const rawFileContent = await file.text();
|
|
|
|
const partial = {
|
|
_raw: rawFileContent,
|
|
filePath,
|
|
meta: {},
|
|
};
|
|
|
|
if (fileType === "md") {
|
|
const parsed = EMDY.parse(rawFileContent, contentKey);
|
|
return [
|
|
{
|
|
...partial,
|
|
data: parsed,
|
|
},
|
|
];
|
|
}
|
|
|
|
if (fileType === "yaml") {
|
|
return parseYAMLEntries(rawFileContent).map((data) => ({
|
|
...partial,
|
|
data,
|
|
}));
|
|
}
|
|
|
|
if (fileType === "json") {
|
|
return parseJSONEntries(rawFileContent).map((data) => ({
|
|
...partial,
|
|
data,
|
|
}));
|
|
}
|
|
|
|
if (fileType === "toml") {
|
|
return parseTOMLEntries(rawFileContent).map((data) => ({
|
|
...partial,
|
|
data,
|
|
}));
|
|
}
|
|
|
|
throw new Error(`Unsupported file type: ${fileType}`);
|
|
}
|