You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You can define sub commands and attach them to main command to create a nested command structure. This is recursive so you can attach sub commands to sub commands, etc.
83
+
84
+
```js
85
+
import { defineCommand, runMain } from"citty";
86
+
87
+
// First, you define a new command
88
+
constsub=defineCommand({
89
+
meta: {
90
+
name:"sub",
91
+
description:"Sub command",
92
+
},
93
+
args: { // Sub commands can have their own arguments like any other command
94
+
name: {
95
+
type:"positional",
96
+
description:"Your name",
97
+
required:true,
98
+
},
99
+
},
100
+
run({ args }) { // Command can be async
101
+
console.log(`Hello ${args.name}!`);
102
+
},
103
+
});
104
+
105
+
// Then, you define a main command and attach sub command to it
106
+
constmain=defineCommand({
107
+
meta: {
108
+
name:"hello",
109
+
version:"1.0.0",
110
+
description:"My Awesome CLI App",
111
+
},
112
+
commands: {
113
+
sub, // Attach sub command to main command
114
+
},
115
+
});
116
+
117
+
runMain(main);
118
+
```
119
+
120
+
### Hooks
121
+
122
+
`citty` supports a `setup` and `cleanup` functions that are called before and after command execution. This is useful for setting up and cleaning up resources.
123
+
124
+
Only the `setup` and `cleanup` functions from the command called are executed. For example, if you run `hello sub`, only the `setup` and `cleanup` functions from `sub` command are executed and not the ones from `hello` command.
125
+
126
+
```js
127
+
import { defineCommand, runMain } from"citty";
128
+
129
+
constmain=defineCommand({
130
+
meta: {
131
+
name:"hello",
132
+
version:"1.0.0",
133
+
description:"My Awesome CLI App",
134
+
},
135
+
setup() { // Setup function is called before command execution or before any sub command execution
136
+
console.log("Setting up...");
137
+
},
138
+
cleanup() { // Cleanup function is called after command execution or after any sub command execution
139
+
console.log("Cleaning up...");
140
+
},
141
+
run() {
142
+
console.log("Hello World!");
143
+
},
144
+
});
145
+
146
+
runMain(main);
147
+
```
148
+
149
+
### Lazy Load Commands
150
+
151
+
For large CLI apps, you may want to only load the command that is being executed.
152
+
153
+
First, create a command in a file and export it.
154
+
155
+
```js
156
+
import { defineCommand } from"citty";
157
+
158
+
exportdefaultdefineCommand({
159
+
meta: {
160
+
name:"sub",
161
+
description:"Sub command",
162
+
},
163
+
run({ args }) {
164
+
console.log(`Hello ${args.name}!`);
165
+
},
166
+
});
167
+
```
168
+
169
+
Then, create the main command and import the sub command.
170
+
171
+
```js
172
+
constmain=defineCommand({
173
+
meta: {
174
+
name:"hello",
175
+
version:"1.0.0",
176
+
description:"My Awesome CLI App",
177
+
},
178
+
commands: {
179
+
sub: () =>import("./sub.js").then((m) =>m.default), // Lazy Import Sub Command
180
+
},
181
+
});
182
+
```
183
+
184
+
Now, when you run `hello sub`, the sub command will be loaded and executed. This avoid to load all commands at once.
185
+
186
+
### Publish CLI App as an Executable
187
+
188
+
You must first bundle your CLI app. To do so, you can use [`unjs/unbuild`](https://github.com/unjs/unbuild).
189
+
190
+
Then, you must create a file named `index.mjs` in a folder named `bin` at the root of your package. This file must export the main command from the `dist` build.
191
+
192
+
```js
193
+
#!/usr/bin/env node
194
+
195
+
import { runMain } from'../dist/index.mjs'
196
+
197
+
runMain()
198
+
```
199
+
200
+
Then, you will need to update your `package.json` file to enable the usage as a CLI:
201
+
202
+
```json
203
+
{
204
+
"type": "module",
205
+
"bin": "./bin/index.mjs",
206
+
// Name of the CLI will be the name of the package. You can provide an object to change the name.
0 commit comments