@netlify/plugin-nextjs 4.4.0 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/helpers/edge.js
CHANGED
|
@@ -44,7 +44,7 @@ const getMiddlewareBundle = async ({ middlewareDefinition, netlifyConfig, }) =>
|
|
|
44
44
|
chunks.push(exports);
|
|
45
45
|
return chunks.join('\n');
|
|
46
46
|
};
|
|
47
|
-
const copyEdgeSourceFile = ({ file, target, edgeFunctionDir, }) => fs_1.promises.copyFile((0, path_1.join)(__dirname, '..', 'templates', 'edge', file), (0, path_1.join)(edgeFunctionDir, target !== null && target !== void 0 ? target : file));
|
|
47
|
+
const copyEdgeSourceFile = ({ file, target, edgeFunctionDir, }) => fs_1.promises.copyFile((0, path_1.join)(__dirname, '..', '..', 'src', 'templates', 'edge', file), (0, path_1.join)(edgeFunctionDir, target !== null && target !== void 0 ? target : file));
|
|
48
48
|
// Edge functions don't support lookahead expressions
|
|
49
49
|
const stripLookahead = (regex) => regex.replace('^/(?!_next)', '^/');
|
|
50
50
|
/**
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/plugin-nextjs",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.3",
|
|
4
4
|
"description": "Run Next.js seamlessly on Netlify",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"lib/**/*",
|
|
8
|
+
"src/templates/edge/*",
|
|
8
9
|
"manifest.yml"
|
|
9
10
|
],
|
|
10
11
|
"dependencies": {
|
|
@@ -31,15 +32,14 @@
|
|
|
31
32
|
"@types/fs-extra": "^9.0.13",
|
|
32
33
|
"@types/jest": "^27.4.1",
|
|
33
34
|
"@types/node": "^17.0.25",
|
|
34
|
-
"husky": "^7.0.4",
|
|
35
|
-
"if-env": "^1.0.4",
|
|
36
35
|
"npm-run-all": "^4.1.5",
|
|
37
36
|
"typescript": "^4.6.3"
|
|
38
37
|
},
|
|
39
38
|
"scripts": {
|
|
40
|
-
"prepublishOnly": "run-s
|
|
39
|
+
"prepublishOnly": "run-s clean build",
|
|
41
40
|
"publish:pull": "git pull",
|
|
42
41
|
"publish:install": "npm ci",
|
|
42
|
+
"publish:test": "cd .. && npm ci && npm test",
|
|
43
43
|
"clean": "rimraf lib",
|
|
44
44
|
"build": "tsc",
|
|
45
45
|
"watch": "tsc --watch",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Accepts } from 'https://deno.land/x/accepts/mod.ts'
|
|
2
|
+
import type { Context } from 'netlify:edge'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Implement content negotiation for images
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const handler = async (req: Request, context: Context) => {
|
|
9
|
+
const { searchParams } = new URL(req.url)
|
|
10
|
+
const accept = new Accepts(req.headers)
|
|
11
|
+
const type = accept.types(['avif', 'webp'])
|
|
12
|
+
|
|
13
|
+
const source = searchParams.get('url')
|
|
14
|
+
const width = searchParams.get('w')
|
|
15
|
+
const quality = searchParams.get('q') ?? 75
|
|
16
|
+
|
|
17
|
+
if (!source || !width) {
|
|
18
|
+
return new Response('Invalid request', {
|
|
19
|
+
status: 400,
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const modifiers = [`w_${width}`, `q_${quality}`]
|
|
24
|
+
|
|
25
|
+
if (type) {
|
|
26
|
+
modifiers.push(`f_${type}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return context.rewrite(`/_ipx/${modifiers.join(',')}/${encodeURIComponent(source)}`)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default handler
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Context } from 'netlify:edge'
|
|
2
|
+
|
|
3
|
+
import edgeFunction from './bundle.js'
|
|
4
|
+
import { buildResponse } from './utils.ts'
|
|
5
|
+
|
|
6
|
+
export interface FetchEventResult {
|
|
7
|
+
response: Response
|
|
8
|
+
waitUntil: Promise<any>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface RequestData {
|
|
12
|
+
geo?: {
|
|
13
|
+
city?: string
|
|
14
|
+
country?: string
|
|
15
|
+
region?: string
|
|
16
|
+
latitude?: string
|
|
17
|
+
longitude?: string
|
|
18
|
+
}
|
|
19
|
+
headers: Record<string, string>
|
|
20
|
+
ip?: string
|
|
21
|
+
method: string
|
|
22
|
+
nextConfig?: {
|
|
23
|
+
basePath?: string
|
|
24
|
+
i18n?: Record<string, unknown>
|
|
25
|
+
trailingSlash?: boolean
|
|
26
|
+
}
|
|
27
|
+
page?: {
|
|
28
|
+
name?: string
|
|
29
|
+
params?: { [key: string]: string }
|
|
30
|
+
}
|
|
31
|
+
url: string
|
|
32
|
+
body?: ReadableStream<Uint8Array>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const handler = async (req: Request, context: Context) => {
|
|
36
|
+
const url = new URL(req.url)
|
|
37
|
+
if (url.pathname.startsWith('/_next/')) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const request: RequestData = {
|
|
42
|
+
headers: Object.fromEntries(req.headers.entries()),
|
|
43
|
+
geo: {
|
|
44
|
+
country: context.geo.country?.code,
|
|
45
|
+
region: context.geo.subdivision?.code,
|
|
46
|
+
city: context.geo.city,
|
|
47
|
+
},
|
|
48
|
+
url: url.toString(),
|
|
49
|
+
method: req.method,
|
|
50
|
+
ip: req.headers.get('x-nf-client-address') ?? undefined,
|
|
51
|
+
body: req.body ?? undefined,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const result = await edgeFunction({ request })
|
|
56
|
+
return buildResponse({ result, request: req, context })
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error(error)
|
|
59
|
+
return new Response(error.message, { status: 500 })
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default handler
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Context } from 'netlify:edge'
|
|
2
|
+
|
|
3
|
+
export interface FetchEventResult {
|
|
4
|
+
response: Response
|
|
5
|
+
waitUntil: Promise<any>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const addMiddlewareHeaders = async (
|
|
9
|
+
originResponse: Promise<Response> | Response,
|
|
10
|
+
middlewareResponse: Response,
|
|
11
|
+
) => {
|
|
12
|
+
// If there are extra headers, we need to add them to the response.
|
|
13
|
+
if ([...middlewareResponse.headers.keys()].length === 0) {
|
|
14
|
+
return originResponse
|
|
15
|
+
}
|
|
16
|
+
// We need to await the response to get the origin headers, then we can add the ones from middleware.
|
|
17
|
+
const response = await originResponse
|
|
18
|
+
middlewareResponse.headers.forEach((value, key) => {
|
|
19
|
+
response.headers.set(key, value)
|
|
20
|
+
})
|
|
21
|
+
return response
|
|
22
|
+
}
|
|
23
|
+
export const buildResponse = async ({
|
|
24
|
+
result,
|
|
25
|
+
request,
|
|
26
|
+
context,
|
|
27
|
+
}: {
|
|
28
|
+
result: FetchEventResult
|
|
29
|
+
request: Request
|
|
30
|
+
context: Context
|
|
31
|
+
}) => {
|
|
32
|
+
const res = new Response(result.response.body, result.response)
|
|
33
|
+
request.headers.set('x-nf-next-middleware', 'skip')
|
|
34
|
+
const rewrite = res.headers.get('x-middleware-rewrite')
|
|
35
|
+
if (rewrite) {
|
|
36
|
+
return addMiddlewareHeaders(context.rewrite(rewrite), res)
|
|
37
|
+
}
|
|
38
|
+
if (res.headers.get('x-middleware-next') === '1') {
|
|
39
|
+
return addMiddlewareHeaders(context.next(), res)
|
|
40
|
+
}
|
|
41
|
+
return res
|
|
42
|
+
}
|