Skip to content

fix: refuse an empty or dot path id so a request cannot land on a sibling route - #20

Merged
robrigo merged 1 commit into
mainfrom
fix/path-segment-guard
Aug 17, 2026
Merged

fix: refuse an empty or dot path id so a request cannot land on a sibling route#20
robrigo merged 1 commit into
mainfrom
fix/path-segment-guard

Conversation

@robrigo

@robrigo robrigo commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Why

Every path-building read percent-encodes its ids, but encodeURIComponent leaves dots alone, so an id of . or .. survives into the path and the URL parser inside fetch collapses it onto the route above; an empty id turns a single-row route into its list. The caller reads rows it never asked for instead of seeing a failure. None of those values is ever an id, a name, or an account, so the path builder now throws before the request, naming the field, and a missing value is refused the same way. Dotted Antelope names such as alien.worlds and mycoll.wam pass unchanged. Every other value keeps the existing percent-encoding.

Validation

yarn check-types, yarn lint, and yarn test pass. The new tests drive '', ., .., null, and undefined through a representative reader and assert the fetch stub records no call, sweep every path-building method with .., and pin that a dotted name still reaches the recorded URL unchanged.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Explorer API client’s URL construction by rejecting path segment values that can be normalized by the URL parser ('', ., ..) into sibling routes, preventing unintended reads from different endpoints.

Changes:

  • Add a guarded encodeSegment(value, field) that rejects null/undefined, empty strings, and dot segments before issuing a request.
  • Update Explorer API methods that place caller-supplied values into the path to pass a descriptive field name into the guard.
  • Add tests that assert no fetch occurs on invalid segments and that dotted (non-dot-segment) names remain unchanged; document the behavior in the README.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/explorer-url.test.ts Adds regression tests ensuring invalid path segments reject before any fetch and that dotted names still work.
src/API/Explorer/index.ts Introduces and wires in the path-segment guard via encodeSegment(value, field) across all path-building reads.
README.md Documents the new rejection behavior in the 2.1.1 changelog section.
Suppressed comments (1)

src/API/Explorer/index.ts:207

  • getTemplateStats names its second parameter name but treats it as a template id (field label is "template id" and it’s placed in the template-id path position). This is confusing for API consumers and for future maintenance; rename the parameter to id to match the route and other template methods.
    async getTemplateStats(collection: string, name: string): Promise<ITemplateStats> {
        return await this.fetchEndpoint('/v1/templates/' + encodeSegment(collection, 'collection name') + '/' + encodeSegment(name, 'template id') + '/stats', {});

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/API/Explorer/index.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/API/Explorer/index.ts:46

  • encodeSegment guards against null/undefined, but its parameter is typed as string, making those checks unreachable in TypeScript and potentially triggering no-unnecessary-condition/misleading typing. Widen the parameter type so the signature matches the runtime behavior (especially for JS consumers).
function encodeSegment(value: string, field: string): string {

test/explorer-url.test.ts:170

  • In the guarded-segment sweep, the label says "getTemplateStats name" but the method’s second parameter is an id. This label is used in assertion messages, so it should match the API surface for clarity.
            ['getTemplateStats collection', () => api.getTemplateStats('..', '1')],
            ['getTemplateStats name', () => api.getTemplateStats('mycollection', '..')],
            ['getTemplateLogs collection', () => api.getTemplateLogs('..', '1')],

README.md:193

  • The 2.1.1 summary says "Rejects the path ids…", but the change also applies to collection/schema/template names and accounts. Consider making this line field-agnostic so the release note matches the behavior described below.
Rejects the path ids that would send a read to the wrong route.

…ling route

Every path-building read percent-encoded its segments, but encodeURIComponent
leaves dots alone, so an id of "." or ".." survived into the path and the URL
parser inside fetch collapsed it onto the route above, and an empty id turned
a single-row route into its list. The caller then read rows it never asked
for instead of seeing a failure. Those values are never an id, a name, or an
account, so the path builder now throws before the request, naming the field.
@robrigo
robrigo force-pushed the fix/path-segment-guard branch from 6d40086 to 340df14 Compare August 17, 2026 22:56
@robrigo
robrigo marked this pull request as ready for review August 17, 2026 23:11
@robrigo
robrigo merged commit 5414aef into main Aug 17, 2026
3 checks passed
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.

2 participants