Fix annotations publish/delete to reflect all fields in output#242
Fix annotations publish/delete to reflect all fields in output#242umair-ably merged 4 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR fixes the output of Changes
Review Notes
|
There was a problem hiding this comment.
Review: Fix annotations publish/delete to reflect all fields in output
The JSON fix (conditional spread to avoid undefined fields) is correct and the new labeled non-JSON output is a good improvement. Two issues worth addressing:
Issue 1 — publish.ts: data and encoding missing from non-JSON output (field parity violation)
The JSON path now conditionally includes data and encoding when provided, but the non-JSON else block only shows Type, Name, and Count. Per project conventions, non-JSON output must expose the same fields as JSON output (omitting only null/undefined values).
If a user runs:
ably channels annotations publish my-channel serial123 reactions:flag.v1 --data '{"foo":"bar"}' --encoding utf-8
The --json output will include data and encoding, but the human-readable output silently drops them. This makes the two modes inconsistent and hides the fact that those fields were actually sent.
Fix: Add conditional this.log blocks for data and encoding in the non-JSON path, mirroring the pattern used for count.
Issue 2 — Both files: logCliEvent still passes name: flags.name unconditionally
The PR correctly fixed logJsonResult to avoid name: undefined, but logCliEvent in both files still does:
{ channel: channelName, serial, type, name: flags.name }This passes name: undefined into the verbose log context when no --name was given. While this is lower-severity than the JSON output bug (verbose logs are not user-facing in normal use), it's inconsistent with the stated goal of the PR.
Issue 3 — No regression tests for the specific bug fix
The test for JSON output in publish.test.ts only asserts channel and serial are present. It does not verify:
nameis absent when not provided (the bug this PR fixes)count,data,encodingare present when provided
If this regresses, no test would catch it. Worth adding a test case like "should not include undefined fields in JSON output" that publishes without --name and asserts result.annotation does not have a name key.
Summary
| File | Issues |
|---|---|
src/commands/channels/annotations/publish.ts |
data/encoding missing from non-JSON output; logCliEvent passes name: undefined |
src/commands/channels/annotations/delete.ts |
logCliEvent passes name: undefined |
test/unit/commands/channels/annotations/publish.test.ts |
No test for absent-field correctness in JSON output |
Issue 1 is the most impactful as it causes a visible inconsistency between --json and human output. Issues 2 and 3 are lower priority but worth fixing while you're in this area.
There was a problem hiding this comment.
Review: Fix annotations publish/delete to reflect all fields in output
This is a clean, focused fix. The JSON output bug (name: undefined included unconditionally) is correctly resolved, and the new labeled non-JSON output is structured properly. A couple of minor things worth checking:
src/commands/channels/annotations/publish.ts — data field parity
In JSON mode, annotation.data is emitted (the parsed value — e.g., {"foo":"bar"} becomes {foo: "bar"}). In non-JSON mode, flags.data is shown (the raw input string). These diverge when the user passes a JSON payload:
$ ably channels annotations publish … --data '{"foo":"bar"}'
- JSON output:
"data": {"foo": "bar"}(object) - Non-JSON output:
Data: {"foo":"bar"}(string)
For a human-readable display, showing the raw input isn't wrong, but it can surprise users who are cross-checking the two modes. Consider using JSON.stringify(annotation.data, null, 2) (or similar) in the non-JSON path so both surfaces reflect the same interpretation.
test/unit/commands/channels/annotations/delete.test.ts — no coverage for new non-JSON output
The PR adds tests for the JSON fixes (conditional name field) but doesn't test the new non-JSON labels (Type, Name) added to delete. The publish.test.ts at least has one non-JSON test for Data/Encoding. delete.test.ts has none for the new lines.
Not a blocker, but a quick expect(stdout).toContain("Type") test in the "functionality" block would give confidence the non-JSON path works.
Everything else looks good
logCliEventandlogJsonResultboth correctly fixed in both files — no strayname: flags.nameremaining- All new
this.log()calls are inside theelsebranch (properly guarded) formatLabel/formatResourceused correctly, no rawchalk.cyan()or quoted strings- Flag architecture unchanged and correct (
productApiFlags,clientIdFlag) - Error handling unchanged and correct (
this.fail(), nothis.error()) - Test describe blocks follow standard naming
The data-parity note is a quality improvement, not a blocker. The missing delete non-JSON test is low risk given the simplicity of the change. Ready to merge if the team is comfortable with the data display divergence.
…he reaction type/name
…arsed data in JSON
…de, add non-JSON delete test
fe1c578 to
646da6b
Compare
|
Missing fields |
…n output, use conditional spread for optional JSON fields
sacOO7
left a comment
There was a problem hiding this comment.
Thanks for addressing feedback : )
LGTM
Summary
count,data, andencodingfrom the response, and always includedname(even whenundefined). Now all fields are conditionally included only when provided.Applies to both
annotations publishandannotations delete.Before (JSON)
{"annotation":{"channel":"...","serial":"...","type":"metrics:total.v1","name":undefined}}After (JSON)
{"annotation":{"channel":"...","serial":"...","type":"metrics:total.v1"}} {"annotation":{"channel":"...","serial":"...","type":"rating:multiple.v1","name":"stars","count":4}}Before (non-JSON)
After (non-JSON)
Test plan
pnpm exec eslint .— 0 errorspnpm test test/unit/commands/channels/annotations/— 68 tests pass🤖 Generated with Claude Code