UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

158 lines (136 loc) 4.72 kB
/** * This file exports things that will be used to modify the forked code in `getPathFromState.ts`. * * The purpose of keeping things in this separated file is to keep changes to the copied code as little as possible, making merging upstream updates easier. */ import type { Route } from '@react-navigation/core' import { matchDeepDynamicRouteName, matchDynamicName, matchGroupName } from '../router/matchers' import { getParamName } from './_shared' export type AdditionalOptions = { preserveDynamicRoutes?: boolean preserveGroups?: boolean shouldEncodeURISegment?: boolean } export type ConfigItemMods = { // Used as fallback for groups initialRouteName?: string } export function getPathWithConventionsCollapsed({ pattern, route, params, preserveGroups, preserveDynamicRoutes, shouldEncodeURISegment = true, initialRouteName, }: AdditionalOptions & { pattern: string route: Route<any> params: Record<string, any> initialRouteName?: string }) { const segments = pattern.split('/') return segments .map((p, i) => { const name = getParamName(p) // We don't know what to show for wildcard patterns // Showing the route name seems ok, though whatever we show here will be incorrect // Since the page doesn't actually exist if (p.startsWith('*')) { if (preserveDynamicRoutes) { if (name === 'not-found') { return '+not-found' } return `[...${name}]` } if (params[name]) { if (Array.isArray(params[name])) { return params[name].join('/') } return params[name] } if (route.name.startsWith('[') && route.name.endsWith(']')) { return '' } if (i === 0) { // This can occur when a wildcard matches all routes and the given path was `/`. return route } if (p === '*not-found') { return '' } // remove existing segments from route.path and return it // this is used for nested wildcard routes. Without this, the path would add // all nested segments to the beginning of the wildcard route. return route.name ?.split('/') .slice(i + 1) .join('/') } // If the path has a pattern for a param, put the param in the path if (p.startsWith(':')) { if (preserveDynamicRoutes) { return `[${name}]` } // Optional params without value assigned in route.params should be ignored const value = params[name] if (value === undefined && p.endsWith('?')) { return } // return params[name] return (shouldEncodeURISegment ? encodeURISegment(value) : value) ?? 'undefined' } if (!preserveGroups && matchGroupName(p) != null) { // When the last part is a group it could be a shared URL // if the route has an initialRouteName defined, then we should // use that as the component path as we can assume it will be shown. if (segments.length - 1 === i) { if (initialRouteName) { // Return an empty string if the init route is ambiguous. if (segmentMatchesConvention(initialRouteName)) { return '' } return shouldEncodeURISegment ? encodeURIComponentPreservingBrackets(initialRouteName) : initialRouteName } } return '' } return shouldEncodeURISegment ? encodeURIComponentPreservingBrackets(p) : p }) .map((v) => v ?? '') .join('/') } function encodeURIComponentPreservingBrackets(str: string) { return encodeURIComponent(str).replace(/%5B/g, '[').replace(/%5D/g, ']') } export function appendBaseUrl( path: string, baseUrl: string | undefined = process.env.EXPO_BASE_URL ) { if (process.env.NODE_ENV !== 'development') { if (baseUrl) { return `/${baseUrl.replace(/^\/+/, '').replace(/\/$/, '')}${path}` } } return path } function segmentMatchesConvention(segment: string): boolean { return ( segment === 'index' || matchDynamicName(segment) != null || matchGroupName(segment) != null || matchDeepDynamicRouteName(segment) != null ) } function encodeURISegment(str: string, { preserveBrackets = false } = {}) { // Valid characters according to // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 (see pchar definition) str = String(str).replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]/g, (char) => encodeURIComponent(char)) if (preserveBrackets) { // Preserve brackets str = str.replace(/%5B/g, '[').replace(/%5D/g, ']') } return str }