@netlify/plugin-nextjs 3.9.0 → 4.0.0-beta.10

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.
Files changed (97) hide show
  1. package/README.md +32 -51
  2. package/lib/.DS_Store +0 -0
  3. package/lib/constants.js +21 -0
  4. package/lib/helpers/cache.js +20 -0
  5. package/lib/helpers/config.js +174 -0
  6. package/lib/helpers/files.js +187 -0
  7. package/lib/helpers/functions.js +65 -0
  8. package/lib/helpers/verification.js +93 -0
  9. package/lib/index.js +50 -0
  10. package/lib/templates/getHandler.js +161 -0
  11. package/lib/templates/getPageResolver.js +24 -0
  12. package/lib/templates/handlerUtils.js +36 -0
  13. package/lib/templates/ipx.js +8 -0
  14. package/manifest.yml +1 -1
  15. package/package.json +50 -55
  16. package/LICENSE.md +0 -7
  17. package/helpers/cacheBuild.js +0 -31
  18. package/helpers/checkNxConfig.js +0 -56
  19. package/helpers/copyUnstableIncludedDirs.js +0 -27
  20. package/helpers/doesNotNeedPlugin.js +0 -49
  21. package/helpers/doesSiteUseNextOnNetlify.js +0 -20
  22. package/helpers/getNextConfig.js +0 -46
  23. package/helpers/getNextRoot.js +0 -20
  24. package/helpers/isStaticExportProject.js +0 -20
  25. package/helpers/resolveNextModule.js +0 -30
  26. package/helpers/usesBuildCommand.js +0 -37
  27. package/helpers/validateNextUsage.js +0 -53
  28. package/helpers/verifyBuildTarget.js +0 -69
  29. package/index.js +0 -166
  30. package/src/index.js +0 -94
  31. package/src/lib/config.js +0 -58
  32. package/src/lib/constants/regex.js +0 -9
  33. package/src/lib/helpers/addDefaultLocaleRedirect.js +0 -25
  34. package/src/lib/helpers/addLocaleRedirects.js +0 -19
  35. package/src/lib/helpers/asyncForEach.js +0 -7
  36. package/src/lib/helpers/convertToBasePathRedirects.js +0 -80
  37. package/src/lib/helpers/copyDynamicImportChunks.js +0 -39
  38. package/src/lib/helpers/formatRedirectTarget.js +0 -9
  39. package/src/lib/helpers/getDataRouteForRoute.js +0 -30
  40. package/src/lib/helpers/getFilePathForRoute.js +0 -10
  41. package/src/lib/helpers/getI18n.js +0 -10
  42. package/src/lib/helpers/getNetlifyFunctionName.js +0 -38
  43. package/src/lib/helpers/getNetlifyRoutes.js +0 -45
  44. package/src/lib/helpers/getNextDistDir.js +0 -12
  45. package/src/lib/helpers/getNextSrcDir.js +0 -5
  46. package/src/lib/helpers/getPagesManifest.js +0 -19
  47. package/src/lib/helpers/getPrerenderManifest.js +0 -40
  48. package/src/lib/helpers/getPreviewModeFunctionName.js +0 -5
  49. package/src/lib/helpers/getRoutesManifest.js +0 -12
  50. package/src/lib/helpers/getSortedRedirects.js +0 -37
  51. package/src/lib/helpers/handleFileTracking.js +0 -61
  52. package/src/lib/helpers/isApiRoute.js +0 -4
  53. package/src/lib/helpers/isDynamicRoute.js +0 -6
  54. package/src/lib/helpers/isFrameworkRoute.js +0 -5
  55. package/src/lib/helpers/isHtmlFile.js +0 -4
  56. package/src/lib/helpers/isRootCatchAllRedirect.js +0 -6
  57. package/src/lib/helpers/isRouteInPrerenderManifest.js +0 -23
  58. package/src/lib/helpers/isRouteWithDataRoute.js +0 -13
  59. package/src/lib/helpers/isRouteWithFallback.js +0 -12
  60. package/src/lib/helpers/logger.js +0 -44
  61. package/src/lib/helpers/removeFileExtension.js +0 -4
  62. package/src/lib/helpers/runJobsQueue.js +0 -18
  63. package/src/lib/helpers/setupNetlifyFunctionForPage.js +0 -44
  64. package/src/lib/helpers/setupStaticFileForPage.js +0 -18
  65. package/src/lib/pages/api/pages.js +0 -22
  66. package/src/lib/pages/api/redirects.js +0 -13
  67. package/src/lib/pages/api/setup.js +0 -15
  68. package/src/lib/pages/getInitialProps/pages.js +0 -40
  69. package/src/lib/pages/getInitialProps/redirects.js +0 -26
  70. package/src/lib/pages/getInitialProps/setup.js +0 -15
  71. package/src/lib/pages/getServerSideProps/pages.js +0 -43
  72. package/src/lib/pages/getServerSideProps/redirects.js +0 -44
  73. package/src/lib/pages/getServerSideProps/setup.js +0 -15
  74. package/src/lib/pages/getStaticProps/pages.js +0 -26
  75. package/src/lib/pages/getStaticProps/redirects.js +0 -70
  76. package/src/lib/pages/getStaticProps/setup.js +0 -68
  77. package/src/lib/pages/getStaticPropsWithFallback/pages.js +0 -24
  78. package/src/lib/pages/getStaticPropsWithFallback/redirects.js +0 -51
  79. package/src/lib/pages/getStaticPropsWithFallback/setup.js +0 -29
  80. package/src/lib/pages/getStaticPropsWithRevalidate/pages.js +0 -45
  81. package/src/lib/pages/getStaticPropsWithRevalidate/redirects.js +0 -55
  82. package/src/lib/pages/getStaticPropsWithRevalidate/setup.js +0 -40
  83. package/src/lib/pages/withoutProps/pages.js +0 -27
  84. package/src/lib/pages/withoutProps/redirects.js +0 -51
  85. package/src/lib/pages/withoutProps/setup.js +0 -34
  86. package/src/lib/pages/worker.js +0 -19
  87. package/src/lib/steps/copyNextAssets.js +0 -31
  88. package/src/lib/steps/copyPublicFiles.js +0 -18
  89. package/src/lib/steps/prepareFolders.js +0 -39
  90. package/src/lib/steps/setupHeaders.js +0 -37
  91. package/src/lib/steps/setupImageFunction.js +0 -17
  92. package/src/lib/steps/setupPages.js +0 -25
  93. package/src/lib/steps/setupRedirects.js +0 -105
  94. package/src/lib/templates/getHandlerFunction.js +0 -209
  95. package/src/lib/templates/getTemplate.js +0 -15
  96. package/src/lib/templates/imageFunction.js +0 -135
  97. package/src/next-on-netlify.js +0 -22
