From 49c9af4c213d5f420a405d860c0454fade26c297 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 30 Jun 2026 11:02:43 +0200 Subject: feat: name-to-id resolver with loud ambiguity errors --- firefly_cli/resolver.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 firefly_cli/resolver.py (limited to 'firefly_cli/resolver.py') diff --git a/firefly_cli/resolver.py b/firefly_cli/resolver.py new file mode 100644 index 0000000..7673af6 --- /dev/null +++ b/firefly_cli/resolver.py @@ -0,0 +1,35 @@ +# Copyright (C) 2026 Danilo M. GPL-2.0-only +from firefly_cli.errors import ResolutionError + +class Resolver: + def __init__(self, client): + self.client = client + + def _list(self, path): + resp = self.client.request("GET", path, params={"limit": 1000}) + out = [] + for item in resp.get("data", []): + attrs = item.get("attributes", {}) + out.append({"id": item.get("id"), **attrs}) + return out + + def _match(self, kind, items, name): + hits = [i for i in items if str(i.get("name", "")).lower() == name.lower()] + if len(hits) == 1: + return hits[0] + names = ", ".join(f'{i.get("name")}(id={i.get("id")})' for i in items) + if not hits: + raise ResolutionError( + f'No {kind} named "{name}". Available: {names or "(none)"}') + raise ResolutionError( + f'Ambiguous {kind} "{name}" matches ids ' + + ", ".join(i["id"] for i in hits)) + + def account(self, name): + return self._match("account", self._list("/api/v1/accounts"), name) + + def tag(self, name): + return self._match("tag", self._list("/api/v1/tags"), name) + + def category(self, name): + return self._match("category", self._list("/api/v1/categories"), name) -- cgit v1.2.3