|
| 1 | +// --- |
| 2 | +// id: zod-middleware |
| 3 | +// title: Zod Middleware |
| 4 | +// description: | |
| 5 | +// As another example of middleware, we can look at how to integrate [Zod](https://npmjs.com/zod). CLI Forge |
| 6 | +// provides a middleware function under `cli-forge/middleware/zod` that can be used to validate, parse, transform, |
| 7 | +// and otherwise manipulate command arguments using Zod schemas. |
| 8 | + |
| 9 | +// commands: |
| 10 | +// - '{filename} hello --name sir' |
| 11 | +// --- |
| 12 | +import cliForge from 'cli-forge'; |
| 13 | +import { zodMiddleware } from 'cli-forge/middleware/zod'; |
| 14 | +import { z } from 'zod'; |
| 15 | + |
| 16 | +const cli = cliForge('basic-cli') |
| 17 | + // Requires a command to be provided |
| 18 | + .demandCommand() |
| 19 | + |
| 20 | + // Registers "hello" command |
| 21 | + .command('hello', { |
| 22 | + // Builder is used to define the command's options |
| 23 | + builder: (args) => |
| 24 | + args |
| 25 | + .option('name', { |
| 26 | + type: 'string', |
| 27 | + description: 'The name to say hello to', |
| 28 | + default: 'World', |
| 29 | + }) |
| 30 | + // Middleware registered on parent commands will be invoked before the child command's middleware |
| 31 | + .middleware( |
| 32 | + zodMiddleware( |
| 33 | + z |
| 34 | + .object({ |
| 35 | + name: z |
| 36 | + .string() |
| 37 | + .min(2, 'Name must be at least 2 characters long'), |
| 38 | + }) |
| 39 | + .transform((data) => ({ |
| 40 | + name: data.name.trim().toUpperCase(), |
| 41 | + snakeCase: data.name.trim().replace(/\s+/g, '_').toLowerCase(), |
| 42 | + })) |
| 43 | + ) |
| 44 | + ), |
| 45 | + |
| 46 | + // Handler is used to define the command's behavior |
| 47 | + handler: (args) => { |
| 48 | + console.log(`Hello, ${args.name}!`); |
| 49 | + console.log(`sssssnake_case: ${args.snakeCase}`); |
| 50 | + }, |
| 51 | + }); |
| 52 | + |
| 53 | +// We export the CLI for a few reasons: |
| 54 | +// - Testing |
| 55 | +// - Composition (a CLI can be a subcommand of another CLI) |
| 56 | +// - Docs generation |
| 57 | +export default cli; |
| 58 | + |
| 59 | +// Calling `.forge()` executes the CLI. It's single parameter is the CLI args |
| 60 | +// and they default to `process.argv.slice(2)`. |
| 61 | +if (require.main === module) { |
| 62 | + (async () => { |
| 63 | + await cli.forge(); |
| 64 | + })(); |
| 65 | +} |
0 commit comments