| 1 | import type { SearchMiddleware } from "@tanstack/react-router"; |
| 2 | |
| 3 | import { validateSettingsScopeSearch, type SettingsScopeSearch } from "./settingsScope"; |
| 4 | |
| 5 | /** Accept legacy provider links without replacing an explicit settings scope. */ |
| 6 | export function validateSettingsRouteSearch(raw: Record<string, unknown>) { |
| 7 | return validateSettingsScopeSearch( |
| 8 | typeof raw.environmentId === "string" && raw.machine === undefined && raw.project === undefined |
| 9 | ? { ...raw, machine: raw.environmentId } |
| 10 | : raw, |
| 11 | ); |
| 12 | } |
| 13 | |
| 14 | const SCOPE_KEYS = [ |
| 15 | "project", |
| 16 | "machine", |
| 17 | "checkout", |
| 18 | ] as const satisfies readonly (keyof SettingsScopeSearch)[]; |
| 19 | const TARGET_INPUT_KEYS = [...SCOPE_KEYS, "environmentId"]; |
| 20 | |
| 21 | /** |
| 22 | * Category links keep the target, while an explicit target replaces the entire |
| 23 | * previous selection. `environmentId` is the legacy provider deep-link target. |
| 24 | */ |
| 25 | export const retainSettingsScope: SearchMiddleware<SettingsScopeSearch> = ({ search, next }) => { |
| 26 | const result = next(search); |
| 27 | if (TARGET_INPUT_KEYS.some((key) => Object.hasOwn(result, key))) return result; |
| 28 | const previousScope = Object.fromEntries( |
| 29 | SCOPE_KEYS.filter((key) => search[key] !== undefined).map((key) => [key, search[key]]), |
| 30 | ); |
| 31 | return { ...previousScope, ...result }; |
| 32 | }; |