Skip to content

Commit 3c805d4

Browse files
committed
feat: add refresh hooks api implementation
1 parent 8033d60 commit 3c805d4

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

packages/runtime/src/templates/getHandler.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str
6565
// We memoize this because it can be shared between requests, but don't instantiate it until
6666
// the first request because we need the host and port.
6767
let bridge: NodeBridge
68-
const getBridge = (event: HandlerEvent): NodeBridge => {
68+
const getBridge = (event: HandlerEvent, context: HandlerContext): NodeBridge => {
6969
if (bridge) {
7070
return bridge
7171
}
@@ -79,6 +79,7 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str
7979
customServer: false,
8080
hostname: url.hostname,
8181
port,
82+
netlifyRevalidateToken: context.clientContext?.custom?.odb_refresh_hooks,
8283
})
8384
const requestHandler = nextServer.getRequestHandler()
8485
const server = new Server(async (req, res) => {
@@ -115,7 +116,7 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str
115116
process.env._NETLIFY_GRAPH_TOKEN = graphToken
116117
}
117118

118-
const { headers, ...result } = await getBridge(event).launcher(event, context)
119+
const { headers, ...result } = await getBridge(event, context).launcher(event, context)
119120

120121
// Convert all headers to multiValueHeaders
121122

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,81 @@
1-
import { NodeRequestHandler } from 'next/dist/server/next-server'
1+
import https from 'https'
2+
3+
import { NodeRequestHandler, Options } from 'next/dist/server/next-server'
24

35
import { getNextServer, NextServerType } from './handlerUtils'
46

57
const NextServer: NextServerType = getNextServer()
68

9+
interface NetlifyNextServerOptions extends Options {
10+
netlifyRevalidateToken: string
11+
}
12+
713
class NetlifyNextServer extends NextServer {
14+
private netlifyRevalidateToken?: string
15+
16+
public constructor(options: NetlifyNextServerOptions) {
17+
super(options)
18+
this.netlifyRevalidateToken = options.netlifyRevalidateToken
19+
}
20+
821
public getRequestHandler(): NodeRequestHandler {
922
const handler = super.getRequestHandler()
10-
return (req, res, parsedUrl) => {
23+
return async (req, res, parsedUrl) => {
1124
if (req.headers['x-prerender-revalidate']) {
12-
console.log('Revalidate request')
25+
if (this.netlifyRevalidateToken) {
26+
try {
27+
await this.netlifyRevalidate(req.url)
28+
console.log('Revalidated', req.url)
29+
} catch {
30+
// TODO: status 500 error refreshing ODB cache
31+
console.log('Error revalidating', req.url)
32+
}
33+
} else {
34+
// TODO: status 400 refresh hooks not enabled for site in proxy
35+
console.log('Missing revalidate token', req.url)
36+
}
1337
}
1438
return handler(req, res, parsedUrl)
1539
}
1640
}
41+
42+
private netlifyRevalidate(url: string) {
43+
const path = new URL(url).pathname
44+
const domain = this.hostname
45+
const siteId = process.env.SITE_ID
46+
47+
return new Promise((resolve, reject) => {
48+
const body = JSON.stringify({ paths: [path], domain })
49+
50+
const req = https
51+
.request(
52+
{
53+
hostname: 'api.netlify.com',
54+
port: 443,
55+
path: `/api/v1/sites/${siteId}/refresh_on_demand_builders`,
56+
method: 'POST',
57+
headers: {
58+
'Content-Type': 'application/json',
59+
'Content-Length': body.length,
60+
Authorization: `Bearer ${this.netlifyRevalidateToken}`,
61+
},
62+
},
63+
(res) => {
64+
let data = ''
65+
res.on('data', (chunk) => {
66+
data += chunk
67+
})
68+
res.on('end', () => {
69+
resolve(JSON.parse(data))
70+
})
71+
},
72+
)
73+
.on('error', reject)
74+
75+
req.write(body)
76+
req.end()
77+
})
78+
}
1779
}
1880

1981
export { NetlifyNextServer }

0 commit comments

Comments
 (0)