Skip to content

Commit

Permalink
Handle dynamic routes / catchall routes in on-demand-entries (#38512)
Browse files Browse the repository at this point in the history
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
timneutkens and kodiakhq[bot] committed Jul 11, 2022
1 parent d2eb786 commit b014343
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
42 changes: 37 additions & 5 deletions packages/next/server/app-render.tsx
Expand Up @@ -248,7 +248,30 @@ function createServerComponentRenderer(
return ServerComponentWrapper
}

export type Segment = string | [param: string, value: string]
type DynamicParamTypes = 'catchall' | 'optional-catchall' | 'dynamic'
// c = catchall
// oc = optional catchall
// d = dynamic
export type DynamicParamTypesShort = 'c' | 'oc' | 'd'

function getShortDynamicParamType(
type: DynamicParamTypes
): DynamicParamTypesShort {
switch (type) {
case 'catchall':
return 'c'
case 'optional-catchall':
return 'oc'
case 'dynamic':
return 'd'
default:
throw new Error('Unknown dynamic param type')
}
}

export type Segment =
| string
| [param: string, value: string, type: DynamicParamTypesShort]

type LoaderTree = [
segment: string,
Expand Down Expand Up @@ -301,7 +324,7 @@ export type ChildProp = {

function getSegmentParam(segment: string): {
param: string
type: 'catchall' | 'optional-catchall' | 'dynamic'
type: DynamicParamTypes
} | null {
if (segment.startsWith('[[...') && segment.endsWith(']]')) {
return {
Expand Down Expand Up @@ -416,6 +439,7 @@ export async function renderToHTML(
param: string
value: string | string[] | null
treeValue: string
type: DynamicParamTypesShort
} | null => {
// TODO: use correct matching for dynamic routes to get segment param
const segmentParam = getSegmentParam(segment)
Expand All @@ -431,6 +455,7 @@ export async function renderToHTML(
return {
param: key,
value: null,
type: getShortDynamicParamType(segmentParam.type),
treeValue: '',
}
}
Expand All @@ -441,6 +466,7 @@ export async function renderToHTML(
param: key,
value: value,
treeValue: Array.isArray(value) ? value.join('/') : value,
type: getShortDynamicParamType(segmentParam.type),
}
}

Expand All @@ -451,7 +477,9 @@ export async function renderToHTML(
const dynamicParam = getDynamicParamFromSegment(segment)

const segmentTree: FlightRouterState = [
dynamicParam ? [dynamicParam.param, dynamicParam.treeValue] : segment,
dynamicParam
? [dynamicParam.param, dynamicParam.treeValue, dynamicParam.type]
: segment,
{},
]

Expand Down Expand Up @@ -539,7 +567,11 @@ export async function renderToHTML(
const childProp: ChildProp = {
current: <ChildComponent />,
segment: childSegmentParam
? [childSegmentParam.param, childSegmentParam.treeValue]
? [
childSegmentParam.param,
childSegmentParam.treeValue,
childSegmentParam.type,
]
: parallelRoutes[currentValue][0],
}

Expand Down Expand Up @@ -686,7 +718,7 @@ export async function renderToHTML(
}
: parentParams
const actualSegment: Segment = segmentParam
? [segmentParam.param, segmentParam.treeValue]
? [segmentParam.param, segmentParam.treeValue, segmentParam.type]
: segment

const renderComponentsOnThisLevel =
Expand Down
22 changes: 20 additions & 2 deletions packages/next/server/dev/on-demand-entry-handler.ts
Expand Up @@ -15,7 +15,7 @@ import { serverComponentRegex } from '../../build/webpack/loaders/utils'
import { getPageStaticInfo } from '../../build/analysis/get-page-static-info'
import { isMiddlewareFile, isMiddlewareFilename } from '../../build/utils'
import { PageNotFoundError } from '../../shared/lib/utils'
import { FlightRouterState } from '../app-render'
import { DynamicParamTypesShort, FlightRouterState } from '../app-render'

function treePathToEntrypoint(
segmentPath: string[],
Expand All @@ -38,14 +38,32 @@ function treePathToEntrypoint(
return treePathToEntrypoint(childSegmentPath, path)
}

function convertDynamicParamTypeToSyntax(
dynamicParamTypeShort: DynamicParamTypesShort,
param: string
) {
switch (dynamicParamTypeShort) {
case 'c':
return `[...${param}]`
case 'oc':
return `[[...${param}]]`
case 'd':
return `[${param}]`
default:
throw new Error('Unknown dynamic param type')
}
}

function getEntrypointsFromTree(
tree: FlightRouterState,
isFirst: boolean,
parentPath: string[] = []
) {
const [segment, parallelRoutes] = tree

const currentSegment = Array.isArray(segment) ? segment[0] : segment
const currentSegment = Array.isArray(segment)
? convertDynamicParamTypeToSyntax(segment[2], segment[0])
: segment

const currentPath = [...parentPath, currentSegment]

Expand Down

0 comments on commit b014343

Please sign in to comment.