Skip to content

Commit 2365301

Browse files
committed
use buildId from adapter context and don't read on our own
1 parent da090ce commit 2365301

File tree

3 files changed

+71
-19
lines changed

3 files changed

+71
-19
lines changed

src/adapter/build/netlify-adapter-context.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
1-
import { readFile } from 'fs/promises'
2-
import { join } from 'path/posix'
3-
4-
import type { FrameworksAPIConfig, OnBuildCompleteContext } from './types.js'
5-
6-
export function createNetlifyAdapterContext(nextAdapterContext: OnBuildCompleteContext) {
7-
let buildId: string | undefined
1+
import type { FrameworksAPIConfig } from './types.js'
82

3+
export function createNetlifyAdapterContext() {
94
return {
10-
async getBuildId() {
11-
if (!buildId) {
12-
buildId = await readFile(join(nextAdapterContext.distDir, 'BUILD_ID'), 'utf-8')
13-
}
14-
return buildId
15-
},
165
frameworksAPIConfig: undefined as FrameworksAPIConfig | undefined,
176
preparedOutputs: {
187
staticAssets: [] as string[],

src/adapter/build/routing.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { join } from 'node:path/posix'
33

44
import { glob } from 'fast-glob'
55

6-
import type { RoutingRule, RoutingRuleRedirect, RoutingRuleRewrite } from '../run/routing.js'
6+
import type {
7+
RoutingRule,
8+
RoutingRuleApply,
9+
RoutingRuleRedirect,
10+
RoutingRuleRewrite,
11+
} from '../run/routing.js'
712

813
import {
914
DISPLAY_NAME_ROUTING,
@@ -80,10 +85,18 @@ export function convertDynamicRouteToRoutingRule(
8085
} satisfies RoutingRuleRewrite
8186
}
8287

88+
const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g
89+
90+
export function escapeStringRegexp(str: string): string {
91+
return str.replace(matchOperatorsRegex, '\\$&')
92+
}
93+
8394
export async function generateRoutingRules(
8495
nextAdapterContext: OnBuildCompleteContext,
8596
netlifyAdapterContext: NetlifyAdapterContext,
8697
) {
98+
const escapedBuildId = escapeStringRegexp(nextAdapterContext.buildId)
99+
87100
const hasMiddleware = Boolean(nextAdapterContext.outputs.middleware)
88101
const hasPages =
89102
nextAdapterContext.outputs.pages.length !== 0 ||
@@ -148,7 +161,7 @@ export async function generateRoutingRules(
148161
{
149162
description: 'Normalize _next/data',
150163
match: {
151-
path: `^${nextAdapterContext.config.basePath}/_next/data/${await netlifyAdapterContext.getBuildId()}/(.*)\\.json`,
164+
path: `^${nextAdapterContext.config.basePath}/_next/data/${escapedBuildId}/(.*)\\.json`,
152165
has: [
153166
{
154167
type: 'header',
@@ -211,7 +224,7 @@ export async function generateRoutingRules(
211224
},
212225
apply: {
213226
type: 'rewrite',
214-
destination: `${nextAdapterContext.config.basePath}/_next/data/${await netlifyAdapterContext.getBuildId()}/$1.json`,
227+
destination: `${nextAdapterContext.config.basePath}/_next/data/${nextAdapterContext.buildId}/$1.json`,
215228
},
216229
},
217230
]
@@ -432,8 +445,44 @@ export async function generateRoutingRules(
432445
// apply normal dynamic routes
433446
...dynamicRoutes, // originally: ...convertedDynamicRoutes,
434447

435-
// apply x-nextjs-matched-path header and __next_data_catchall rewrite
436-
// if middleware + pages
448+
...(hasMiddleware && hasPages
449+
? [
450+
// apply x-nextjs-matched-path header
451+
// if middleware + pages
452+
{
453+
description: 'Apply x-nextjs-matched-path header if middleware + pages',
454+
match: {
455+
path: `^${join(
456+
'/',
457+
nextAdapterContext.config.basePath,
458+
'/_next/data/',
459+
escapedBuildId,
460+
'/(.*).json',
461+
)}`,
462+
},
463+
apply: {
464+
type: 'apply',
465+
headers: {
466+
'x-nextjs-matched-path': '/$1',
467+
},
468+
},
469+
continue: true,
470+
} satisfies RoutingRuleApply,
471+
{
472+
// apply __next_data_catchall rewrite
473+
// if middleware + pages
474+
description: 'Apply __next_data_catchall rewrite if middleware + pages',
475+
match: {
476+
path: ``,
477+
},
478+
apply: {
479+
type: 'rewrite',
480+
destination: '__next_data_catchall',
481+
statusCode: 200,
482+
},
483+
} satisfies RoutingRule,
484+
]
485+
: []),
437486

438487
{
439488
// originally: handle: 'hit' },

src/adapter/build/static-assets.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export async function onBuildComplete(
1919
NEXT_RUNTIME_STATIC_ASSETS,
2020
'_next',
2121
'data',
22-
await netlifyAdapterContext.getBuildId(),
22+
nextAdapterContext.buildId,
2323
// eslint-disable-next-line unicorn/no-nested-ternary
2424
`${distPathname === '/' ? 'index' : distPathname.endsWith('/') ? distPathname.slice(0, -1) : distPathname}.json`,
2525
)
@@ -65,5 +65,19 @@ export async function onBuildComplete(
6565
await cp('public', NEXT_RUNTIME_STATIC_ASSETS, {
6666
recursive: true,
6767
})
68+
// TODO: glob things to add to preparedOutputs.staticAssets
69+
}
70+
71+
const hasMiddleware = Boolean(nextAdapterContext.outputs.middleware)
72+
const hasPages =
73+
nextAdapterContext.outputs.pages.length !== 0 ||
74+
nextAdapterContext.outputs.pagesApi.length !== 0
75+
76+
if (hasMiddleware && hasPages) {
77+
// create empty __next_data_catchall json file used for fully static pages
78+
await writeFile(join(NEXT_RUNTIME_STATIC_ASSETS, '__next_data_catchall.json'), '{}')
79+
netlifyAdapterContext.preparedOutputs.staticAssets.push('__next_data_catchall.json')
80+
netlifyAdapterContext.preparedOutputs.staticAssetsAliases.__next_data_catchall =
81+
'__next_data_catchall.json'
6882
}
6983
}

0 commit comments

Comments
 (0)