awkawbandClaude Sonnet 5 1236a15ebb
CI / test (push) Canceled after 0s
CI / Build on the declared MSRV (push) Canceled after 0s
CI / Latest stable (advisory) (push) Canceled after 0s
Add entity action and PDF download to invoices/quotes/credits/purchase-orders
These four resources are the only ones with the SDK's
entity_action_methods! route. Adds:

- `action <id> <action>` - mark_sent, mark_paid, archive, restore,
  clone_to_invoice, clone_to_quote, auto_bill, delete (routed), returning
  the updated record.
- `download <id>...` - the rendered PDF, to stdout or `--out <path>`;
  more than one id streams a single merged PDF (Invoice Ninja's bulk
  download action).

New EntityResourceArgs/EntityAction in cli.rs rather than extending the
existing ResourceArgs/Action: Rust enums don't compose, and every
resource's `run` match on Action needs to stay exhaustive without a
catch-all arm for variants it doesn't support.

Found and fixed along the way: the Download variant's --output <path>
field collided by name with the global --output table|json flag,
causing clap to panic at runtime trying to downcast the wrong type.
Renamed to --out.

Extended tests/nixos-test.nix to exercise action/download for real
against the VM. That caught a test-ordering bug of its own - asserting
mark_sent on an invoice *after* paying it off, which correctly doesn't
revert status_id from paid back to sent - fixed by reordering the
subtests. nix flake check passes clean.

Also backfills two CHANGELOG.md gaps from earlier sessions: the VM test
and CI additions had never actually been logged there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-26 17:29:00 -04:00

invoiceninja-cli

A command-line client for the Invoice Ninja v5 API, built on invoiceninja-sdk.

Scaffold status. Every resource with a simple list/get/create/update/ delete API (33 of them) is wired up — see CLAUDE.md for what's still missing (bulk actions, uploads, entity actions, non-CRUD endpoints) and the pattern those will follow. GOALS.md covers what the crate is for and what it is not.

Development

Enter the dev shell (Rust toolchain via rust-overlay, matching the SDK's):

nix develop

Usage

Every subcommand needs an API token and, for a self-hosted install, a base URL. Both can be passed as flags or environment variables (the same names the SDK's own examples use):

export IN_API_TOKEN=...
# export IN_BASE_URL=https://your-domain.example/api/v1   # self-hosted only

invoiceninja-cli clients list
invoiceninja-cli clients list --all --status active,archived
invoiceninja-cli clients get <id>
invoiceninja-cli clients create --data '{"name": "Acme Inc"}'
invoiceninja-cli clients update <id> --data '{"city": "Springfield"}'
invoiceninja-cli clients delete <id>

create and update read the record body as JSON, from --data inline, --file <path> (- for stdin), or stdin if neither flag is given. update fetches the current record first and overlays the given fields on top of it, so you only need to mention what's changing — see the comment in src/body.rs for why that matters (Invoice Ninja's PUT is a full replace, not a patch).

Add --output json to any command for the full record instead of the table view's few key columns:

invoiceninja-cli --output json clients get <id>

Every other wired-up resource follows the same list/get/create/update/delete shape, e.g. invoiceninja-cli invoices list --status active or invoiceninja-cli purchase-orders get <id>. Run invoiceninja-cli --help for the full list.

S
Description
No description provided
Readme MIT
239 KiB
Languages
Rust 90.5%
Nix 9.5%