Zod Middleware

As another example of middleware, we can look at how to integrate Zod. CLI Forge provides a middleware function under cli-forge/middleware/zod that can be used to validate, parse, transform, and otherwise manipulate command arguments using Zod schemas.

All Example Files

FILE EXPLORER
zod.ts
1import cliForge from 'cli-forge';
2import { zodMiddleware } from 'cli-forge/middleware/zod';
3import { z } from 'zod';
4
5const cli = cliForge('basic-cli')
6  // Requires a command to be provided
7  .demandCommand()
8
9  // Registers "hello" command
10  .command('hello', {
11    // Builder is used to define the command's options
12    builder: (args) =>
13      args
14        .option('name', {
15          type: 'string',
16          description: 'The name to say hello to',
17          default: 'World',
18        })
19        // Middleware registered on parent commands will be invoked before the child command's middleware
20        .middleware(
21          zodMiddleware(
22            z
23              .object({
24                name: z
25                  .string()
26                  .min(2, 'Name must be at least 2 characters long'),
27              })
28              .transform((data) => ({
29                name: data.name.trim().toUpperCase(),
30                snakeCase: data.name.trim().replace(/\s+/g, '_').toLowerCase(),
31              }))
32          )
33        ),
34
35    // Handler is used to define the command's behavior
36    handler: (args) => {
37      console.log(`Hello, ${args.name}!`);
38      console.log(`sssssnake_case: ${args.snakeCase}`);
39    },
40  });
41
42// We export the CLI for a few reasons:
43// - Testing
44// - Composition (a CLI can be a subcommand of another CLI)
45// - Docs generation
46export default cli;
47
48// Calling `.forge()` executes the CLI. It's single parameter is the CLI args
49// and they default to `process.argv.slice(2)`.
50if (require.main === module) {
51  (async () => {
52    await cli.forge();
53  })();
54}
55