mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-09-28 05:54:50 +08:00
fix(backend-registry): preserve URL fragments in withBackendSelectionParams (#16619)
Co-authored-by: VascoSch92 <vasco.schiavo@protonmail.com>
This commit is contained in:
co-authored by
VascoSch92
parent
d636ae6893
commit
551e9a9ee6
@@ -65,6 +65,73 @@ describe("withBackendSelectionParams", () => {
|
||||
`/conversations/abc?tab=files&${BACKEND_QUERY_PARAM}=local-1`,
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps a fragment after existing query parameters intact and after the query", () => {
|
||||
const path = withBackendSelectionParams(
|
||||
"/conversations/abc?tab=files#detail",
|
||||
{
|
||||
backend: localBackend,
|
||||
orgId: null,
|
||||
},
|
||||
);
|
||||
|
||||
expect(path).toBe(
|
||||
`/conversations/abc?tab=files&${BACKEND_QUERY_PARAM}=local-1#detail`,
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps a fragment on a path without query parameters after the query", () => {
|
||||
const path = withBackendSelectionParams("/conversations/abc#detail", {
|
||||
backend: localBackend,
|
||||
orgId: null,
|
||||
});
|
||||
|
||||
expect(path).toBe(
|
||||
`/conversations/abc?${BACKEND_QUERY_PARAM}=local-1#detail`,
|
||||
);
|
||||
});
|
||||
|
||||
it("does not treat a ? inside the fragment as a query separator", () => {
|
||||
const path = withBackendSelectionParams("/conversations/abc#detail?x=1", {
|
||||
backend: localBackend,
|
||||
orgId: null,
|
||||
});
|
||||
|
||||
expect(path).toBe(
|
||||
`/conversations/abc?${BACKEND_QUERY_PARAM}=local-1#detail?x=1`,
|
||||
);
|
||||
});
|
||||
|
||||
it("round-trips an empty fragment verbatim", () => {
|
||||
const path = withBackendSelectionParams("/conversations/abc#", {
|
||||
backend: localBackend,
|
||||
orgId: null,
|
||||
});
|
||||
|
||||
expect(path).toBe(`/conversations/abc?${BACKEND_QUERY_PARAM}=local-1#`);
|
||||
});
|
||||
|
||||
it("keeps the org id and the fragment together", () => {
|
||||
const path = withBackendSelectionParams("/conversations/abc#detail", {
|
||||
backend: cloudBackend,
|
||||
orgId: "org-7",
|
||||
});
|
||||
|
||||
expect(path).toBe(
|
||||
`/conversations/abc?${BACKEND_QUERY_PARAM}=prod&${ORG_QUERY_PARAM}=org-7#detail`,
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps query data that itself contains a ?", () => {
|
||||
const path = withBackendSelectionParams("/conversations/abc?next=/a?b=1", {
|
||||
backend: localBackend,
|
||||
orgId: null,
|
||||
});
|
||||
|
||||
expect(path).toBe(
|
||||
`/conversations/abc?next=%2Fa%3Fb%3D1&${BACKEND_QUERY_PARAM}=local-1`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("readBackendSelectionFromUrl", () => {
|
||||
|
||||
@@ -19,7 +19,8 @@ export const ORG_QUERY_PARAM = "org";
|
||||
|
||||
/**
|
||||
* Append the active backend identity to an in-app path so opening it in a new
|
||||
* browsing context resolves against the same backend.
|
||||
* browsing context resolves against the same backend. Any fragment on the
|
||||
* path is preserved verbatim and kept after the query string.
|
||||
*/
|
||||
export function withBackendSelectionParams(
|
||||
path: string,
|
||||
@@ -28,12 +29,24 @@ export function withBackendSelectionParams(
|
||||
const { backend, orgId } = active;
|
||||
if (!backend.id) return path;
|
||||
|
||||
const [pathname, existingSearch = ""] = path.split("?");
|
||||
const hashIndex = path.indexOf("#");
|
||||
const fragment = hashIndex === -1 ? "" : path.slice(hashIndex);
|
||||
const withoutFragment = hashIndex === -1 ? path : path.slice(0, hashIndex);
|
||||
|
||||
// Split at the *first* `?` only. A later `?` is ordinary query data (a
|
||||
// `next=` redirect carrying its own query, say), and `split("?")` would
|
||||
// silently drop everything past it.
|
||||
const queryIndex = withoutFragment.indexOf("?");
|
||||
const pathname =
|
||||
queryIndex === -1 ? withoutFragment : withoutFragment.slice(0, queryIndex);
|
||||
const existingSearch =
|
||||
queryIndex === -1 ? "" : withoutFragment.slice(queryIndex + 1);
|
||||
|
||||
const params = new URLSearchParams(existingSearch);
|
||||
params.set(BACKEND_QUERY_PARAM, backend.id);
|
||||
if (orgId) params.set(ORG_QUERY_PARAM, orgId);
|
||||
|
||||
return `${pathname}?${params.toString()}`;
|
||||
return `${pathname}?${params.toString()}${fragment}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user