-
Notifications
You must be signed in to change notification settings - Fork 61
/
index.js
117 lines (91 loc) · 3.12 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
'use strict'
const assert = require('node:assert')
const fp = require('fastify-plugin')
const Next = require('next')
function fastifyNext (fastify, options, next) {
const { underPressure, noServeAssets, ...nextOptions } = options
if (underPressure) {
const opts = typeof underPressure === 'object' ? underPressure : Object.create(null)
fastify.register(require('@fastify/under-pressure'), opts)
}
const app = Next(Object.assign({}, { dev: process.env.NODE_ENV !== 'production' }, nextOptions))
const handleNextRequests = app.getRequestHandler()
app
.prepare()
.then(() => {
fastify
.decorate('next', route.bind(fastify))
.decorateReply('nextRender', render)
.decorateReply('nextRenderError', renderError)
.addHook('onClose', function () {
return app.close()
})
if (noServeAssets) {
return next()
}
app.getServer().then(server => {
const basePath = server?.nextConfig?.basePath || ''
const nextAssetsPath = `${basePath}/_next/*`
fastify
.after(() => {
fastify.next(nextAssetsPath)
})
next()
})
})
.catch(err => next(err))
function route (path, opts, callback) {
opts = opts || {
logLevel: options.logLevel
}
if (typeof opts === 'function') {
callback = opts
opts = {
logLevel: options.logLevel
}
}
assert(typeof path === 'string', 'path must be a string')
if (opts.method) { assert(typeof opts.method === 'string', 'options.method must be a string') }
if (opts.schema) { assert(typeof opts.schema === 'object', 'options.schema must be an object') }
if (callback) { assert(typeof callback === 'function', 'callback must be a function') }
const method = opts.method || 'get'
this[method.toLowerCase()](path, opts, handler)
function handler (req, reply) {
for (const [headerName, headerValue] of Object.entries(reply.getHeaders())) {
reply.raw.setHeader(headerName, headerValue)
}
if (callback) {
return callback(app, req, reply)
}
return handleNextRequests(req.raw, reply.raw)
.then(() => {
reply.hijack()
})
}
}
async function render (path) {
assert(typeof path === 'string', 'path must be a string')
const reply = this
const { request } = reply
// set custom headers as next will finish the request
for (const [headerName, headerValue] of Object.entries(reply.getHeaders())) {
reply.raw.setHeader(headerName, headerValue)
}
await app.render(request.raw, reply.raw, path, request.query)
reply.hijack()
}
async function renderError (err) {
const reply = this
const { request } = reply
// set custom headers as next will finish the request
for (const [headerName, headerValue] of Object.entries(reply.getHeaders())) {
reply.raw.setHeader(headerName, headerValue)
}
await app.renderError(err, request.raw, reply.raw, request.url, request.query)
reply.hijack()
}
}
module.exports = fp(fastifyNext, {
fastify: '5.x',
name: '@fastify/nextjs'
})