Skip to content

Commit d296323

Browse files
meshdeclaude
andauthored
feat: add scripted/non-interactive usage support (#31)
* feat: add scripted/non-interactive usage support Add four features for scripted/non-interactive CLI usage: - Typed parameter substitution (|boolean, |number, |file) with validation - Multipart file uploads via |file type params - Non-interactive body handling (editor no longer opens by default, use -e) - Structured JSON output via --json flag Also resolves all pre-existing clippy warnings across the codebase and bumps version to 0.6.0 (breaking: editor behavior change). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add one-time upgrade notice for v0.6.0 editor behavior change Shows a one-time warning on first run after upgrading that the editor no longer opens automatically for request bodies, and exits early so the user can re-run with awareness of the --edit-body flag. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update README with new v0.6.0 features Add documentation for request body handling, typed parameters (boolean, number, file), multipart file uploads, --edit-body, --body-file, and --json output flags. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e723d5a commit d296323

20 files changed

Lines changed: 1123 additions & 142 deletions

File tree

Cargo.lock

Lines changed: 120 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "hit-cli"
3-
version = "0.5.1"
3+
version = "0.6.0"
44
edition = "2021"
55
authors = ["Mehmood S. Deshmukh <meshde.md@gmail.com>"]
66
homepage = "https://usehit.dev"
@@ -29,7 +29,7 @@ hyper = "1.3.1"
2929
inquire = "0.7.5"
3030
openapiv3 = "1.0.1"
3131
regex = "1.10.4"
32-
reqwest = {version="0.12.3", features=["json"]}
32+
reqwest = {version="0.12.3", features=["json", "multipart"]}
3333
serde = {version="1.0.200", features=["derive"]}
3434
serde_json = "1.0"
3535
serde_yaml = "0.9"
@@ -40,5 +40,6 @@ tokio = {version = "1.37.0", features = ["full"]}
4040
[dev-dependencies]
4141
assert_cmd = "2.0.17"
4242
insta = {version="1.43.1", features=["json"]}
43+
mockito = "1.7"
4344
predicates = "3.1.3"
4445
rstest = "0.25.0"

README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,135 @@ hit run users get --user-id 47
258258
```
259259

260260

261+
### Request Body
262+
263+
Commands that use `POST`, `PUT`, or `PATCH` methods can include a request body in the config. Parameters in the body work the same way as route params — prefix them with `:` and pass values as command-line options.
264+
265+
```json
266+
{
267+
"commands": {
268+
"create-user": {
269+
"url": "{{API_URL}}/users",
270+
"method": "POST",
271+
"body": {
272+
"name": ":name",
273+
"email": ":email"
274+
}
275+
}
276+
}
277+
}
278+
```
279+
280+
```bash
281+
hit run create-user --name "Jane Doe" --email "jane@example.com"
282+
```
283+
284+
#### Editing the Body Before Sending
285+
286+
If you want to review or modify the request body in your system editor before sending, use the `--edit-body` (or `-e`) flag:
287+
288+
```bash
289+
hit run create-user --name "Jane Doe" --email "jane@example.com" --edit-body
290+
```
291+
292+
#### Providing the Body from a File
293+
294+
Instead of using the body defined in the config, you can provide a body from a file using `--body-file`:
295+
296+
```bash
297+
hit run create-user --body-file payload.json
298+
```
299+
300+
The file contents support environment variable substitution (double curly brace syntax) just like the config body.
301+
302+
### Typed Parameters
303+
304+
By default, all parameter values are substituted as strings. For JSON request bodies, you may need values to be a specific JSON type. `hit` supports type annotations on parameters using the `|type` suffix.
305+
306+
#### Boolean Parameters
307+
308+
Use `|boolean` to substitute the value as a JSON boolean (`true`/`false`) instead of a string:
309+
310+
```json
311+
{
312+
"commands": {
313+
"update-setting": {
314+
"url": "{{API_URL}}/settings",
315+
"method": "POST",
316+
"body": {
317+
"dryRun": ":dryRun|boolean",
318+
"name": ":name"
319+
}
320+
}
321+
}
322+
}
323+
```
324+
325+
```bash
326+
hit run update-setting --dry-run true --name "test"
327+
# Sends: {"dryRun": true, "name": "test"}
328+
```
329+
330+
#### Number Parameters
331+
332+
Use `|number` to substitute the value as a JSON number:
333+
334+
```json
335+
{
336+
"commands": {
337+
"list-items": {
338+
"url": "{{API_URL}}/items",
339+
"method": "POST",
340+
"body": {
341+
"limit": ":limit|number"
342+
}
343+
}
344+
}
345+
}
346+
```
347+
348+
```bash
349+
hit run list-items --limit 42
350+
# Sends: {"limit": 42}
351+
```
352+
353+
#### File Parameters
354+
355+
Use `|file` to upload a file as part of a multipart form request. When a file parameter is present, the request is automatically sent as `multipart/form-data`:
356+
357+
```json
358+
{
359+
"commands": {
360+
"upload": {
361+
"url": "{{API_URL}}/upload",
362+
"method": "POST",
363+
"body": {
364+
"document": ":filePath|file",
365+
"description": ":description"
366+
}
367+
}
368+
}
369+
}
370+
```
371+
372+
```bash
373+
hit run upload --file-path ./report.pdf --description "Monthly report"
374+
```
375+
376+
### JSON Output
377+
378+
By default, `hit` pretty-prints the response body with syntax highlighting. For scripted or non-interactive usage, the `--json` flag outputs the full response (URL, status code, headers, and body) as a single JSON object:
379+
380+
```bash
381+
hit run list-users --json
382+
```
383+
384+
This is useful for piping into `jq` or other tools:
385+
386+
```bash
387+
hit run list-users --json | jq '.body | fromjson | .[] | .name'
388+
```
389+
261390
### Inspecting the response of an API call
262391

263392
Normally, running a command would simply output the body of the response of the API call being made. If you would like to inspect the entire response including the status code and response headers, this can be done by running the command:

src/cli/env/use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ pub struct EnvUseArguments {
77
}
88

99
pub fn init(args: EnvUseArguments) -> Result<(), Box<dyn std::error::Error>> {
10-
Ok(set_env(args.env))
10+
set_env(args.env);
11+
Ok(())
1112
}

src/cli/ephenv/set.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ pub struct EphenvSetArguments {
88
}
99

1010
pub fn init(args: EphenvSetArguments) -> Result<(), Box<dyn std::error::Error>> {
11-
Ok(set_ephenv(args.key, args.value))
11+
set_ephenv(args.key, args.value);
12+
Ok(())
1213
}

0 commit comments

Comments
 (0)