fix(entities): honor configured baseUrl in entity links#10
Merged
Conversation
When a consumer constructs `new CommsApi(token, { baseUrl })`, the `.url`
field on returned entities (Channel, Thread, Conversation, Comment,
ConversationMessage, InboxThread) ignored the configured `baseUrl` and
always pointed at the hardcoded `https://comms.todoist.com`. The
url-building Zod schemas were module-level singletons, so the per-instance
`baseUrl` never reached them.
Each entity schema is now built by a `createXxxSchema(linkBaseUrl?)`
factory that threads the base into `getFullCommsURL`. The exported
`XxxSchema = createXxxSchema()` singletons and inferred types are
unchanged (non-breaking). Entity-producing clients hold a per-instance
schema built from a new `BaseClient.getLinkBaseUrl()`, which returns the
configured `baseUrl` as-is (trailing slash stripped), falling back to the
default web app when unset. `InboxThread.lastComment` uses
`createCommentSchema(linkBaseUrl)` so the nested link honors the base too.
Ported from Doist/twist-sdk-typescript#137.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doistbot
reviewed
May 22, 2026
Member
doistbot
left a comment
There was a problem hiding this comment.
This PR successfully ports the fix to ensure entity links honor the configured baseUrl by transitioning Zod schemas to a factory pattern. It is a solid architectural adjustment that achieves the correct behavior while preserving backwards compatibility. A few refinements are suggested to optimize performance by reusing schemas on hot paths and default configurations, improve maintainability by leveraging Zod's built-in methods to reduce duplication, handle trailing slashes consistently, and ensure the new helper logic is fully tested.
- Normalize a trailing slash in `getFullCommsURL` so direct schema
consumers (`createXxxSchema('https://x/')`) get the same single-slash
links as `CommsApi` clients; `getLinkBaseUrl` now returns the value
verbatim.
- Reuse the exported singleton schemas/list schemas when no custom
`baseUrl` is configured, so the common `new CommsApi(token)` path no
longer builds duplicate Zod wrappers per client.
- Lift the `getone` wrapped-comment schema off the request hot path to a
per-client field.
- Add `InboxThreadListSchema` and parse the inbox list through it.
- Export `createInboxThreadObjectSchema` per the all-schemas-exported rule.
- Tests: trailing-slash normalization for a direct schema consumer, and a
base-bound schema assertion through the add-comment helper (close/reopen
path).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doist-release-bot Bot
added a commit
that referenced
this pull request
May 22, 2026
## [0.2.1](v0.2.0...v0.2.1) (2026-05-22) ### Bug Fixes * **entities:** honor configured baseUrl in entity links ([#10](#10)) ([024d9cb](024d9cb))
Contributor
|
🎉 This PR is included in version 0.2.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Port of Doist/twist-sdk-typescript#137 to comms-sdk.
When a consumer constructs
new CommsApi(token, { baseUrl }), the.urlfield on every returned entity (Channel, Thread, Conversation, Comment, ConversationMessage, InboxThread) ignored the configuredbaseUrland always pointed at the hardcodedhttps://comms.todoist.com. The url-building Zod schemas are module-level singletons, so the per-instancebaseUrlnever reached them.What changed
src/types/entities.ts— each of the 6 entity schemas is now built by acreateXxxSchema(linkBaseUrl?)factory that threads the base intogetFullCommsURL. The exportedXxxSchema = createXxxSchema()singletons and inferred types are unchanged (non-breaking).InboxThread.lastCommentnow usescreateCommentSchema(linkBaseUrl)so the nested comment link honors the base too.src/clients/base-client.ts— newgetLinkBaseUrl(): returns the configuredbaseUrlas-is (trailing slash stripped), falling back to the default web app when unset.getLinkBaseUrl().src/clients/add-comment-helper.ts—ClientContextgainsschema, threaded from the comments and threads clients.Difference from the twist PR
comms-sdk has no batch-descriptor pattern, so the batch paths the twist PR touched don't exist here — the port is smaller. The public module-level
XxxListSchemaexports are kept on the singletons for back-compat; clients use per-instance list schemas internally.Behavior
baseUrl: 'https://x'→ links likehttps://x/a/1/ch/.../baseUrl→ unchangedhttps://comms.todoist.com/...The base is used verbatim, matching the chosen "use baseUrl as-is" semantics.
Test plan
npm run type-checkcleannpm run check(oxlint + oxfmt) cleannpm test— 124 pass: entity factory unit tests (base threading, default fallback, nested-comment propagation) + comments-client e2e for custom / trailing-slash bases🤖 Generated with Claude Code