UNPKG

bluecodex

Version:

Turn repetitive dev tasks into CLI commands with Typescript

293 lines (232 loc) 6.34 kB
import chalk from "chalk"; import path from "node:path"; import type { Alias } from "../alias/alias"; import type { Arg } from "../arg/arg"; import type { Command } from "../command/command"; import type { Flag } from "../flag/flag"; import { ioc } from "../ioc"; import { ParseArgvMalformattedInputError } from "../parse-argv/errors/parse-argv-malformatted-input-error"; export class ThemeClass { /* * Colors */ styleDim(text: string) { return chalk.dim(text); } stylePrimary(text: string) { return chalk.blueBright(text); } styleLocal(text: string) { return chalk.magenta(text); } styleBold(text: string) { return chalk.bold(text); } styleShell(text: string) { return chalk.yellowBright(text); } styleSuccess(text: string) { return chalk.greenBright(text); } styleWarning(text: string) { return chalk.yellowBright(text); } styleError(text: string) { return chalk.redBright(text); } /* * Data type */ rangeText({ min, max }: { min: number | null; max: number | null }) { if (min === null) return `<= ${max}`; if (max === null) return `>= ${min}`; return `>= ${min} and <= ${max}`; } /* * Arg */ requiredArgName(arg: Arg) { return arg.name; } optionalArgName(arg: Arg) { return this.styleDim(`${arg.name}?`); } argType(arg: Arg) { return this.styleDim(`:${arg.type}`); } argFallback(arg: Arg) { if (arg.fallback === null) return; return this.styleDim(`=${arg.fallback}`); } arg(arg: Arg) { return [ arg.optional ? this.optionalArgName(arg) : this.requiredArgName(arg), this.argType(arg), this.argFallback(arg), ] .filter(Boolean) .join(""); } /* * Flag */ flagName(flag: Flag) { const text = [ flag.short === true ? "-" : "--", flag.name, flag.required && "!", ] .filter(Boolean) .join(""); return flag.required ? text : this.styleDim(text); } flagShort(flag: Flag) { if (!flag.short) return; return this.styleDim(`(-${flag.short})`); } flagType(flag: Flag) { return this.styleDim(`:${flag.type}`); } flagFallback(flag: Flag) { if (flag.fallback === null) return; return this.styleDim(`=${flag.fallback}`); } flag(flag: Flag) { return [ this.flagName(flag), this.flagShort(flag), this.flagType(flag), this.flagFallback(flag), ] .filter(Boolean) .join(""); } /* * Command */ commandName(command: Command) { if (command.meta.local) { return `${this.styleLocal("⎇")} ${this.stylePrimary(`${command.blueprint.name}`)}`; } return this.stylePrimary(`⎇ ${command.blueprint.name}`); } commandParts(command: Command) { return command.blueprint.fields .map((part) => part.__objectType__ === "flag" ? this.flag(part) : this.arg(part), ) .filter(Boolean) .join(" "); } embeddedCommandGroupTitle() { return this.styleDim(this.stylePrimary("§ bluecodex")); } ungroupedCommandGroupTitle() { return this.styleDim(this.stylePrimary("∅ no group")); } commandGroupTitle(title: string) { return this.styleDim(`${this.stylePrimary("⧉")} ${title}`); } command(command: Command, aliases: Alias[]) { const firstLine = [ " ", this.commandName(command), this.commandParts(command), ] .filter(Boolean) .join(" "); const aliasesLine = [ " ", this.styleDim("└ "), aliases.map((alias) => ioc.theme.aliasName(alias)).join(" "), ].join(""); return [firstLine, aliases.length > 0 && aliasesLine] .filter(Boolean) .join("\n"); } aliasName(alias: Alias) { if (alias.meta.local) { return `${this.styleLocal("⌁")} ${this.stylePrimary(`${alias.name}`)}`; } return this.stylePrimary(`⌁ ${alias.name}`); } aliasTarget(alias: Alias) { return alias.target; } alias(alias: Alias) { return this.aliasName(alias) + this.styleDim("=") + this.aliasTarget(alias); } shellAliasesGroupTitle() { return this.styleDim(`${this.stylePrimary("$")} Shell aliases`); } commandOrAliasNotFound(name: string) { return `Command or alias ${this.styleError(`⎇ ${name}`)} not found`; } commandAlreadyRegisteredMessage(command: Command) { return `Command with name "${command.blueprint.name}" already exists.`; } aliasAlreadyRegisteredMessage(commandAlis: Alias) { return `Alias with name "${commandAlis.name}" already exists.`; } /* * Run */ runBinName(name: string) { return this.styleShell(`$ ${name}`); } runPackageBinName(name: string) { return this.styleShell(`$ ${name}`); } runArgv(argv: string[]) { return argv.join(" "); } runSpawn(name: string, argv: string[]) { return this.styleDim( [this.runBinName(name), this.runArgv(argv)].filter(Boolean).join(" "), ); } runSpawnPackageBin(name: string, argv: string[]) { return this.styleDim( [this.runPackageBinName(name), this.runArgv(argv)] .filter(Boolean) .join(" "), ); } runCommand(command: Command, argv: string[]) { return this.styleDim( [this.commandName(command), this.runArgv(argv)].filter(Boolean).join(" "), ); } runNotFound(name: string) { return ( this.styleError("[error]") + ` ${name} was not found.\n` + this.styleDim( "It's not in your $PATH, an npm package executable, or a bluecodex command.", ) ); } /* * Parse argv */ parseArgvMalformattedInputErrorMessage( error: ParseArgvMalformattedInputError, ) { return `Invalid input ${this.styleError(error.input)} for ${error.field.__objectType__} ${this.styleBold(`${error.field.name}:${error.field.type}`)}`; } /* * File */ relativePath(filePath: string) { return path.relative(ioc.project.rootPath, filePath); } fileCreated(filePath: string) { return this.styleSuccess(`+ ${this.relativePath(filePath)} created`); } fileUpdated(filePath: string) { return this.styleSuccess(`◉ ${this.relativePath(filePath)} updated`); } fileDeleted(filePath: string) { return this.styleSuccess(`- ${this.relativePath(filePath)} deleted`); } }