citty
citty copied to clipboard
CLI Plugins
inspired from https://github.com/unjs/citty/issues/98#issuecomment-2011718215 by @jgoux
With plugins, we can allow them to intercept to different hooks but also preserve their context. We can extend to more hooks if needed.
Example:
const telemetryPlugin = defineCittyPlugin(() => {
const telemetry = new TelemetryClient();
return {
name: 'telemetry',
async setup() {
telemetry.init();
await telemetry.captureEvent(`$command:${ctx.cmd.meta.name}:start`);
},
async cleanup() {
await telemetry.captureEvent(`$command:${ctx.cmd.meta.name}:end`);
telemetry.flush();
}
}
})
defineCommand({
meta: {
name: "hello",
version: "1.0.0",
description: "My Awesome CLI App",
},
plugins: [telemetryPlugin],
run({ args }) {
console.log(`${args.friendly ? "Hi" : "Greetings"} ${args.name}!`);
},
})
Sounds good to me! 👍
Hello there, I was looking for a kind of interceptor/plugin for citty that I could hook without changing a command's code, and stumbled upon #98 and this issue. @Barbapapazes made some initial work on it, I was wondering if there was any other conversation to resume or abandon the idea?
My use case is the following:
There's a cli using citty, and we wanted to do a wrapper on top of it for a few commands of ours. So we import it's main defineCommand, merge with our commands and provide that to the main defineCommand as subcommands.
For a command ABC from said cli, I'd like it to invoke N commands/functions of mine before/after, but not touch anything the other CLI does because I want it's behavior to happen.
So, in that fashion, I think we can just make a setup() on our main defineCommand which will check the context.args._[0] to know which command was called and do what needs to be done before the other command runs for our case, and that should be enough.
But I was wondering if a plugin would look cleaner? idk. Visually the suggested approach felt just like vue2 mixin which I liked to use back then so I'm biased lol.