expo-router 3.5.10 → 3.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -261,7 +261,7 @@ function getFileMeta(key, options) {
261
261
  const parts = key.split('/');
262
262
  let route = (0, matchers_1.removeSupportedExtensions)(key);
263
263
  const filename = parts[parts.length - 1];
264
- const filenameWithoutExtensions = (0, matchers_1.removeSupportedExtensions)(filename);
264
+ const [filenameWithoutExtensions, platformExtension] = (0, matchers_1.removeSupportedExtensions)(filename).split('.');
265
265
  const isLayout = filenameWithoutExtensions === '_layout';
266
266
  const isApi = filename.match(/\+api\.(\w+\.)?[jt]sx?$/);
267
267
  if (filenameWithoutExtensions.startsWith('(') && filenameWithoutExtensions.endsWith(')')) {
@@ -273,7 +273,6 @@ function getFileMeta(key, options) {
273
273
  throw new Error(`Invalid route ./${key}. Route nodes cannot start with the '+' character. "Please rename to ${renamedRoute}"`);
274
274
  }
275
275
  let specificity = 0;
276
- const platformExtension = filenameWithoutExtensions.split('.')[1];
277
276
  const hasPlatformExtension = validPlatforms.has(platformExtension);
278
277
  const usePlatformRoutes = options.platformRoutes ?? true;
279
278
  if (hasPlatformExtension) {
@@ -1 +1 @@
1
- {"version":3,"file":"getRoutes.js","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicConvention, RouteNode } from './Route';\nimport {\n matchArrayGroupName,\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchGroupName,\n removeSupportedExtensions,\n} from './matchers';\nimport { RequireContext } from './types';\n\nexport type Options = {\n ignore?: RegExp[];\n preserveApiRoutes?: boolean;\n ignoreRequireErrors?: boolean;\n ignoreEntryPoints?: boolean;\n /* Used to simplify testing for toEqual() comparison */\n internal_stripLoadRoute?: boolean;\n /* Used to simplify by skipping the generated routes */\n skipGenerated?: boolean;\n importMode?: string;\n platformRoutes?: boolean;\n platform?: string;\n};\n\ntype DirectoryNode = {\n layout?: RouteNode[];\n files: Map<string, RouteNode[]>;\n subdirectories: Map<string, DirectoryNode>;\n};\n\nconst validPlatforms = new Set(['android', 'ios', 'native', 'web']);\n\n/**\n * Given a Metro context module, return an array of nested routes.\n *\n * This is a two step process:\n * 1. Convert the RequireContext keys (file paths) into a directory tree.\n * - This should extrapolate array syntax into multiple routes\n * - Routes are given a specificity score\n * 2. Flatten the directory tree into routes\n * - Routes in directories without _layout files are hoisted to the nearest _layout\n * - The name of the route is relative to the nearest _layout\n * - If multiple routes have the same name, the most specific route is used\n */\nexport function getRoutes(contextModule: RequireContext, options: Options = {}): RouteNode | null {\n const directoryTree = getDirectoryTree(contextModule, options);\n\n // If there are no routes\n if (!directoryTree) {\n return null;\n }\n\n const rootNode = flattenDirectoryTreeToRoutes(directoryTree, options);\n\n if (!options.ignoreEntryPoints) {\n crawlAndAppendInitialRoutesAndEntryFiles(rootNode, options);\n }\n\n return rootNode;\n}\n\nexport function getExactRoutes(\n contextModule: RequireContext,\n options: Options = {}\n): RouteNode | null {\n return getRoutes(contextModule, {\n ...options,\n skipGenerated: true,\n });\n}\n\n/**\n * Converts the RequireContext keys (file paths) into a directory tree.\n */\nfunction getDirectoryTree(contextModule: RequireContext, options: Options) {\n const importMode = options.importMode || process.env.EXPO_ROUTER_IMPORT_MODE;\n\n const ignoreList: RegExp[] = [/^\\.\\/\\+(html|native-intent)\\.[tj]sx?$/]; // Ignore the top level ./+html file\n\n if (options.ignore) {\n ignoreList.push(...options.ignore);\n }\n if (!options.preserveApiRoutes) {\n ignoreList.push(/\\+api\\.[tj]sx?$/);\n }\n\n const rootDirectory: DirectoryNode = {\n files: new Map(),\n subdirectories: new Map(),\n };\n\n let hasRoutes = false;\n let isValid = false;\n\n for (const filePath of contextModule.keys()) {\n if (ignoreList.some((regex) => regex.test(filePath))) {\n continue;\n }\n\n isValid = true;\n\n const meta = getFileMeta(filePath, options);\n\n // This is a file that should be ignored. e.g maybe it has an invalid platform?\n if (meta.specificity < 0) {\n continue;\n }\n\n let node: RouteNode = {\n type: meta.isApi ? 'api' : meta.isLayout ? 'layout' : 'route',\n loadRoute() {\n if (options.ignoreRequireErrors) {\n try {\n return contextModule(filePath);\n } catch {\n return {};\n }\n } else {\n return contextModule(filePath);\n }\n },\n contextKey: filePath,\n route: '', // This is overwritten during hoisting based upon the _layout\n dynamic: null,\n children: [], // While we are building the directory tree, we don't know the node's children just yet. This is added during hoisting\n };\n\n if (process.env.NODE_ENV === 'development') {\n // If the user has set the `EXPO_ROUTER_IMPORT_MODE` to `sync` then we should\n // filter the missing routes.\n if (node.type !== 'api' && importMode === 'sync') {\n if (!node.loadRoute()?.default) {\n continue;\n }\n }\n }\n\n /**\n * A single filepath may be extrapolated into multiple routes if it contains array syntax.\n * Another way to thinking about is that a filepath node is present in multiple leaves of the directory tree.\n */\n for (const route of extrapolateGroups(meta.route)) {\n // Traverse the directory tree to its leaf node, creating any missing directories along the way\n const subdirectoryParts = route.split('/').slice(0, -1);\n\n // Start at the root directory and traverse the path to the leaf directory\n let directory = rootDirectory;\n\n for (const part of subdirectoryParts) {\n let subDirectory = directory.subdirectories.get(part);\n\n // Create any missing subdirectories\n if (!subDirectory) {\n subDirectory = {\n files: new Map(),\n subdirectories: new Map(),\n };\n directory.subdirectories.set(part, subDirectory);\n }\n\n directory = subDirectory;\n }\n\n // Clone the node for this route\n node = { ...node, route };\n\n if (meta.isLayout) {\n directory.layout ??= [];\n const existing = directory.layout[meta.specificity];\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The layouts \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n node = getLayoutNode(node, options);\n directory.layout[meta.specificity] = node;\n }\n } else if (meta.isApi) {\n const fileKey = `${route}+api`;\n let nodes = directory.files.get(fileKey);\n\n if (!nodes) {\n nodes = [];\n directory.files.set(fileKey, nodes);\n }\n\n // API Routes have no specificity, they are always the first node\n const existing = nodes[0];\n\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The API route file \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n nodes[0] = node;\n }\n } else {\n let nodes = directory.files.get(route);\n\n if (!nodes) {\n nodes = [];\n directory.files.set(route, nodes);\n }\n\n /**\n * If there is an existing node with the same specificity, then we have a conflict.\n * NOTE(Platform Routes):\n * We cannot check for specificity conflicts here, as we haven't processed all the context keys yet!\n * This will be checked during hoisting, as well as enforcing that all routes have a non-platform route.\n */\n const existing = nodes[meta.specificity];\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The route files \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n hasRoutes ||= true;\n nodes[meta.specificity] = node;\n }\n }\n }\n }\n\n // If there are no routes/layouts then we should display the tutorial.\n if (!isValid) {\n return null;\n }\n\n /**\n * If there are no top-level _layout, add a default _layout\n * While this is a generated route, it will still be generated even if skipGenerated is true.\n */\n if (!rootDirectory.layout) {\n rootDirectory.layout = [\n {\n type: 'layout',\n loadRoute: () => ({\n default: (require('./views/Navigator') as typeof import('./views/Navigator'))\n .DefaultNavigator,\n }),\n // Generate a fake file name for the directory\n contextKey: 'expo-router/build/views/Navigator.js',\n route: '',\n generated: true,\n dynamic: null,\n children: [],\n },\n ];\n }\n\n // Only include the sitemap if there are routes.\n if (!options.skipGenerated) {\n if (hasRoutes) {\n appendSitemapRoute(rootDirectory);\n }\n appendNotFoundRoute(rootDirectory);\n }\n return rootDirectory;\n}\n\n/**\n * Flatten the directory tree into routes, hoisting routes to the nearest _layout.\n */\nfunction flattenDirectoryTreeToRoutes(\n directory: DirectoryNode,\n options: Options,\n /* The nearest _layout file in the directory tree */\n layout?: RouteNode,\n /* Route names are relative to their layout */\n pathToRemove = ''\n) {\n /**\n * This directory has a _layout file so it becomes the new target for hoisting routes.\n */\n if (directory.layout) {\n const previousLayout = layout;\n layout = getMostSpecific(directory.layout);\n\n // Add the new layout as a child of its parent\n if (previousLayout) {\n previousLayout.children.push(layout);\n }\n\n if (options.internal_stripLoadRoute) {\n delete (layout as any).loadRoute;\n }\n\n // `route` is the absolute pathname. We need to make this relative to the last _layout\n const newRoute = layout.route.replace(pathToRemove, '');\n pathToRemove = layout.route ? `${layout.route}/` : '';\n\n // Now update this layout with the new relative route and dynamic conventions\n layout.route = newRoute;\n layout.dynamic = generateDynamic(layout.route);\n }\n\n // This should never occur as there will always be a root layout, but it makes the type system happy\n if (!layout) throw new Error('Expo Router Internal Error: No nearest layout');\n\n for (const routes of directory.files.values()) {\n const routeNode = getMostSpecific(routes);\n\n // `route` is the absolute pathname. We need to make this relative to the nearest layout\n routeNode.route = routeNode.route.replace(pathToRemove, '');\n routeNode.dynamic = generateDynamic(routeNode.route);\n\n if (options.internal_stripLoadRoute) {\n delete (routeNode as any).loadRoute;\n }\n\n layout.children.push(routeNode);\n }\n\n // Recursively flatten the subdirectories\n for (const child of directory.subdirectories.values()) {\n flattenDirectoryTreeToRoutes(child, options, layout, pathToRemove);\n }\n\n return layout;\n}\n\nfunction getFileMeta(key: string, options: Options) {\n // Remove the leading `./`\n key = key.replace(/^\\.\\//, '');\n\n const parts = key.split('/');\n let route = removeSupportedExtensions(key);\n const filename = parts[parts.length - 1];\n const filenameWithoutExtensions = removeSupportedExtensions(filename);\n const isLayout = filenameWithoutExtensions === '_layout';\n const isApi = filename.match(/\\+api\\.(\\w+\\.)?[jt]sx?$/);\n\n if (filenameWithoutExtensions.startsWith('(') && filenameWithoutExtensions.endsWith(')')) {\n throw new Error(`Invalid route ./${key}. Routes cannot end with '(group)' syntax`);\n }\n\n // Nested routes cannot start with the '+' character, except for the '+not-found' route\n if (!isApi && filename.startsWith('+') && filenameWithoutExtensions !== '+not-found') {\n const renamedRoute = [...parts.slice(0, -1), filename.slice(1)].join('/');\n throw new Error(\n `Invalid route ./${key}. Route nodes cannot start with the '+' character. \"Please rename to ${renamedRoute}\"`\n );\n }\n let specificity = 0;\n\n const platformExtension = filenameWithoutExtensions.split('.')[1];\n const hasPlatformExtension = validPlatforms.has(platformExtension);\n const usePlatformRoutes = options.platformRoutes ?? true;\n\n if (hasPlatformExtension) {\n if (!usePlatformRoutes) {\n // If the user has disabled platform routes, then we should ignore this file\n specificity = -1;\n } else if (!options.platform) {\n // If we don't have a platform, then we should ignore this file\n // This used by typed routes, sitemap, etc\n specificity = -1;\n } else if (platformExtension === options.platform) {\n // If the platform extension is the same as the options.platform, then it is the most specific\n specificity = 2;\n } else if (platformExtension === 'native' && options.platform !== 'web') {\n // `native` is allow but isn't as specific as the platform\n specificity = 1;\n } else if (platformExtension !== options.platform) {\n // Somehow we have a platform extension that doesn't match the options.platform and it isn't native\n // This is an invalid file and we will ignore it\n specificity = -1;\n }\n\n if (isApi && specificity !== 0) {\n throw new Error(\n `Api routes cannot have platform extensions. Please remove '.${platformExtension}' from './${key}'`\n );\n }\n\n route = route.replace(new RegExp(`.${platformExtension}$`), '');\n }\n\n return {\n route,\n specificity,\n isLayout,\n isApi,\n };\n}\n\nexport function getIgnoreList(options?: Options) {\n const ignore: RegExp[] = [/^\\.\\/\\+html\\.[tj]sx?$/, ...(options?.ignore ?? [])];\n if (options?.preserveApiRoutes !== true) {\n ignore.push(/\\+api\\.[tj]sx?$/);\n }\n return ignore;\n}\n\n/**\n * Generates a set of strings which have the router array syntax extrapolated.\n *\n * /(a,b)/(c,d)/e.tsx => new Set(['a/c/e.tsx', 'a/d/e.tsx', 'b/c/e.tsx', 'b/d/e.tsx'])\n */\nexport function extrapolateGroups(key: string, keys: Set<string> = new Set()): Set<string> {\n const match = matchArrayGroupName(key);\n\n if (!match) {\n keys.add(key);\n return keys;\n }\n const groups = match.split(',');\n const groupsSet = new Set(groups);\n\n if (groupsSet.size !== groups.length) {\n throw new Error(`Array syntax cannot contain duplicate group name \"${groups}\" in \"${key}\".`);\n }\n\n if (groups.length === 1) {\n keys.add(key);\n return keys;\n }\n\n for (const group of groups) {\n extrapolateGroups(key.replace(match, group.trim()), keys);\n }\n\n return keys;\n}\n\nexport function generateDynamic(path: string): DynamicConvention[] | null {\n const dynamic = path\n .split('/')\n .map((part): DynamicConvention | null => {\n if (part === '+not-found') {\n return {\n name: '+not-found',\n deep: true,\n notFound: true,\n };\n }\n\n const deepDynamicName = matchDeepDynamicRouteName(part);\n const dynamicName = deepDynamicName ?? matchDynamicName(part);\n\n if (!dynamicName) return null;\n return { name: dynamicName, deep: !!deepDynamicName };\n })\n .filter((part): part is DynamicConvention => !!part);\n\n return dynamic.length === 0 ? null : dynamic;\n}\n\nfunction appendSitemapRoute(directory: DirectoryNode) {\n if (!directory.files.has('_sitemap')) {\n directory.files.set('_sitemap', [\n {\n loadRoute() {\n const { Sitemap, getNavOptions } = require('./views/Sitemap');\n return { default: Sitemap, getNavOptions };\n },\n route: '_sitemap',\n type: 'route',\n contextKey: 'expo-router/build/views/Sitemap.js',\n generated: true,\n internal: true,\n dynamic: null,\n children: [],\n },\n ]);\n }\n}\n\nfunction appendNotFoundRoute(directory: DirectoryNode) {\n if (!directory.files.has('+not-found')) {\n directory.files.set('+not-found', [\n {\n loadRoute() {\n return { default: require('./views/Unmatched').Unmatched };\n },\n type: 'route',\n route: '+not-found',\n contextKey: 'expo-router/build/views/Unmatched.js',\n generated: true,\n internal: true,\n dynamic: [{ name: '+not-found', deep: true, notFound: true }],\n children: [],\n },\n ]);\n }\n}\n\nfunction getLayoutNode(node: RouteNode, options: Options) {\n /**\n * A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.\n * Each of these layouts will have a different initialRouteName based upon the first group name.\n *\n * So\n */\n\n // We may strip loadRoute during testing\n const groupName = matchGroupName(node.route);\n const childMatchingGroup = node.children.find((child) => {\n return child.route.replace(/\\/index$/, '') === groupName;\n });\n let initialRouteName = childMatchingGroup?.route;\n const loaded = node.loadRoute();\n if (loaded?.unstable_settings) {\n // Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.\n initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;\n\n if (groupName) {\n // Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.\n const groupSpecificInitialRouteName = loaded.unstable_settings?.[groupName]?.initialRouteName;\n\n initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;\n }\n }\n\n return {\n ...node,\n route: node.route.replace(/\\/?_layout$/, ''),\n children: [], // Each layout should have its own children\n initialRouteName,\n };\n}\n\nfunction crawlAndAppendInitialRoutesAndEntryFiles(\n node: RouteNode,\n options: Options,\n entryPoints: string[] = []\n) {\n if (node.type === 'route') {\n node.entryPoints = [...new Set([...entryPoints, node.contextKey])];\n } else if (node.type === 'layout') {\n if (!node.children) {\n throw new Error(`Layout \"${node.contextKey}\" does not contain any child routes`);\n }\n\n // Every node below this layout will have it as an entryPoint\n entryPoints = [...entryPoints, node.contextKey];\n\n /**\n * Calculate the initialRouteNode\n *\n * A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.\n * Each of these layouts will have a different initialRouteName based upon the first group.\n */\n const groupName = matchGroupName(node.route);\n const childMatchingGroup = node.children.find((child) => {\n return child.route.replace(/\\/index$/, '') === groupName;\n });\n let initialRouteName = childMatchingGroup?.route;\n // We may strip loadRoute during testing\n if (!options.internal_stripLoadRoute) {\n const loaded = node.loadRoute();\n if (loaded?.unstable_settings) {\n // Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.\n initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;\n\n if (groupName) {\n // Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.\n const groupSpecificInitialRouteName =\n loaded.unstable_settings?.[groupName]?.initialRouteName;\n\n initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;\n }\n }\n }\n\n if (initialRouteName) {\n const initialRoute = node.children.find((child) => child.route === initialRouteName);\n if (!initialRoute) {\n const validInitialRoutes = node.children\n .filter((child) => !child.generated)\n .map((child) => `'${child.route}'`)\n .join(', ');\n\n if (groupName) {\n throw new Error(\n `Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}' for group '(${groupName})'. Valid options are: ${validInitialRoutes}`\n );\n } else {\n throw new Error(\n `Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}'. Valid options are: ${validInitialRoutes}`\n );\n }\n }\n\n // Navigators can add initialsRoutes into the history, so they need to be to be included in the entryPoints\n node.initialRouteName = initialRouteName;\n entryPoints.push(initialRoute.contextKey);\n }\n\n for (const child of node.children) {\n crawlAndAppendInitialRoutesAndEntryFiles(child, options, entryPoints);\n }\n }\n}\n\nfunction getMostSpecific(routes: RouteNode[]) {\n const route = routes[routes.length - 1];\n\n if (!routes[0]) {\n throw new Error(\n `The file ${route.contextKey} does not have a fallback sibling file without a platform extension.`\n );\n }\n\n // This works even tho routes is holey array (e.g it might have index 0 and 2 but not 1)\n // `.length` includes the holes in its count\n return routes[routes.length - 1];\n}\n"]}
1
+ {"version":3,"file":"getRoutes.js","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicConvention, RouteNode } from './Route';\nimport {\n matchArrayGroupName,\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchGroupName,\n removeSupportedExtensions,\n} from './matchers';\nimport { RequireContext } from './types';\n\nexport type Options = {\n ignore?: RegExp[];\n preserveApiRoutes?: boolean;\n ignoreRequireErrors?: boolean;\n ignoreEntryPoints?: boolean;\n /* Used to simplify testing for toEqual() comparison */\n internal_stripLoadRoute?: boolean;\n /* Used to simplify by skipping the generated routes */\n skipGenerated?: boolean;\n importMode?: string;\n platformRoutes?: boolean;\n platform?: string;\n};\n\ntype DirectoryNode = {\n layout?: RouteNode[];\n files: Map<string, RouteNode[]>;\n subdirectories: Map<string, DirectoryNode>;\n};\n\nconst validPlatforms = new Set(['android', 'ios', 'native', 'web']);\n\n/**\n * Given a Metro context module, return an array of nested routes.\n *\n * This is a two step process:\n * 1. Convert the RequireContext keys (file paths) into a directory tree.\n * - This should extrapolate array syntax into multiple routes\n * - Routes are given a specificity score\n * 2. Flatten the directory tree into routes\n * - Routes in directories without _layout files are hoisted to the nearest _layout\n * - The name of the route is relative to the nearest _layout\n * - If multiple routes have the same name, the most specific route is used\n */\nexport function getRoutes(contextModule: RequireContext, options: Options = {}): RouteNode | null {\n const directoryTree = getDirectoryTree(contextModule, options);\n\n // If there are no routes\n if (!directoryTree) {\n return null;\n }\n\n const rootNode = flattenDirectoryTreeToRoutes(directoryTree, options);\n\n if (!options.ignoreEntryPoints) {\n crawlAndAppendInitialRoutesAndEntryFiles(rootNode, options);\n }\n\n return rootNode;\n}\n\nexport function getExactRoutes(\n contextModule: RequireContext,\n options: Options = {}\n): RouteNode | null {\n return getRoutes(contextModule, {\n ...options,\n skipGenerated: true,\n });\n}\n\n/**\n * Converts the RequireContext keys (file paths) into a directory tree.\n */\nfunction getDirectoryTree(contextModule: RequireContext, options: Options) {\n const importMode = options.importMode || process.env.EXPO_ROUTER_IMPORT_MODE;\n\n const ignoreList: RegExp[] = [/^\\.\\/\\+(html|native-intent)\\.[tj]sx?$/]; // Ignore the top level ./+html file\n\n if (options.ignore) {\n ignoreList.push(...options.ignore);\n }\n if (!options.preserveApiRoutes) {\n ignoreList.push(/\\+api\\.[tj]sx?$/);\n }\n\n const rootDirectory: DirectoryNode = {\n files: new Map(),\n subdirectories: new Map(),\n };\n\n let hasRoutes = false;\n let isValid = false;\n\n for (const filePath of contextModule.keys()) {\n if (ignoreList.some((regex) => regex.test(filePath))) {\n continue;\n }\n\n isValid = true;\n\n const meta = getFileMeta(filePath, options);\n\n // This is a file that should be ignored. e.g maybe it has an invalid platform?\n if (meta.specificity < 0) {\n continue;\n }\n\n let node: RouteNode = {\n type: meta.isApi ? 'api' : meta.isLayout ? 'layout' : 'route',\n loadRoute() {\n if (options.ignoreRequireErrors) {\n try {\n return contextModule(filePath);\n } catch {\n return {};\n }\n } else {\n return contextModule(filePath);\n }\n },\n contextKey: filePath,\n route: '', // This is overwritten during hoisting based upon the _layout\n dynamic: null,\n children: [], // While we are building the directory tree, we don't know the node's children just yet. This is added during hoisting\n };\n\n if (process.env.NODE_ENV === 'development') {\n // If the user has set the `EXPO_ROUTER_IMPORT_MODE` to `sync` then we should\n // filter the missing routes.\n if (node.type !== 'api' && importMode === 'sync') {\n if (!node.loadRoute()?.default) {\n continue;\n }\n }\n }\n\n /**\n * A single filepath may be extrapolated into multiple routes if it contains array syntax.\n * Another way to thinking about is that a filepath node is present in multiple leaves of the directory tree.\n */\n for (const route of extrapolateGroups(meta.route)) {\n // Traverse the directory tree to its leaf node, creating any missing directories along the way\n const subdirectoryParts = route.split('/').slice(0, -1);\n\n // Start at the root directory and traverse the path to the leaf directory\n let directory = rootDirectory;\n\n for (const part of subdirectoryParts) {\n let subDirectory = directory.subdirectories.get(part);\n\n // Create any missing subdirectories\n if (!subDirectory) {\n subDirectory = {\n files: new Map(),\n subdirectories: new Map(),\n };\n directory.subdirectories.set(part, subDirectory);\n }\n\n directory = subDirectory;\n }\n\n // Clone the node for this route\n node = { ...node, route };\n\n if (meta.isLayout) {\n directory.layout ??= [];\n const existing = directory.layout[meta.specificity];\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The layouts \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n node = getLayoutNode(node, options);\n directory.layout[meta.specificity] = node;\n }\n } else if (meta.isApi) {\n const fileKey = `${route}+api`;\n let nodes = directory.files.get(fileKey);\n\n if (!nodes) {\n nodes = [];\n directory.files.set(fileKey, nodes);\n }\n\n // API Routes have no specificity, they are always the first node\n const existing = nodes[0];\n\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The API route file \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n nodes[0] = node;\n }\n } else {\n let nodes = directory.files.get(route);\n\n if (!nodes) {\n nodes = [];\n directory.files.set(route, nodes);\n }\n\n /**\n * If there is an existing node with the same specificity, then we have a conflict.\n * NOTE(Platform Routes):\n * We cannot check for specificity conflicts here, as we haven't processed all the context keys yet!\n * This will be checked during hoisting, as well as enforcing that all routes have a non-platform route.\n */\n const existing = nodes[meta.specificity];\n if (existing) {\n // In production, use the first route found\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The route files \"${filePath}\" and \"${existing.contextKey}\" conflict on the route \"/${route}\". Please remove or rename one of these files.`\n );\n }\n } else {\n hasRoutes ||= true;\n nodes[meta.specificity] = node;\n }\n }\n }\n }\n\n // If there are no routes/layouts then we should display the tutorial.\n if (!isValid) {\n return null;\n }\n\n /**\n * If there are no top-level _layout, add a default _layout\n * While this is a generated route, it will still be generated even if skipGenerated is true.\n */\n if (!rootDirectory.layout) {\n rootDirectory.layout = [\n {\n type: 'layout',\n loadRoute: () => ({\n default: (require('./views/Navigator') as typeof import('./views/Navigator'))\n .DefaultNavigator,\n }),\n // Generate a fake file name for the directory\n contextKey: 'expo-router/build/views/Navigator.js',\n route: '',\n generated: true,\n dynamic: null,\n children: [],\n },\n ];\n }\n\n // Only include the sitemap if there are routes.\n if (!options.skipGenerated) {\n if (hasRoutes) {\n appendSitemapRoute(rootDirectory);\n }\n appendNotFoundRoute(rootDirectory);\n }\n return rootDirectory;\n}\n\n/**\n * Flatten the directory tree into routes, hoisting routes to the nearest _layout.\n */\nfunction flattenDirectoryTreeToRoutes(\n directory: DirectoryNode,\n options: Options,\n /* The nearest _layout file in the directory tree */\n layout?: RouteNode,\n /* Route names are relative to their layout */\n pathToRemove = ''\n) {\n /**\n * This directory has a _layout file so it becomes the new target for hoisting routes.\n */\n if (directory.layout) {\n const previousLayout = layout;\n layout = getMostSpecific(directory.layout);\n\n // Add the new layout as a child of its parent\n if (previousLayout) {\n previousLayout.children.push(layout);\n }\n\n if (options.internal_stripLoadRoute) {\n delete (layout as any).loadRoute;\n }\n\n // `route` is the absolute pathname. We need to make this relative to the last _layout\n const newRoute = layout.route.replace(pathToRemove, '');\n pathToRemove = layout.route ? `${layout.route}/` : '';\n\n // Now update this layout with the new relative route and dynamic conventions\n layout.route = newRoute;\n layout.dynamic = generateDynamic(layout.route);\n }\n\n // This should never occur as there will always be a root layout, but it makes the type system happy\n if (!layout) throw new Error('Expo Router Internal Error: No nearest layout');\n\n for (const routes of directory.files.values()) {\n const routeNode = getMostSpecific(routes);\n\n // `route` is the absolute pathname. We need to make this relative to the nearest layout\n routeNode.route = routeNode.route.replace(pathToRemove, '');\n routeNode.dynamic = generateDynamic(routeNode.route);\n\n if (options.internal_stripLoadRoute) {\n delete (routeNode as any).loadRoute;\n }\n\n layout.children.push(routeNode);\n }\n\n // Recursively flatten the subdirectories\n for (const child of directory.subdirectories.values()) {\n flattenDirectoryTreeToRoutes(child, options, layout, pathToRemove);\n }\n\n return layout;\n}\n\nfunction getFileMeta(key: string, options: Options) {\n // Remove the leading `./`\n key = key.replace(/^\\.\\//, '');\n\n const parts = key.split('/');\n let route = removeSupportedExtensions(key);\n const filename = parts[parts.length - 1];\n const [filenameWithoutExtensions, platformExtension] =\n removeSupportedExtensions(filename).split('.');\n const isLayout = filenameWithoutExtensions === '_layout';\n const isApi = filename.match(/\\+api\\.(\\w+\\.)?[jt]sx?$/);\n\n if (filenameWithoutExtensions.startsWith('(') && filenameWithoutExtensions.endsWith(')')) {\n throw new Error(`Invalid route ./${key}. Routes cannot end with '(group)' syntax`);\n }\n\n // Nested routes cannot start with the '+' character, except for the '+not-found' route\n if (!isApi && filename.startsWith('+') && filenameWithoutExtensions !== '+not-found') {\n const renamedRoute = [...parts.slice(0, -1), filename.slice(1)].join('/');\n throw new Error(\n `Invalid route ./${key}. Route nodes cannot start with the '+' character. \"Please rename to ${renamedRoute}\"`\n );\n }\n let specificity = 0;\n\n const hasPlatformExtension = validPlatforms.has(platformExtension);\n const usePlatformRoutes = options.platformRoutes ?? true;\n\n if (hasPlatformExtension) {\n if (!usePlatformRoutes) {\n // If the user has disabled platform routes, then we should ignore this file\n specificity = -1;\n } else if (!options.platform) {\n // If we don't have a platform, then we should ignore this file\n // This used by typed routes, sitemap, etc\n specificity = -1;\n } else if (platformExtension === options.platform) {\n // If the platform extension is the same as the options.platform, then it is the most specific\n specificity = 2;\n } else if (platformExtension === 'native' && options.platform !== 'web') {\n // `native` is allow but isn't as specific as the platform\n specificity = 1;\n } else if (platformExtension !== options.platform) {\n // Somehow we have a platform extension that doesn't match the options.platform and it isn't native\n // This is an invalid file and we will ignore it\n specificity = -1;\n }\n\n if (isApi && specificity !== 0) {\n throw new Error(\n `Api routes cannot have platform extensions. Please remove '.${platformExtension}' from './${key}'`\n );\n }\n\n route = route.replace(new RegExp(`.${platformExtension}$`), '');\n }\n\n return {\n route,\n specificity,\n isLayout,\n isApi,\n };\n}\n\nexport function getIgnoreList(options?: Options) {\n const ignore: RegExp[] = [/^\\.\\/\\+html\\.[tj]sx?$/, ...(options?.ignore ?? [])];\n if (options?.preserveApiRoutes !== true) {\n ignore.push(/\\+api\\.[tj]sx?$/);\n }\n return ignore;\n}\n\n/**\n * Generates a set of strings which have the router array syntax extrapolated.\n *\n * /(a,b)/(c,d)/e.tsx => new Set(['a/c/e.tsx', 'a/d/e.tsx', 'b/c/e.tsx', 'b/d/e.tsx'])\n */\nexport function extrapolateGroups(key: string, keys: Set<string> = new Set()): Set<string> {\n const match = matchArrayGroupName(key);\n\n if (!match) {\n keys.add(key);\n return keys;\n }\n const groups = match.split(',');\n const groupsSet = new Set(groups);\n\n if (groupsSet.size !== groups.length) {\n throw new Error(`Array syntax cannot contain duplicate group name \"${groups}\" in \"${key}\".`);\n }\n\n if (groups.length === 1) {\n keys.add(key);\n return keys;\n }\n\n for (const group of groups) {\n extrapolateGroups(key.replace(match, group.trim()), keys);\n }\n\n return keys;\n}\n\nexport function generateDynamic(path: string): DynamicConvention[] | null {\n const dynamic = path\n .split('/')\n .map((part): DynamicConvention | null => {\n if (part === '+not-found') {\n return {\n name: '+not-found',\n deep: true,\n notFound: true,\n };\n }\n\n const deepDynamicName = matchDeepDynamicRouteName(part);\n const dynamicName = deepDynamicName ?? matchDynamicName(part);\n\n if (!dynamicName) return null;\n return { name: dynamicName, deep: !!deepDynamicName };\n })\n .filter((part): part is DynamicConvention => !!part);\n\n return dynamic.length === 0 ? null : dynamic;\n}\n\nfunction appendSitemapRoute(directory: DirectoryNode) {\n if (!directory.files.has('_sitemap')) {\n directory.files.set('_sitemap', [\n {\n loadRoute() {\n const { Sitemap, getNavOptions } = require('./views/Sitemap');\n return { default: Sitemap, getNavOptions };\n },\n route: '_sitemap',\n type: 'route',\n contextKey: 'expo-router/build/views/Sitemap.js',\n generated: true,\n internal: true,\n dynamic: null,\n children: [],\n },\n ]);\n }\n}\n\nfunction appendNotFoundRoute(directory: DirectoryNode) {\n if (!directory.files.has('+not-found')) {\n directory.files.set('+not-found', [\n {\n loadRoute() {\n return { default: require('./views/Unmatched').Unmatched };\n },\n type: 'route',\n route: '+not-found',\n contextKey: 'expo-router/build/views/Unmatched.js',\n generated: true,\n internal: true,\n dynamic: [{ name: '+not-found', deep: true, notFound: true }],\n children: [],\n },\n ]);\n }\n}\n\nfunction getLayoutNode(node: RouteNode, options: Options) {\n /**\n * A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.\n * Each of these layouts will have a different initialRouteName based upon the first group name.\n *\n * So\n */\n\n // We may strip loadRoute during testing\n const groupName = matchGroupName(node.route);\n const childMatchingGroup = node.children.find((child) => {\n return child.route.replace(/\\/index$/, '') === groupName;\n });\n let initialRouteName = childMatchingGroup?.route;\n const loaded = node.loadRoute();\n if (loaded?.unstable_settings) {\n // Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.\n initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;\n\n if (groupName) {\n // Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.\n const groupSpecificInitialRouteName = loaded.unstable_settings?.[groupName]?.initialRouteName;\n\n initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;\n }\n }\n\n return {\n ...node,\n route: node.route.replace(/\\/?_layout$/, ''),\n children: [], // Each layout should have its own children\n initialRouteName,\n };\n}\n\nfunction crawlAndAppendInitialRoutesAndEntryFiles(\n node: RouteNode,\n options: Options,\n entryPoints: string[] = []\n) {\n if (node.type === 'route') {\n node.entryPoints = [...new Set([...entryPoints, node.contextKey])];\n } else if (node.type === 'layout') {\n if (!node.children) {\n throw new Error(`Layout \"${node.contextKey}\" does not contain any child routes`);\n }\n\n // Every node below this layout will have it as an entryPoint\n entryPoints = [...entryPoints, node.contextKey];\n\n /**\n * Calculate the initialRouteNode\n *\n * A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.\n * Each of these layouts will have a different initialRouteName based upon the first group.\n */\n const groupName = matchGroupName(node.route);\n const childMatchingGroup = node.children.find((child) => {\n return child.route.replace(/\\/index$/, '') === groupName;\n });\n let initialRouteName = childMatchingGroup?.route;\n // We may strip loadRoute during testing\n if (!options.internal_stripLoadRoute) {\n const loaded = node.loadRoute();\n if (loaded?.unstable_settings) {\n // Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.\n initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;\n\n if (groupName) {\n // Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.\n const groupSpecificInitialRouteName =\n loaded.unstable_settings?.[groupName]?.initialRouteName;\n\n initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;\n }\n }\n }\n\n if (initialRouteName) {\n const initialRoute = node.children.find((child) => child.route === initialRouteName);\n if (!initialRoute) {\n const validInitialRoutes = node.children\n .filter((child) => !child.generated)\n .map((child) => `'${child.route}'`)\n .join(', ');\n\n if (groupName) {\n throw new Error(\n `Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}' for group '(${groupName})'. Valid options are: ${validInitialRoutes}`\n );\n } else {\n throw new Error(\n `Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}'. Valid options are: ${validInitialRoutes}`\n );\n }\n }\n\n // Navigators can add initialsRoutes into the history, so they need to be to be included in the entryPoints\n node.initialRouteName = initialRouteName;\n entryPoints.push(initialRoute.contextKey);\n }\n\n for (const child of node.children) {\n crawlAndAppendInitialRoutesAndEntryFiles(child, options, entryPoints);\n }\n }\n}\n\nfunction getMostSpecific(routes: RouteNode[]) {\n const route = routes[routes.length - 1];\n\n if (!routes[0]) {\n throw new Error(\n `The file ${route.contextKey} does not have a fallback sibling file without a platform extension.`\n );\n }\n\n // This works even tho routes is holey array (e.g it might have index 0 and 2 but not 1)\n // `.length` includes the holes in its count\n return routes[routes.length - 1];\n}\n"]}
@@ -1,8 +1,7 @@
1
1
  import type { RequireContext } from '../types';
2
- interface RequireContextPonyFill extends RequireContext {
2
+ export interface RequireContextPonyFill extends RequireContext {
3
3
  __add(file: string): void;
4
4
  __delete(file: string): void;
5
5
  }
6
- export default function requireContext(base?: string, scanSubDirectories?: boolean, regularExpression?: RegExp): RequireContextPonyFill;
7
- export {};
6
+ export default function requireContext(base?: string, scanSubDirectories?: boolean, regularExpression?: RegExp, files?: Record<string, unknown>): RequireContextPonyFill;
8
7
  //# sourceMappingURL=require-context-ponyfill.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"require-context-ponyfill.d.ts","sourceRoot":"","sources":["../../src/testing-library/require-context-ponyfill.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,UAAU,sBAAuB,SAAQ,cAAc;IACrD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,IAAI,SAAM,EACV,kBAAkB,UAAO,EACzB,iBAAiB,SAAe,0BA2CjC"}
1
+ {"version":3,"file":"require-context-ponyfill.d.ts","sourceRoot":"","sources":["../../src/testing-library/require-context-ponyfill.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,IAAI,SAAM,EACV,kBAAkB,UAAO,EACzB,iBAAiB,SAAe,EAChC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,0BAyCpC"}
@@ -7,8 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  // @ts-ignore: types node
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
- function requireContext(base = '.', scanSubDirectories = true, regularExpression = /\.[tj]sx?$/) {
11
- const files = {};
10
+ function requireContext(base = '.', scanSubDirectories = true, regularExpression = /\.[tj]sx?$/, files = {}) {
12
11
  function readDirectory(directory) {
13
12
  node_fs_1.default.readdirSync(directory).forEach((file) => {
14
13
  const fullPath = node_path_1.default.resolve(directory, file);
@@ -1 +1 @@
1
- {"version":3,"file":"require-context-ponyfill.js","sourceRoot":"","sources":["../../src/testing-library/require-context-ponyfill.ts"],"names":[],"mappings":";;;;;AAAA,yBAAyB;AACzB,sDAAyB;AACzB,yBAAyB;AACzB,0DAA6B;AAS7B,SAAwB,cAAc,CACpC,IAAI,GAAG,GAAG,EACV,kBAAkB,GAAG,IAAI,EACzB,iBAAiB,GAAG,YAAY;IAEhC,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,SAAS,aAAa,CAAC,SAAiB;QACtC,iBAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;YACjD,MAAM,QAAQ,GAAG,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,KAAK,mBAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAEpF,IAAI,iBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE;gBACvC,IAAI,kBAAkB;oBAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAEhD,OAAO;aACR;YAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC;gBAAE,OAAO;YAElD,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,iBAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACvB,aAAa,CAAC,IAAI,CAAC,CAAC;KACrB;IAED,MAAM,OAAO,GAA2B,MAAM,CAAC,MAAM,CACnD,SAAS,MAAM,CAAC,IAAY;QAC1B,OAAO,OAAO,CAAC,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC,EACD;QACE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC7B,EAAE,EAAE,GAAG;QACP,KAAK,CAAC,IAAY;YAChB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,QAAQ,CAAC,IAAY;YACnB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;KACF,CACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AA9CD,iCA8CC","sourcesContent":["// @ts-ignore: types node\nimport fs from 'node:fs';\n// @ts-ignore: types node\nimport path from 'node:path';\n\nimport type { RequireContext } from '../types';\n\ninterface RequireContextPonyFill extends RequireContext {\n __add(file: string): void;\n __delete(file: string): void;\n}\n\nexport default function requireContext(\n base = '.',\n scanSubDirectories = true,\n regularExpression = /\\.[tj]sx?$/\n) {\n const files: Record<string, unknown> = {};\n\n function readDirectory(directory: string) {\n fs.readdirSync(directory).forEach((file: string) => {\n const fullPath = path.resolve(directory, file);\n const relativePath = `./${path.relative(base, fullPath).split(path.sep).join('/')}`;\n\n if (fs.statSync(fullPath).isDirectory()) {\n if (scanSubDirectories) readDirectory(fullPath);\n\n return;\n }\n\n if (!regularExpression.test(relativePath)) return;\n\n files[relativePath] = true;\n });\n }\n\n if (fs.existsSync(base)) {\n readDirectory(base);\n }\n\n const context: RequireContextPonyFill = Object.assign(\n function Module(file: string) {\n return require(path.join(base, file));\n },\n {\n keys: () => Object.keys(files),\n resolve: (key: string) => key,\n id: '0',\n __add(file: string) {\n files[file] = true;\n },\n __delete(file: string) {\n delete files[file];\n },\n }\n );\n\n return context;\n}\n"]}
1
+ {"version":3,"file":"require-context-ponyfill.js","sourceRoot":"","sources":["../../src/testing-library/require-context-ponyfill.ts"],"names":[],"mappings":";;;;;AAAA,yBAAyB;AACzB,sDAAyB;AACzB,yBAAyB;AACzB,0DAA6B;AAS7B,SAAwB,cAAc,CACpC,IAAI,GAAG,GAAG,EACV,kBAAkB,GAAG,IAAI,EACzB,iBAAiB,GAAG,YAAY,EAChC,QAAiC,EAAE;IAEnC,SAAS,aAAa,CAAC,SAAiB;QACtC,iBAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;YACjD,MAAM,QAAQ,GAAG,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,KAAK,mBAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAEpF,IAAI,iBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE;gBACvC,IAAI,kBAAkB;oBAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAEhD,OAAO;aACR;YAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC;gBAAE,OAAO;YAElD,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,iBAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACvB,aAAa,CAAC,IAAI,CAAC,CAAC;KACrB;IAED,MAAM,OAAO,GAA2B,MAAM,CAAC,MAAM,CACnD,SAAS,MAAM,CAAC,IAAY;QAC1B,OAAO,OAAO,CAAC,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC,EACD;QACE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC7B,EAAE,EAAE,GAAG;QACP,KAAK,CAAC,IAAY;YAChB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,QAAQ,CAAC,IAAY;YACnB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;KACF,CACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AA7CD,iCA6CC","sourcesContent":["// @ts-ignore: types node\nimport fs from 'node:fs';\n// @ts-ignore: types node\nimport path from 'node:path';\n\nimport type { RequireContext } from '../types';\n\nexport interface RequireContextPonyFill extends RequireContext {\n __add(file: string): void;\n __delete(file: string): void;\n}\n\nexport default function requireContext(\n base = '.',\n scanSubDirectories = true,\n regularExpression = /\\.[tj]sx?$/,\n files: Record<string, unknown> = {}\n) {\n function readDirectory(directory: string) {\n fs.readdirSync(directory).forEach((file: string) => {\n const fullPath = path.resolve(directory, file);\n const relativePath = `./${path.relative(base, fullPath).split(path.sep).join('/')}`;\n\n if (fs.statSync(fullPath).isDirectory()) {\n if (scanSubDirectories) readDirectory(fullPath);\n\n return;\n }\n\n if (!regularExpression.test(relativePath)) return;\n\n files[relativePath] = true;\n });\n }\n\n if (fs.existsSync(base)) {\n readDirectory(base);\n }\n\n const context: RequireContextPonyFill = Object.assign(\n function Module(file: string) {\n return require(path.join(base, file));\n },\n {\n keys: () => Object.keys(files),\n resolve: (key: string) => key,\n id: '0',\n __add(file: string) {\n files[file] = true;\n },\n __delete(file: string) {\n delete files[file];\n },\n }\n );\n\n return context;\n}\n"]}
@@ -75,7 +75,12 @@ function addRouteNode(routeNode, staticRoutes, dynamicRoutes, dynamicRouteContex
75
75
  * Converts a Set to a TypeScript union type
76
76
  */
77
77
  const setToUnionType = (set) => {
78
- return set.size > 0 ? [...set].map((s) => `\`${s}\``).join(' | ') : 'never';
78
+ return set.size > 0
79
+ ? [...set]
80
+ .sort()
81
+ .map((s) => `\`${s}\``)
82
+ .join(' | ')
83
+ : 'never';
79
84
  };
80
85
  function generateCombinations(pathname) {
81
86
  const groups = pathname.split('/').filter((part) => part.startsWith('(') && part.endsWith(')'));
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/typed-routes/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs';\nimport path from 'path';\n\nimport { RouteNode } from '../Route';\nimport { getRoutes } from '../getRoutes';\nimport { isTypedRoute, removeSupportedExtensions } from '../matchers';\nimport { RequireContext } from '../types';\n\n// /[...param1]/ - Match [...param1]\nconst CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nconst SLUG = /\\[.+?\\]/g;\n\nexport function getTypedRoutesDeclarationFile(ctx: RequireContext) {\n const staticRoutes = new Set<string>();\n const dynamicRoutes = new Set<string>();\n const dynamicRouteContextKeys = new Set<string>();\n\n walkRouteNode(\n getRoutes(ctx, {\n platformRoutes: false, // We don't need to generate platform specific routes\n ignoreEntryPoints: true,\n ignoreRequireErrors: true,\n importMode: 'async',\n }),\n staticRoutes,\n dynamicRoutes,\n dynamicRouteContextKeys\n );\n\n // If the user has expo-router v3+ installed, we can use the types from the package\n return (\n fs\n .readFileSync(path.join(__dirname, '../../types/expo-router.d.ts'), 'utf-8')\n // Swap from being a namespace to a module\n .replace('declare namespace ExpoRouter {', `declare module \"expo-router\" {`)\n // Add the route values\n .replace(\n 'type StaticRoutes = string;',\n `type StaticRoutes = ${setToUnionType(staticRoutes)};`\n )\n .replace(\n 'type DynamicRoutes<T extends string> = string;',\n `type DynamicRoutes<T extends string> = ${setToUnionType(dynamicRoutes)};`\n )\n .replace(\n 'type DynamicRouteTemplate = never;',\n `type DynamicRouteTemplate = ${setToUnionType(dynamicRouteContextKeys)};`\n )\n );\n}\n\n/**\n * Walks a RouteNode tree and adds the routes to the provided sets\n */\nfunction walkRouteNode(\n routeNode: RouteNode | null,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteContextKeys: Set<string>\n) {\n if (!routeNode) return;\n\n addRouteNode(routeNode, staticRoutes, dynamicRoutes, dynamicRouteContextKeys);\n\n for (const child of routeNode.children) {\n walkRouteNode(child, staticRoutes, dynamicRoutes, dynamicRouteContextKeys);\n }\n}\n\n/**\n * Given a RouteNode, adds the route to the correct sets\n * Modifies the RouteNode.route to be a typed-route string\n */\nfunction addRouteNode(\n routeNode: RouteNode | null,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteContextKeys: Set<string>\n) {\n if (!routeNode?.route) return;\n if (!isTypedRoute(routeNode.route)) return;\n\n let routePath = `${removeSupportedExtensions(routeNode.route).replace(/\\/?index$/, '')}`; // replace /index with /\n\n if (!routePath.startsWith('/')) {\n routePath = `/${routePath}`;\n }\n\n if (routeNode.dynamic) {\n for (const path of generateCombinations(routePath)) {\n dynamicRouteContextKeys.add(path);\n dynamicRoutes.add(\n `${path\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')}`\n );\n }\n } else {\n for (const combination of generateCombinations(routePath)) {\n staticRoutes.add(combination);\n }\n }\n}\n\n/**\n * Converts a Set to a TypeScript union type\n */\nconst setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\nfunction generateCombinations(pathname) {\n const groups = pathname.split('/').filter((part) => part.startsWith('(') && part.endsWith(')'));\n const combinations: string[] = [];\n\n function generate(currentIndex, currentPath) {\n if (currentIndex === groups.length) {\n combinations.push(currentPath.replace(/\\/{2,}/g, '/'));\n return;\n }\n\n const group = groups[currentIndex];\n const withoutGroup = currentPath.replace(group, '');\n generate(currentIndex + 1, withoutGroup);\n generate(currentIndex + 1, currentPath);\n }\n\n generate(0, pathname);\n return combinations;\n}\n"]}
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/typed-routes/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs';\nimport path from 'path';\n\nimport { RouteNode } from '../Route';\nimport { getRoutes } from '../getRoutes';\nimport { isTypedRoute, removeSupportedExtensions } from '../matchers';\nimport { RequireContext } from '../types';\n\n// /[...param1]/ - Match [...param1]\nconst CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nconst SLUG = /\\[.+?\\]/g;\n\nexport function getTypedRoutesDeclarationFile(ctx: RequireContext) {\n const staticRoutes = new Set<string>();\n const dynamicRoutes = new Set<string>();\n const dynamicRouteContextKeys = new Set<string>();\n\n walkRouteNode(\n getRoutes(ctx, {\n platformRoutes: false, // We don't need to generate platform specific routes\n ignoreEntryPoints: true,\n ignoreRequireErrors: true,\n importMode: 'async',\n }),\n staticRoutes,\n dynamicRoutes,\n dynamicRouteContextKeys\n );\n\n // If the user has expo-router v3+ installed, we can use the types from the package\n return (\n fs\n .readFileSync(path.join(__dirname, '../../types/expo-router.d.ts'), 'utf-8')\n // Swap from being a namespace to a module\n .replace('declare namespace ExpoRouter {', `declare module \"expo-router\" {`)\n // Add the route values\n .replace(\n 'type StaticRoutes = string;',\n `type StaticRoutes = ${setToUnionType(staticRoutes)};`\n )\n .replace(\n 'type DynamicRoutes<T extends string> = string;',\n `type DynamicRoutes<T extends string> = ${setToUnionType(dynamicRoutes)};`\n )\n .replace(\n 'type DynamicRouteTemplate = never;',\n `type DynamicRouteTemplate = ${setToUnionType(dynamicRouteContextKeys)};`\n )\n );\n}\n\n/**\n * Walks a RouteNode tree and adds the routes to the provided sets\n */\nfunction walkRouteNode(\n routeNode: RouteNode | null,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteContextKeys: Set<string>\n) {\n if (!routeNode) return;\n\n addRouteNode(routeNode, staticRoutes, dynamicRoutes, dynamicRouteContextKeys);\n\n for (const child of routeNode.children) {\n walkRouteNode(child, staticRoutes, dynamicRoutes, dynamicRouteContextKeys);\n }\n}\n\n/**\n * Given a RouteNode, adds the route to the correct sets\n * Modifies the RouteNode.route to be a typed-route string\n */\nfunction addRouteNode(\n routeNode: RouteNode | null,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteContextKeys: Set<string>\n) {\n if (!routeNode?.route) return;\n if (!isTypedRoute(routeNode.route)) return;\n\n let routePath = `${removeSupportedExtensions(routeNode.route).replace(/\\/?index$/, '')}`; // replace /index with /\n\n if (!routePath.startsWith('/')) {\n routePath = `/${routePath}`;\n }\n\n if (routeNode.dynamic) {\n for (const path of generateCombinations(routePath)) {\n dynamicRouteContextKeys.add(path);\n dynamicRoutes.add(\n `${path\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')}`\n );\n }\n } else {\n for (const combination of generateCombinations(routePath)) {\n staticRoutes.add(combination);\n }\n }\n}\n\n/**\n * Converts a Set to a TypeScript union type\n */\nconst setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0\n ? [...set]\n .sort()\n .map((s) => `\\`${s}\\``)\n .join(' | ')\n : 'never';\n};\n\nfunction generateCombinations(pathname) {\n const groups = pathname.split('/').filter((part) => part.startsWith('(') && part.endsWith(')'));\n const combinations: string[] = [];\n\n function generate(currentIndex, currentPath) {\n if (currentIndex === groups.length) {\n combinations.push(currentPath.replace(/\\/{2,}/g, '/'));\n return;\n }\n\n const group = groups[currentIndex];\n const withoutGroup = currentPath.replace(group, '');\n generate(currentIndex + 1, withoutGroup);\n generate(currentIndex + 1, currentPath);\n }\n\n generate(0, pathname);\n return combinations;\n}\n"]}
@@ -1,12 +1,17 @@
1
+ import { RequireContextPonyFill } from '../testing-library/require-context-ponyfill';
2
+ export type { RequireContextPonyFill } from '../testing-library/require-context-ponyfill';
1
3
  /**
2
4
  * Generate a Metro watch handler that regenerates the typed routes declaration file
3
5
  */
4
- export declare function getWatchHandler(outputDir: string): ({ filePath, type }: {
6
+ export declare function getWatchHandler(outputDir: string, { ctx, regenerateFn }?: {
7
+ ctx?: RequireContextPonyFill | undefined;
8
+ regenerateFn?: ((outputDir: string, ctx?: RequireContextPonyFill | undefined) => void) | undefined;
9
+ }): ({ filePath, type }: {
5
10
  filePath: string;
6
11
  type: string;
7
12
  }) => Promise<void>;
8
13
  /**
9
14
  * A throttled function that regenerates the typed routes declaration file
10
15
  */
11
- export declare const regenerateDeclarations: (outputDir: string) => void;
16
+ export declare const regenerateDeclarations: (outputDir: string, ctx?: RequireContextPonyFill | undefined) => void;
12
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/typed-routes/index.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM;cAGgB,MAAM;UAAQ,MAAM;oBAoBpF;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,6BAI5B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/typed-routes/index.ts"],"names":[],"mappings":"AAMA,OAAuB,EACrB,sBAAsB,EACvB,MAAM,6CAA6C,CAAC;AAIrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAE1F;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,EAAE,GAAgB,EAAE,YAAqC,EAAE;;;CAAK;cAID,MAAM;UAAQ,MAAM;oBAkCpF;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,uEAOlC,CAAC"}
@@ -10,30 +10,44 @@ const node_path_1 = __importDefault(require("node:path"));
10
10
  const generate_1 = require("./generate");
11
11
  const matchers_1 = require("../matchers");
12
12
  const require_context_ponyfill_1 = __importDefault(require("../testing-library/require-context-ponyfill"));
13
- const ctx = (0, require_context_ponyfill_1.default)(process.env.EXPO_ROUTER_APP_ROOT, true, _ctx_shared_1.EXPO_ROUTER_CTX_IGNORE);
13
+ const defaultCtx = (0, require_context_ponyfill_1.default)(process.env.EXPO_ROUTER_APP_ROOT, true, _ctx_shared_1.EXPO_ROUTER_CTX_IGNORE);
14
14
  /**
15
15
  * Generate a Metro watch handler that regenerates the typed routes declaration file
16
16
  */
17
- function getWatchHandler(outputDir) {
17
+ function getWatchHandler(outputDir, { ctx = defaultCtx, regenerateFn = exports.regenerateDeclarations } = {} // Exposed for testing
18
+ ) {
18
19
  const routeFiles = new Set(ctx.keys().filter((key) => (0, matchers_1.isTypedRoute)(key)));
19
20
  return async function callback({ filePath, type }) {
21
+ // Sanity check that we are in an Expo Router project
22
+ if (!process.env.EXPO_ROUTER_APP_ROOT)
23
+ return;
20
24
  let shouldRegenerate = false;
25
+ let relativePath = node_path_1.default.relative(process.env.EXPO_ROUTER_APP_ROOT, filePath);
26
+ const isInsideAppRoot = !relativePath.startsWith('../');
27
+ const basename = node_path_1.default.basename(relativePath);
28
+ if (!isInsideAppRoot)
29
+ return;
30
+ // require.context paths always start with './' when relative to the root
31
+ relativePath = `./${relativePath}`;
21
32
  if (type === 'delete') {
22
- ctx.__delete(filePath);
23
- if (routeFiles.has(filePath)) {
24
- routeFiles.delete(filePath);
33
+ ctx.__delete(relativePath);
34
+ if (routeFiles.has(relativePath)) {
35
+ routeFiles.delete(relativePath);
25
36
  shouldRegenerate = true;
26
37
  }
27
38
  }
28
39
  else if (type === 'add') {
29
- ctx.__add(filePath);
30
- shouldRegenerate = (0, matchers_1.isTypedRoute)(filePath);
40
+ ctx.__add(relativePath);
41
+ if ((0, matchers_1.isTypedRoute)(basename)) {
42
+ routeFiles.add(relativePath);
43
+ shouldRegenerate = true;
44
+ }
31
45
  }
32
46
  else {
33
- shouldRegenerate = routeFiles.has(filePath);
47
+ shouldRegenerate = routeFiles.has(relativePath);
34
48
  }
35
49
  if (shouldRegenerate) {
36
- (0, exports.regenerateDeclarations)(outputDir);
50
+ regenerateFn(outputDir, ctx);
37
51
  }
38
52
  };
39
53
  }
@@ -41,7 +55,7 @@ exports.getWatchHandler = getWatchHandler;
41
55
  /**
42
56
  * A throttled function that regenerates the typed routes declaration file
43
57
  */
44
- exports.regenerateDeclarations = throttle((outputDir) => {
58
+ exports.regenerateDeclarations = throttle((outputDir, ctx = defaultCtx) => {
45
59
  const file = (0, generate_1.getTypedRoutesDeclarationFile)(ctx);
46
60
  if (!file)
47
61
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/typed-routes/index.ts"],"names":[],"mappings":";;;;;;AAAA,yDAAiE;AACjE,sDAAyB;AACzB,0DAA6B;AAE7B,yCAA2D;AAC3D,0CAA2C;AAC3C,2GAAyE;AAEzE,MAAM,GAAG,GAAG,IAAA,kCAAc,EAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,oCAAsB,CAAC,CAAC;AAE3F;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAiB;IAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE1E,OAAO,KAAK,UAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAsC;QACnF,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAE7B,IAAI,IAAI,KAAK,QAAQ,EAAE;YACrB,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACvB,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;gBAC5B,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC5B,gBAAgB,GAAG,IAAI,CAAC;aACzB;SACF;aAAM,IAAI,IAAI,KAAK,KAAK,EAAE;YACzB,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpB,gBAAgB,GAAG,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC;SAC3C;aAAM;YACL,gBAAgB,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAC7C;QAED,IAAI,gBAAgB,EAAE;YACpB,IAAA,8BAAsB,EAAC,SAAS,CAAC,CAAC;SACnC;IACH,CAAC,CAAC;AACJ,CAAC;AAvBD,0CAuBC;AAED;;GAEG;AACU,QAAA,sBAAsB,GAAG,QAAQ,CAAC,CAAC,SAAiB,EAAE,EAAE;IACnE,MAAM,IAAI,GAAG,IAAA,wCAA6B,EAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,iBAAE,CAAC,aAAa,CAAC,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC,EAAE,GAAG,CAAC,CAAC;AAER;;;GAGG;AACH,SAAS,QAAQ,CAAoC,EAAK,EAAE,QAAgB;IAC1E,IAAI,OAAO,CAAC;IACZ,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,OAAO,SAAS,GAAG,CAAC,GAAG,IAAmB;QACxC,IAAI,OAAO,EAAE;YACX,cAAc,GAAG,IAAI,CAAC;SACvB;aAAM;YACL,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACZ,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBACxB,OAAO,GAAG,IAAI,CAAC,CAAC,gDAAgD;gBAChE,IAAI,cAAc,EAAE;oBAClB,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,0BAA0B;iBACzC;YACH,CAAC,EAAE,QAAQ,CAAC,CAAC;SACd;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { EXPO_ROUTER_CTX_IGNORE } from 'expo-router/_ctx-shared';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { getTypedRoutesDeclarationFile } from './generate';\nimport { isTypedRoute } from '../matchers';\nimport requireContext from '../testing-library/require-context-ponyfill';\n\nconst ctx = requireContext(process.env.EXPO_ROUTER_APP_ROOT, true, EXPO_ROUTER_CTX_IGNORE);\n\n/**\n * Generate a Metro watch handler that regenerates the typed routes declaration file\n */\nexport function getWatchHandler(outputDir: string) {\n const routeFiles = new Set(ctx.keys().filter((key) => isTypedRoute(key)));\n\n return async function callback({ filePath, type }: { filePath: string; type: string }) {\n let shouldRegenerate = false;\n\n if (type === 'delete') {\n ctx.__delete(filePath);\n if (routeFiles.has(filePath)) {\n routeFiles.delete(filePath);\n shouldRegenerate = true;\n }\n } else if (type === 'add') {\n ctx.__add(filePath);\n shouldRegenerate = isTypedRoute(filePath);\n } else {\n shouldRegenerate = routeFiles.has(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateDeclarations(outputDir);\n }\n };\n}\n\n/**\n * A throttled function that regenerates the typed routes declaration file\n */\nexport const regenerateDeclarations = throttle((outputDir: string) => {\n const file = getTypedRoutesDeclarationFile(ctx);\n if (!file) return;\n fs.writeFileSync(path.resolve(outputDir, './router.d.ts'), file);\n}, 100);\n\n/**\n * Throttles a function to only run once every `internal` milliseconds.\n * If called while waiting, it will run again after the timer has elapsed.\n */\nfunction throttle<T extends (...args: any[]) => any>(fn: T, interval: number) {\n let timerId;\n let shouldRunAgain = false;\n return function run(...args: Parameters<T>) {\n if (timerId) {\n shouldRunAgain = true;\n } else {\n fn(...args);\n timerId = setTimeout(() => {\n timerId = null; // reset the timer so next call will be executed\n if (shouldRunAgain) {\n run(...args); // call the function again\n }\n }, interval);\n }\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/typed-routes/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { EXPO_ROUTER_CTX_IGNORE } from 'expo-router/_ctx-shared';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { getTypedRoutesDeclarationFile } from './generate';\nimport { isTypedRoute } from '../matchers';\nimport requireContext, {\n RequireContextPonyFill,\n} from '../testing-library/require-context-ponyfill';\n\nconst defaultCtx = requireContext(process.env.EXPO_ROUTER_APP_ROOT, true, EXPO_ROUTER_CTX_IGNORE);\n\nexport type { RequireContextPonyFill } from '../testing-library/require-context-ponyfill';\n\n/**\n * Generate a Metro watch handler that regenerates the typed routes declaration file\n */\nexport function getWatchHandler(\n outputDir: string,\n { ctx = defaultCtx, regenerateFn = regenerateDeclarations } = {} // Exposed for testing\n) {\n const routeFiles = new Set(ctx.keys().filter((key) => isTypedRoute(key)));\n\n return async function callback({ filePath, type }: { filePath: string; type: string }) {\n // Sanity check that we are in an Expo Router project\n if (!process.env.EXPO_ROUTER_APP_ROOT) return;\n\n let shouldRegenerate = false;\n let relativePath = path.relative(process.env.EXPO_ROUTER_APP_ROOT, filePath);\n const isInsideAppRoot = !relativePath.startsWith('../');\n const basename = path.basename(relativePath);\n\n if (!isInsideAppRoot) return;\n\n // require.context paths always start with './' when relative to the root\n relativePath = `./${relativePath}`;\n\n if (type === 'delete') {\n ctx.__delete(relativePath);\n if (routeFiles.has(relativePath)) {\n routeFiles.delete(relativePath);\n shouldRegenerate = true;\n }\n } else if (type === 'add') {\n ctx.__add(relativePath);\n if (isTypedRoute(basename)) {\n routeFiles.add(relativePath);\n shouldRegenerate = true;\n }\n } else {\n shouldRegenerate = routeFiles.has(relativePath);\n }\n\n if (shouldRegenerate) {\n regenerateFn(outputDir, ctx);\n }\n };\n}\n\n/**\n * A throttled function that regenerates the typed routes declaration file\n */\nexport const regenerateDeclarations = throttle(\n (outputDir: string, ctx: RequireContextPonyFill = defaultCtx) => {\n const file = getTypedRoutesDeclarationFile(ctx);\n if (!file) return;\n fs.writeFileSync(path.resolve(outputDir, './router.d.ts'), file);\n },\n 100\n);\n\n/**\n * Throttles a function to only run once every `internal` milliseconds.\n * If called while waiting, it will run again after the timer has elapsed.\n */\nfunction throttle<T extends (...args: any[]) => any>(fn: T, interval: number) {\n let timerId;\n let shouldRunAgain = false;\n return function run(...args: Parameters<T>) {\n if (timerId) {\n shouldRunAgain = true;\n } else {\n fn(...args);\n timerId = setTimeout(() => {\n timerId = null; // reset the timer so next call will be executed\n if (shouldRunAgain) {\n run(...args); // call the function again\n }\n }, interval);\n }\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "3.5.10",
3
+ "version": "3.5.11",
4
4
  "description": "Expo Router is a file-based router for React Native and web applications.",
5
5
  "author": "650 Industries, Inc.",
6
6
  "license": "MIT",
@@ -102,5 +102,5 @@
102
102
  "react-native-helmet-async": "2.0.4",
103
103
  "schema-utils": "^4.0.1"
104
104
  },
105
- "gitHead": "97498fe1199c949dbf63d8961954bb28081a25c7"
105
+ "gitHead": "9c05bec11c7f5b031d1b9b0ebee78c3b71a7e11d"
106
106
  }