Skip to content

Add cart set/update/remove with bulk patch + fix cart clear (#7)#8

Open
axelpaul wants to merge 2 commits into
arnif:mainfrom
axelpaul:feature/cart-update-remove
Open

Add cart set/update/remove with bulk patch + fix cart clear (#7)#8
axelpaul wants to merge 2 commits into
arnif:mainfrom
axelpaul:feature/cart-update-remove

Conversation

@axelpaul

@axelpaul axelpaul commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

The CLI previously only supported cart, cart add, and cart clear. There was no safe way to correct a single bad item — agents had to nuke the whole cart and rebuild. And as reported in #7, cart clear itself was actually broken.

This PR adds:

  • cart set '<json>' — replace the whole cart with JSON lines (accepts either an array of {sku,quantity,substitution?} or an object map {sku:qty})
  • cart update <sku-or-line-id> --quantity N — single-line update; --quantity 0 removes
  • cart update '<json-patch>' — bulk patch: listed SKUs are set to the given qty (0 removes), unlisted lines are untouched, new SKUs are added when qty > 0
  • cart remove <sku-or-line-id> — shorthand for --quantity 0
  • --dry-run on set, update, remove, clear — prints the planned cart and skips the API call

And fixes:

  • cart clear (closes "kronan cart clear" ekki að virka #7)POST /checkout/lines/ with {lines: [], replace: true} is silently a no-op against the live Krónan API; the CLI was printing "Cart cleared." without checking the response. Worked around by detecting the empty-replace case inside replaceCheckoutLines and resending the existing lines with quantity: 0, which the backend honours. cartClearCommand now also throws if the response still contains lines, so silent regressions surface.

The workaround applies transparently to every code path that produces an empty cart (cart clear, cart set '[]', cart update/remove of the last remaining line, bulk patches that zero out the cart).

Implementation notes

  • Substitution is preserved from existing lines unless explicitly overridden in the patch; new lines default to substitution: true.
  • Identifier resolution for single-line update matches by exact SKU or numeric checkout line id, dedupes by line id, and refuses ambiguous matches.
  • Bulk update rejects empty patches and duplicate SKUs.
  • Both update forms use POST /checkout/lines/ with replace: true (the documented default).
  • Help text and the README are updated with examples.

Test plan

  • bun run check (lint + typecheck + 27 tests) passes
  • Unit tests for parseCartLinesJson cover both shapes, negatives, non-integers, missing SKU, non-number values, scalar JSON
  • CLI tests confirm new commands appear in help and bad invocations error cleanly
  • Live smoke-tested against a real authenticated cart:
    • cart addcart clear → cart actually empty (was the bug in "kronan cart clear" ekki að virka #7)
    • cart clear on an already-empty cart → no-op, prints success
    • cart update <sku> --quantity 3 → quantity changes, other lines preserved
    • cart update <line-id> --quantity 0 → line removed
    • cart update '{"<sku>":2,"<other>":0,"NEW":1}' → update + remove + add in one call, untouched lines preserved
    • cart update '{"<only-sku>":0}' → cart actually emptied (workaround kicked in)
    • Unknown identifier → No cart line matched "..."
    • Negative quantity / empty patch / duplicate SKU in patch → rejected

Closes #7.

axelpaul added 2 commits May 20, 2026 13:54
Exposes safe per-line cart edits so agents can correct individual items
without rebuilding the whole cart. Adds:

- cart set '<json>'              replace whole cart (array or {sku:qty} map)
- cart update <sku|id> --quantity N   single-line update; 0 removes
- cart update '<json-patch>'     bulk patch: listed SKUs set/removed,
                                 untouched SKUs preserved, new SKUs added
- cart remove <sku|id>           shorthand for --quantity 0
- --dry-run on set/update/remove/clear prints the planned cart without
  hitting the API

Substitution is preserved from existing lines unless overridden in the
patch. Single-line update refuses negatives, ambiguous matches, and
unknown identifiers with clear errors.
POST /checkout/lines/ with {lines: [], replace: true} is silently a
no-op against the live Krónan API — it returns the unchanged checkout
instead of clearing it. The CLI was printing "Cart cleared." regardless,
because it never inspected the response.

Work around the API by detecting the empty-replace case inside
replaceCheckoutLines: fetch the current lines and resend them with
quantity: 0, which the backend honours. This transparently fixes:

- cart clear
- cart update <only-sku> --quantity 0
- cart remove <only-sku>
- cart set '[]'
- cart update '{"<sku>":0,...}' patches that zero out every line

Also harden cartClearCommand to throw if the API response still contains
lines, so silent regressions surface instead of being reported as success.

Verified live: add → clear leaves cart empty; clear-when-empty is a no-op;
bulk patch that zeroes the last line also empties the cart.
@axelpaul axelpaul changed the title Add cart set/update/remove with bulk patch Add cart set/update/remove with bulk patch + fix cart clear (#7) May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"kronan cart clear" ekki að virka

1 participant