Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/cli/src/input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ describe('resolveInput', () => {
expect(r.inferredName).toBe('example.com');
});

it('preserves query and fragment trailing slashes for live-site urls', () => {
expect(resolveInput('https://example.com/search/?q=/').value).toBe(
'https://example.com/search?q=/',
);
expect(resolveInput('https://example.com/docs/#/intro/').value).toBe(
'https://example.com/docs#/intro/',
);
});
Comment on lines +51 to +58

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Missing coverage for query-only trailing slash (no path slash)

The test suite covers the case where a path trailing slash exists (/search/, /docs/) before the ? or #, but there's no test for the complementary case where there is no path trailing slash yet the query or fragment ends in / — e.g. https://example.com/search?q=/. Under the current implementation that URL normalizes to https://example.com/search?q= (trailing slash stripped), which may surprise callers. Adding an assertion for this input would make the boundary of the fix explicit and prevent silent regressions.


it('strips www from inferred hostname', () => {
const r = resolveInput('https://www.acme.io');
expect(r.inferredName).toBe('acme.io');
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ function normalizeGitUrl(u: string): string {
}

function normalizeUrl(u: string): string {
// For live-site URLs keep query strings and fragments intact; only strip trailing slashes.
return u.replace(/\/+$/, '');
// For live-site URLs keep query strings and fragments intact; only strip
// trailing slashes from the path segment.
return u.replace(/\/+(?=[?#]|$)/, '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Query/fragment trailing slash still stripped when no path slash precedes it

When the URL has no path trailing slash but the query or fragment itself ends with /, the regex still matches that final / and strips it. For example, https://example.com/search?q=/https://example.com/search?q= because the regex scans left-to-right, finds no slash before ?, and then matches the / at end-of-string inside the query value. The no-g-flag design only protects fragment/query slashes when a path slash is found first.

A URL-based approach (new URL(u)) would be more surgical — it lets you rewrite only pathname and reconstruct the full URL with search and hash untouched, regardless of whether those components happen to end in /.

}

function repoNameFromGit(u: string): string | undefined {
Expand Down
Loading