Adds an invoiceninja-nixos flake input and two things built from it: - nixosConfigurations.invoiceninja-test-nginx/-caddy: manual test VMs, re-exported as-is from that repo rather than redefined here — same principle as this crate being a client of the SDK, not a second implementation of it. - checks.invoiceninja-cli: an automated nixosTest (tests/, adapted from invoiceninja-nixos's own test scaffolding) that boots a real Invoice Ninja instance and runs the actual invoiceninja-cli binary against it - create/list/get/update/invoice/payment/delete across clients, invoices, and payments - rather than raw curl. tests/common.nix's module import had to change from a relative ../nixos-module/invoiceninja.nix (which doesn't exist here) to a parameter threaded from the flake input's nixosModules.invoiceninja. Building the VM pulls from the invoiceninja-nixos cachix cache via a nixConfig block, mirroring that repo's own. Also fixes a wrong assumption the first version of this test's final assertion made, caught by actually running it against a real server: `clients list` with no `--status` does not exclude soft-deleted records - confirmed empirically (Invoice Ninja returns everything regardless of is_deleted unless status=active is passed explicitly). Corrected the test to check is_deleted via `clients get` instead, and fixed the misleadingly-incomplete --status doc comment in cli.rs that had the same wrong assumption baked in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.mdfor what's still missing (bulk actions, uploads, entity actions, non-CRUD endpoints) and the pattern those will follow.GOALS.mdcovers 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.