Additional directives
This commit is contained in:
parent
542d28cb53
commit
3c6d7c18cd
7 changed files with 304 additions and 166 deletions
343
src/index.ts
343
src/index.ts
|
@ -1,164 +1,211 @@
|
|||
import chalk from "chalk";
|
||||
import { parseArgs } from "node:util";
|
||||
import chalk from "chalk";
|
||||
import { loadBindingFile } from "./binding";
|
||||
import { DirectiveError, processLang } from "./lang";
|
||||
import {
|
||||
type AnyResource,
|
||||
ValidatedPlaybillSchema,
|
||||
getEmptyPlaybill,
|
||||
} from "./playbill-schema";
|
||||
import { loadResourceFile } from "./resource";
|
||||
import { version } from "../package.json" with { type: "json" };
|
||||
import { usage } from "./usage";
|
||||
|
||||
const { values: options, positionals: args } = parseArgs({
|
||||
args: Bun.argv.slice(2),
|
||||
options: {
|
||||
write: {
|
||||
short: "w",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
check: {
|
||||
short: "c",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
outfile: {
|
||||
short: "o",
|
||||
type: "string",
|
||||
default: "playbill.json",
|
||||
},
|
||||
help: {
|
||||
short: "h",
|
||||
default: false,
|
||||
type: "boolean",
|
||||
},
|
||||
verbose: {
|
||||
short: "v",
|
||||
default: false,
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
class CLIError extends Error { }
|
||||
|
||||
if (args.length === 0 || options.help) {
|
||||
console.log(`${chalk.bold("muse")} - Compile and validate Playbills for Proscenium
|
||||
${chalk.dim(`v${version}`)}
|
||||
async function main(): Promise<boolean> {
|
||||
// Parse command line arguments
|
||||
const { values: options, positionals: args } = parseArgs({
|
||||
args: Bun.argv.slice(2),
|
||||
options: {
|
||||
write: {
|
||||
short: "w",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
check: {
|
||||
short: "c",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
outfile: {
|
||||
short: "o",
|
||||
type: "string",
|
||||
default: "playbill.json",
|
||||
},
|
||||
help: {
|
||||
short: "h",
|
||||
default: false,
|
||||
type: "boolean",
|
||||
},
|
||||
verbose: {
|
||||
short: "v",
|
||||
default: false,
|
||||
type: "boolean",
|
||||
},
|
||||
minify: {
|
||||
short: "m",
|
||||
default: false,
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
|
||||
Usage:
|
||||
muse [/path/to/binding.yaml] <options>
|
||||
if (options.help) {
|
||||
console.log(usage);
|
||||
return true;
|
||||
}
|
||||
|
||||
Options:
|
||||
--check Only load and check the current binding and resources, but do not compile
|
||||
--write Write the output to a file. If not specified, outputs to stdout
|
||||
--outfile Specify the output file path [default: playbill.json]
|
||||
--verbose, -v Verbose output
|
||||
--help, -h Show this help message
|
||||
`);
|
||||
process.exit(0);
|
||||
if (options.check && options.write) {
|
||||
throw new CLIError("Cannot use --check and --write together");
|
||||
}
|
||||
|
||||
const VERBOSE = options.verbose;
|
||||
|
||||
/**
|
||||
* Log a message if the vervose flag has been set
|
||||
* @param msg - The message to log
|
||||
*/
|
||||
function v(msg: string) {
|
||||
if (VERBOSE) {
|
||||
console.log(chalk.dim(msg));
|
||||
}
|
||||
}
|
||||
|
||||
const bindingPath = args[0] ?? "./binding.yaml";
|
||||
|
||||
v(`Building Playbill with binding: ${bindingPath}`);
|
||||
|
||||
// Check if the binding file exists
|
||||
const bindingFileCheck = Bun.file(bindingPath);
|
||||
const bindingFileExists = await bindingFileCheck.exists();
|
||||
|
||||
if (!bindingFileExists) {
|
||||
throw new Error(`Binding file not found: ${bindingPath}`);
|
||||
}
|
||||
|
||||
const binding = await loadBindingFile(bindingPath);
|
||||
|
||||
v(`↳ Binding loaded with ${binding.files.length} associated resources`);
|
||||
|
||||
const loadedResources: AnyResource[] = [];
|
||||
|
||||
v("Loading resources");
|
||||
|
||||
// Load resources listed in the binding file
|
||||
for (const filepath of binding.files) {
|
||||
v(`↳ Loading ${filepath}`);
|
||||
const loaded = await loadResourceFile(filepath);
|
||||
v(` ↳ Loaded ${loaded.length} resources`);
|
||||
loadedResources.push(...loaded);
|
||||
}
|
||||
|
||||
v("Constructing playbill");
|
||||
|
||||
// Consjtruct the playbill object
|
||||
const playbill = getEmptyPlaybill();
|
||||
|
||||
playbill.id = binding.info.id;
|
||||
playbill.name = binding.info.name;
|
||||
playbill.author = binding.info.author ?? "Anonymous";
|
||||
playbill.version = binding.info.version;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate directives in descriptions for all resources
|
||||
v("Processing descriptions");
|
||||
for (const resource of loadedResources) {
|
||||
try {
|
||||
resource.description = await processLang(resource.description, playbill);
|
||||
} catch (error) {
|
||||
if (error instanceof DirectiveError) {
|
||||
console.error(
|
||||
`Error processing directives in ${resource.$define}/${resource.id}`,
|
||||
);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
console.error(error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the playbill object
|
||||
v("Validating playbill");
|
||||
const validatedPlaybill = ValidatedPlaybillSchema.safeParse(playbill);
|
||||
|
||||
if (!validatedPlaybill.success) {
|
||||
console.error("Error validating playbill");
|
||||
console.error(validatedPlaybill.error.errors);
|
||||
return false;
|
||||
}
|
||||
|
||||
v("Playbill validated");
|
||||
|
||||
// If --check is set, exit here
|
||||
if (options.check) {
|
||||
console.log(chalk.green("Playbill validated successfully"));
|
||||
return true;
|
||||
}
|
||||
|
||||
const finalizedPlaybill = JSON.stringify(
|
||||
validatedPlaybill.data,
|
||||
null,
|
||||
options.minify ? undefined : 2,
|
||||
);
|
||||
if (options.write) {
|
||||
await Bun.write(options.outfile, finalizedPlaybill);
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log(finalizedPlaybill);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.check && options.write) {
|
||||
console.error("Cannot use --check and --write together");
|
||||
try {
|
||||
const success = await main();
|
||||
if (success) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error(chalk.red(error.message));
|
||||
} else {
|
||||
console.error("An unknown error occurred");
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const VERBOSE = options.verbose;
|
||||
|
||||
function verboseLog(msg: string) {
|
||||
if (VERBOSE) {
|
||||
console.log(chalk.dim(msg));
|
||||
}
|
||||
}
|
||||
|
||||
const bindingPath = args[0] ?? "./binding.yaml";
|
||||
|
||||
verboseLog(`Using binding file: ${bindingPath}`);
|
||||
|
||||
// Check if the binding file exists
|
||||
const bindingFileCheck = Bun.file(bindingPath);
|
||||
const bindingFileExists = await bindingFileCheck.exists();
|
||||
|
||||
if (!bindingFileExists) {
|
||||
console.error(`Binding file not found: ${bindingPath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
verboseLog("↳ Binding file found");
|
||||
|
||||
const binding = await loadBindingFile(bindingPath);
|
||||
|
||||
verboseLog(
|
||||
`↳ Binding loaded with ${binding.files.length} associated resources`,
|
||||
);
|
||||
|
||||
const loadedResources: AnyResource[] = [];
|
||||
|
||||
verboseLog("Loading resources");
|
||||
|
||||
// Load resources listed in the binding file
|
||||
for (const filepath of binding.files) {
|
||||
verboseLog(`↳ Loading ${filepath}...`);
|
||||
const loaded = await loadResourceFile(filepath);
|
||||
verboseLog(` ↳ ${filepath} loaded with ${loaded.length} resources`);
|
||||
loadedResources.push(...loaded);
|
||||
}
|
||||
|
||||
verboseLog("Constructing playbill");
|
||||
|
||||
// Consjtruct the playbill object
|
||||
const playbill = getEmptyPlaybill();
|
||||
|
||||
playbill.id = binding.info.id;
|
||||
playbill.name = binding.info.name;
|
||||
playbill.author = binding.info.author ?? "Anonymous";
|
||||
playbill.version = binding.info.version;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
verboseLog("Validating playbill");
|
||||
|
||||
// Validate the playbill object
|
||||
const validatedPlaybill = ValidatedPlaybillSchema.parse(playbill);
|
||||
|
||||
verboseLog("Playbill validated");
|
||||
|
||||
if (options.write) {
|
||||
await Bun.write(options.outfile, JSON.stringify(validatedPlaybill, null, 2));
|
||||
} else if (!options.check) {
|
||||
console.log(validatedPlaybill);
|
||||
}
|
||||
|
||||
if (options.check) {
|
||||
console.log(chalk.green("Playbill validated successfully"));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue