Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
1 line
No EOL
17 KiB
Text
1 line
No EOL
17 KiB
Text
{"version":3,"sources":["../../../src/server/route-matcher-managers/default-route-matcher-manager.ts"],"sourcesContent":["import { isDynamicRoute } from '../../shared/lib/router/utils'\nimport type { RouteKind } from '../route-kind'\nimport type { RouteMatch } from '../route-matches/route-match'\nimport type { RouteDefinition } from '../route-definitions/route-definition'\nimport type { RouteMatcherProvider } from '../route-matcher-providers/route-matcher-provider'\nimport type { RouteMatcher } from '../route-matchers/route-matcher'\nimport type { MatchOptions, RouteMatcherManager } from './route-matcher-manager'\nimport { getSortedRoutes } from '../../shared/lib/router/utils'\nimport { LocaleRouteMatcher } from '../route-matchers/locale-route-matcher'\nimport { ensureLeadingSlash } from '../../shared/lib/page-path/ensure-leading-slash'\nimport { DetachedPromise } from '../../lib/detached-promise'\n\ninterface RouteMatchers {\n static: ReadonlyArray<RouteMatcher>\n dynamic: ReadonlyArray<RouteMatcher>\n duplicates: Record<string, ReadonlyArray<RouteMatcher>>\n}\n\nexport class DefaultRouteMatcherManager implements RouteMatcherManager {\n private readonly providers: Array<RouteMatcherProvider> = []\n protected readonly matchers: RouteMatchers = {\n static: [],\n dynamic: [],\n duplicates: {},\n }\n private lastCompilationID = this.compilationID\n\n /**\n * When this value changes, it indicates that a change has been introduced\n * that requires recompilation.\n */\n private get compilationID() {\n return this.providers.length\n }\n\n private waitTillReadyPromise?: Promise<void>\n public async waitTillReady(): Promise<void> {\n if (this.waitTillReadyPromise) {\n await this.waitTillReadyPromise\n delete this.waitTillReadyPromise\n }\n }\n\n private previousMatchers: ReadonlyArray<RouteMatcher> = []\n public async reload() {\n const { promise, resolve, reject } = new DetachedPromise<void>()\n this.waitTillReadyPromise = promise\n\n // Grab the compilation ID for this run, we'll verify it at the end to\n // ensure that if any routes were added before reloading is finished that\n // we error out.\n const compilationID = this.compilationID\n\n try {\n // Collect all the matchers from each provider.\n const matchers: Array<RouteMatcher> = []\n\n // Get all the providers matchers.\n const providersMatchers: ReadonlyArray<ReadonlyArray<RouteMatcher>> =\n await Promise.all(this.providers.map((provider) => provider.matchers()))\n\n // Use this to detect duplicate pathnames.\n const all = new Map<string, RouteMatcher>()\n const duplicates: Record<string, RouteMatcher[]> = {}\n for (const providerMatchers of providersMatchers) {\n for (const matcher of providerMatchers) {\n // Reset duplicated matches when reloading from pages conflicting state.\n if (matcher.duplicated) delete matcher.duplicated\n // Test to see if the matcher being added is a duplicate.\n const duplicate = all.get(matcher.definition.pathname)\n if (duplicate) {\n // This looks a little weird, but essentially if the pathname\n // already exists in the duplicates map, then we got that array\n // reference. Otherwise, we create a new array with the original\n // duplicate first. Then we push the new matcher into the duplicate\n // array, and reset it to the duplicates object (which may be a\n // no-op if the pathname already existed in the duplicates object).\n // Then we set the array of duplicates on both the original\n // duplicate object and the new one, so we can keep them in sync.\n // If a new duplicate is found, and it matches an existing pathname,\n // the retrieval of the `other` will actually return the array\n // reference used by all other duplicates. This is why ReadonlyArray\n // is so important! Array's are always references!\n const others = duplicates[matcher.definition.pathname] ?? [\n duplicate,\n ]\n others.push(matcher)\n duplicates[matcher.definition.pathname] = others\n\n // Add duplicated details to each route.\n duplicate.duplicated = others\n matcher.duplicated = others\n\n // TODO: see if we should error for duplicates in production?\n }\n\n matchers.push(matcher)\n\n // Add the matcher's pathname to the set.\n all.set(matcher.definition.pathname, matcher)\n }\n }\n\n // Update the duplicate matchers. This is used in the development manager\n // to warn about duplicates.\n this.matchers.duplicates = duplicates\n\n // If the cache is the same as what we just parsed, we can exit now. We\n // can tell by using the `===` which compares object identity, which for\n // the manifest matchers, will return the same matcher each time.\n if (\n this.previousMatchers.length === matchers.length &&\n this.previousMatchers.every(\n (cachedMatcher, index) => cachedMatcher === matchers[index]\n )\n ) {\n return\n }\n this.previousMatchers = matchers\n\n // For matchers that are for static routes, filter them now.\n this.matchers.static = matchers.filter((matcher) => !matcher.isDynamic)\n\n // For matchers that are for dynamic routes, filter them and sort them now.\n const dynamic = matchers.filter((matcher) => matcher.isDynamic)\n\n // As `getSortedRoutes` only takes an array of strings, we need to create\n // a map of the pathnames (used for sorting) and the matchers. When we\n // have locales, there may be multiple matches for the same pathname. To\n // handle this, we keep a map of all the indexes (in `reference`) and\n // merge them in later.\n\n const reference = new Map<string, number[]>()\n const pathnames = new Array<string>()\n for (let index = 0; index < dynamic.length; index++) {\n // Grab the pathname from the definition.\n const pathname = dynamic[index].definition.pathname\n\n // Grab the index in the dynamic array, push it into the reference.\n const indexes = reference.get(pathname) ?? []\n indexes.push(index)\n\n // If this is the first one set it. If it isn't, we don't need to\n // because pushing above on the array will mutate the array already\n // stored there because array's are always a reference!\n if (indexes.length === 1) reference.set(pathname, indexes)\n // Otherwise, continue, we've already added this pathname before.\n else continue\n\n pathnames.push(pathname)\n }\n\n // Sort the array of pathnames.\n const sorted = getSortedRoutes(pathnames)\n\n // For each of the sorted pathnames, iterate over them, grabbing the list\n // of indexes and merging them back into the new `sortedDynamicMatchers`\n // array. The order of the same matching pathname doesn't matter because\n // they will have other matching characteristics (like the locale) that\n // is considered.\n const sortedDynamicMatchers: Array<RouteMatcher> = []\n for (const pathname of sorted) {\n const indexes = reference.get(pathname)\n if (!Array.isArray(indexes)) {\n throw new Error('Invariant: expected to find identity in indexes map')\n }\n\n const dynamicMatches = indexes.map((index) => dynamic[index])\n\n sortedDynamicMatchers.push(...dynamicMatches)\n }\n\n this.matchers.dynamic = sortedDynamicMatchers\n\n // This means that there was a new matcher pushed while we were waiting\n if (this.compilationID !== compilationID) {\n throw new Error(\n 'Invariant: expected compilation to finish before new matchers were added, possible missing await'\n )\n }\n } catch (err) {\n reject(err)\n } finally {\n // The compilation ID matched, so mark the complication as finished.\n this.lastCompilationID = compilationID\n resolve()\n }\n }\n\n public push(provider: RouteMatcherProvider): void {\n this.providers.push(provider)\n }\n\n public async test(pathname: string, options: MatchOptions): Promise<boolean> {\n // See if there's a match for the pathname...\n const match = await this.match(pathname, options)\n\n // This default implementation only needs to check to see if there _was_ a\n // match. The development matcher actually changes it's behavior by not\n // recompiling the routes.\n return match !== null\n }\n\n public async match(\n pathname: string,\n options: MatchOptions\n ): Promise<RouteMatch<RouteDefinition<RouteKind>> | null> {\n // \"Iterate\" over the match options. Once we found a single match, exit with\n // it, otherwise return null below. If no match is found, the inner block\n // won't be called.\n for await (const match of this.matchAll(pathname, options)) {\n return match\n }\n\n return null\n }\n\n /**\n * This is a point for other managers to override to inject other checking\n * behavior like duplicate route checking on a per-request basis.\n *\n * @param pathname the pathname to validate against\n * @param matcher the matcher to validate/test with\n * @returns the match if found\n */\n protected validate(\n pathname: string,\n matcher: RouteMatcher,\n options: MatchOptions\n ): RouteMatch | null {\n if (matcher instanceof LocaleRouteMatcher) {\n return matcher.match(pathname, options)\n }\n\n // If the locale was inferred from the default locale, then it will have\n // already added a locale to the pathname. We need to remove it before\n // matching because this matcher is not locale aware.\n if (options.i18n?.inferredFromDefault) {\n return matcher.match(options.i18n.pathname)\n }\n\n return matcher.match(pathname)\n }\n\n public async *matchAll(\n pathname: string,\n options: MatchOptions\n ): AsyncGenerator<RouteMatch<RouteDefinition<RouteKind>>, null, undefined> {\n // Guard against the matcher manager from being run before it needs to be\n // recompiled. This was preferred to re-running the compilation here because\n // it should be re-ran only when it changes. If a match is attempted before\n // this is done, it indicates that there is a case where a provider is added\n // before it was recompiled (an error). We also don't want to affect request\n // times.\n if (this.lastCompilationID !== this.compilationID) {\n throw new Error(\n 'Invariant: expected routes to have been loaded before match'\n )\n }\n\n // Ensure that path matching is done with a leading slash.\n pathname = ensureLeadingSlash(pathname)\n\n // If this pathname doesn't look like a dynamic route, and this pathname is\n // listed in the normalized list of routes, then return it. This ensures\n // that when a route like `/user/[id]` is encountered, it doesn't just match\n // with the list of normalized routes.\n if (!isDynamicRoute(pathname)) {\n for (const matcher of this.matchers.static) {\n const match = this.validate(pathname, matcher, options)\n if (!match) continue\n\n yield match\n }\n }\n\n // If we should skip handling dynamic routes, exit now.\n if (options?.skipDynamic) return null\n\n // Loop over the dynamic matchers, yielding each match.\n for (const matcher of this.matchers.dynamic) {\n const match = this.validate(pathname, matcher, options)\n if (!match) continue\n\n yield match\n }\n\n // We tried direct matching against the pathname and against all the dynamic\n // paths, so there was no match.\n return null\n }\n}\n"],"names":["DefaultRouteMatcherManager","compilationID","providers","length","waitTillReady","waitTillReadyPromise","reload","promise","resolve","reject","DetachedPromise","matchers","providersMatchers","Promise","all","map","provider","Map","duplicates","providerMatchers","matcher","duplicated","duplicate","get","definition","pathname","others","push","set","previousMatchers","every","cachedMatcher","index","static","filter","isDynamic","dynamic","reference","pathnames","Array","indexes","sorted","getSortedRoutes","sortedDynamicMatchers","isArray","Error","dynamicMatches","err","lastCompilationID","test","options","match","matchAll","validate","LocaleRouteMatcher","i18n","inferredFromDefault","ensureLeadingSlash","isDynamicRoute","skipDynamic"],"mappings":"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","ignoreList":[0]} |