31 lines
1.6 KiB
TypeScript
31 lines
1.6 KiB
TypeScript
import { AI_MODULE_SELECTION_PATH, getGuardedAiModuleForPath } from './ai-modules';
|
|
|
|
type SettingsLocation = { pathname: string; search?: string; hash?: string; state?: unknown };
|
|
|
|
function localReturnPath(value: unknown): string | null {
|
|
if (typeof value !== 'string' || !value.startsWith('/') || value.startsWith('//') || value.includes('\\')) return null;
|
|
try {
|
|
const target = new URL(value, 'https://makelore.local');
|
|
if (target.origin !== 'https://makelore.local') return null;
|
|
if (target.pathname !== AI_MODULE_SELECTION_PATH && !getGuardedAiModuleForPath(target.pathname)) return null;
|
|
return `${target.pathname}${target.search}${target.hash}`;
|
|
} catch { return null; }
|
|
}
|
|
|
|
export function getSettingsReturnPath(state: unknown): string {
|
|
const candidate = state && typeof state === 'object' && 'settingsReturnTo' in state
|
|
? (state as { settingsReturnTo?: unknown }).settingsReturnTo : null;
|
|
return localReturnPath(candidate) ?? AI_MODULE_SELECTION_PATH;
|
|
}
|
|
|
|
export function getSettingsReturnState(location: SettingsLocation): { settingsReturnTo: string } {
|
|
const inSettings = location.pathname === '/settings' || location.pathname.startsWith('/settings/');
|
|
return { settingsReturnTo: inSettings ? getSettingsReturnPath(location.state)
|
|
: localReturnPath(`${location.pathname}${location.search ?? ''}${location.hash ?? ''}`) ?? AI_MODULE_SELECTION_PATH };
|
|
}
|
|
|
|
/** Honor the current page's existing unsaved-input protection before internal navigation. */
|
|
export function canLeaveCurrentPage(): boolean {
|
|
return typeof window === 'undefined' || window.dispatchEvent(new Event('beforeunload', { cancelable: true }));
|
|
}
|