also looking at this
fix(operations): the inventory read a location Hetzner no longer sends
#193The bug
toInventoryServer resolved a box's place name as:
text(raw?.datacenter?.location?.name) ?? text(raw?.datacenter?.name) ?? text(raw?.location)Hetzner has retired datacenter (it sends an explicit null) and nests the place under location as an object. So on a live listing:
datacenter.location.namemisses,datacenteris nulldatacenter.namemisses, same reasonlocationmisses, because it is{ name: 'fsn1' }andtext()only accepts a string
All three miss and every box reports no location at all. buddy cloud:sites prints the column empty for the whole fleet.
ts-cloud already knew
This is not new information to this package, which is what makes it worth fixing rather than shrugging at:
drivers/hetzner/resize.ts:116readsserver.location?.name ?? server.datacenter?.location.name- current shape first.drivers/hetzner/role-swap.tscarries a comment about the retirement and a regression suite for it, includingfalls back to the location now that datacenter is gonewith the note "The current API shape: datacenter null, location present."
operations/inventory.ts was written against the recorded fixtures, which still carry datacenter, so it picked up the legacy order and the string assumption. This is the third reader to need the same fallback.
The fix
A placeName() helper that accepts either { name } or a bare string, read in the current-shape-first order the rest of the package uses. Older fixtures with datacenter still resolve, and a non-Hetzner driver answering a flat string still resolves.
Also here
raw: any becomes ProviderServerPayload, matching the any sweep Chris ran over the copy that used to live in stacks (c379cee). Two notes on the shape:
- The flat
ipv4/ipv6/type/locationfields are declared alongside the nested ones, because this function's contract is that a simpler driver can satisfy it. The stacks copy did not read those, so its interface did not need them. datacenteris typed| nullbecause null is what the API actually sends. Stating that is what let the regression test drop the cast it needed at first - a cast there would have been the type disagreeing with reality.
Verification
- New test goes red on the old resolution (
24 pass / 1 fail) and green on the new. operations: 126 pass / 0 fail.- Full suite: 4331 pass / 0 fail (4382 across 327 files).
typecheckclean,lintclean (865 files),buildclean.
Follow-up to #192.
2 changed files on the files tab, with 0 review threads.