Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11,734 changes: 11,338 additions & 396 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@
"fs-extra": "^9.1.0",
"image-size": "^1.0.0",
"image-type": "^4.1.0",
"ipx": "^0.7.2",
"is-svg": "^4.3.1",
"make-dir": "^3.1.0",
"mime-types": "^2.1.30",
"moize": "^6.0.0",
"node-fetch": "^2.6.1",
"semver": "^7.3.5",
"sharp": "^0.28.1",
"slash": "^2.0.0"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/steps/setupRedirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ const setupRedirects = async (publishPath) => {
// Add necessary next/image redirects for our image function
dynamicRedirects.push({
route: `${basePath || ''}/_next/image* url=:url w=:width q=:quality`,
target: `/nextimg/:url/:width/:quality`,
target: `/_ipx/w_:width,q_:quality/:url?=`,
statusCode: '301',
force: true,
})
dynamicRedirects.push({
route: '/nextimg/*',
route: '/_ipx/*',
target: `/.netlify/functions/${NEXT_IMAGE_FUNCTION_NAME}`,
})

Expand Down
61 changes: 61 additions & 0 deletions src/lib/templates/imageFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createIPX, handleRequest, IPXOptions } from 'ipx'
import { builder, Handler } from '@netlify/functions'
//@ts-ignore injected at build time
import * as config from './imageconfig.json'

// 6MB is hard max Lambda response size
const MAX_RESPONSE_SIZE = 6291456
interface IPXHandlerOptions extends IPXOptions {
prefix: string
}
export function createIPXHandler({ prefix = '', ...opts }: Partial<IPXHandlerOptions> = {}) {
const ipx = createIPX({ ...opts })

const handler: Handler = async (event) => {
const host = event.headers.host
const protocol = event.headers['x-forwarded-proto'] || 'http'

const path = prefix ? event.path.replace(prefix, '') : event.path

const [modifiers = '_', ...segments] = path.substr(1).split('/')
let id = decodeURIComponent(segments.join('/')).replace('+', '%20')
const isLocal = !id.startsWith('http://') && !id.startsWith('https://')
if (isLocal) {
id = `${protocol}://${host}/${id}`
}

const { statusCode, statusMessage, headers, body } = await handleRequest(
{
url: `/${modifiers}/${id}`,
headers: event.headers,
options: {
bypassDomain: isLocal,
},
},
ipx,
)

if (body.length > MAX_RESPONSE_SIZE) {
return {
statusCode: 400,
body: 'Generated image is too large. Maximum size is 6MB.',
}
}

return {
statusCode,
message: statusMessage,
headers,
isBase64Encoded: typeof body !== 'string',
body: typeof body === 'string' ? body : body.toString('base64'),
}
}

return builder(handler)
}

