feat(view-options): add saved view options API - #665
Conversation
doistbot
left a comment
There was a problem hiding this comment.
This PR adds a clean saved view-options API surface — a new sub-client, public TodoistApi methods (get/set/delete), expanded Zod schemas, and a findViewOptions helper — that follows the existing sub-client and Sync request conventions nicely.
Few things worth tightening:
ViewOptionsSetArgstypesdeadlineandcalendarSettingsas non-null, but the response schema marks both as nullable and the siblingProjectViewOptionsDefaultsSetArgsalready accepts| null. This means callers can't send{ deadline: null }or{ calendarSettings: null }to clear an existing saved value — add| nullto both fields.
I also included a few optional follow-up notes in the details below.
Optional follow-up notes (3)
src/utils/view-options.ts:19: The "active view option" check (
isDeleted !== true) is now duplicated inViewOptionsClient.getViewOptions(src/clients/view-options-client.ts:14) and here infindViewOptions, both added in this PR. Extract a shared helper (e.g.isActiveViewOption) so the definition of "active" lives in one place and can't drift between the two.src/todoist-api.view-options.test.ts:133:
findViewOptionsis a utility insrc/utils/view-options.ts, but its tests are embedded in theTodoistApiview-options test file. Every other utility in this repo has a matchingsrc/utils/<name>.test.ts. Move thisdescribeblock intosrc/utils/view-options.test.tsto keep the test layout consistent and the utility testable independently of the API surface.src/todoist-api.ts:362: These three public methods only have one-line summaries, while every other method on
TodoistApidocuments@paramand@returns. Add the matching JSDoc (e.g.@param args,@param requestId,@returns) so IDE hints and generated docs stay consistent for this public SDK surface.
`td filter view` printed tasks in whatever order the API returned. Todoist doesn't sort server-side: every client applies the sorting saved on the view, and falls back to a documented default hierarchy when the view has none, which is what "Manual (default)" means in the app. The CLI read neither piece, so a saved filter listed in an order no other Todoist client shows. Reads the saved options with `api.getViewOptions()` and orders the results with `sortTasks`, both from the SDK. What lives here is the part the SDK asks the caller to supply: the vocabulary `--sort` speaks, the mapping from a saved view to that vocabulary, the sidebar layout it wants as a lookup, and the guess at whether a filter query is date-driven, which picks between the priority-first and date-first hierarchies. Adds `--sort default|priority|date|deadline|date-added|name|project|assignee| workspace|none` and `--sort-order asc|desc`, resolved flag first, then saved view, then Todoist default. `--sort none` returns the raw API order. Each section of a comma-separated filter sorts on its own, and `--json` / `--ndjson` come back in the same order as the pretty output. BLOCKED: needs the SDK release carrying Doist/todoist-sdk-typescript#665 and #666, plus the v14 bump in #477. `package.json` still pins 13.0.2, so this branch does not build until both land and the pin moves. Closes #473 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
f55acd2 to
726dc1c
Compare
doistbot
left a comment
There was a problem hiding this comment.
This PR adds a clean saved view-options API surface — sub-client, public TodoistApi methods, expanded Zod schemas, and reusable helpers — that follows existing Sync conventions.
Few things worth tightening:
ViewOptionsSetArgs.viewModeis still typed as non-nullViewMode, but the response schema now allowsnulland the siblingProjectViewOptionsDefaultsSetArgs.viewModealready acceptsViewMode | null. Add| nullso callers can clear a saved view mode via{ viewMode: null }, matching every other nullable field in the set args.
I also left one optional follow-up note in the details below.
Optional follow-up note (1)
src/utils/view-options.test.ts:31: The test title claims
objectIdis matched both whennulland when omitted, but only the omitted case is exercised.FindViewOptionsArgs.objectIdexplicitly acceptsstring | null, andfindViewOptionsnormalizes both via?? null— passobjectId: nullin this assertion too (or narrow the title) so the null path is covered and the name matches what's actually tested.
`td filter view` printed tasks in whatever order the API returned. Todoist doesn't sort server-side: every client applies the sorting saved on the view, and falls back to a documented default hierarchy when the view has none, which is what "Manual (default)" means in the app. The CLI read neither piece, so a saved filter listed in an order no other Todoist client shows. Reads the saved options with `api.getViewOptions()` and orders the results with `sortTasks`, both from the SDK. What lives here is the part the SDK asks the caller to supply: the vocabulary `--sort` speaks, the mapping from a saved view to that vocabulary, the sidebar layout it wants as a lookup, and the guess at whether a filter query is date-driven, which picks between the priority-first and date-first hierarchies. Adds `--sort default|priority|date|deadline|date-added|name|project|assignee| workspace|none` and `--sort-order asc|desc`, resolved flag first, then saved view, then Todoist default. `--sort none` returns the raw API order. Each section of a comma-separated filter sorts on its own, and `--json` / `--ndjson` come back in the same order as the pretty output. BLOCKED: needs the SDK release carrying Doist/todoist-sdk-typescript#665 and #666, plus the v14 bump in #477. `package.json` still pins 13.0.2, so this branch does not build until both land and the pin moves. Closes #473 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every other exported shape in src/ is declared with export type. This was the only export interface, so bring it in line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
🎉 This PR is included in version 14.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
`td filter view` printed tasks in whatever order the API returned. Todoist doesn't sort server-side: every client applies the sorting saved on the view, and falls back to a documented default hierarchy when the view has none, which is what "Manual (default)" means in the app. The CLI read neither piece, so a saved filter listed in an order no other Todoist client shows. Reads the saved options with `api.getViewOptions()` and orders the results with `sortTasks`, both added to the SDK by @gnapse in Doist/todoist-sdk-typescript#665 and #666. What lives here is the part the SDK asks the caller to supply: the vocabulary `--sort` speaks, the mapping from a saved view to that vocabulary, the sidebar layout it wants as a lookup, and the guess at whether a filter query is date-driven, which picks between the priority-first and date-first hierarchies. Adds `--sort default|priority|date|deadline|date-added|name|project|assignee| workspace|none` and `--sort-order asc|desc`, resolved flag first, then saved view, then Todoist default. `--sort none` returns the raw API order. Each section of a comma-separated filter sorts on its own, and `--json` / `--ndjson` come back in the same order as the pretty output. Closes #473 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`td filter view` printed tasks in whatever order the API returned. Todoist doesn't sort server-side: every client applies the sorting saved on the view, and falls back to a documented default hierarchy when the view has none, which is what "Manual (default)" means in the app. The CLI read neither piece, so a saved filter listed in an order no other Todoist client shows. Reads the saved options with `api.getViewOptions()` and orders the results with `sortTasks`, both added to the SDK by @gnapse in Doist/todoist-sdk-typescript#665 and #666. What lives here is the part the SDK asks the caller to supply: the vocabulary `--sort` speaks, the mapping from a saved view to that vocabulary, the sidebar layout it wants as a lookup, and the guess at whether a filter query is date-driven, which picks between the priority-first and date-first hierarchies. Adds `--sort default|priority|date|deadline|date-added|name|project|assignee| workspace|none` and `--sort-order asc|desc`, resolved flag first, then saved view, then Todoist default. `--sort none` returns the raw API order. Each section of a comma-separated filter sorts on its own, and `--json` / `--ndjson` come back in the same order as the pretty output. Closes #473 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`td filter view` printed tasks in whatever order the API returned. Todoist doesn't sort server-side: every client applies the sorting saved on the view, and falls back to a documented default hierarchy when the view has none, which is what "Manual (default)" means in the app. The CLI read neither piece, so a saved filter listed in an order no other Todoist client shows. Reads the saved options with `api.getViewOptions()` and orders the results with `sortTasks`, both added to the SDK by @gnapse in Doist/todoist-sdk-typescript#665 and #666. What lives here is the part the SDK asks the caller to supply: the vocabulary `--sort` speaks, the mapping from a saved view to that vocabulary, the sidebar layout it wants as a lookup, and the guess at whether a filter query is date-driven, which picks between the priority-first and date-first hierarchies. Adds `--sort default|priority|date|deadline|date-added|name|project|assignee| workspace|none` and `--sort-order asc|desc`, resolved flag first, then saved view, then Todoist default. `--sort none` returns the raw API order. Each section of a comma-separated filter sorts on its own, and `--json` / `--ndjson` come back in the same order as the pretty output. Closes #473 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
TodoistApi.Example
Validation
todoist-cli#463locally to useTodoistApi.setViewOptions()from a packed local SDK build. Its full test and check suites passed.Context
This is the first PR in the stack. It lets SDK consumers use saved view options without parsing raw Sync responses.
Related CLI work:
Stack created with GitHub Stacks CLI • Give Feedback 💬