@@ -1,209 +0,0 @@
1
- // TEMPLATE: This file will be copied to the Netlify functions directory
2
-
3
- // Render function for the Next.js page
4
- const { Buffer } = require('buffer')
5
- const http = require('http')
6
- const queryString = require('querystring')
7
- const Stream = require('stream')
8
-
9
- // Mock a HTTP IncomingMessage object from the Netlify Function event parameters
10
- // Based on API Gateway Lambda Compat
11
- // Source: https://github.com/serverless-nextjs/serverless-next.js/blob/master/packages/compat-layers/apigw-lambda-compat/lib/compatLayer.js
12
-
13
- const createRequestObject = ({ event, context }) => {
14
- const {
15
- requestContext = {},
16
- path = '',
17
- multiValueQueryStringParameters,
18
- pathParameters,
19
- httpMethod,
20
- multiValueHeaders = {},
21
- body,
22
- isBase64Encoded,
23
- } = event
24
-
25
- const newStream = new Stream.Readable()
26
- const req = Object.assign(newStream, http.IncomingMessage.prototype)
27
- req.url = (requestContext.path || path || '').replace(new RegExp(`^/${requestContext.stage}`), '') || '/'
28
-
29
- let qs = ''
30
-
31
- if (multiValueQueryStringParameters) {
32
- qs += queryString.stringify(multiValueQueryStringParameters)
33
- }
34
-
35
- if (pathParameters) {
36
- const pathParametersQs = queryString.stringify(pathParameters)
37
-
38
- qs += qs.length === 0 ? pathParametersQs : `&${pathParametersQs}`
39
- }
40
-
41
- const hasQueryString = qs.length !== 0
42
-
43
- if (hasQueryString) {
44
- req.url += `?${qs}`
45
- }
46
-
47
- req.method = httpMethod
48
- req.rawHeaders = []
49
- req.headers = {}
50
-
51
- // Expose Netlify Function event and callback on request object.
52
- // This makes it possible to access the clientContext, for example.
53
- // See: https://github.com/netlify/next-on-netlify/issues/20
54
- // It also allows users to change the behavior of waiting for empty event
55
- // loop.
56
- // See: https://github.com/netlify/next-on-netlify/issues/66#issuecomment-719988804
57
- req.netlifyFunctionParams = { event, context }
58
-
59
- for (const key of Object.keys(multiValueHeaders)) {
60
- for (const value of multiValueHeaders[key]) {
61
- req.rawHeaders.push(key)
62
- req.rawHeaders.push(value)
63
- }
64
- req.headers[key.toLowerCase()] = multiValueHeaders[key].toString()
65
- }
66
-
67
- req.getHeader = (name) => req.headers[name.toLowerCase()]
68
- req.getHeaders = () => req.headers
69
-
70
- req.connection = {}
71
-
72
- if (body) {
73
- req.push(body, isBase64Encoded ? 'base64' : undefined)
74
- }
75
-
76
- req.push(null)
77
-
78
- return req
79
- }
80
-
81
- // Mock a HTTP ServerResponse object that returns a Netlify Function-compatible
82
- // response via the onResEnd callback when res.end() is called.
83
- // Based on API Gateway Lambda Compat
84
- // Source: https://github.com/serverless-nextjs/serverless-next.js/blob/master/packages/compat-layers/apigw-lambda-compat/lib/compatLayer.js
85
-
86
- const createResponseObject = ({ onResEnd }) => {
87
- const response = {
88
- isBase64Encoded: true,
89
- multiValueHeaders: {},
90
- }
91
-
92
- const res = new Stream()
93
- Object.defineProperty(res, 'statusCode', {
94
- get() {
95
- return response.statusCode
96
- },
97
- set(statusCode) {
98
- response.statusCode = statusCode
99
- },
100
- })
101
- res.headers = {}
102
- res.writeHead = (status, headers) => {
103
- response.statusCode = status
104
- if (headers) res.headers = Object.assign(res.headers, headers)
105
-
106
- // Return res object to allow for chaining
107
- // Fixes: https://github.com/netlify/next-on-netlify/pull/74
108
- return res
109
- }
110
- res.write = (chunk) => {
111
- if (!response.body) {
112
- response.body = Buffer.from('')
113
- }
114
-
115
- response.body = Buffer.concat([
116
- Buffer.isBuffer(response.body) ? response.body : Buffer.from(response.body),
117
- Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk),
118
- ])
119
- }
120
- res.setHeader = (name, value) => {
121
- res.headers[name.toLowerCase()] = value
122
- }
123
- res.removeHeader = (name) => {
124
- delete res.headers[name.toLowerCase()]
125
- }
126
- res.getHeader = (name) => res.headers[name.toLowerCase()]
127
- res.getHeaders = () => res.headers
128
- res.hasHeader = (name) => Boolean(res.getHeader(name))
129
- res.end = (text) => {
130
- if (text) res.write(text)
131
- if (!res.statusCode) {
132
- res.statusCode = 200
133
- }
134
-
135
- if (response.body) {
136
- response.body = Buffer.from(response.body).toString('base64')
137
- }
138
- response.multiValueHeaders = res.headers
139
- res.writeHead(response.statusCode)
140
-
141
- // Convert all multiValueHeaders into arrays
142
- for (const key of Object.keys(response.multiValueHeaders)) {
143
- if (!Array.isArray(response.multiValueHeaders[key])) {
144
- response.multiValueHeaders[key] = [response.multiValueHeaders[key]]
145
- }
146
- }
147
-
148
- res.finished = true
149
- res.writableEnded = true
150
- // Call onResEnd handler with the response object
151
- onResEnd(response)
152
- }
153
-
154
- return res
155
- }
156
-
157
- // Render the Next.js page
158
- const renderNextPage = ({ event, context }, nextPage) => {
159
- // The Next.js page is rendered inside a promise that is resolved when the
160
- // Next.js page ends the response via `res.end()`
161
- const promise = new Promise((resolve) => {
162
- // Create a Next.js-compatible request and response object
163
- // These mock the ClientRequest and ServerResponse classes from node http
164
- // See: https://nodejs.org/api/http.html
165
- const req = createRequestObject({ event, context })
166
- const res = createResponseObject({
167
- onResEnd: (response) => resolve(response),
168
- })
169
-
170
- // Check if page is a Next.js page or an API route
171
- const isNextPage = nextPage.render instanceof Function
172
- const isApiRoute = !isNextPage
173
-
174
- // Perform the render: render() for Next.js page or default() for API route
175
- if (isNextPage) return nextPage.render(req, res)
176
- if (isApiRoute) return nextPage.default(req, res)
177
- })
178
-
179
- // Return the promise
180
- return promise
181
- }
182
-
183
- const getHandlerFunction = (nextPage) => async (event, context) => {
184
- // x-forwarded-host is undefined on Netlify for proxied apps that need it
185
- // fixes https://github.com/netlify/next-on-netlify/issues/46
186
- if (!event.multiValueHeaders.hasOwnProperty('x-forwarded-host')) {
187
- // eslint-disable-next-line no-param-reassign
188
- event.multiValueHeaders['x-forwarded-host'] = [event.headers.host]
189
- }
190
-
191
- // Get the request URL
192
- const { path } = event
193
- console.log('[request]', path)
194
-
195
- // Render the Next.js page
196
- const response = await renderNextPage({ event, context }, nextPage)
197
-
198
- // Convert header values to string. Netlify does not support integers as
199
- // header values. See: https://github.com/netlify/cli/issues/451
200
- Object.keys(response.multiValueHeaders).forEach((key) => {
201
- response.multiValueHeaders[key] = response.multiValueHeaders[key].map((value) => String(value))
202
- })
203
-
204
- response.multiValueHeaders['Cache-Control'] = ['no-cache']
205
-
206
- return response
207
- }
208
-
209
- exports.getHandlerFunction = getHandlerFunction
@@ -1,15 +0,0 @@
1
- const getTemplate = ({ filePath, isODB }) => {
2
- if (isODB) {
3
- return `// Auto-generated file. DO NOT MODIFY.
4
- const { getHandlerFunction } = require('./getHandlerFunction')
5
- const { builder } = require('@netlify/functions')
6
- exports.handler = builder(getHandlerFunction(require("./nextPage/${filePath}")))
7
- `
8
- }
9
- return `// Auto-generated file. DO NOT MODIFY.
10
- const { getHandlerFunction } = require('./getHandlerFunction')
11
- exports.handler = getHandlerFunction(require("./nextPage/${filePath}"))
12
- `
13
- }
14
-
15
- module.exports = getTemplate
@@ -1,135 +0,0 @@
1
- const { builder } = require('@netlify/functions')
2
- const etag = require('etag')
3
- const config = require('./imageconfig.json')
4
- const imageType = require('image-type')
5
- const isSvg = require('is-svg')
6
- const fetch = require('node-fetch')
7
- const sharp = require('sharp')
8
- // 6MB is hard max Lambda response size
9
- const MAX_RESPONSE_SIZE = 6291456
10
-
11
- function getImageType(buffer) {
12
- const type = imageType(buffer)
13
- if (type) {
14
- return type
15
- }
16
- if (isSvg(buffer)) {
17
- return { ext: 'svg', mime: 'image/svg' }
18
- }
19
- return null
20
- }
21
-
22
- const IGNORED_FORMATS = new Set(['svg', 'gif'])
23
- const OUTPUT_FORMATS = new Set(['png', 'jpg', 'webp', 'avif'])
24
-
25
- // Function used to mimic next/image
26
- const handler = async (event) => {
27
- const [, , url, w = 500, q = 75] = event.path.split('/')
28
- // Work-around a bug in redirect handling. Remove when fixed.
29
- const parsedUrl = decodeURIComponent(url).replace('+', '%20')
30
- const width = Number.parseInt(w)
31
-
32
- if (!width) {
33
- return {
34
- statusCode: 400,
35
- body: 'Invalid image parameters',
36
- }
37
- }
38
-
39
- const quality = Number.parseInt(q) || 60
40
-
41
- let imageUrl
42
- let isRemoteImage = false
43
- // Relative image
44
- if (parsedUrl.startsWith('/')) {
45
- const protocol = event.headers['x-nf-connection-proto'] || event.headers['x-forwarded-proto'] || 'http'
46
- imageUrl = `${protocol}://${event.headers.host || event.hostname}${parsedUrl}`
47
- } else {
48
- isRemoteImage = true
49
- // Remote images need to be in the allowlist
50
- let allowedDomains = config.domains || []
51
-
52
- if (process.env.NEXT_IMAGE_ALLOWED_DOMAINS) {
53
- console.log('Combining `NEXT_IMAGE_ALLOWED_DOMAINS` with any domains found in `next.config.js`')
54
- allowedDomains = allowedDomains.concat(
55
- process.env.NEXT_IMAGE_ALLOWED_DOMAINS.split(',').map((domain) => domain.trim()),
56
- )
57
- }
58
-
59
- if (!allowedDomains.includes(new URL(parsedUrl).hostname)) {
60
- return {
61
- statusCode: 403,
62
- body: 'Image is not from a permitted domain',
63
- }
64
- }
65
- imageUrl = parsedUrl
66
- }
67
-
68
- const imageData = await fetch(imageUrl)
69
-
70
- if (!imageData.ok) {
71
- console.error(`Failed to download image ${imageUrl}. Status ${imageData.status} ${imageData.statusText}`)
72
- return {
73
- statusCode: imageData.status,
74
- body: imageData.statusText,
75
- }
76
- }
77
-
78
- const bufferData = await imageData.buffer()
79
-
80
- const type = getImageType(bufferData)
81
-
82
- if (!type) {
83
- return { statusCode: 400, body: 'Source does not appear to be an image' }
84
- }
85
-
86
- let { ext } = type
87
-
88
- // For unsupported formats (gif, svg) we redirect to the original
89
- if (IGNORED_FORMATS.has(ext)) {
90
- return {
91
- statusCode: 302,
92
- headers: {
93
- Location: isRemoteImage ? imageUrl : parsedUrl,
94
- },
95
- }
96
- }
97
-
98
- if (process.env.FORCE_WEBP_OUTPUT === 'true' || process.env.FORCE_WEBP_OUTPUT === '1') {
99
- ext = 'webp'
100
- }
101
-
102
- if (!OUTPUT_FORMATS.has(ext)) {
103
- ext = 'jpg'
104
- }
105
-
106
- // The format methods are just to set options: they don't
107
- // make it return that format.
108
- const { info, data: imageBuffer } = await sharp(bufferData)
109
- .rotate()
110
- .jpeg({ quality, force: ext === 'jpg' })
111
- .png({ quality, force: ext === 'png' })
112
- .webp({ quality, force: ext === 'webp' })
113
- .avif({ quality, force: ext === 'avif' })
114
- .resize(width, null, { withoutEnlargement: true })
115
- .toBuffer({ resolveWithObject: true })
116
-
117
- if (imageBuffer.length > MAX_RESPONSE_SIZE) {
118
- return {
119
- statusCode: 400,
120
- body: 'Requested image is too large. Maximum size is 6MB.',
121
- }
122
- }
123
-
124
- return {
125
- statusCode: 200,
126
- headers: {
127
- 'Content-Type': `image/${info.format}`,
128
- etag: etag(imageBuffer),
129
- },
130
- body: imageBuffer.toString('base64'),
131
- isBase64Encoded: true,
132
- }
133
- }
134
-
135
- exports.handler = builder(handler)
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
- const { program } = require('commander')
3
-
4
- const nextOnNetlify = require('./index')
5
-
6
- program.option('--max-log-lines [number]', 'lines of build output to show for each section', 50)
7
-
8
- program
9
- .command('watch')
10
- .description('re-runs next-on-netlify on changes')
11
- .action(async () => {
12
- await nextOnNetlify({ watch: true })
13
- })
14
-
15
- program
16
- .command('build', { isDefault: true })
17
- .description('runs next-on-netlify')
18
- .action(async () => {
19
- await nextOnNetlify()
20
- })
21
-
22
- program.parse(process.argv)