mirror of
https://github.com/enso-org/enso.git
synced 2024-11-27 06:32:30 +03:00
Add prefixes for cloud url params (#9649)
This PR adds an ability to exclude some keys in URLSearchParams from being parsed by GUI.
This commit is contained in:
parent
fc557f8fd2
commit
2c78f4eefd
@ -11,6 +11,14 @@ async function runApp(
|
||||
_metadata?: object | undefined,
|
||||
pinia?: Pinia | undefined,
|
||||
) {
|
||||
const ignoreParamsRegex = (() => {
|
||||
if (_metadata)
|
||||
if ('ignoreParamsRegex' in _metadata)
|
||||
if (_metadata['ignoreParamsRegex'] instanceof RegExp) return _metadata['ignoreParamsRegex']
|
||||
|
||||
return null
|
||||
})()
|
||||
|
||||
running = true
|
||||
const { mountProjectApp } = await import('./createApp')
|
||||
if (!running) return
|
||||
@ -19,7 +27,11 @@ async function runApp(
|
||||
function onUnrecognizedOption(path: string[]) {
|
||||
unrecognizedOptions.push(path.join('.'))
|
||||
}
|
||||
const intermediateConfig = mergeConfig(baseConfig, urlParams(), { onUnrecognizedOption })
|
||||
const intermediateConfig = mergeConfig(
|
||||
baseConfig,
|
||||
urlParams({ ignoreKeysRegExp: ignoreParamsRegex }),
|
||||
{ onUnrecognizedOption },
|
||||
)
|
||||
const appConfig = mergeConfig(intermediateConfig, config ?? {})
|
||||
unmount = await mountProjectApp({ config: appConfig, accessToken, unrecognizedOptions }, pinia)
|
||||
}
|
||||
|
@ -1,13 +1,25 @@
|
||||
import type { StringConfig } from './config'
|
||||
|
||||
export interface UrlParamsProps {
|
||||
ignoreKeysRegExp?: RegExp | null
|
||||
}
|
||||
|
||||
/** Returns the parameters passed in the URL query string. */
|
||||
export function urlParams(): StringConfig {
|
||||
export function urlParams(props: UrlParamsProps = {}): StringConfig {
|
||||
const { ignoreKeysRegExp } = props
|
||||
|
||||
const params: StringConfig = {}
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
|
||||
for (const [name, value] of urlParams.entries()) {
|
||||
let obj = params
|
||||
const path = name.split('.')
|
||||
const lastSegment = path.pop()
|
||||
|
||||
if (ignoreKeysRegExp != null && ignoreKeysRegExp.test(name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (lastSegment == null) {
|
||||
console.error(`Invalid URL parameter name: '${name}'`)
|
||||
} else {
|
||||
|
@ -4,6 +4,10 @@
|
||||
// === Constants ===
|
||||
// =================
|
||||
|
||||
// =============
|
||||
// === Paths ===
|
||||
// =============
|
||||
|
||||
/** Path to the root of the app (i.e., the Cloud dashboard). */
|
||||
export const DASHBOARD_PATH = '/'
|
||||
/** Path to the login page. */
|
||||
@ -28,3 +32,9 @@ export const ALL_PATHS_REGEX = new RegExp(
|
||||
`${FORGOT_PASSWORD_PATH}|${RESET_PASSWORD_PATH}|${SET_USERNAME_PATH}|` +
|
||||
`${ENTER_OFFLINE_MODE_PATH}|${SUBSCRIBE_PATH})$`
|
||||
)
|
||||
|
||||
// ===========
|
||||
// === URL ===
|
||||
// ===========
|
||||
|
||||
export const SEARCH_PARAMS_PREFIX = 'cloud-ide_'
|
||||
|
@ -7,6 +7,8 @@ import * as React from 'react'
|
||||
|
||||
import * as reactRouterDom from 'react-router-dom'
|
||||
|
||||
import * as appUtils from '#/appUtils'
|
||||
|
||||
import * as eventCallback from '#/hooks/eventCallbackHooks'
|
||||
import * as lazyMemo from '#/hooks/useLazyMemoHooks'
|
||||
|
||||
@ -32,22 +34,31 @@ export function useSearchParamsState<T = unknown>(
|
||||
): SearchParamsStateReturnType<T> {
|
||||
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams()
|
||||
|
||||
const prefixedKey = `${appUtils.SEARCH_PARAMS_PREFIX}${key}`
|
||||
|
||||
const lazyDefaultValueInitializer = lazyMemo.useLazyMemoHooks(defaultValue, [])
|
||||
const predicateEventCallback = eventCallback.useEventCallback(predicate)
|
||||
|
||||
const clear = eventCallback.useEventCallback((replace: boolean = false) => {
|
||||
searchParams.delete(key)
|
||||
searchParams.delete(prefixedKey)
|
||||
setSearchParams(searchParams, { replace })
|
||||
})
|
||||
|
||||
const unprefixedValue = searchParams.get(key)
|
||||
if (unprefixedValue != null) {
|
||||
searchParams.set(prefixedKey, unprefixedValue)
|
||||
searchParams.delete(key)
|
||||
setSearchParams(searchParams)
|
||||
}
|
||||
|
||||
const rawValue = React.useMemo<T>(() => {
|
||||
const maybeValue = searchParams.get(key)
|
||||
const maybeValue = searchParams.get(prefixedKey)
|
||||
const defaultValueFrom = lazyDefaultValueInitializer()
|
||||
|
||||
return maybeValue != null
|
||||
? safeJsonParse.safeJsonParse(maybeValue, defaultValueFrom, (unknown): unknown is T => true)
|
||||
: defaultValueFrom
|
||||
}, [key, lazyDefaultValueInitializer, searchParams])
|
||||
}, [prefixedKey, lazyDefaultValueInitializer, searchParams])
|
||||
|
||||
const isValueValid = predicateEventCallback(rawValue)
|
||||
|
||||
@ -71,7 +82,7 @@ export function useSearchParamsState<T = unknown>(
|
||||
if (nextValue === lazyDefaultValueInitializer()) {
|
||||
clear()
|
||||
} else {
|
||||
searchParams.set(key, JSON.stringify(nextValue))
|
||||
searchParams.set(prefixedKey, JSON.stringify(nextValue))
|
||||
setSearchParams(searchParams)
|
||||
}
|
||||
})
|
||||
|
@ -1,6 +1,8 @@
|
||||
/** @file The container that launches the IDE. */
|
||||
import * as React from 'react'
|
||||
|
||||
import * as appUtils from '#/appUtils'
|
||||
|
||||
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
|
||||
|
||||
import * as backendModule from '#/services/Backend'
|
||||
@ -114,7 +116,10 @@ export default function Editor(props: EditorProps) {
|
||||
},
|
||||
},
|
||||
accessToken,
|
||||
{ projectId: project.projectId }
|
||||
{
|
||||
projectId: project.projectId,
|
||||
ignoreParamsRegex: new RegExp(`^${appUtils.SEARCH_PARAMS_PREFIX}(.+)$`),
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
toastAndLog('openEditorError', error)
|
||||
|
Loading…
Reference in New Issue
Block a user