one
Version:
One is a new React Framework that makes Vite serve both native and web.
82 lines (72 loc) • 2.72 kB
text/typescript
/**
* This file is copied from the react-navigation repo:
* https://github.com/react-navigation/react-navigation/blob/%40react-navigation/core%407.1.2/packages/core/src/validatePathConfig.tsx
*
* Please refrain from making changes to this file, as it will make merging updates from the upstream harder.
* All modifications except formatting should be marked with `// @modified` comment.
*/
const formatToList = (items: Record<string, string>) =>
Object.entries(items)
.map(([key, value]) => `- ${key} (${value})`)
.join('\n')
export function validatePathConfig(config: unknown, root = true) {
const validation = {
path: 'string',
initialRouteName: 'string',
screens: 'object',
// @modified - start
preserveDynamicRoutes: 'boolean',
preserveGroups: 'boolean',
// @modified - end
...(root
? null
: {
exact: 'boolean',
stringify: 'object',
parse: 'object',
}),
}
if (typeof config !== 'object' || config === null) {
throw new Error(
`Expected the configuration to be an object, but got ${JSON.stringify(config)}.`
)
}
const validationErrors = Object.fromEntries(
Object.keys(config)
.map((key) => {
if (key in validation) {
const type = validation[key as keyof typeof validation] as string
const value: string = config[key]
// biome-ignore lint/suspicious/useValidTypeof: do not check copied code
if (value !== undefined && typeof value !== type) {
return [key, `expected '${type}', got '${typeof value}'`]
}
} else {
return [key, 'extraneous']
}
return null
})
.filter(Boolean) as [string, string][]
)
if (Object.keys(validationErrors).length) {
throw new Error(
`Found invalid properties in the configuration:\n${formatToList(
validationErrors
)}\n\nYou can only specify the following properties:\n${formatToList(
validation
)}\n\nIf you want to specify configuration for screens, you need to specify them under a 'screens' property.\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
)
}
if (root && 'path' in config && typeof config.path === 'string' && config.path.includes(':')) {
throw new Error(
`Found invalid path '${config.path}'. The 'path' in the top-level configuration cannot contain patterns for params.`
)
}
if ('screens' in config && config.screens) {
Object.entries(config.screens).forEach(([_, value]) => {
if (typeof value !== 'string') {
validatePathConfig(value, false)
}
})
}
}