-
Notifications
You must be signed in to change notification settings - Fork 86
feat: add enhanced middleware support #1479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
5d67f5f
fix: update patch syntax
ascorbic efdb03d
feat: add support for rewriting middleware responses
ascorbic e1c41e9
chore: format
ascorbic d9011d0
chore: add extra content
ascorbic a2c88b7
chore: use city in demo
ascorbic ba284d9
feat: add html rewriting
ascorbic d66e08e
feat: add request header support
ascorbic 55b5282
feat: add rewriting
ascorbic 426a116
chore: move NetlifyReponse into a subpackage
ascorbic 733e352
feat: allow returning `NetlifyReponse` directly
ascorbic 138c225
chore: remove inlined types from middleware demo
ascorbic 0256f25
chore: remove modified toml
ascorbic f35a285
chore: add demo links
ascorbic e5df385
chore: add comments to example
ascorbic 2e1a4c6
chore: don't lint generated types
ascorbic 5f5e17d
Merge branch 'main' into mk/rewrite-props-middleware
ascorbic d2d16df
chore: rename class
ascorbic e0861cb
chore: add comment about source of htmlrewriter types
ascorbic 9d0f004
refactor: use type guards
ascorbic 8deaba4
chore: rename classes
ascorbic 5215688
chore: rename again
ascorbic 3854370
chore: rename again
ascorbic e54fec6
chore: update example
ascorbic 468a0d3
chore: make req a subclass of Request
ascorbic d4c0dc0
chore: switch from hidden fields to global map
ascorbic d5f2b95
Merge branch 'main' into mk/rewrite-props-middleware
ascorbic 71fa122
Merge branch 'main' into mk/rewrite-props-middleware
ascorbic 0fd6c33
ci: add cypress middleware tests
ascorbic 328a584
ci: add tests for middleware headers
ascorbic 4f6a2aa
ci: add tests for enhanced middleware
ascorbic 1cf3e1f
chore: fix test
ascorbic 33ade90
fix: handle other HTTP verbs
ascorbic 9f4044c
feat: add helper methods
ascorbic 78c8225
fix: less flaky test
ascorbic 6c5664e
Merge branch 'main' into mk/rewrite-props-middleware
nickytonline File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,6 @@ node_modules | |
test | ||
lib | ||
demos | ||
plugin/src/templates/edge | ||
plugin/src/templates/edge | ||
plugin/lib | ||
plugin/dist-types |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: Run e2e (middleware demo) | ||
on: | ||
pull_request: | ||
types: [opened, labeled, unlabeled, synchronize] | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- 'demos/middleware/**/*.{js,jsx,ts,tsx}' | ||
- 'cypress/integration/middleware/**/*.{ts,js}' | ||
- 'src/**/*.{ts,js}' | ||
jobs: | ||
cypress: | ||
name: Cypress | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
containers: [1, 2, 3, 4] | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
- name: Generate Github token | ||
uses: navikt/github-app-token-generator@v1 | ||
id: get-token | ||
with: | ||
private-key: ${{ secrets.TOKENS_PRIVATE_KEY }} | ||
app-id: ${{ secrets.TOKENS_APP_ID }} | ||
|
||
- name: Checkout @netlify/wait-for-deploy-action | ||
uses: actions/checkout@v2 | ||
with: | ||
repository: netlify/wait-for-deploy-action | ||
token: ${{ steps.get-token.outputs.token }} | ||
path: ./.github/actions/wait-for-netlify-deploy | ||
|
||
- name: Wait for Netlify Deploy | ||
id: deploy | ||
uses: ./.github/actions/wait-for-netlify-deploy | ||
with: | ||
site-name: next-plugin-edge-middleware | ||
timeout: 300 | ||
|
||
- name: Deploy successful | ||
if: ${{ steps.deploy.outputs.origin-url }} | ||
run: echo ${{ steps.deploy.outputs.origin-url }} | ||
|
||
- name: Node | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: '16' | ||
|
||
- run: npm install | ||
|
||
- name: Cypress run | ||
if: ${{ steps.deploy.outputs.origin-url }} | ||
id: cypress | ||
uses: cypress-io/github-action@v2 | ||
with: | ||
browser: chrome | ||
headless: true | ||
record: true | ||
parallel: true | ||
config-file: cypress/config/middleware.json | ||
group: 'Next Plugin - Middleware' | ||
spec: cypress/integration/middleware/* | ||
env: | ||
DEBUG: '@cypress/github-action' | ||
CYPRESS_baseUrl: ${{ steps.deploy.outputs.origin-url }} | ||
CYPRESS_NETLIFY_CONTEXT: ${{ steps.deploy.outputs.context }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
CYPRESS_RECORD_KEY: ${{ secrets.MIDDLEWARE_CYPRESS_RECORD_KEY }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,7 @@ Temporary Items | |
demos/default/.next | ||
.parcel-cache | ||
plugin/lib | ||
plugin/dist-types | ||
|
||
# Cypress | ||
cypress/screenshots |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"baseUrl": "http://localhost:8888", | ||
"integrationFolder": "cypress/integration/middleware", | ||
"projectId": "yn8qwi" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
describe('Enhanced middleware', () => { | ||
it('adds request headers', () => { | ||
cy.request('/api/hello').then((response) => { | ||
expect(response.body).to.have.nested.property('headers.x-hello', 'world') | ||
}) | ||
}) | ||
|
||
it('adds request headers to a rewrite', () => { | ||
cy.request('/headers').then((response) => { | ||
expect(response.body).to.have.nested.property('headers.x-hello', 'world') | ||
}) | ||
}) | ||
|
||
it('rewrites the response body', () => { | ||
cy.visit('/static') | ||
cy.get('#message').contains('This was static but has been transformed in') | ||
cy.contains("This is an ad that isn't shown by default") | ||
}) | ||
|
||
it('modifies the page props', () => { | ||
cy.request('/_next/data/build-id/static.json').then((response) => { | ||
expect(response.body).to.have.nested.property('pageProps.showAd', true) | ||
expect(response.body) | ||
.to.have.nested.property('pageProps.message') | ||
.that.includes('This was static but has been transformed in') | ||
}) | ||
}) | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
describe('Standard middleware', () => { | ||
it('rewrites to internal page', () => { | ||
// preview mode is off by default | ||
cy.visit('/shows/rewriteme') | ||
cy.get('h1').should('contain', 'Show #100') | ||
cy.url().should('eq', `${Cypress.config().baseUrl}/shows/rewriteme`) | ||
}) | ||
|
||
it('rewrites to external page', () => { | ||
cy.visit('/shows/rewrite-external') | ||
cy.get('h1').should('contain', 'Example Domain') | ||
cy.url().should('eq', `${Cypress.config().baseUrl}/shows/rewrite-external`) | ||
}) | ||
|
||
it('adds headers to static pages', () => { | ||
cy.request('/shows/static/3').then((response) => { | ||
expect(response.headers).to.have.property('x-middleware-date') | ||
expect(response.headers).to.have.property('x-is-deno', 'true') | ||
expect(response.headers).to.have.property('x-modified-edge', 'true') | ||
}) | ||
}) | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ const nextConfig = { | |
// your project has ESLint errors. | ||
ignoreDuringBuilds: true, | ||
}, | ||
generateBuildId: () => 'build-id', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [dust] Consider leaving a comment linking to https://nextjs.org/docs/api-reference/next.config.js/configuring-the-build-id |
||
} | ||
|
||
module.exports = nextConfig |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction | ||
|
||
export default function handler(req, res) { | ||
res.status(200).json({ name: 'John Doe' }) | ||
res.status(200).json({ name: 'John Doe', headers: req.headers }) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import * as React from 'react' | ||
|
||
const useHydrated = () => { | ||
const [hydrated, setHydrated] = React.useState(false) | ||
React.useEffect(() => { | ||
setHydrated(true) | ||
}, []) | ||
return hydrated | ||
} | ||
|
||
const Page = ({ message, showAd }) => { | ||
const hydrated = useHydrated() | ||
return ( | ||
<div> | ||
<p id="message">{message}</p> | ||
{hydrated && showAd ? ( | ||
<div> | ||
<p>This is an ad that isn't shown by default</p> | ||
<img src="http://placekitten.com/400/300" /> | ||
</div> | ||
) : ( | ||
<p>No ads for me</p> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export async function getStaticProps() { | ||
return { | ||
props: { | ||
message: 'This is a static page', | ||
showAd: false, | ||
}, | ||
} | ||
} | ||
|
||
export default Page |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[dust] Use the full name request and response for variable names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request
andresponse
are already used for theMiddlewareRequest
andMiddlewareResponse
. I considered changing them tonextRequest
andnextResponse
but thought it made the code examples a bit verbose. Hard to say which is better tbhThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realise I've mixed the different styles, so yeah this should be tidied up in a follow-up.