{"id":51096153,"url":"https://github.com/lassoColombo/nu-http-client-generator","last_synced_at":"2026-07-12T11:00:36.261Z","repository":{"id":360067326,"uuid":"1248534717","full_name":"lassoColombo/nu-http-client-generator","owner":"lassoColombo","description":null,"archived":false,"fork":false,"pushed_at":"2026-07-08T07:34:32.000Z","size":8172,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-08T09:11:45.895Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Nushell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lassoColombo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T19:11:27.000Z","updated_at":"2026-07-08T07:34:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lassoColombo/nu-http-client-generator","commit_stats":null,"previous_names":["lassocolombo/nu-http-client-generator"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lassoColombo/nu-http-client-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lassoColombo%2Fnu-http-client-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lassoColombo%2Fnu-http-client-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lassoColombo%2Fnu-http-client-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lassoColombo%2Fnu-http-client-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lassoColombo","download_url":"https://codeload.github.com/lassoColombo/nu-http-client-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lassoColombo%2Fnu-http-client-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35390360,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-24T07:00:24.915Z","updated_at":"2026-07-12T11:00:36.254Z","avatar_url":"https://github.com/lassoColombo.png","language":"Nushell","funding_links":[],"categories":["Scripts"],"sub_categories":[],"readme":"# nu-http-client-generator\n\nReads an API specification and generates a typed Nushell HTTP client module.\n\n[![asciicast](https://asciinema.org/a/IQtLxd5nJoZSf0AW.svg)](https://asciinema.org/a/IQtLxd5nJoZSf0AW)\n\n- [Supported specs](#supported-specs)\n- [Quick start](#quick-start)\n- [Installation](#installation)\n- [Subcommands](#subcommands)\n- [Generation flags](#generation-flags)\n  - [Source \u0026 output](#source-\u0026-output)\n  - [Filtering](#filtering)\n  - [Naming](#naming)\n  - [Runtime defaults](#runtime-defaults)\n  - [Module behaviour](#module-behaviour)\n- [Using a generated client](#using-a-generated-client)\n  - [Passing inputs](#passing-inputs)\n  - [Request bodies](#request-bodies)\n  - [Auth](#auth)\n  - [Tab completion and dry runs](#tab-completion-and-dry-runs)\n  - [Introspecting the client](#introspecting-the-client)\n- [How command names get built](#how-command-names-get-built)\n- [Acknowledgments](#acknowledgments)\n\n## Supported specs\n\n| Format  | Versions               |\n| ------- | ---------------------- |\n| OpenAPI | 3.0.x, 3.1.x           |\n| Swagger | 2.0                    |\n\nSpecs can be loaded from a local file or fetched directly from a URL.\n\n---\n\n## Quick start\n\n```nu\nuse nu-http-client-generator\n\n# Generate from a file\nnu-http-client-generator ./petstore.yaml -o ./petstore.nu\n\n# Generate from a URL\nnu-http-client-generator https://petstore3.swagger.io/api/v3/openapi.json -o ./petstore.nu\n\n# Preview what would be generated (no file written)\nnu-http-client-generator preview ./petstore.yaml\n```\n\nThen use it:\n\n```nu\nuse petstore.nu\n\npetstore pet-find-by-status findPetsByStatus --status available | where status == \"available\"\npetstore pet get 10\npetstore store-inventory get --token $env.PETSTORE_TOKEN\n```\n\n---\n\n## Installation\n\n```nu\n# Clone into one of your NU_LIB_DIRS\nlet dest = [($env.NU_LIB_DIRS | first) nu-http-client-generator] | path join\ngit clone git@github.com:lassoColombo/nu-http-client-generator.git $dest\n\n# Use the module\nuse nu-http-client-generator\nnu-http-client-generator --help\n```\n\n---\n\n## Subcommands\n\n| Command                                   | Purpose                                       |\n| ----------------------------------------- | --------------------------------------------- |\n| `nu-http-client-generator \u003csrc\u003e`          | Generate a client from OpenAPI/Swagger.       |\n| `nu-http-client-generator preview \u003csrc\u003e`  | List the commands that would be generated.   |\n\n`\u003csrc\u003e` is either a local file path or an `http(s)://` URL.\n\n---\n\n## Generation flags\n\n### Source \u0026 output\n\n| Flag                       | Default            | Description                                                                                                                |\n| -------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------- |\n| `-o, --output: path`       | `./{title}.nu`     | Where to write the generated module.                                                                                       |\n| `--name: string`           | spec `info.title`  | Module name. Used as the file stem (when `-o` is not set), as the prefix of the token env var, and as the command namespace. |\n| `--autocompletion-base-urls: list\u003cstring\u003e` | spec servers | Extra base URLs in `--base-url`'s tab-completer. First becomes the baked default when `--default-base-url` is unset.         |\n| `--default-base-url: string` | spec / none      | Override the base URL embedded in the module.                                                                              |\n| `--default-unix-socket: string` | none           | Talk to the API over this Unix socket by default. Bakes `UNIX_SOCKET` + a `--unix-socket` flag into every command (the Docker case). |\n| `--autocompletion-unix-sockets: list\u003cstring\u003e` | none | Unix socket paths in the `--unix-socket` tab-completer. First becomes the baked default when `--default-unix-socket` is unset. |\n| `--spec-headers: record`   | `{}`               | Headers used when fetching a remote spec (e.g. `{Authorization: \"Bearer …\"}`). Does not appear in the generated client.    |\n\n### Filtering\n\nFilters apply to both the generation command and `preview`. Combine freely.\n\n| Flag                            | Description                                                                              |\n| ------------------------------- | ---------------------------------------------------------------------------------------- |\n| `--tags: list\u003cstring\u003e`          | Only operations tagged with one of these.                                                |\n| `--prefixes: list\u003cstring\u003e`      | Only paths starting with one of these prefixes (e.g. `[\"/pet\"]`).                        |\n| `--methods: list\u003cstring\u003e`       | Only these HTTP methods (e.g. `[get post]`). Case-insensitive.                           |\n| `--exclude-deprecated`          | Skip operations marked deprecated in the spec.                                           |\n\n### Naming\n\n| Flag                  | Default | Description                                                                                                                                                |\n| --------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `--verb-map: record`  | `{}`    | Override the action verb in command names. The key is the original verb (from the `operationId` or HTTP method), the value is the replacement. Example: `{retrieve: \"fetch\", list: \"ls\"}`. |\n\nDefault action-verb rewrites baked in: `retrieve` → `get`, `destroy` → `delete`, `partial_update` → `patch`.\n\n### Runtime defaults\n\nThese flags control the behaviour of the *generated* commands. They don't affect generation itself - they get embedded as defaults.\n\n| Flag                            | Default     | Description                                                                                                                |\n| ------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |\n| `--token-env-var: string`       | `\u003cNAME\u003e_TOKEN` | The env-var the generated `build-auth` helper falls back to when `--token` is not passed. Derived from `--name` by default. |\n| `--default-timeout: string`     | `\"30min\"`   | Default request timeout. Overridable per-call via `--max-time`.                                                            |\n| `--default-headers: record`     | `{}`        | Headers merged into every request the client makes (e.g. `{X-Tenant-Id: \"acme\"}`).                                          |\n\n### Module behaviour\n\n| Flag                  | Default | Description                                                                                                                          |\n| --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |\n| `--body-threshold: int` | `0`     | When the body has more than this many fields, collapse them into a single `--body: record` flag. `0` = never collapse. |\n| `--no-introspection`  | off     | Omit the auto-generated `commands` subcommand from the module.                                                                       |\n| `--no-descriptions`   | off     | Omit the `# description` comments next to each parameter in the generated signatures. Keeps doc lines above each `def` regardless.   |\n\n---\n\n## Using a generated client\n\nA generated client is a regular Nushell module:\n```nu\nuse petstore.nu\npetstore pet get 10\n```\n\nEvery command follows the same `\u003cresource\u003e \u003cverb\u003e` shape, object first and action second.   \nAlongside the spec-derived flags, every command also ships with the same set of built-in flags:\n\n| Flag              | Short | Type       | Purpose                                                                                          |\n| ----------------- | ----- | ---------- | ------------------------------------------------------------------------------------------------ |\n| `--base-url`      | `-b`  | `string`   | Override the base URL. Tab-completes from spec servers + `--autocompletion-base-urls`.           |\n| `--token`         | `-t`  | `string`   | Auth token. Falls back to `$env.\u003cNAME\u003e_TOKEN`.                                                   |\n| `--auth-scheme`   | `-a`  | `string`   | Override the auth scheme. Tab-completes from schemes the spec declared.                          |\n| `--insecure`      | `-k`  | switch     | Skip TLS certificate verification.                                                               |\n| `--max-time`      | `-m`  | `duration` | Per-request timeout. Defaults to `--default-timeout` from generation.                            |\n| `--raw`           | `-r`  | switch     | Return the response body as text (no JSON parsing).                                              |\n| `--allow-errors`  | `-e`  | switch     | Return the full HTTP response record instead of erroring on non-2xx.                             |\n| `--dry-run`       | `-n`  | switch     | Return the request that *would* be sent as a structured record (method, url, query, headers, body, auth, …) without executing it.    |\n| `--accept`        |       | `string`   | Override the `Accept` header. Only present on operations whose spec declares more than one response content type; tab-completes from those types. |\n| `--unix-socket`   | `-U`  | `string`   | Connect over a Unix socket instead of TCP. Only present when the client was generated with `--default-unix-socket` / `--autocompletion-unix-sockets`; defaults to the baked `UNIX_SOCKET`, pass `\"\"` to force TCP. |\n\n### Passing inputs\n\nRequired path parameters are positional, in the order they appear in the path.   \nEverything else - query strings, headers, cookies - becomes a `--flag`.   \nEnum-typed params get tab-completion automatically, and boolean query params render as plain switches:\n```nu\npetstore pet get 10\npetstore pet-find-by-status findPetsByStatus --status available\n```\n\n### Request bodies\n\nRequest bodies show up in one of two shapes, depending on the spec. When the body schema exposes flat top-level fields, each one becomes its own flag and required scalars become positional - the most ergonomic form, but only available when the schema is clean enough to enumerate. When the schema is freeform, deeply nested, or has been collapsed by `--body-threshold`, the entire payload goes through a single `--body: record` flag instead:\n\n```nu\npetstore user createUser --body {\n  username: \"alice\"\n  firstName: \"Alice\"\n  email: \"alice@example.com\"\n  password: \"s3cret\"\n}\n```\n\nEither form also accepts pipeline input. In practice this means you can shape the bulk of the payload from a file or upstream pipe and then patch in last-moment overrides via flags:\n\n```nu\nopen new-user.json | petstore user createUser --userStatus 1\n```\n\nA few edge cases bake in transparently. File-typed body fields accept a path: the generator opens it with `open --raw` and inlines the bytes into a multipart request - so a file upload command like `petstore pet-upload-image uploadFile 10 ~/photos/rex.jpg` will read the file from disk and attach it for you. And `DELETE` endpoints with a body work despite Nushell's `http delete` expecting `--data` rather than a positional argument.\n\nIf you generated with `--body-threshold N`, any endpoint with more than N body fields collapses its per-field flags into the single `--body: record` form.\n\n### Auth\n\nAt call time the client resolves a token by checking `--token` first, then `$env.\u003cNAME\u003e_TOKEN`. You can customize the default token name at generation time by using the `--token-env-var` flag.\nThe scheme comes from `--auth-scheme` if set, otherwise the default the spec declared - or `bearer` if the spec didn't declare one. If the scheme resolves to `none` or no token turns up, the request goes out unauthenticated.\n\nThe generator knows about `jwt`, `bearer`, `basic`, `private-token`, `query-*` (token in the query string), `cookie-*` (token in a cookie), and `none`. Anything else falls back to `Authorization: Bearer \u003ctoken\u003e`. The base URL is baked into the module header so you can see it at a glance:\n\n```nu\n# Auth: --token flag or $env.PETSTORE_TOKEN\nconst BASE_URL = \"https://petstore3.swagger.io/api/v3\"\n```\n\n### Tab completion and dry runs\n\n`--base-url` completes from the spec's `servers` list plus anything you passed via `--autocompletion-base-urls` at generation time, and `--auth-scheme` completes from the schemes the spec declared (plus `none` if any operation was marked public). When the client was generated with `--default-unix-socket` / `--autocompletion-unix-sockets`, `--unix-socket` completes from the baked default plus those paths. Enum-typed parameters each get their own completer, with identical enum sets deduplicated across the module - one completer per unique enum, not one per parameter.\n\n`--dry-run` is useful when you want to see what a call would do without actually making it. It returns a structured request record so you can sanity-check the shape before it hits production - or assert against individual fields in tests:\n\n```nu\n\u003e petstore user createUser --body {username: \"alice\", email: \"alice@example.com\"} --dry-run\n╭──────────────┬────────────────────────────────────────────────────────────╮\n│ dry_run      │ true                                                       │\n│ method       │ post                                                       │\n│ url          │ https://petstore3.swagger.io/api/v3/user                   │\n│ query        │ {}                                                         │\n│ headers      │ {Authorization: \"Bearer …\", Accept: \"application/json\"}    │\n│ body         │ {username: \"alice\", email: \"alice@example.com\"}            │\n│ content_type │ application/json                                           │\n│ timeout      │ 30min                                                      │\n│ auth         │ {scheme: \"bearer\", location: \"header\"}                     │\n╰──────────────┴────────────────────────────────────────────────────────────╯\n```\n\n| Field | Meaning |\n|---|---|\n| `dry_run: true` | Marker — distinguishes a dry-run record from a real response. |\n| `method` | Lowercase HTTP verb. |\n| `url` | The final URL as it would be sent on the wire (including any auth-token query fragment). |\n| `query` | The user-passed query params as a record keyed by spec param name, with nulls dropped. Use this for tests instead of parsing the URL. |\n| `headers` | The final merged headers as they would be sent — including the resolved `Authorization` and `Accept`. |\n| `body` | The **logical** body the caller expressed: a record for JSON/form-urlencoded/multipart, a string for text/xml, or `null` when there's no body. Form-urlencoded and multipart specifically: this is the record **before** wire serialization, so `$r.body.field == \"value\"` works regardless of content-type. |\n| `content_type` | The effective content-type the real request would use. |\n| `timeout` | The effective timeout (a `duration`). |\n| `auth` | `{scheme, location}` — which scheme actually fired and where the token went: `\"header\"`, `\"query\"`, `\"cookie\"`, or `\"none\"`. |\n\nSecrets are not redacted — `$r.url` and `$r.headers.Authorization` contain the actual token that would be sent. If you log dry-run records, strip them first: `$r | update headers.Authorization \"[REDACTED]\"`.\n\n### Introspecting the client\n\nUnless you generated with `--no-introspection`, the module exposes a `commands` subcommand that returns a table of every command, its parameters and their types, whether each is optional, the descriptions, and the return type. It's handy both for scripting against the client itself and for browsing what's available when you're new to a spec:\n\n```nu\npetstore commands | where name =~ \"pet\" | select name return_type\npetstore commands | get params | first 5\n```\n\n---\n\n## How command names get built\n\nNames follow `\u003cresource\u003e \u003cverb\u003e`: the path segments form the resource - with path params and version chunks like `v1`/`v2` stripped - and the verb comes from the operation's `operationId` (its trailing camelCase chunk) or the HTTP method. So `GET /pet/{petId}` becomes `pet get`, and `POST /pet/{petId}/uploadImage` becomes `pet-upload-image uploadFile`.\n\nCollisions get resolved in a few specific ways. The most common case is a collection-vs-item pair, where two GET endpoints differ only by a single path parameter (imagine a spec with both `GET /users` and `GET /users/{userId}`); in that case the collection variant is renamed `list` rather than suffixed. Any other collision is disambiguated by appending `-by-\u003cpath-param-name\u003e` - you'd end up with `users get-by-userId` - and if even that leaves duplicates, a numeric suffix (`-1`, `-2`) is appended on top. An `operationId` ending in `_\u003cnumber\u003e` (a common pattern in machine-generated specs) triggers the `-by-\u003cparams\u003e` rename pre-emptively so you don't end up with numeric suffixes everywhere. Reserved Nushell identifiers (`get`, `delete`, `in`, `version`, `nothing`) are forbidden as standalone names and get sanitized whenever they'd otherwise appear bare.\n\n---\n\n## Acknowledgments\n\nTests are powered by [nutest](https://github.com/vyadh/nutest), an incredible testing framework for nushell.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FlassoColombo%2Fnu-http-client-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FlassoColombo%2Fnu-http-client-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FlassoColombo%2Fnu-http-client-generator/lists"}