Clean up exports

This commit is contained in:
Endeavorance 2025-04-03 09:36:56 -04:00
parent afbb0cbaa5
commit b5136c5d02
4 changed files with 40 additions and 48 deletions

View file

@ -1,6 +1,6 @@
import path, { dirname } from "node:path"; import path, { dirname } from "node:path";
import { Glob } from "bun"; import { Glob } from "bun";
import { FileNotFoundError, MuseError } from "./errors"; import { MuseFileNotFoundError, MuseError } from "./errors";
import { parseMuseFile } from "./parse"; import { parseMuseFile } from "./parse";
import { import {
type Binding, type Binding,
@ -33,6 +33,7 @@ async function loadProcessor(
description: processorDescription, description: processorDescription,
}; };
} }
/** /**
* Given a path, find the binding file * Given a path, find the binding file
* If the path is to a directory, check for a binding inside * If the path is to a directory, check for a binding inside
@ -42,7 +43,7 @@ async function loadProcessor(
* @param bindingPath - The path to the binding file * @param bindingPath - The path to the binding file
* @returns The absolute resolved path to the binding file * @returns The absolute resolved path to the binding file
*/ */
export async function resolveBindingPath(bindingPath: string): Promise<string> { async function resolveBindingPath(bindingPath: string): Promise<string> {
// If the path does not specify a filename, use binding.yaml // If the path does not specify a filename, use binding.yaml
const inputLocation = Bun.file(bindingPath); const inputLocation = Bun.file(bindingPath);
@ -77,13 +78,13 @@ export async function resolveBindingPath(bindingPath: string): Promise<string> {
return mdPath; return mdPath;
} }
throw new FileNotFoundError(bindingPath); throw new MuseFileNotFoundError(bindingPath);
} }
const exists = await inputLocation.exists(); const exists = await inputLocation.exists();
if (!exists) { if (!exists) {
throw new FileNotFoundError(bindingPath); throw new MuseFileNotFoundError(bindingPath);
} }
// If it is a file, return the path // If it is a file, return the path
@ -103,21 +104,8 @@ export async function loadBinding(initialPath: string): Promise<Binding> {
// Load and parse the Binding YAML content // Load and parse the Binding YAML content
const parsedBinding = BindingSchema.parse(loadedBindingData[0].data); const parsedBinding = BindingSchema.parse(loadedBindingData[0].data);
// Prepare collections to load into
const extendsFrom: Binding[] = [];
const entries: MuseEntry[] = [];
// Process imported bindings and bring in their entries
for (const includePath of parsedBinding.include) {
const pathFromHere = path.resolve(bindingDirname, includePath);
const extendBindingPath = await resolveBindingPath(pathFromHere);
const loadedBinding = await loadBinding(extendBindingPath);
extendsFrom.push(loadedBinding);
entries.push(...loadedBinding.entries);
}
// Aggregate file paths to import // Aggregate file paths to import
const includedFilePaths = parsedBinding.files const includedFilePaths = parsedBinding.sources
.flatMap((thisGlob) => { .flatMap((thisGlob) => {
return Array.from( return Array.from(
new Glob(thisGlob).scanSync({ new Glob(thisGlob).scanSync({
@ -131,16 +119,15 @@ export async function loadBinding(initialPath: string): Promise<Binding> {
.filter((filePath) => filePath !== bindingPath); .filter((filePath) => filePath !== bindingPath);
// Load files // Load files
const loadedEntries = await Promise.all( const entries: MuseEntry[] = (
includedFilePaths.map((filePath) => { await Promise.all(
return parseMuseFile(filePath, { includedFilePaths.map((filePath) => {
contentKey: parsedBinding.contentKey, return parseMuseFile(filePath, {
}); contentKey: parsedBinding.contentKey,
}), });
); }),
)
// Add loaded entries to main list ).flat();
entries.push(...loadedEntries.flat());
// Load and check processors // Load and check processors
const processors: MuseProcessor[] = await Promise.all( const processors: MuseProcessor[] = await Promise.all(
@ -154,7 +141,6 @@ export async function loadBinding(initialPath: string): Promise<Binding> {
entries, entries,
options: parsedBinding.options, options: parsedBinding.options,
processors: processors, processors: processors,
imports: extendsFrom,
meta: {}, meta: {},
}; };
} }

View file

@ -4,7 +4,7 @@ export class MuseError extends Error {
} }
} }
export class FileError extends MuseError { export class MuseFileError extends MuseError {
filePath: string; filePath: string;
details?: string; details?: string;
@ -19,7 +19,7 @@ export class FileError extends MuseError {
} }
} }
export class FileNotFoundError extends FileError { export class MuseFileNotFoundError extends MuseFileError {
constructor(filePath: string) { constructor(filePath: string) {
super("File not found", filePath); super("File not found", filePath);
this.message = "File not found"; this.message = "File not found";
@ -27,4 +27,4 @@ export class FileNotFoundError extends FileError {
} }
} }
export class CLIError extends MuseError {} export class CLIError extends MuseError { }

View file

@ -1,2 +1,3 @@
export type * from "./types"; export type * from "./types";
export * from "./errors";
export const DEFAULT_CONTENT_KEY = "content"; export const DEFAULT_CONTENT_KEY = "content";

View file

@ -1,5 +1,7 @@
import { z } from "zod"; import { z } from "zod";
export type UnknownRecord = Record<string, unknown>;
export interface CLIFlags { export interface CLIFlags {
help: boolean; help: boolean;
verbose: boolean; verbose: boolean;
@ -12,32 +14,27 @@ export interface CLIArguments {
} }
export const BindingSchema = z.object({ export const BindingSchema = z.object({
include: z.array(z.string()).default([]),
contentKey: z.string().default("content"), contentKey: z.string().default("content"),
files: z sources: z
.array(z.string()) .array(z.string())
.default(["**/*.yaml", "**/*.md", "**/*.toml", "**/*.json"]), .default(["**/*.yaml", "**/*.md", "**/*.toml", "**/*.json"]),
options: z.record(z.string(), z.any()).default({}), options: z.record(z.string(), z.any()).default({}),
processors: z.array(z.string()).default([]), processors: z.array(z.string()).default([]),
renderer: z.string().optional(),
}); });
export interface Binding {
readonly _raw: z.infer<typeof BindingSchema>;
readonly bindingPath: string;
readonly contentKey: string;
readonly entries: MuseEntry[];
readonly meta: Record<string, unknown>;
readonly options: Record<string, unknown>;
readonly processors: MuseProcessor[];
readonly imports: Binding[];
}
export type MuseProcessorFn = ( export type MuseProcessorFn = (
binding: Binding, binding: Binding,
opts: Record<string, unknown>, opts: Record<string, unknown>,
flags: CLIFlags, flags: CLIFlags,
) => Promise<Binding>; ) => Promise<Binding>;
export type MuseRenderFn = (
binding: Binding,
opts: UnknownRecord,
flags: CLIFlags,
) => Promise<boolean>;
export interface MuseProcessor { export interface MuseProcessor {
readonly filePath: string; readonly filePath: string;
readonly name: string; readonly name: string;
@ -45,11 +42,19 @@ export interface MuseProcessor {
readonly process: MuseProcessorFn; readonly process: MuseProcessorFn;
} }
export interface MuseEntry { export interface MuseEntry<MetaShape = UnknownRecord> {
_raw: string; _raw: string;
filePath: string; filePath: string;
data: Record<string, unknown>; data: Record<string, unknown>;
meta: Record<string, unknown>; meta: MetaShape;
} }
export type UnknownRecord = Record<string, unknown>; export interface Binding<MetaShape = UnknownRecord> {
readonly _raw: z.infer<typeof BindingSchema>;
readonly bindingPath: string;
readonly contentKey: string;
readonly entries: MuseEntry[];
readonly processors: MuseProcessor[];
readonly meta: MetaShape;
readonly options: UnknownRecord;
}