export const handler = createIPXHandler({
prefix: '/_ipx',
domains: config.domains || [],
dir: false,
})
4 changes: 2 additions & 2 deletions src/tests/__snapshots__/basePath.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/with-revalidate /foo/getStaticProps/with-revalidate 301!
/getStaticProps/withRevalidate/1 /foo/getStaticProps/withRevalidate/1 301!
/getStaticProps/withRevalidate/2 /foo/getStaticProps/withRevalidate/2 301!
/_ipx/* /.netlify/functions/next_image 200
/_next/data/%BUILD_ID%/getServerSideProps/all.json /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/getServerSideProps/:id.json /.netlify/functions/next_getServerSideProps_id 200
Expand All @@ -65,7 +66,7 @@ exports[`Routing creates Netlify redirects 1`] = `
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/withFallback/:id.json /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
/api/shows/:id /foo/api/shows/:id 301!
/api/shows/:params/* /foo/api/shows/:params 301!
/foo/_next/image* url=:url w=:width q=:quality /nextimg/:url/:width/:quality 301!
/foo/_next/image* url=:url w=:width q=:quality /_ipx/w_:width,q_:quality/:url?= 301!
/foo/api/shows/:id /.netlify/functions/next_api_shows_id 200
/foo/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
/foo/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
Expand All @@ -89,7 +90,6 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/withFallback/:slug/* /foo/getStaticProps/withFallback/:slug 301!
/getStaticProps/withFallbackBlocking/:id /foo/getStaticProps/withFallbackBlocking/:id 301!
/getStaticProps/withRevalidate/withFallback/:id /foo/getStaticProps/withRevalidate/withFallback/:id 301!
/nextimg/* /.netlify/functions/next_image 200
/shows/:id /foo/shows/:id 301!
/shows/:params/* /foo/shows/:params 301!
/static/:id /static/[id].html 200"
Expand Down
4 changes: 2 additions & 2 deletions src/tests/__snapshots__/defaults.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/withRevalidate/2 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
/getStaticProps/withRevalidate/withFallback/1 /.netlify/functions/preview-next_getStaticProps_withRevalidate_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
/getStaticProps/withRevalidate/withFallback/2 /.netlify/functions/preview-next_getStaticProps_withRevalidate_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
/_ipx/* /.netlify/functions/next_image 200
/_next/data/%BUILD_ID%/getServerSideProps/all.json /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/getServerSideProps/:id.json /.netlify/functions/next_getServerSideProps_id 200
/_next/data/%BUILD_ID%/getStaticProps/withFallback/:id.json /.netlify/functions/next_getStaticProps_withFallback_id 200
/_next/data/%BUILD_ID%/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
/_next/data/%BUILD_ID%/getStaticProps/withFallbackBlocking/:id.json /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/withFallback/:id.json /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
/_next/image* url=:url w=:width q=:quality /nextimg/:url/:width/:quality 301!
/_next/image* url=:url w=:width q=:quality /_ipx/w_:width,q_:quality/:url?= 301!
/api/shows/:id /.netlify/functions/next_api_shows_id 200
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
Expand All @@ -64,7 +65,6 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/preview-next_getStaticProps_withRevalidate_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
/nextimg/* /.netlify/functions/next_image 200
/shows/:id /.netlify/functions/next_shows_id 200
/shows/:params/* /.netlify/functions/next_shows_params 200
/static/:id /static/[id].html 200"
Expand Down
4 changes: 2 additions & 2 deletions src/tests/__snapshots__/i18n.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/withRevalidate/withFallback/2 /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
/getStaticProps/withRevalidate/withFallback/2 /en/getStaticProps/withRevalidate/withFallback/2 200
/static /en/static.html 200
/_ipx/* /.netlify/functions/next_image 200
/_next/data/%BUILD_ID%/en/getServerSideProps/all.json /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/en/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
/_next/data/%BUILD_ID%/en/getServerSideProps/:id.json /.netlify/functions/next_getServerSideProps_id 200
Expand All @@ -100,7 +101,7 @@ exports[`Routing creates Netlify redirects 1`] = `
/_next/data/%BUILD_ID%/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
/_next/data/%BUILD_ID%/getStaticProps/withFallbackBlocking/:id.json /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/withFallback/:id.json /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
/_next/image* url=:url w=:width q=:quality /nextimg/:url/:width/:quality 301!
/_next/image* url=:url w=:width q=:quality /_ipx/w_:width,q_:quality/:url?= 301!
/api/shows/:id /.netlify/functions/next_api_shows_id 200
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
/en/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
Expand Down Expand Up @@ -134,7 +135,6 @@ exports[`Routing creates Netlify redirects 1`] = `
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/preview-next_getStaticProps_withRevalidate_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
/nextimg/* /.netlify/functions/next_image 200
/shows/:id /.netlify/functions/next_shows_id 200
/shows/:params/* /.netlify/functions/next_shows_params 200
/static/:id /en/static/[id].html 200"
Expand Down
4 changes: 2 additions & 2 deletions src/tests/__snapshots__/optionalCatchAll.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ exports[`Routing creates Netlify redirects 1`] = `
"# Next-on-Netlify Redirects
/_next/data/%BUILD_ID%/page.json /.netlify/functions/next_page 200
/page /.netlify/functions/next_page 200
/_ipx/* /.netlify/functions/next_image 200
/_next/data/%BUILD_ID%/index.json /.netlify/functions/next_all 200
/_next/data/%BUILD_ID%/* /.netlify/functions/next_all 200
/_next/image* url=:url w=:width q=:quality /nextimg/:url/:width/:quality 301!
/nextimg/* /.netlify/functions/next_image 200
/_next/image* url=:url w=:width q=:quality /_ipx/w_:width,q_:quality/:url?= 301!
/ /.netlify/functions/next_all 200
/_next/* /_next/:splat 200
/* /.netlify/functions/next_all 200"
Expand Down
10 changes: 6 additions & 4 deletions src/tests/preRenderedIndexPages.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,13 @@ describe('404 Page', () => {
describe('Routing', () => {
test('adds next_image redirect only', async () => {
// Read _redirects file
const contents = readFileSync(join(PROJECT_PATH, 'out_publish', '_redirects'))
const redirects = contents.toString().trim().split(/\n/)
const contents = readFileSync(join(PROJECT_PATH, 'out_publish', '_redirects'), 'utf-8')

// Check that no redirects are present
expect(redirects[0]).toEqual('# Next-on-Netlify Redirects')
expect(redirects[1]).toEqual('/_next/image* url=:url w=:width q=:quality /nextimg/:url/:width/:quality 301!')
expect(contents).toMatchInlineSnapshot(`
"# Next-on-Netlify Redirects
/_ipx/* /.netlify/functions/next_image 200
/_next/image* url=:url w=:width q=:quality /_ipx/w_:width,q_:quality/:url?= 301!"
`)
})
})