├── .editorconfig
├── .eslintignore
├── .eslintrc.cjs
├── .github
├── .kodiak.toml
├── CODEOWNERS
├── pull_request_template.md
└── workflows
│ ├── deno-test.yml
│ ├── e2e-report.yml
│ ├── lint.yml
│ ├── pre-release.yml
│ ├── release-please.yml
│ ├── run-tests.yml
│ ├── size-check.yml
│ └── test-e2e.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.cjs
├── .release-please-manifest.json
├── .vscode
└── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── deno.json
├── e2e-report
├── .eslintrc.json
├── .gitignore
├── README.md
├── app
│ ├── badge
│ │ └── route.js
│ ├── globals.css
│ ├── layout.js
│ └── page.js
├── components
│ ├── copy-badge.js
│ ├── icons.js
│ ├── stats.js
│ ├── switcher.js
│ └── table.js
├── data
│ ├── issues.json
│ └── test-results.json
├── jsconfig.json
├── netlify.toml
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── MulishVar-latin.woff2
│ ├── favicon.ico
│ └── logo.svg
├── tailwind.config.js
└── utils
│ ├── consts.js
│ └── data.js
├── edge-runtime
├── README.md
├── lib
│ ├── headers.ts
│ ├── logging.ts
│ ├── middleware.test.ts
│ ├── middleware.ts
│ ├── next-request.ts
│ ├── response.ts
│ ├── routing.ts
│ ├── util.test.ts
│ └── util.ts
├── matchers.json
├── middleware.ts
├── next.config.json
├── shim
│ └── index.js
└── vendor.ts
├── manifest.yml
├── next-js-runtime.png
├── package-lock.json
├── package.json
├── playwright.config.ts
├── release-please-config.json
├── renovate.json
├── report
├── netlify.toml
├── style.css
└── test-results.json
├── run-local-test.sh
├── src
├── build
│ ├── advanced-api-routes.ts
│ ├── cache.ts
│ ├── content
│ │ ├── next-shims
│ │ │ └── telemetry-storage.cts
│ │ ├── prerendered.ts
│ │ ├── server.test.ts
│ │ ├── server.ts
│ │ ├── static.test.ts
│ │ └── static.ts
│ ├── functions
│ │ ├── edge.ts
│ │ └── server.ts
│ ├── image-cdn.test.ts
│ ├── image-cdn.ts
│ ├── plugin-context.test.ts
│ ├── plugin-context.ts
│ ├── templates
│ │ ├── handler-monorepo.tmpl.js
│ │ └── handler.tmpl.js
│ └── verification.ts
├── index.ts
├── run
│ ├── config.ts
│ ├── constants.ts
│ ├── handlers
│ │ ├── cache.cts
│ │ ├── request-context.cts
│ │ ├── server.ts
│ │ ├── tags-handler.cts
│ │ ├── tracer.cts
│ │ ├── use-cache-handler.ts
│ │ └── wait-until.cts
│ ├── headers.test.ts
│ ├── headers.ts
│ ├── next.cts
│ ├── revalidate.ts
│ └── storage
│ │ ├── regional-blob-store.cts
│ │ ├── request-scoped-in-memory-cache.cts
│ │ ├── storage.cts
│ │ └── storage.test.ts
└── shared
│ ├── blob-types.cts
│ ├── blob-types.test.ts
│ ├── blobkey.test.ts
│ ├── blobkey.ts
│ └── cache-types.cts
├── tests
├── e2e-skip-retry-legacy.json
├── e2e-skip-retry.json
├── e2e-utils-v2.patch
├── e2e-utils.patch
├── e2e
│ ├── after.test.ts
│ ├── cli-before-regional-blobs-support.test.ts
│ ├── dynamic-cms.test.ts
│ ├── edge-middleware.test.ts
│ ├── export.test.ts
│ ├── nx-integrated.test.ts
│ ├── on-demand-app.test.ts
│ ├── package-manager.test.ts
│ ├── page-router.test.ts
│ ├── simple-app.test.ts
│ └── turborepo.test.ts
├── fixtures
│ ├── advanced-api-routes
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ └── api
│ │ │ │ ├── hello-background.ts
│ │ │ │ └── hello-scheduled.js
│ │ └── tsconfig.json
│ ├── after
│ │ ├── app
│ │ │ ├── after
│ │ │ │ ├── check
│ │ │ │ │ └── page.js
│ │ │ │ └── trigger
│ │ │ │ │ └── page.js
│ │ │ └── layout.js
│ │ ├── next.config.js
│ │ └── package.json
│ ├── base-path
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ ├── cli-before-regional-blobs-support
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ └── index.js
│ ├── dist-dir
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── api
│ │ │ │ ├── headers
│ │ │ │ │ └── route.js
│ │ │ │ └── url
│ │ │ │ │ └── route.js
│ │ │ ├── image
│ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ ├── page.js
│ │ │ ├── redirect
│ │ │ │ ├── response
│ │ │ │ │ └── route.js
│ │ │ │ └── route.js
│ │ │ └── stale-cache-serving
│ │ │ │ └── app-page
│ │ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ ├── dynamic-cms
│ │ ├── README.md
│ │ ├── netlify
│ │ │ └── functions
│ │ │ │ └── cms.mts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── 404.js
│ │ │ ├── api
│ │ │ └── revalidate.js
│ │ │ └── content
│ │ │ └── [...slug].js
│ ├── middleware-conditions
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ ├── page.js
│ │ │ └── test
│ │ │ │ ├── next
│ │ │ │ └── page.js
│ │ │ │ ├── redirect
│ │ │ │ └── page.js
│ │ │ │ └── rewrite
│ │ │ │ └── page.js
│ │ ├── middleware.ts
│ │ ├── next.config.js
│ │ └── package.json
│ ├── middleware-i18n-excluded-paths
│ │ ├── middleware.ts
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ ├── [[...catchall]].tsx
│ │ │ └── api
│ │ │ │ └── [[...catchall]].ts
│ │ └── tsconfig.json
│ ├── middleware-i18n-skip-normalize
│ │ ├── middleware.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── api
│ │ │ └── ok.js
│ │ │ ├── dynamic
│ │ │ └── [slug].js
│ │ │ ├── index.js
│ │ │ └── new-home.js
│ ├── middleware-i18n
│ │ ├── middleware.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── api
│ │ │ └── ok.js
│ │ │ ├── dynamic
│ │ │ └── [slug].js
│ │ │ ├── index.js
│ │ │ └── new-home.js
│ ├── middleware-og
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── og.js
│ │ │ ├── opengraph-image.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ └── package.json
│ ├── middleware-pages
│ │ ├── middleware.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ ├── [id].js
│ │ │ ├── _app.js
│ │ │ ├── about
│ │ │ │ ├── a.js
│ │ │ │ └── b.js
│ │ │ ├── api
│ │ │ │ ├── edge-headers.js
│ │ │ │ └── headers.js
│ │ │ ├── blog
│ │ │ │ └── [slug].js
│ │ │ ├── error-throw.js
│ │ │ ├── error.js
│ │ │ ├── html-links.js
│ │ │ ├── product
│ │ │ │ └── [...product-params].tsx
│ │ │ ├── shallow.js
│ │ │ ├── ssg
│ │ │ │ └── [slug].js
│ │ │ ├── ssr-page-2.js
│ │ │ └── ssr-page.js
│ │ └── tsconfig.json
│ ├── middleware-src
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── src
│ │ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── page.js
│ │ │ └── test
│ │ │ │ └── next
│ │ │ │ └── page.js
│ │ │ └── middleware.ts
│ ├── middleware-static-asset-matcher
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── middleware.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ └── hello
│ │ │ └── world.txt
│ ├── middleware-subrequest-vuln
│ │ ├── app
│ │ │ ├── [[...wildcard]]
│ │ │ │ └── page.js
│ │ │ └── layout.js
│ │ ├── middleware.ts
│ │ ├── next.config.js
│ │ └── package.json
│ ├── middleware-trailing-slash
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ ├── page.js
│ │ │ └── test
│ │ │ │ ├── next
│ │ │ │ └── page.js
│ │ │ │ ├── redirect
│ │ │ │ └── page.js
│ │ │ │ └── rewrite
│ │ │ │ └── page.js
│ │ ├── middleware.ts
│ │ ├── next.config.js
│ │ └── package.json
│ ├── middleware
│ │ ├── app
│ │ │ ├── caching-redirect-target
│ │ │ │ └── page.js
│ │ │ ├── caching-rewrite-target
│ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ ├── link-to-redirect-to-cached-page
│ │ │ │ └── page.js
│ │ │ ├── link-to-rewrite-to-cached-page
│ │ │ │ └── page.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ ├── page.js
│ │ │ └── test
│ │ │ │ ├── next
│ │ │ │ └── page.js
│ │ │ │ ├── redirect
│ │ │ │ └── page.js
│ │ │ │ ├── rewrite-target
│ │ │ │ └── page.js
│ │ │ │ └── rewrite
│ │ │ │ └── page.js
│ │ ├── middleware.ts
│ │ ├── next.config.js
│ │ └── package.json
│ ├── netlify-forms-workaround
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── public
│ │ │ └── form.html
│ │ └── tsconfig.json
│ ├── netlify-forms
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── public
│ │ │ └── form.html
│ │ └── tsconfig.json
│ ├── nx-integrated
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── apps
│ │ │ ├── custom-dist-dir
│ │ │ │ ├── .env
│ │ │ │ ├── .env.local
│ │ │ │ ├── .env.production
│ │ │ │ ├── .env.production.local
│ │ │ │ ├── app
│ │ │ │ │ ├── api
│ │ │ │ │ │ ├── env
│ │ │ │ │ │ │ └── route.ts
│ │ │ │ │ │ ├── headers
│ │ │ │ │ │ │ └── route.js
│ │ │ │ │ │ └── url
│ │ │ │ │ │ │ └── route.js
│ │ │ │ │ ├── image
│ │ │ │ │ │ └── page.js
│ │ │ │ │ ├── layout.js
│ │ │ │ │ ├── other
│ │ │ │ │ │ └── page.js
│ │ │ │ │ ├── page.js
│ │ │ │ │ ├── redirect
│ │ │ │ │ │ ├── response
│ │ │ │ │ │ │ └── route.js
│ │ │ │ │ │ └── route.js
│ │ │ │ │ └── stale-cache-serving
│ │ │ │ │ │ └── app-page
│ │ │ │ │ │ └── page.js
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── project.json
│ │ │ │ ├── public
│ │ │ │ │ ├── next.svg
│ │ │ │ │ └── squirrel.jpg
│ │ │ │ ├── tsconfig.json
│ │ │ │ └── tsconfig.spec.json
│ │ │ └── next-app
│ │ │ │ ├── app
│ │ │ │ ├── api
│ │ │ │ │ ├── hello
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── static
│ │ │ │ │ │ └── route.js
│ │ │ │ ├── global.css
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.module.css
│ │ │ │ └── page.tsx
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── netlify.toml
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── project.json
│ │ │ │ ├── public
│ │ │ │ ├── .gitkeep
│ │ │ │ └── favicon.ico
│ │ │ │ ├── static
│ │ │ │ └── words.txt
│ │ │ │ ├── tsconfig.json
│ │ │ │ └── tsconfig.spec.json
│ │ ├── nx.json
│ │ ├── package.json
│ │ └── tsconfig.base.json
│ ├── output-export-custom-dist
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ ├── output-export
│ │ ├── app
│ │ │ ├── image
│ │ │ │ └── local
│ │ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ ├── page-router-404-get-static-props-with-revalidate
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── 404.js
│ │ │ └── products
│ │ │ └── [slug].js
│ ├── page-router-base-path-i18n
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ ├── 404.js
│ │ │ ├── api
│ │ │ │ ├── purge-cdn.js
│ │ │ │ ├── revalidate-no-await.js
│ │ │ │ └── revalidate.js
│ │ │ ├── fallback-true
│ │ │ │ └── [slug].js
│ │ │ ├── products
│ │ │ │ └── [slug].js
│ │ │ └── static
│ │ │ │ ├── not-found.js
│ │ │ │ └── revalidate-manual.js
│ │ └── public
│ │ │ └── next.svg
│ ├── page-router
│ │ ├── .env
│ │ ├── .env.local
│ │ ├── .env.production
│ │ ├── .env.production.local
│ │ ├── netlify
│ │ │ └── functions
│ │ │ │ ├── purge-cdn.ts
│ │ │ │ └── read-static-props-blobs.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ ├── 404.js
│ │ │ ├── always-the-same-body
│ │ │ │ └── [slug].js
│ │ │ ├── api
│ │ │ │ ├── env.js
│ │ │ │ ├── revalidate-no-await.js
│ │ │ │ ├── revalidate.js
│ │ │ │ ├── sleep-5.js
│ │ │ │ └── unstable-cache-node.js
│ │ │ ├── fallback-true
│ │ │ │ └── [slug].js
│ │ │ ├── products
│ │ │ │ └── [slug].js
│ │ │ ├── revalidate-60
│ │ │ │ └── [slug].js
│ │ │ └── static
│ │ │ │ ├── fully-static.js
│ │ │ │ ├── not-found.js
│ │ │ │ ├── revalidate-automatic.js
│ │ │ │ ├── revalidate-manual.js
│ │ │ │ ├── revalidate-slow-data.js
│ │ │ │ └── revalidate-slow.js
│ │ └── public
│ │ │ └── next.svg
│ ├── pnpm
│ │ ├── .npmrc
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ └── package.json
│ ├── ppr
│ │ ├── app
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ ├── revalidate-fetch
│ │ ├── app
│ │ │ ├── dynamic-posts
│ │ │ │ └── [id]
│ │ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ ├── page.js
│ │ │ ├── posts
│ │ │ │ └── [id]
│ │ │ │ │ └── page.js
│ │ │ └── same-fetch-multiple-times
│ │ │ │ └── [id]
│ │ │ │ └── page.js
│ │ ├── next.config.js
│ │ └── package.json
│ ├── server-components
│ │ ├── app
│ │ │ ├── api
│ │ │ │ ├── on-demand-revalidate
│ │ │ │ │ ├── path
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── tag
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── purge-cdn
│ │ │ │ │ └── route.ts
│ │ │ │ ├── revalidate-handler
│ │ │ │ │ └── route.ts
│ │ │ │ ├── static
│ │ │ │ │ └── [slug]
│ │ │ │ │ │ └── route.ts
│ │ │ │ └── zero-length-response
│ │ │ │ │ └── route.ts
│ │ │ ├── dynamic-fetch
│ │ │ │ ├── loading.js
│ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ ├── page.js
│ │ │ ├── product
│ │ │ │ └── [slug]
│ │ │ │ │ └── page.js
│ │ │ ├── revalidate-fetch
│ │ │ │ └── page.js
│ │ │ ├── static-fetch-1
│ │ │ │ └── page.js
│ │ │ ├── static-fetch-2
│ │ │ │ └── page.js
│ │ │ ├── static-fetch-3
│ │ │ │ └── page.js
│ │ │ ├── static-fetch-dynamic
│ │ │ │ └── page.js
│ │ │ └── static-fetch
│ │ │ │ └── [id]
│ │ │ │ └── page.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── simple
│ │ ├── app
│ │ │ ├── api
│ │ │ │ ├── cached-permanent
│ │ │ │ │ └── route.js
│ │ │ │ ├── cached-revalidate
│ │ │ │ │ └── route.js
│ │ │ │ ├── cjs-file-with-js-extension
│ │ │ │ │ ├── bundled.cjs
│ │ │ │ │ └── route.js
│ │ │ │ ├── headers
│ │ │ │ │ └── route.js
│ │ │ │ ├── slow-not-cacheable-with-html-read
│ │ │ │ │ └── route.js
│ │ │ │ ├── slow-not-cacheable
│ │ │ │ │ └── route.js
│ │ │ │ ├── static
│ │ │ │ │ └── route.js
│ │ │ │ └── url
│ │ │ │ │ └── route.js
│ │ │ ├── config-redirect
│ │ │ │ ├── dest
│ │ │ │ │ └── page.js
│ │ │ │ └── page.js
│ │ │ ├── config-rewrite
│ │ │ │ ├── dest
│ │ │ │ │ └── page.js
│ │ │ │ └── page.js
│ │ │ ├── image
│ │ │ │ ├── local
│ │ │ │ │ └── page.js
│ │ │ │ ├── migration-from-v4-runtime
│ │ │ │ │ ├── next-image-runtime-v4.js
│ │ │ │ │ └── page.js
│ │ │ │ ├── remote-domain
│ │ │ │ │ └── page.js
│ │ │ │ ├── remote-pattern-1
│ │ │ │ │ └── page.js
│ │ │ │ └── remote-pattern-2
│ │ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ ├── not-found.js
│ │ │ ├── other
│ │ │ │ └── page.js
│ │ │ ├── page.js
│ │ │ ├── redirect
│ │ │ │ ├── response
│ │ │ │ │ └── route.js
│ │ │ │ └── route.js
│ │ │ ├── route-resolves-to-not-found
│ │ │ │ └── page.js
│ │ │ ├── stale-cache-serving
│ │ │ │ └── app-page
│ │ │ │ │ └── page.js
│ │ │ └── unstable_cache
│ │ │ │ └── page.js
│ │ ├── cjs-file-with-js-extension.js
│ │ ├── netlify.toml
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ └── fully-static.js
│ │ ├── public
│ │ │ ├── next.svg
│ │ │ └── squirrel.jpg
│ │ └── static
│ │ │ ├── prebuilt.html
│ │ │ └── words.txt
│ ├── turborepo-npm
│ │ ├── .eslintrc.js
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── README.md
│ │ ├── apps
│ │ │ ├── docs
│ │ │ │ ├── .eslintrc.js
│ │ │ │ ├── README.md
│ │ │ │ ├── app
│ │ │ │ │ ├── favicon.ico
│ │ │ │ │ ├── globals.css
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.module.css
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── public
│ │ │ │ │ ├── circles.svg
│ │ │ │ │ ├── next.svg
│ │ │ │ │ ├── turborepo.svg
│ │ │ │ │ └── vercel.svg
│ │ │ │ └── tsconfig.json
│ │ │ ├── page-router
│ │ │ │ ├── .env
│ │ │ │ ├── .env.local
│ │ │ │ ├── .env.production
│ │ │ │ ├── .env.production.local
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── pages
│ │ │ │ │ ├── api
│ │ │ │ │ │ ├── env.js
│ │ │ │ │ │ ├── purge-cdn.js
│ │ │ │ │ │ └── revalidate.js
│ │ │ │ │ └── static
│ │ │ │ │ │ ├── revalidate-automatic.js
│ │ │ │ │ │ ├── revalidate-manual.js
│ │ │ │ │ │ └── revalidate-slow.js
│ │ │ │ ├── public
│ │ │ │ │ └── next.svg
│ │ │ │ ├── test.cjs
│ │ │ │ └── tsconfig.json
│ │ │ └── web
│ │ │ │ ├── .eslintrc.js
│ │ │ │ ├── README.md
│ │ │ │ ├── app
│ │ │ │ ├── favicon.ico
│ │ │ │ ├── globals.css
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.module.css
│ │ │ │ └── page.tsx
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── public
│ │ │ │ ├── circles.svg
│ │ │ │ ├── next.svg
│ │ │ │ ├── turborepo.svg
│ │ │ │ └── vercel.svg
│ │ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── packages
│ │ │ ├── eslint-config
│ │ │ │ ├── README.md
│ │ │ │ ├── library.js
│ │ │ │ ├── next.js
│ │ │ │ ├── package.json
│ │ │ │ └── react-internal.js
│ │ │ ├── typescript-config
│ │ │ │ ├── base.json
│ │ │ │ ├── nextjs.json
│ │ │ │ ├── package.json
│ │ │ │ └── react-library.json
│ │ │ └── ui
│ │ │ │ ├── .eslintrc.js
│ │ │ │ ├── package.json
│ │ │ │ ├── src
│ │ │ │ ├── button.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ └── code.tsx
│ │ │ │ ├── tsconfig.json
│ │ │ │ ├── tsconfig.lint.json
│ │ │ │ ├── turbo.json
│ │ │ │ └── turbo
│ │ │ │ └── generators
│ │ │ │ ├── config.ts
│ │ │ │ └── templates
│ │ │ │ └── component.hbs
│ │ ├── tsconfig.json
│ │ └── turbo.json
│ ├── turborepo
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── apps
│ │ │ ├── docs
│ │ │ │ ├── app
│ │ │ │ │ ├── favicon.ico
│ │ │ │ │ ├── globals.css
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.module.css
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── public
│ │ │ │ │ ├── circles.svg
│ │ │ │ │ ├── next.svg
│ │ │ │ │ ├── turborepo.svg
│ │ │ │ │ └── vercel.svg
│ │ │ │ └── tsconfig.json
│ │ │ ├── page-router
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── src
│ │ │ │ │ ├── middleware.ts
│ │ │ │ │ └── pages
│ │ │ │ │ │ ├── api
│ │ │ │ │ │ ├── purge-cdn.js
│ │ │ │ │ │ └── revalidate.js
│ │ │ │ │ │ └── static
│ │ │ │ │ │ ├── revalidate-automatic.js
│ │ │ │ │ │ ├── revalidate-manual.js
│ │ │ │ │ │ └── revalidate-slow.js
│ │ │ │ └── tsconfig.json
│ │ │ └── web
│ │ │ │ ├── app
│ │ │ │ ├── favicon.ico
│ │ │ │ ├── globals.css
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.module.css
│ │ │ │ └── page.tsx
│ │ │ │ ├── next-env.d.ts
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── public
│ │ │ │ ├── circles.svg
│ │ │ │ ├── next.svg
│ │ │ │ ├── turborepo.svg
│ │ │ │ └── vercel.svg
│ │ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── packages
│ │ │ ├── typescript-config
│ │ │ │ ├── base.json
│ │ │ │ ├── nextjs.json
│ │ │ │ ├── package.json
│ │ │ │ └── react-library.json
│ │ │ └── ui
│ │ │ │ ├── package.json
│ │ │ │ ├── src
│ │ │ │ ├── button.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ └── code.tsx
│ │ │ │ ├── tsconfig.json
│ │ │ │ ├── tsconfig.lint.json
│ │ │ │ ├── turbo.json
│ │ │ │ └── turbo
│ │ │ │ └── generators
│ │ │ │ ├── config.ts
│ │ │ │ └── templates
│ │ │ │ └── component.hbs
│ │ ├── pnpm-workspace.yaml
│ │ ├── tsconfig.json
│ │ └── turbo.json
│ ├── use-cache
│ │ ├── app
│ │ │ ├── api
│ │ │ │ └── revalidate
│ │ │ │ │ └── [...slug]
│ │ │ │ │ └── route.ts
│ │ │ ├── default
│ │ │ │ ├── use-cache-component
│ │ │ │ │ ├── dynamic
│ │ │ │ │ │ ├── ttl-1year
│ │ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── ttl-5seconds
│ │ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── static
│ │ │ │ │ │ ├── ttl-10seconds
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── ttl-1year
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── use-cache-data
│ │ │ │ │ ├── dynamic
│ │ │ │ │ │ ├── ttl-1year
│ │ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── ttl-5seconds
│ │ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── static
│ │ │ │ │ │ ├── ttl-10seconds
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── ttl-1year
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ └── use-cache-page
│ │ │ │ │ ├── dynamic
│ │ │ │ │ ├── ttl-1year
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── ttl-5seconds
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── static
│ │ │ │ │ ├── ttl-10seconds
│ │ │ │ │ └── [slug]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── ttl-1year
│ │ │ │ │ └── [slug]
│ │ │ │ │ └── page.tsx
│ │ │ ├── helpers.tsx
│ │ │ └── layout.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── wasm-src
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── src
│ │ │ ├── add.wasm
│ │ │ ├── app
│ │ │ ├── og-node
│ │ │ │ └── route.js
│ │ │ └── og
│ │ │ │ └── route.js
│ │ │ ├── middleware.js
│ │ │ └── pages
│ │ │ ├── api
│ │ │ ├── og-wrong-runtime.js
│ │ │ └── og.js
│ │ │ └── index.js
│ └── wasm
│ │ ├── add.wasm
│ │ ├── app
│ │ ├── og-node
│ │ │ └── route.js
│ │ └── og
│ │ │ └── route.js
│ │ ├── middleware.js
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ ├── api
│ │ ├── og-wrong-runtime.js
│ │ └── og.js
│ │ └── index.js
├── index.ts
├── integration
│ ├── advanced-api-routes.test.ts
│ ├── build
│ │ └── copy-next-code.test.ts
│ ├── cache-handler.test.ts
│ ├── edge-handler.test.ts
│ ├── fetch-handler.test.ts
│ ├── netlify-forms.test.ts
│ ├── page-router.test.ts
│ ├── pnpm.test.ts
│ ├── request-context.test.ts
│ ├── revalidate-path.test.ts
│ ├── revalidate-tags.test.ts
│ ├── simple-app.test.ts
│ ├── static.test.ts
│ ├── use-cache.test.ts
│ └── wasm.test.ts
├── netlify-deploy.ts
├── netlify-e2e-legacy.json
├── netlify-e2e.cjs
├── playwright-slack-conf.json
├── prepare.mjs
├── smoke
│ ├── deploy.test.ts
│ └── fixtures
│ │ ├── .gitignore
│ │ ├── next-12.0.3
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ └── index.js
│ │ ├── next-12.1.0
│ │ ├── next.config.js
│ │ ├── package.json
│ │ └── pages
│ │ │ └── index.js
│ │ ├── npm-monorepo-empty-base
│ │ ├── apps
│ │ │ └── site
│ │ │ │ ├── netlify.toml
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ └── pages
│ │ │ │ └── index.js
│ │ ├── package.json
│ │ └── packages
│ │ │ └── ui
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ └── test.jsx
│ │ ├── npm-monorepo-site-created-at-build
│ │ ├── mock-download
│ │ │ ├── apps
│ │ │ │ └── site
│ │ │ │ │ ├── next.config.js
│ │ │ │ │ ├── package.json
│ │ │ │ │ └── pages
│ │ │ │ │ └── index.js
│ │ │ └── packages
│ │ │ │ └── ui
│ │ │ │ ├── package.json
│ │ │ │ └── src
│ │ │ │ └── test.jsx
│ │ ├── netlify.toml
│ │ ├── package.json
│ │ ├── pre-deploy.mjs
│ │ └── setup-site.mjs
│ │ ├── npm-nested-site-multiple-next-version-site-compatible
│ │ ├── apps
│ │ │ └── site
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ └── pages
│ │ │ │ └── index.js
│ │ └── package.json
│ │ ├── npm-nested-site-multiple-next-version-site-incompatible
│ │ ├── apps
│ │ │ └── site
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ └── pages
│ │ │ │ └── index.js
│ │ └── package.json
│ │ ├── yarn-monorepo-multiple-next-versions-site-compatible
│ │ ├── apps
│ │ │ └── site
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ └── pages
│ │ │ │ └── index.js
│ │ ├── package.json
│ │ └── packages
│ │ │ └── ui
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ └── test.jsx
│ │ ├── yarn-monorepo-multiple-next-versions-site-incompatible
│ │ ├── apps
│ │ │ └── site
│ │ │ │ ├── next.config.js
│ │ │ │ ├── package.json
│ │ │ │ └── pages
│ │ │ │ └── index.js
│ │ ├── package.json
│ │ └── packages
│ │ │ └── ui
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ └── test.jsx
│ │ └── yarn-monorepo-with-pnpm-linker
│ │ ├── .yarnrc.yml
│ │ ├── apps
│ │ └── site
│ │ │ ├── next.config.js
│ │ │ ├── package.json
│ │ │ └── pages
│ │ │ └── index.js
│ │ ├── package.json
│ │ └── packages
│ │ └── ui
│ │ ├── package.json
│ │ └── src
│ │ └── test.jsx
├── test-config.json
├── test-setup-e2e.ts
├── test-setup.ts
└── utils
│ ├── constants.mjs
│ ├── contexts.ts
│ ├── create-e2e-fixture.ts
│ ├── fixture.ts
│ ├── helpers.ts
│ ├── index.ts
│ ├── lambda-helpers.mjs
│ ├── local-server.ts
│ ├── mock-file-system.ts
│ ├── next-version-helpers.mjs
│ ├── playwright-helpers.ts
│ └── sandbox-child.mjs
├── tools
├── build-helpers.js
├── build.js
├── deno
│ ├── eszip.ts
│ ├── generate-md.ts
│ ├── ghIssues2json.ts
│ └── junit2json.ts
└── vendor-deno-tools.js
├── tsconfig.json
├── turbofan
├── netlify.toml
└── netlify
│ └── edge-functions
│ └── turbofan.ts
├── vitest.config.ts
└── vitest.workspace.ts
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | max_line_length = 100
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | demo/
3 | tests/
4 | edge-runtime
5 | tools/deno
--------------------------------------------------------------------------------
/.github/.kodiak.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 |
3 | [merge.automerge_dependencies]
4 | versions = ["minor", "patch"]
5 | usernames = ["renovate"]
6 |
7 | [approve]
8 | auto_approve_usernames = ["renovate"]
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @opennextjs/netlify-frameworks-and-build
2 |
--------------------------------------------------------------------------------
/.github/workflows/deno-test.yml:
--------------------------------------------------------------------------------
1 | name: Deno test
2 | on:
3 | pull_request:
4 | branches: [main]
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v4
11 | - name: Setup Deno
12 | uses: denoland/setup-deno@v1
13 | with:
14 | deno-version: v1.x.x
15 | - name: Vendor Deno modules
16 | run: deno vendor edge-runtime/vendor.ts --output=edge-runtime/vendor --force
17 | - name: Test
18 | run: deno test -A edge-runtime/
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | .next
4 | edge-runtime/vendor
5 | # deno.json is ephemeral and generated for the purpose of vendoring remote modules in CI
6 | tools/deno/deno.json
7 | tools/deno/vendor
8 |
9 | # Local Netlify folder
10 | .netlify
11 |
12 | /test-results/
13 | /playwright-report/
14 | /blob-report/
15 | /playwright/.cache/
16 |
17 | deno.lock
18 | .eslintcache
19 | .DS_Store
20 | tests/**/package-lock.json
21 | tests/**/pnpm-lock.yaml
22 | tests/**/yarn.lock
23 | tests/**/out/
24 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist/
2 | .next
3 | playwright-report/
4 | .netlify
5 | CHANGELOG.md
6 | package-lock.json
7 | package.json
8 | edge-runtime/vendor/
9 | deno.lock
10 | tests/fixtures/dist-dir/cool/output
11 | tests/fixtures/output-export-custom-dist/custom-dist
12 | .nx
13 | custom-dist-dir
14 | pnpm.lock
15 | # to avoid needing extra permissions to format files
16 | .github/workflows
--------------------------------------------------------------------------------
/.prettierrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ...require('@netlify/eslint-config-node/.prettierrc.json'),
3 | printWidth: 100,
4 | }
5 |
--------------------------------------------------------------------------------
/.release-please-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | ".": "5.11.2"
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "deno.enablePaths": ["tools/deno", "edge-runtime"],
3 | "deno.unstable": true
4 | }
5 |
--------------------------------------------------------------------------------
/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "lint": {
3 | "files": {
4 | "include": ["edge-runtime/middleware.ts"]
5 | }
6 | },
7 | "imports": {
8 | "@netlify/edge-functions": "https://edge.netlify.com/v1/index.ts"
9 | },
10 | "importMap": "./edge-runtime/vendor/import_map.json"
11 | }
12 |
--------------------------------------------------------------------------------
/e2e-report/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals",
3 | "root": true
4 | }
5 |
--------------------------------------------------------------------------------
/e2e-report/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/e2e-report/README.md:
--------------------------------------------------------------------------------
1 | # Next Runtime v5 Report
2 |
--------------------------------------------------------------------------------
/e2e-report/app/layout.js:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 |
3 | export const metadata = {
4 | title: 'Netlify - Next.js E2E Tests',
5 | }
6 |
7 | export default function RootLayout({ children }) {
8 | return (
9 |
10 |
{children}
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/e2e-report/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/e2e-report/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | base = "e2e-report/"
3 | command = "next build"
4 | publish = ".next"
5 |
6 | [[plugins]]
7 | package = "@netlify/plugin-nextjs"
--------------------------------------------------------------------------------
/e2e-report/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {}
3 |
4 | export default nextConfig
5 |
--------------------------------------------------------------------------------
/e2e-report/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/e2e-report/public/MulishVar-latin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/e2e-report/public/MulishVar-latin.woff2
--------------------------------------------------------------------------------
/e2e-report/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/e2e-report/public/favicon.ico
--------------------------------------------------------------------------------
/e2e-report/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
4 | daisyui: {
5 | themes: ['light'],
6 | },
7 | theme: {
8 | extend: {
9 | fontFamily: {
10 | primary: 'Mulish',
11 | },
12 | colors: {
13 | primary: '#2036a1',
14 | },
15 | },
16 | },
17 | plugins: [require('daisyui')],
18 | }
19 |
--------------------------------------------------------------------------------
/e2e-report/utils/consts.js:
--------------------------------------------------------------------------------
1 | export const badgeSettings = {
2 | // Badge image resolution should be 2x display size for hi-res displays
3 | imageSize: { width: 370, height: 50 },
4 | displaySize: { width: 185, height: 25 },
5 | label: 'Next.js runtime v5',
6 | alt: 'Netlify Next.js runtime v5 test status',
7 | }
8 |
--------------------------------------------------------------------------------
/edge-runtime/lib/logging.ts:
--------------------------------------------------------------------------------
1 | export {
2 | logger,
3 | LogLevel,
4 | StructuredLogger,
5 | } from '../vendor/v1-7-0--edge-utils.netlify.app/logger/mod.ts'
6 |
--------------------------------------------------------------------------------
/edge-runtime/matchers.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/edge-runtime/next.config.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/manifest.yml:
--------------------------------------------------------------------------------
1 | name: '@netlify/plugin-nextjs'
2 |
--------------------------------------------------------------------------------
/next-js-runtime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/next-js-runtime.png
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3 | "exclude-paths": [".github", ".vscode", "e2e-report", "report", "tests", "tools", "turbofan"],
4 | "include-component-in-tag": false,
5 | "packages": {
6 | ".": {}
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["local>netlify/renovate-config"]
4 | }
5 |
--------------------------------------------------------------------------------
/report/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | publish = "."
3 |
--------------------------------------------------------------------------------
/report/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | font-family:
3 | system-ui,
4 | -apple-system,
5 | BlinkMacSystemFont,
6 | 'Segoe UI',
7 | Roboto,
8 | Oxygen,
9 | Ubuntu,
10 | Cantarell,
11 | 'Open Sans',
12 | 'Helvetica Neue',
13 | sans-serif;
14 | }
15 |
16 | .test-results {
17 | display: flex;
18 | flex-wrap: wrap;
19 | }
20 |
21 | .test-results a {
22 | display: inline-block;
23 | width: 16px;
24 | height: 16px;
25 | margin: 1px;
26 | }
27 |
28 | a[data-status='passed'] {
29 | background-color: #2ecc71;
30 | }
31 |
32 | a[data-status='failed'] {
33 | background-color: #e74c3c;
34 | }
35 |
--------------------------------------------------------------------------------
/src/run/constants.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'node:path'
2 | import { fileURLToPath } from 'node:url'
3 |
4 | export const MODULE_DIR = fileURLToPath(new URL('.', import.meta.url))
5 | export const PLUGIN_DIR = resolve(`${MODULE_DIR}../../..`)
6 | // a file where we store the required-server-files config object in to access during runtime
7 | export const RUN_CONFIG_FILE = 'run-config.json'
8 |
--------------------------------------------------------------------------------
/tests/e2e-utils-v2.patch:
--------------------------------------------------------------------------------
1 | diff --git a/test/lib/e2e-utils/index.ts b/test/lib/e2e-utils/index.ts
2 | index 06765e81d9..a7a5a9e4bd 100644
3 | --- a/test/lib/e2e-utils/index.ts
4 | +++ b/test/lib/e2e-utils/index.ts
5 | @@ -5,7 +5,7 @@ import { PHASE_DEVELOPMENT_SERVER } from 'next/constants'
6 | import { NextInstance, NextInstanceOpts } from '../next-modes/base'
7 | import { NextDevInstance } from '../next-modes/next-dev'
8 | import { NextStartInstance } from '../next-modes/next-start'
9 | -import { NextDeployInstance } from '../next-modes/next-deploy'
10 | +import { NextDeployInstance } from '../next-modes/netlify-deploy'
11 | import { shouldRunTurboDevTest } from '../next-test-utils'
12 |
13 | export type { NextInstance }
14 |
--------------------------------------------------------------------------------
/tests/e2e-utils.patch:
--------------------------------------------------------------------------------
1 | diff --git a/test/lib/e2e-utils.ts b/test/lib/e2e-utils.ts
2 | index ee43a460d6..9f9aa30d33 100644
3 | --- a/test/lib/e2e-utils.ts
4 | +++ b/test/lib/e2e-utils.ts
5 | @@ -7,3 +7,3 @@ import { NextDevInstance } from './next-modes/next-dev'
6 | import { NextStartInstance } from './next-modes/next-start'
7 | -import { NextDeployInstance } from './next-modes/next-deploy'
8 | +import { NextDeployInstance } from './next-modes/netlify-deploy'
9 | import { shouldRunTurboDevTest } from './next-test-utils'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/advanced-api-routes/next-env.d.ts:
--------------------------------------------------------------------------------
1 | /// ) {
10 | res.status(200).json({ params: req.query })
11 | }
12 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-excluded-paths/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "noEmit": true,
9 | "incremental": true,
10 | "module": "esnext",
11 | "esModuleInterop": true,
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve"
16 | },
17 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
18 | "exclude": ["node_modules"]
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | output: 'standalone',
3 | eslint: {
4 | ignoreDuringBuilds: true,
5 | },
6 | i18n: {
7 | locales: ['en', 'fr', 'nl', 'es'],
8 | defaultLocale: 'en',
9 | },
10 | skipMiddlewareUrlNormalize: true,
11 | experimental: {
12 | clientRouterFilter: true,
13 | clientRouterFilterRedirects: true,
14 | },
15 | redirects() {
16 | return [
17 | {
18 | source: '/to-new',
19 | destination: '/dynamic/new',
20 | permanent: false,
21 | },
22 | ]
23 | },
24 | }
25 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-pages",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "18.2.47"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/pages/_app.js:
--------------------------------------------------------------------------------
1 | export default function App({ Component, pageProps }) {
2 | if (!pageProps || typeof pageProps !== 'object') {
3 | throw new Error(`Invariant: received invalid pageProps in _app, received ${pageProps}`)
4 | }
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/pages/api/ok.js:
--------------------------------------------------------------------------------
1 | export default function handler(req, res) {
2 | res.send('ok')
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/pages/dynamic/[slug].js:
--------------------------------------------------------------------------------
1 | export default function Account({ slug }) {
2 | return (
3 |
4 | Welcome to a /dynamic/[slug]: {slug}
5 |
6 | )
7 | }
8 |
9 | export function getServerSideProps({ params }) {
10 | return {
11 | props: {
12 | slug: params.slug,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n-skip-normalize/pages/new-home.js:
--------------------------------------------------------------------------------
1 | export default function Account() {
2 | return (
3 |
4 | Welcome to a new page
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | output: 'standalone',
3 | eslint: {
4 | ignoreDuringBuilds: true,
5 | },
6 | i18n: {
7 | locales: ['en', 'fr', 'nl', 'es'],
8 | defaultLocale: 'en',
9 | },
10 | experimental: {
11 | clientRouterFilter: true,
12 | clientRouterFilterRedirects: true,
13 | },
14 | redirects() {
15 | return [
16 | {
17 | source: '/to-new',
18 | destination: '/dynamic/new',
19 | permanent: false,
20 | },
21 | ]
22 | },
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-pages",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "18.2.47"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/pages/_app.js:
--------------------------------------------------------------------------------
1 | export default function App({ Component, pageProps }) {
2 | if (!pageProps || typeof pageProps !== 'object') {
3 | throw new Error(`Invariant: received invalid pageProps in _app, received ${pageProps}`)
4 | }
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/pages/api/ok.js:
--------------------------------------------------------------------------------
1 | export default function handler(req, res) {
2 | res.send('ok')
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/pages/dynamic/[slug].js:
--------------------------------------------------------------------------------
1 | export default function Account({ slug }) {
2 | return (
3 |
4 | Welcome to a /dynamic/[slug]: {slug}
5 |
6 | )
7 | }
8 |
9 | export function getServerSideProps({ params }) {
10 | return {
11 | props: {
12 | slug: params.slug,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-i18n/pages/new-home.js:
--------------------------------------------------------------------------------
1 | export default function Account() {
2 | return (
3 |
4 | Welcome to a new page
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/app/og.js:
--------------------------------------------------------------------------------
1 | import { ImageResponse } from 'next/og'
2 |
3 | export default function og() {
4 | return new ImageResponse(
5 | (
6 |
17 | Open Graph
18 |
19 | ),
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/app/opengraph-image.js:
--------------------------------------------------------------------------------
1 | export const alt = 'Open Graph'
2 |
3 | export { default } from './og'
4 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-og/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-og",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "test": {
16 | "dependencies": {
17 | "next": ">=14.0.0"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-pages",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/node": "^20.10.6",
17 | "@types/react": "18.2.47",
18 | "typescript": "^5.3.3"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/[id].js:
--------------------------------------------------------------------------------
1 | export default function Index() {
2 | return Dynamic route
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/_app.js:
--------------------------------------------------------------------------------
1 | export default function App({ Component, pageProps }) {
2 | if (!pageProps || typeof pageProps !== 'object') {
3 | throw new Error(`Invariant: received invalid pageProps in _app, received ${pageProps}`)
4 | }
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/about/a.js:
--------------------------------------------------------------------------------
1 | export default function AboutA() {
2 | return (
3 |
4 |
AboutA
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/about/b.js:
--------------------------------------------------------------------------------
1 | export default function AboutB() {
2 | return (
3 |
4 |
AboutB
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/api/edge-headers.js:
--------------------------------------------------------------------------------
1 | export const runtime = 'edge'
2 |
3 | export default (req) => {
4 | return Response.json(Object.fromEntries(req.headers.entries()), {
5 | headers: {
6 | 'headers-from-edge-function': '1',
7 | },
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/api/headers.js:
--------------------------------------------------------------------------------
1 | export default function handler(req, res) {
2 | res.headers = { 'headers-from-function': '1' }
3 | res.json({ url: req.url, headers: req.headers })
4 | }
5 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/blog/[slug].js:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router'
2 |
3 | export default function Page(props) {
4 | const router = useRouter()
5 | return (
6 | <>
7 | /blog/[slug]
8 | {JSON.stringify(router.query)}
9 | {router.pathname}
10 | {router.asPath}
11 | {JSON.stringify(props)}
12 | >
13 | )
14 | }
15 |
16 | export function getServerSideProps({ params }) {
17 | return {
18 | props: {
19 | now: Date.now(),
20 | params,
21 | },
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/error-throw.js:
--------------------------------------------------------------------------------
1 | export default function ThrowOnData({ message }) {
2 | return (
3 |
4 |
Throw on data request
5 |
{message}
6 |
7 | )
8 | }
9 |
10 | export const getServerSideProps = ({ query }) => ({
11 | props: { message: query.message || '' },
12 | })
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/error.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function Errors() {
4 | return (
5 |
6 |
7 | Throw on data
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/html-links.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function Page() {
4 | return (
5 |
6 | -
7 |
8 | Does not work
9 |
10 |
11 | -
12 |
13 | Works
14 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/ssr-page-2.js:
--------------------------------------------------------------------------------
1 | export default function SSRPage(props) {
2 | return {props.message}
3 | }
4 |
5 | export const getServerSideProps = (req) => {
6 | return {
7 | props: {
8 | message: 'Bye Cruel World',
9 | },
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/pages/ssr-page.js:
--------------------------------------------------------------------------------
1 | export default function SSRPage(props) {
2 | return {props.message}
3 | }
4 |
5 | export const getServerSideProps = (req) => {
6 | return {
7 | props: {
8 | message: 'Hello World',
9 | },
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-pages/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "target": "ES2017"
16 | },
17 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
18 | "exclude": ["node_modules"]
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-src/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-src/src/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-src/src/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-src/src/app/test/next/page.js:
--------------------------------------------------------------------------------
1 | import { headers } from 'next/headers'
2 |
3 | export default function Page() {
4 | const headersList = headers()
5 | const message = headersList.get('x-hello-from-middleware-req')
6 |
7 | return (
8 |
9 | Message from middleware: {message}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/middleware.ts:
--------------------------------------------------------------------------------
1 | export default function middleware() {
2 | return new Response('hello from middleware')
3 | }
4 |
5 | export const config = {
6 | matcher: '/hello/world.txt',
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-static-asset-matcher/public/hello/world.txt:
--------------------------------------------------------------------------------
1 | hello from a static asset
2 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-subrequest-vuln/app/[[...wildcard]]/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Hi
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-subrequest-vuln/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-subrequest-vuln/middleware.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { NextRequest } from 'next/server'
3 |
4 | import packageJson from 'next/package.json'
5 |
6 | export async function middleware(request: NextRequest) {
7 | const response = NextResponse.next()
8 |
9 | response.headers.set('x-test-used-middleware', 'true')
10 | response.headers.set('x-test-used-next-version', packageJson.version)
11 |
12 | return response
13 | }
14 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-subrequest-vuln/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-subrequest-vuln/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-subrequest-vuln",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "15.2.2",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "test": {
16 | "dependencies": {
17 | "next": "15.2.2"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/other/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 | Other
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/test/next/page.js:
--------------------------------------------------------------------------------
1 | import { headers } from 'next/headers'
2 |
3 | export default function Page() {
4 | const headersList = headers()
5 | const message = headersList.get('x-hello-from-middleware-req')
6 |
7 | return (
8 |
9 | Message from middleware: {message}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/test/redirect/page.js:
--------------------------------------------------------------------------------
1 | export default function Redirect() {
2 | return (
3 |
4 | If middleware works, we shoudn't get here
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/app/test/rewrite/page.js:
--------------------------------------------------------------------------------
1 | export default function Rewrite() {
2 | return (
3 |
4 | If middleware works, we shoudn't get here
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | trailingSlash: true,
4 | output: 'standalone',
5 | eslint: {
6 | ignoreDuringBuilds: true,
7 | },
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware-trailing-slash/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware-trailing-slash",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/caching-redirect-target/page.js:
--------------------------------------------------------------------------------
1 | export default function CachingRedirect() {
2 | return (
3 |
4 | Hello redirect target
5 |
6 | )
7 | }
8 |
9 | export const dynamic = 'force-static'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/caching-rewrite-target/page.js:
--------------------------------------------------------------------------------
1 | export default function CachingRewrite() {
2 | return (
3 |
4 | Hello rewrite target
5 |
6 | )
7 | }
8 |
9 | export const dynamic = 'force-static'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/link-to-redirect-to-cached-page/page.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function LinksToRedirectedCachedPage() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/link-to-rewrite-to-cached-page/page.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function LinksToRewrittenCachedPage() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/other/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 | Other
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/test/next/page.js:
--------------------------------------------------------------------------------
1 | import { headers } from 'next/headers'
2 |
3 | export default function Page() {
4 | const headersList = headers()
5 | const message = headersList.get('x-hello-from-middleware-req')
6 |
7 | return (
8 |
9 | Message from middleware: {message}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/test/redirect/page.js:
--------------------------------------------------------------------------------
1 | export default function Redirect() {
2 | return (
3 |
4 | If middleware works, we shoudn't get here
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/test/rewrite-target/page.js:
--------------------------------------------------------------------------------
1 | export default function Rewrite() {
2 | return (
3 |
4 | Hello rewrite
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/app/test/rewrite/page.js:
--------------------------------------------------------------------------------
1 | export default function Rewrite() {
2 | return (
3 |
4 | If middleware works, we shoudn't get here
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | webpack: (config) => {
8 | // this is a trigger to generate multiple `.next/server/middleware-[hash].js` files instead of
9 | // single `.next/server/middleware.js` file
10 | config.optimization.splitChunks.maxSize = 100_000
11 |
12 | return config
13 | },
14 | }
15 |
16 | module.exports = nextConfig
17 |
--------------------------------------------------------------------------------
/tests/fixtures/middleware/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleware",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@aws-amplify/adapter-nextjs": "^1.0.18",
12 | "aws-amplify": "^6.0.18",
13 | "next": "latest",
14 | "react": "18.2.0",
15 | "react-dom": "18.2.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Netlify Forms',
3 | description: 'Test for verifying Netlify Forms',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | generateBuildId: () => 'build-id',
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "netlify-forms",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@netlify/functions": "^2.7.0",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | },
16 | "devDependencies": {
17 | "@types/react": "18.2.75"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/public/form.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms-workaround/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ]
20 | },
21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Netlify Forms',
3 | description: 'Test for verifying Netlify Forms',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | generateBuildId: () => 'build-id',
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "netlify-forms",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@netlify/functions": "^2.7.0",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | },
16 | "devDependencies": {
17 | "@types/react": "18.2.75"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/public/form.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tests/fixtures/netlify-forms/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ]
20 | },
21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/.npmrc:
--------------------------------------------------------------------------------
1 | strict-peer-dependencies=false
2 | auto-install-peers=true
3 | public-hoist-pattern[]=*
4 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/.env:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV="defined in .env"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/.env.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_LOCAL="defined in .env.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/.env.production:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION="defined in .env.production"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/.env.production.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL="defined in .env.production.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/api/env/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | return NextResponse.json({
5 | '.env': process.env.FROM_DOT_ENV ?? 'undefined',
6 | '.env.local': process.env.FROM_DOT_ENV_DOT_LOCAL ?? 'undefined',
7 | '.env.production': process.env.FROM_DOT_ENV_DOT_PRODUCTION ?? 'undefined',
8 | '.env.production.local': process.env.FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL ?? 'undefined',
9 | })
10 | }
11 |
12 | export const dynamic = 'force-dynamic'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/api/headers/route.js:
--------------------------------------------------------------------------------
1 | import { cookies } from 'next/headers'
2 |
3 | export const GET = async () => {
4 | cookies().set('foo', 'foo1')
5 | cookies().set('bar', 'bar1')
6 |
7 | // Key, value, options
8 | cookies().set('test1', 'value1', { secure: true })
9 |
10 | // One object
11 | cookies().set({
12 | name: 'test2',
13 | value: 'value2',
14 | httpOnly: true,
15 | path: '/handler',
16 | })
17 |
18 | // Cookies here will be merged with the ones above
19 | return new Response('Hello, world!', {
20 | headers: [
21 | ['Content-Type', 'text/custom'],
22 | ['Set-Cookie', 'bar=bar2'],
23 | ['Set-Cookie', 'baz=baz2'],
24 | ],
25 | })
26 | }
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/api/url/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET(request) {
4 | return NextResponse.json({ url: request.url })
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/image/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Next/Image + Netlify Image CDN
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/other/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Other
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/redirect/response/route.js:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | return NextResponse.redirect('https://www.netlify.com/')
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/redirect/route.js:
--------------------------------------------------------------------------------
1 | import { redirect } from 'next/navigation'
2 |
3 | export async function GET() {
4 | return redirect('https://www.netlify.com/')
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/app/stale-cache-serving/app-page/page.js:
--------------------------------------------------------------------------------
1 | export const dynamic = 'force-dynamic'
2 |
3 | const delay = 3000
4 |
5 | export default async function Page(props) {
6 | const start = Date.now()
7 | const data = await fetch(
8 | `https://next-data-api-endpoint.vercel.app/api/delay?delay=${delay}`,
9 | { next: { revalidate: 3 } }
10 | ).then((res) => res.json())
11 | const fetchDuration = Date.now() - start
12 |
13 | return (
14 | <>
15 |
16 | {JSON.stringify({ fetchDuration, data, now: Date.now() })}
17 |
18 | >
19 | )
20 | }
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/next.config.js:
--------------------------------------------------------------------------------
1 | const { composePlugins, withNx } = require('@nx/next')
2 |
3 | /**
4 | * @type {import('@nx/next/plugins/with-nx').WithNxOptions}
5 | **/
6 | const nextConfig = {
7 | distDir: 'dist',
8 | nx: {
9 | // Set this to true if you would like to use SVGR
10 | // See: https://github.com/gregberge/svgr
11 | svgr: false,
12 | },
13 | }
14 |
15 | const plugins = [
16 | // Add more Next.js plugins to this list if needed.
17 | withNx,
18 | ]
19 |
20 | module.exports = composePlugins(...plugins)(nextConfig)
21 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/public/squirrel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/nx-integrated/apps/custom-dist-dir/public/squirrel.jpg
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/custom-dist-dir/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"],
7 | "jsx": "react"
8 | },
9 | "include": [
10 | "jest.config.ts",
11 | "src/**/*.test.ts",
12 | "src/**/*.spec.ts",
13 | "src/**/*.test.tsx",
14 | "src/**/*.spec.tsx",
15 | "src/**/*.test.js",
16 | "src/**/*.spec.js",
17 | "src/**/*.test.jsx",
18 | "src/**/*.spec.jsx",
19 | "src/**/*.d.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/app/api/hello/route.ts:
--------------------------------------------------------------------------------
1 | export async function GET(request: Request) {
2 | return new Response('Hello, from API!')
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/app/api/static/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { readFile } from 'node:fs/promises'
3 |
4 | export async function GET(request) {
5 | const words = await readFile('static/words.txt', 'utf-8')
6 | return NextResponse.json({ words })
7 | }
8 |
9 | export const dynamic = 'force-dynamic'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './global.css'
2 |
3 | export const metadata = {
4 | title: 'Welcome to next-app',
5 | description: 'Generated by create-nx-workspace',
6 | }
7 |
8 | export default function RootLayout({ children }: { children: React.ReactNode }) {
9 | return (
10 |
11 | {children}
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | }
3 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/index.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-explicit-any */
2 | declare module '*.svg' {
3 | const content: any
4 | export const ReactComponent: any
5 | export default content
6 | }
7 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/netlify.toml:
--------------------------------------------------------------------------------
1 | [functions]
2 | directory = "netlify/functions"
3 | included_files = ["apps/next-app/static/**"]
4 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/next.config.js:
--------------------------------------------------------------------------------
1 | const { composePlugins, withNx } = require('@nx/next')
2 |
3 | /**
4 | * @type {import('@nx/next/plugins/with-nx').WithNxOptions}
5 | **/
6 | const nextConfig = {
7 | nx: {
8 | // Set this to true if you would like to use SVGR
9 | // See: https://github.com/gregberge/svgr
10 | svgr: false,
11 | },
12 | }
13 |
14 | const plugins = [
15 | // Add more Next.js plugins to this list if needed.
16 | withNx,
17 | ]
18 |
19 | module.exports = composePlugins(...plugins)(nextConfig)
20 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/public/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/nx-integrated/apps/next-app/public/.gitkeep
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/nx-integrated/apps/next-app/public/favicon.ico
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/static/words.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/apps/next-app/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"],
7 | "jsx": "react"
8 | },
9 | "include": [
10 | "jest.config.ts",
11 | "src/**/*.test.ts",
12 | "src/**/*.spec.ts",
13 | "src/**/*.test.tsx",
14 | "src/**/*.spec.tsx",
15 | "src/**/*.test.js",
16 | "src/**/*.spec.js",
17 | "src/**/*.test.jsx",
18 | "src/**/*.spec.jsx",
19 | "src/**/*.d.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/nx-integrated/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "lib": ["es2020", "dom"],
14 | "skipLibCheck": true,
15 | "skipDefaultLibCheck": true,
16 | "baseUrl": ".",
17 | "paths": {}
18 | },
19 | "exclude": ["node_modules", "tmp"]
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/.gitignore:
--------------------------------------------------------------------------------
1 | custom-dist
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'export',
4 | distDir: 'custom-dist',
5 | eslint: {
6 | ignoreDuringBuilds: true,
7 | },
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "output-export",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export-custom-dist/public/squirrel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/output-export-custom-dist/public/squirrel.jpg
--------------------------------------------------------------------------------
/tests/fixtures/output-export/app/image/local/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Next/Image + Netlify Image CDN
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'export',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "output-export",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/output-export/public/squirrel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/output-export/public/squirrel.jpg
--------------------------------------------------------------------------------
/tests/fixtures/page-router-404-get-static-props-with-revalidate/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | generateBuildId: () => 'build-id',
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-404-get-static-props-with-revalidate/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "page-router-404-get-static-props-with-revalidate",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-404-get-static-props-with-revalidate/pages/404.js:
--------------------------------------------------------------------------------
1 | export default function NotFound({ timestamp }) {
2 | return (
3 |
4 | Custom 404 page with revalidate:
{timestamp}
5 |
6 | )
7 | }
8 |
9 | /** @type {import('next').GetStaticProps} */
10 | export const getStaticProps = ({ locale }) => {
11 | return {
12 | props: {
13 | timestamp: Date.now(),
14 | },
15 | revalidate: 300,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | generateBuildId: () => 'build-id',
8 | basePath: '/base/path',
9 | i18n: {
10 | locales: ['en', 'fr', 'de'],
11 | defaultLocale: 'en',
12 | },
13 | }
14 |
15 | module.exports = nextConfig
16 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "page-router",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@netlify/functions": "^2.7.0",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/pages/404.js:
--------------------------------------------------------------------------------
1 | export default function NotFound({ locale }) {
2 | return (
3 |
4 | Custom 404 page for locale:
{locale}
5 |
6 | )
7 | }
8 |
9 | /** @type {import('next').GetStaticProps} */
10 | export const getStaticProps = ({ locale }) => {
11 | return {
12 | props: {
13 | locale,
14 | },
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/pages/api/revalidate-no-await.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | const pathToPurge = req.query.path ?? '/static/revalidate-manual'
4 | // res.revalidate returns a promise that can be awaited to wait for the revalidation to complete
5 | // if user doesn't await it, we still want to ensure the revalidation is completed, so we internally track
6 | // this as "background work" to ensure it completes before function suspends execution
7 | res.revalidate(pathToPurge)
8 | return res.json({ code: 200, message: 'success' })
9 | } catch (err) {
10 | return res.status(500).send({ code: 500, message: err.message })
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/pages/api/revalidate.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | const pathToRevalidate = req.query.path
4 | if (!pathToRevalidate) {
5 | return res.status(400).send({
6 | status: 'error',
7 | error: 'missing "path" query parameter',
8 | })
9 | }
10 | await res.revalidate(pathToRevalidate)
11 | return res.status(200).json({ message: 'ok' })
12 | } catch (err) {
13 | return res.status(500).send({
14 | status: 'error',
15 | error: error.toString(),
16 | })
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/pages/static/not-found.js:
--------------------------------------------------------------------------------
1 | const Show = () => Won't be used
2 |
3 | export async function getStaticProps() {
4 | return {
5 | notFound: true,
6 | }
7 | }
8 |
9 | export default Show
10 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router-base-path-i18n/pages/static/revalidate-manual.js:
--------------------------------------------------------------------------------
1 | const Show = ({ show, time }) => (
2 |
3 |
4 | This page uses getStaticProps() to pre-fetch a TV show at
5 | {time}
6 |
7 |
8 |
Show #{show.id}
9 |
{show.name}
10 |
11 | )
12 |
13 | export async function getStaticProps() {
14 | const res = await fetch(`https://tvproxy.netlify.app/shows/71`)
15 | const data = await res.json()
16 |
17 | return {
18 | props: {
19 | show: data,
20 | time: new Date().toISOString(),
21 | },
22 | }
23 | }
24 |
25 | export default Show
26 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/.env:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV="defined in .env"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/.env.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_LOCAL="defined in .env.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/.env.production:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION="defined in .env.production"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/.env.production.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL="defined in .env.production.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | generateBuildId: () => 'build-id',
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "page-router",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@netlify/blobs": "^8.1.0",
12 | "@netlify/functions": "^2.7.0",
13 | "next": "latest",
14 | "react": "18.2.0",
15 | "react-dom": "18.2.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/404.js:
--------------------------------------------------------------------------------
1 | export default function NotFound() {
2 | return Custom 404 page
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/api/env.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {import('next').NextApiRequest} _req
3 | * @param {import('next').NextApiResponse} res
4 | */
5 | export default async function handler(_req, res) {
6 | res.status(200).json({
7 | '.env': process.env.FROM_DOT_ENV ?? 'undefined',
8 | '.env.local': process.env.FROM_DOT_ENV_DOT_LOCAL ?? 'undefined',
9 | '.env.production': process.env.FROM_DOT_ENV_DOT_PRODUCTION ?? 'undefined',
10 | '.env.production.local': process.env.FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL ?? 'undefined',
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/api/revalidate-no-await.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | const pathToPurge = req.query.path ?? '/static/revalidate-manual'
4 | // res.revalidate returns a promise that can be awaited to wait for the revalidation to complete
5 | // if user doesn't await it, we still want to ensure the revalidation is completed, so we internally track
6 | // this as "background work" to ensure it completes before function suspends execution
7 | res.revalidate(pathToPurge)
8 | return res.json({ code: 200, message: 'success' })
9 | } catch (err) {
10 | return res.status(500).send({ code: 500, message: err.message })
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/api/revalidate.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | const pathToPurge = req.query.path ?? '/static/revalidate-manual'
4 | await res.revalidate(pathToPurge)
5 | return res.json({ code: 200, message: 'success' })
6 | } catch (err) {
7 | return res.status(500).send({ code: 500, message: err.message })
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/api/sleep-5.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | await new Promise((resolve) => setTimeout(resolve, 5000))
3 |
4 | res.json({ message: 'ok' })
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/api/unstable-cache-node.js:
--------------------------------------------------------------------------------
1 | import { unstable_cache } from 'next/cache'
2 |
3 | export default async function handler(req, res) {
4 | const data = await unstable_cache(async () => {
5 | return {
6 | random: Math.random(),
7 | }
8 | })()
9 |
10 | res.json({
11 | now: Date.now(),
12 | data,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/static/fully-static.js:
--------------------------------------------------------------------------------
1 | const FullyStatic = () => (
2 |
3 |
This page is not using getStaticProps()
4 |
5 | )
6 |
7 | export default FullyStatic
8 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/static/not-found.js:
--------------------------------------------------------------------------------
1 | const Show = () => Won't be used
2 |
3 | export async function getStaticProps() {
4 | return {
5 | notFound: true,
6 | }
7 | }
8 |
9 | export default Show
10 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/static/revalidate-manual.js:
--------------------------------------------------------------------------------
1 | const Show = ({ show, time }) => (
2 |
3 |
4 | This page uses getStaticProps() to pre-fetch a TV show at
5 | {time}
6 |
7 |
8 |
Show #{show.id}
9 |
{show.name}
10 |
11 | )
12 |
13 | export async function getStaticProps(context) {
14 | const res = await fetch(`https://tvproxy.netlify.app/shows/71`)
15 | const data = await res.json()
16 |
17 | return {
18 | props: {
19 | show: data,
20 | time: new Date().toISOString(),
21 | },
22 | }
23 | }
24 |
25 | export default Show
26 |
--------------------------------------------------------------------------------
/tests/fixtures/page-router/pages/static/revalidate-slow.js:
--------------------------------------------------------------------------------
1 | const Show = ({ show, time }) => (
2 |
3 |
4 | This page uses getStaticProps() to pre-fetch a TV show at
5 | {time}
6 |
7 |
8 |
Show #{show.id}
9 |
{show.name}
10 |
11 | )
12 |
13 | export async function getStaticProps(context) {
14 | const res = await fetch(`https://tvproxy.netlify.app/shows/71`)
15 | const data = await res.json()
16 |
17 | return {
18 | props: {
19 | show: data,
20 | time: new Date().toISOString(),
21 | },
22 | revalidate: +process.env.REVALIDATE_SECONDS || 10, // In seconds
23 | }
24 | }
25 |
26 | export default Show
27 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/app/other/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Other
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | swcMinify: true,
4 | output: 'standalone',
5 | eslint: {
6 | ignoreDuringBuilds: true,
7 | },
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/pnpm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pnpm",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "packageManager": "pnpm@8.9.0"
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/ppr/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/ppr/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/ppr/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | experimental: {
8 | ppr: true,
9 | },
10 | }
11 |
12 | module.exports = nextConfig
13 |
--------------------------------------------------------------------------------
/tests/fixtures/ppr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ppr",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "canary",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "test": {
16 | "dependencies": {
17 | "next": "canary"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/ppr/public/squirrel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/ppr/public/squirrel.jpg
--------------------------------------------------------------------------------
/tests/fixtures/revalidate-fetch/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Revalidate fetch',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/revalidate-fetch/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/revalidate-fetch/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/revalidate-fetch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "incremental-static-regeneration",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/api/on-demand-revalidate/path/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from 'next/server'
2 | import { revalidatePath } from 'next/cache'
3 |
4 | export async function GET(request: NextRequest) {
5 | const url = new URL(request.url)
6 | const pathToRevalidate = url.searchParams.get('path') ?? '/static-fetch/[id]/page'
7 |
8 | revalidatePath(pathToRevalidate)
9 | return NextResponse.json({ revalidated: true, now: new Date().toISOString() })
10 | }
11 |
12 | export const dynamic = 'force-dynamic'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/api/on-demand-revalidate/tag/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from 'next/server'
2 | import { revalidateTag } from 'next/cache'
3 |
4 | export async function GET(request: NextRequest) {
5 | const url = new URL(request.url)
6 | const tagToRevalidate = url.searchParams.get('tag') ?? 'collection'
7 |
8 | revalidateTag(tagToRevalidate)
9 | return NextResponse.json({ revalidated: true, now: new Date().toISOString() })
10 | }
11 |
12 | export const dynamic = 'force-dynamic'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/api/revalidate-handler/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | const res = await fetch(`https://api.tvmaze.com/shows/1`, {
5 | next: { revalidate: 7 },
6 | })
7 | const data = await res.json()
8 |
9 | return NextResponse.json({ data, time: new Date().toISOString() })
10 | }
11 |
12 | export const dynamic = 'force-static'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/api/static/[slug]/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from 'next/server'
2 |
3 | export function generateStaticParams() {
4 | return [{ slug: 'first' }, { slug: 'second' }]
5 | }
6 |
7 | export const GET = (_req: NextRequest, { params }) => {
8 | return NextResponse.json({ params })
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/api/zero-length-response/route.ts:
--------------------------------------------------------------------------------
1 | export async function GET() {
2 | return new Response('')
3 | }
4 |
5 | export const dynamic = 'force-static'
6 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/dynamic-fetch/loading.js:
--------------------------------------------------------------------------------
1 | export default function Loading() {
2 | return Loading Data...
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/dynamic-fetch/page.js:
--------------------------------------------------------------------------------
1 | async function getData() {
2 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`, {
3 | cache: 'no-store',
4 | })
5 | return res.json()
6 | }
7 |
8 | export default async function Page() {
9 | const data = await getData()
10 |
11 | return (
12 | <>
13 | Hello, Dynamically Rendered Server Component
14 | Fetch cache disabled
15 |
16 | - Quote
17 | - {data[0].quote}
18 | - Time
19 | - {Date.now()}
20 |
21 | >
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Revalidate fetch',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/page.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function Page() {
4 | return (
5 |
6 |
Hello, Statically Rendered Server Component
7 |
8 | -
9 | static-fetch-1
10 |
11 | -
12 | static-fetch-1
13 |
14 | -
15 | static-fetch-dynamic
16 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/product/[slug]/page.js:
--------------------------------------------------------------------------------
1 | const Product = ({ params }) => (
2 |
3 |
Product {decodeURIComponent(params.slug)}
4 |
5 | This page uses generateStaticParams() to prerender a Product
6 | {new Date().toISOString()}
7 |
8 |
9 | )
10 |
11 | export async function generateStaticParams() {
12 | return [
13 | {
14 | // Japanese prerendered (non-ascii) and comma
15 | slug: '事前レンダリング,test',
16 | },
17 | ]
18 | }
19 |
20 | export default Product
21 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/revalidate-fetch/page.js:
--------------------------------------------------------------------------------
1 | const revalidateSeconds = 3
2 |
3 | async function getData() {
4 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`, {
5 | next: { revalidate: revalidateSeconds },
6 | })
7 | return res.json()
8 | }
9 |
10 | export default async function Page() {
11 | const data = await getData()
12 |
13 | return (
14 | <>
15 | Hello, Statically Rendered Server Component
16 | Revalidating every {revalidateSeconds} seconds
17 |
18 | - Quote
19 | - {data[0].quote}
20 | - Time
21 | - {Date.now()}
22 |
23 | >
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/static-fetch-1/page.js:
--------------------------------------------------------------------------------
1 | async function getData() {
2 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`, {
3 | next: { tags: ['collection'] },
4 | })
5 | return res.json()
6 | }
7 |
8 | export default async function Page() {
9 | const data = await getData()
10 |
11 | return (
12 | <>
13 | Hello, Static Fetch 1
14 |
15 | - Quote
16 | - {data[0].quote}
17 | - Time
18 | - {new Date().toISOString()}
19 |
20 | >
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/static-fetch-2/page.js:
--------------------------------------------------------------------------------
1 | async function getData() {
2 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`, {
3 | next: { tags: ['collection'] },
4 | })
5 | return res.json()
6 | }
7 |
8 | export default async function Page() {
9 | const data = await getData()
10 |
11 | return (
12 | <>
13 | Hello, Static Fetch 2
14 |
15 | - Quote
16 | - {data[0].quote}
17 | - Time
18 | - {new Date().toISOString()}
19 |
20 | >
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/static-fetch-3/page.js:
--------------------------------------------------------------------------------
1 | async function getData() {
2 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`, {
3 | next: { tags: ['collection'] },
4 | })
5 | return res.json()
6 | }
7 |
8 | export default async function Page() {
9 | const data = await getData()
10 |
11 | return (
12 | <>
13 | Hello, Static Fetch 3
14 |
15 | - Quote
16 | - {data[0].quote}
17 | - Time
18 | - {new Date().toISOString()}
19 |
20 | >
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/app/static-fetch-dynamic/page.js:
--------------------------------------------------------------------------------
1 | async function getData() {
2 | const res = await fetch(`https://strangerthings-quotes.vercel.app/api/quotes`)
3 | return res.json()
4 | }
5 |
6 | export default async function Page() {
7 | const data = await getData()
8 |
9 | return (
10 | <>
11 | Hello, Force Dynamically Rendered Server Component
12 |
13 | - Quote
14 | - {data[0].quote}
15 | - Time
16 | - {Date.now()}
17 |
18 | >
19 | )
20 | }
21 |
22 | export const dynamic = 'force-dynamic'
23 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | }
8 |
9 | module.exports = nextConfig
10 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-components",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@netlify/functions": "^2.7.0",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^20.11.5",
18 | "@types/react": "18.2.34",
19 | "typescript": "^5.3.3"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/server-components/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ]
20 | },
21 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/cached-permanent/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | return NextResponse.json({
5 | message:
6 | 'Route handler not using request and using force-static dynamic strategy with permanent caching',
7 | })
8 | }
9 | export const revalidate = false
10 |
11 | export const dynamic = 'force-static'
12 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/cached-revalidate/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | return NextResponse.json({
5 | message:
6 | 'Route handler not using request and using force-static dynamic strategy with 15 seconds revalidate',
7 | })
8 | }
9 | export const revalidate = 15
10 |
11 | export const dynamic = 'force-static'
12 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/cjs-file-with-js-extension/bundled.cjs:
--------------------------------------------------------------------------------
1 | const { parse: pathParse } = require('node:path')
2 |
3 | const fileBase = pathParse(__filename).base
4 |
5 | module.exports = {
6 | fileBase,
7 | // if fileBase is not the same as this module name, it was bundled
8 | isBundled: fileBase !== 'bundled.cjs',
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/cjs-file-with-js-extension/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { resolve } from 'node:path'
3 |
4 | export async function GET() {
5 | return NextResponse.json({
6 | notBundledCJSModule: __non_webpack_require__(resolve('./cjs-file-with-js-extension.js')),
7 | bundledCJSModule: require('./bundled.cjs'),
8 | })
9 | }
10 |
11 | export const dynamic = 'force-dynamic'
12 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/headers/route.js:
--------------------------------------------------------------------------------
1 | import { cookies } from 'next/headers'
2 |
3 | export const GET = async () => {
4 | cookies().set('foo', 'foo1')
5 | cookies().set('bar', 'bar1')
6 |
7 | // Key, value, options
8 | cookies().set('test1', 'value1', { secure: true })
9 |
10 | // One object
11 | cookies().set({
12 | name: 'test2',
13 | value: 'value2',
14 | httpOnly: true,
15 | path: '/handler',
16 | })
17 |
18 | // Cookies here will be merged with the ones above
19 | return new Response('Hello, world!', {
20 | headers: [
21 | ['Content-Type', 'text/custom'],
22 | ['Set-Cookie', 'bar=bar2'],
23 | ['Set-Cookie', 'baz=baz2'],
24 | ],
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/static/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { readFile } from 'node:fs/promises'
3 |
4 | export async function GET(request) {
5 | const words = await readFile('static/words.txt', 'utf-8')
6 | return NextResponse.json({ words })
7 | }
8 |
9 | export const dynamic = 'force-dynamic'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/api/url/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export async function GET(request) {
4 | return NextResponse.json({ url: request.url })
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/config-redirect/dest/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 | Hello redirect target
5 |
6 | )
7 | }
8 |
9 | export const dynamic = 'force-static'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/config-redirect/page.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function Home() {
4 | return (
5 |
6 | NextConfig.redirect
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/config-rewrite/dest/page.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 | Hello rewrite target
5 |
6 | )
7 | }
8 |
9 | export const dynamic = 'force-static'
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/config-rewrite/page.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 |
3 | export default function Home() {
4 | return (
5 |
6 | NextConfig.rewrite
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/image/local/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Next/Image + Netlify Image CDN
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/image/migration-from-v4-runtime/page.js:
--------------------------------------------------------------------------------
1 | import { NextImageWithLoaderSimulatingRuntimeV4 } from './next-image-runtime-v4'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Next/Image + Netlify Image CDN
7 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/image/remote-domain/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function Domains() {
4 | return (
5 |
6 | Remote Images with Netlify CDN
7 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/image/remote-pattern-1/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Remote Images with Netlify CDN
7 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/image/remote-pattern-2/page.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 |
3 | export default function NextImageUsingNetlifyImageCDN() {
4 | return (
5 |
6 | Remote Images with Netlify CDN
7 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Simple Next App',
3 | description: 'Description for Simple Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/not-found.js:
--------------------------------------------------------------------------------
1 | export default function NotFound() {
2 | return (
3 |
4 |
404 Not Found
5 |
Custom Not Found Page
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/other/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Other
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Home
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/redirect/response/route.js:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from 'next/server'
2 |
3 | export async function GET() {
4 | return NextResponse.redirect('https://www.netlify.com/')
5 | }
6 |
7 | export const dynamic = 'force-dynamic'
8 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/redirect/route.js:
--------------------------------------------------------------------------------
1 | import { redirect } from 'next/navigation'
2 |
3 | export async function GET() {
4 | return redirect('https://www.netlify.com/')
5 | }
6 |
7 | export const dynamic = 'force-dynamic'
8 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/route-resolves-to-not-found/page.js:
--------------------------------------------------------------------------------
1 | import { notFound } from 'next/navigation'
2 |
3 | export default async function Page() {
4 | notFound()
5 | }
6 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/stale-cache-serving/app-page/page.js:
--------------------------------------------------------------------------------
1 | export const dynamic = 'force-dynamic'
2 |
3 | const delay = 3000
4 |
5 | export default async function Page(props) {
6 | const start = Date.now()
7 | const data = await fetch(`https://next-data-api-endpoint.vercel.app/api/delay?delay=${delay}`, {
8 | next: { revalidate: 3 },
9 | }).then((res) => res.json())
10 | const fetchDuration = Date.now() - start
11 |
12 | return (
13 | <>
14 | {JSON.stringify({ fetchDuration, data, now: Date.now() })}
15 | >
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/app/unstable_cache/page.js:
--------------------------------------------------------------------------------
1 | import { unstable_cache } from 'next/cache'
2 |
3 | export const dynamic = 'force-dynamic'
4 |
5 | const getData = unstable_cache(
6 | async () => {
7 | return {
8 | timestamp: Date.now(),
9 | }
10 | },
11 | [],
12 | {
13 | revalidate: 1,
14 | },
15 | )
16 |
17 | export default async function Page() {
18 | const data = await getData()
19 |
20 | return {JSON.stringify(data, null, 2)}
21 | }
22 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/cjs-file-with-js-extension.js:
--------------------------------------------------------------------------------
1 | const { parse: pathParse } = require('node:path')
2 |
3 | const fileBase = pathParse(__filename).base
4 |
5 | module.exports = {
6 | fileBase,
7 | // if fileBase is not the same as this module name, it was bundled
8 | isBundled: fileBase !== 'cjs-file-with-js-extension.js',
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simple-next-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/pages/fully-static.js:
--------------------------------------------------------------------------------
1 | // This is forcing this fixture to produce static html pages router
2 | // to not rely just on Next.js currently always handling default pages router 404.html page
3 | const FullyStatic = () => (
4 |
5 |
This page is not using getStaticProps()
6 |
7 | )
8 |
9 | export default FullyStatic
10 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/public/squirrel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/simple/public/squirrel.jpg
--------------------------------------------------------------------------------
/tests/fixtures/simple/static/prebuilt.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | hello static html NOT produced by Next.js
4 |
5 |
6 |
--------------------------------------------------------------------------------
/tests/fixtures/simple/static/words.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // This configuration only applies to the package manager root.
2 | /** @type {import("eslint").Linter.Config} */
3 | module.exports = {
4 | ignorePatterns: ['apps/**', 'packages/**'],
5 | extends: ['@repo/eslint-config/library.js'],
6 | parser: '@typescript-eslint/parser',
7 | parserOptions: {
8 | project: true,
9 | },
10 | }
11 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # Testing
9 | coverage
10 |
11 | # Turbo
12 | .turbo
13 |
14 | # Vercel
15 | .vercel
16 |
17 | # Build Outputs
18 | .next/
19 | out/
20 | build
21 | dist
22 |
23 |
24 | # Debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # Misc
30 | .DS_Store
31 | *.pem
32 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/.npmrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/turborepo-npm/.npmrc
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /** @type {import("eslint").Linter.Config} */
2 | module.exports = {
3 | root: true,
4 | extends: ['@repo/eslint-config/next.js'],
5 | parser: '@typescript-eslint/parser',
6 | parserOptions: {
7 | project: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/turborepo-npm/apps/docs/app/favicon.ico
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 | import type { Metadata } from 'next'
3 | import { Inter } from 'next/font/google'
4 |
5 | const inter = Inter({ subsets: ['latin'] })
6 |
7 | export const metadata: Metadata = {
8 | title: 'Create Turborepo',
9 | description: 'Generated by create turbo',
10 | }
11 |
12 | export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element {
13 | return (
14 |
15 | {children}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | module.exports = {
3 | transpilePackages: ['@repo/ui'],
4 | }
5 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/.env:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV="defined in .env"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/.env.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_LOCAL="defined in .env.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/.env.production:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION="defined in .env.production"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/.env.production.local:
--------------------------------------------------------------------------------
1 | FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL="defined in .env.production.local"
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "page-router",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build"
8 | },
9 | "dependencies": {
10 | "@netlify/functions": "^2.7.0",
11 | "@repo/ui": "*",
12 | "next": "latest",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0"
15 | },
16 | "devDependencies": {
17 | "@repo/typescript-config": "*",
18 | "@types/node": "^17.0.12",
19 | "@types/react": "^18.0.22",
20 | "@types/react-dom": "^18.0.7",
21 | "typescript": "^5.2.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/pages/api/env.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {import('next').NextApiRequest} _req
3 | * @param {import('next').NextApiResponse} res
4 | */
5 | export default async function handler(_req, res) {
6 | res.status(200).json({
7 | '.env': process.env.FROM_DOT_ENV ?? 'undefined',
8 | '.env.local': process.env.FROM_DOT_ENV_DOT_LOCAL ?? 'undefined',
9 | '.env.production': process.env.FROM_DOT_ENV_DOT_PRODUCTION ?? 'undefined',
10 | '.env.production.local': process.env.FROM_DOT_ENV_DOT_PRODUCTION_DOT_LOCAL ?? 'undefined',
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/pages/api/revalidate.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | await res.revalidate('/static/revalidate-manual')
4 | return res.json({ code: 200, message: 'success' })
5 | } catch (err) {
6 | return res.status(500).send({ code: 500, message: err.message })
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/pages/static/revalidate-manual.js:
--------------------------------------------------------------------------------
1 | const Show = ({ show, time }) => (
2 |
3 |
4 | This page uses getStaticProps() to pre-fetch a TV show at
5 | {time}
6 |
7 |
8 |
Show #{show.id}
9 |
{show.name}
10 |
11 | )
12 |
13 | export async function getStaticProps(context) {
14 | const res = await fetch(`https://tvproxy.netlify.app/shows/71`)
15 | const data = await res.json()
16 |
17 | return {
18 | props: {
19 | show: data,
20 | time: new Date().toISOString(),
21 | },
22 | }
23 | }
24 |
25 | export default Show
26 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/test.cjs:
--------------------------------------------------------------------------------
1 | console.log(require.resolve('styled-jsx'))
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/page-router/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /** @type {import("eslint").Linter.Config} */
2 | module.exports = {
3 | root: true,
4 | extends: ['@repo/eslint-config/next.js'],
5 | parser: '@typescript-eslint/parser',
6 | parserOptions: {
7 | project: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/turborepo-npm/apps/web/app/favicon.ico
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 | import type { Metadata } from 'next'
3 | import { Inter } from 'next/font/google'
4 |
5 | const inter = Inter({ subsets: ['latin'] })
6 |
7 | export const metadata: Metadata = {
8 | title: 'Create Turborepo',
9 | description: 'Generated by create turbo',
10 | }
11 |
12 | export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element {
13 | return (
14 |
15 | {children}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | module.exports = {
3 | transpilePackages: ['@repo/ui'],
4 | }
5 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/apps/web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turborepo-npm",
3 | "private": true,
4 | "scripts": {
5 | "postinstall": "turbo build",
6 | "build": "turbo build",
7 | "dev": "turbo dev",
8 | "lint": "turbo lint",
9 | "format": "prettier --write \"**/*.{ts,tsx,md}\""
10 | },
11 | "devDependencies": {
12 | "@repo/eslint-config": "*",
13 | "@repo/typescript-config": "*",
14 | "prettier": "^3.1.1",
15 | "turbo": "latest"
16 | },
17 | "engines": {
18 | "node": ">=18"
19 | },
20 | "packageManager": "npm@10.2.3",
21 | "workspaces": [
22 | "apps/*",
23 | "packages/*"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/eslint-config/README.md:
--------------------------------------------------------------------------------
1 | # `@turbo/eslint-config`
2 |
3 | Collection of internal eslint configurations.
4 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/eslint-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/eslint-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "library.js",
7 | "next.js",
8 | "react-internal.js"
9 | ],
10 | "devDependencies": {
11 | "@vercel/style-guide": "^5.1.0",
12 | "eslint-config-turbo": "^1.11.3",
13 | "eslint-config-prettier": "^9.1.0",
14 | "eslint-plugin-only-warn": "^1.1.0",
15 | "@typescript-eslint/parser": "^6.17.0",
16 | "@typescript-eslint/eslint-plugin": "^6.17.0",
17 | "typescript": "^5.3.3"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/typescript-config/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "esModuleInterop": true,
8 | "incremental": false,
9 | "isolatedModules": true,
10 | "lib": ["es2022", "DOM", "DOM.Iterable"],
11 | "module": "NodeNext",
12 | "moduleDetection": "force",
13 | "moduleResolution": "NodeNext",
14 | "noUncheckedIndexedAccess": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "target": "ES2022"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/typescript-config/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "plugins": [{ "name": "next" }],
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "allowJs": true,
10 | "jsx": "preserve",
11 | "noEmit": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/typescript-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/typescript-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "license": "MIT",
6 | "publishConfig": {
7 | "access": "public"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/typescript-config/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /** @type {import("eslint").Linter.Config} */
2 | module.exports = {
3 | root: true,
4 | extends: ['@repo/eslint-config/react-internal.js'],
5 | parser: '@typescript-eslint/parser',
6 | parserOptions: {
7 | project: './tsconfig.lint.json',
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/src/button.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { ReactNode } from 'react'
4 |
5 | interface ButtonProps {
6 | children: ReactNode
7 | className?: string
8 | appName: string
9 | }
10 |
11 | export const Button = ({ children, className, appName }: ButtonProps) => {
12 | return (
13 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/src/card.tsx:
--------------------------------------------------------------------------------
1 | export function Card({
2 | className,
3 | title,
4 | children,
5 | href,
6 | }: {
7 | className?: string
8 | title: string
9 | children: React.ReactNode
10 | href: string
11 | }): JSX.Element {
12 | return (
13 |
19 |
20 | {title} ->
21 |
22 | {children}
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/src/code.tsx:
--------------------------------------------------------------------------------
1 | export function Code({
2 | children,
3 | className,
4 | }: {
5 | children: React.ReactNode
6 | className?: string
7 | }): JSX.Element {
8 | return {children}
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/tsconfig.lint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src", "turbo"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "extends": ["//"],
4 | "tasks": {
5 | "build": {
6 | "outputs": ["dist/**"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/packages/ui/turbo/generators/templates/component.hbs:
--------------------------------------------------------------------------------
1 | export const
2 | {{pascalCase name}}
3 | = ({ children }: { children: React.ReactNode }) => { return (
4 |
5 |
{{pascalCase name}} Component
6 | {children}
7 |
8 | ); };
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/base.json"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo-npm/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "tasks": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "outputs": [".next/**", "!.next/cache/**"]
8 | },
9 | "lint": {
10 | "dependsOn": ["^lint"]
11 | },
12 | "dev": {
13 | "cache": false,
14 | "persistent": true
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # Local env files
9 | .env
10 | .env.local
11 | .env.development.local
12 | .env.test.local
13 | .env.production.local
14 |
15 | # Testing
16 | coverage
17 |
18 | # Turbo
19 | .turbo
20 |
21 | # Vercel
22 | .vercel
23 |
24 | # Build Outputs
25 | .next/
26 | out/
27 | build
28 | dist
29 |
30 |
31 | # Debug
32 | npm-debug.log*
33 | yarn-debug.log*
34 | yarn-error.log*
35 |
36 | # Misc
37 | .DS_Store
38 | *.pem
39 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/.npmrc:
--------------------------------------------------------------------------------
1 | public-hoist-pattern[]=*
2 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.workingDirectories": [
3 | {
4 | "mode": "auto"
5 | }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/turborepo/apps/docs/app/favicon.ico
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 | import type { Metadata } from 'next'
3 | import { Inter } from 'next/font/google'
4 |
5 | const inter = Inter({ subsets: ['latin'] })
6 |
7 | export const metadata: Metadata = {
8 | title: 'Create Turborepo',
9 | description: 'Generated by create turbo',
10 | }
11 |
12 | export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element {
13 | return (
14 |
15 | {children}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | module.exports = {
3 | eslint: {
4 | ignoreDuringBuilds: true,
5 | },
6 | transpilePackages: ['@repo/ui'],
7 | }
8 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev --port 3001",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "@repo/ui": "workspace:*",
12 | "next": "latest",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0"
15 | },
16 | "devDependencies": {
17 | "@repo/typescript-config": "workspace:*",
18 | "@types/node": "^17.0.12",
19 | "@types/react": "^18.0.22",
20 | "@types/react-dom": "^18.0.7",
21 | "typescript": "^5.2.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "page-router",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build"
8 | },
9 | "dependencies": {
10 | "@netlify/functions": "^2.7.0",
11 | "@repo/ui": "workspace:*",
12 | "next": "latest",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0"
15 | },
16 | "devDependencies": {
17 | "@repo/typescript-config": "workspace:*",
18 | "@types/node": "^17.0.12",
19 | "@types/react": "^18.0.22",
20 | "@types/react-dom": "^18.0.7",
21 | "typescript": "^5.2.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/src/pages/api/revalidate.js:
--------------------------------------------------------------------------------
1 | export default async function handler(req, res) {
2 | try {
3 | await res.revalidate('/static/revalidate-manual')
4 | return res.json({ code: 200, message: 'success' })
5 | } catch (err) {
6 | return res.status(500).send({ code: 500, message: err.message })
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/src/pages/static/revalidate-manual.js:
--------------------------------------------------------------------------------
1 | const Show = ({ show, time }) => (
2 |
3 |
4 | This page uses getStaticProps() to pre-fetch a TV show at
5 | {time}
6 |
7 |
8 |
Show #{show.id}
9 |
{show.name}
10 |
11 | )
12 |
13 | export async function getStaticProps(context) {
14 | const res = await fetch(`https://tvproxy.netlify.app/shows/71`)
15 | const data = await res.json()
16 |
17 | return {
18 | props: {
19 | show: data,
20 | time: new Date().toISOString(),
21 | },
22 | }
23 | }
24 |
25 | export default Show
26 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/page-router/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/turborepo/apps/web/app/favicon.ico
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 | import type { Metadata } from 'next'
3 | import { Inter } from 'next/font/google'
4 |
5 | const inter = Inter({ subsets: ['latin'] })
6 |
7 | export const metadata: Metadata = {
8 | title: 'Create Turborepo',
9 | description: 'Generated by create turbo',
10 | }
11 |
12 | export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element {
13 | return (
14 |
15 | {children}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | module.exports = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "web",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "@repo/ui": "workspace:*",
12 | "next": "latest",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0"
15 | },
16 | "devDependencies": {
17 | "@repo/typescript-config": "workspace:*",
18 | "@types/node": "^17.0.12",
19 | "@types/react": "^18.0.22",
20 | "@types/react-dom": "^18.0.7",
21 | "typescript": "^5.2.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/apps/web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "plugins": [
5 | {
6 | "name": "next"
7 | }
8 | ]
9 | },
10 | "include": ["next-env.d.ts", "next.config.js", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turborepo",
3 | "private": true,
4 | "scripts": {
5 | "postinstall": "turbo build",
6 | "build": "turbo build",
7 | "dev": "turbo dev"
8 | },
9 | "devDependencies": {
10 | "@repo/typescript-config": "workspace:*",
11 | "turbo": "latest"
12 | },
13 | "packageManager": "pnpm@8.9.0",
14 | "engines": {
15 | "node": ">=18"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/typescript-config/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "esModuleInterop": true,
8 | "incremental": false,
9 | "isolatedModules": true,
10 | "lib": ["es2022", "DOM", "DOM.Iterable"],
11 | "module": "NodeNext",
12 | "moduleDetection": "force",
13 | "moduleResolution": "NodeNext",
14 | "noUncheckedIndexedAccess": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "target": "ES2022"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/typescript-config/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "plugins": [{ "name": "next" }],
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "allowJs": true,
10 | "jsx": "preserve",
11 | "noEmit": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/typescript-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/typescript-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "license": "MIT",
6 | "publishConfig": {
7 | "access": "public"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/typescript-config/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./button": "./src/button.tsx",
7 | "./card": "./src/card.tsx",
8 | "./code": "./src/code.tsx"
9 | },
10 | "scripts": {
11 | "generate:component": "turbo gen react-component"
12 | },
13 | "devDependencies": {
14 | "@repo/typescript-config": "workspace:*",
15 | "@turbo/gen": "^1.10.12",
16 | "@types/node": "^20.5.2",
17 | "@types/react": "^18.2.0",
18 | "@types/react-dom": "^18.2.0",
19 | "react": "^18.2.0",
20 | "typescript": "^5.2.2"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/src/button.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { ReactNode } from 'react'
4 |
5 | interface ButtonProps {
6 | children: ReactNode
7 | className?: string
8 | appName: string
9 | }
10 |
11 | export const Button = ({ children, className, appName }: ButtonProps) => {
12 | return (
13 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/src/card.tsx:
--------------------------------------------------------------------------------
1 | export function Card({
2 | className,
3 | title,
4 | children,
5 | href,
6 | }: {
7 | className?: string
8 | title: string
9 | children: React.ReactNode
10 | href: string
11 | }): JSX.Element {
12 | return (
13 |
19 |
20 | {title} ->
21 |
22 | {children}
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/src/code.tsx:
--------------------------------------------------------------------------------
1 | export function Code({
2 | children,
3 | className,
4 | }: {
5 | children: React.ReactNode
6 | className?: string
7 | }): JSX.Element {
8 | return {children}
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/tsconfig.lint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src", "turbo"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "extends": ["//"],
4 | "tasks": {
5 | "build": {
6 | "outputs": ["dist/**"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/packages/ui/turbo/generators/templates/component.hbs:
--------------------------------------------------------------------------------
1 | import * as React from "react"; interface Props { children?: React.ReactNode; } export const
2 | {{pascalCase name}}
3 | = ({ children }: Props) => { return (
4 |
5 |
{{name}}
6 | {children}
7 |
8 | ); };
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'apps/*'
3 | - 'packages/*'
4 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/base.json"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/turborepo/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "tasks": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "outputs": [".next/**", "!.next/cache/**"]
8 | },
9 | "dev": {
10 | "cache": false,
11 | "persistent": true
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/fixtures/use-cache/app/api/revalidate/[...slug]/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidateTag } from 'next/cache'
2 | import { NextRequest } from 'next/server'
3 |
4 | export async function GET(request: NextRequest, { params }) {
5 | const { slug } = await params
6 |
7 | const tagToInvalidate = slug.join('/')
8 |
9 | revalidateTag(tagToInvalidate)
10 |
11 | return Response.json({ tagToInvalidate })
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/use-cache/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: 'Use cache App',
3 | description: 'Description for Use cache Next App',
4 | }
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tests/fixtures/use-cache/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tests/fixtures/use-cache/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "use-cache",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "next": "latest",
12 | "react": "18.2.0",
13 | "react-dom": "18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "19.1.2"
17 | },
18 | "test": {
19 | "dependencies": {
20 | "next": ">=15.3.0-canary.13"
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/fixtures/use-cache/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "noEmit": true,
9 | "incremental": true,
10 | "module": "esnext",
11 | "esModuleInterop": true,
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ]
21 | },
22 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
23 | "exclude": ["node_modules"]
24 | }
25 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "og-api",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@vercel/og": "latest",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/add.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/wasm-src/src/add.wasm
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/app/og-node/route.js:
--------------------------------------------------------------------------------
1 | import { ImageResponse } from '@vercel/og'
2 |
3 | export async function GET() {
4 | return new ImageResponse(hi
, {
5 | width: 1200,
6 | height: 630,
7 | })
8 | }
9 |
10 | export const dynamic = 'force-dynamic'
11 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/app/og/route.js:
--------------------------------------------------------------------------------
1 | import { ImageResponse } from '@vercel/og'
2 |
3 | export async function GET() {
4 | return new ImageResponse(hi
, {
5 | width: 1200,
6 | height: 630,
7 | })
8 | }
9 |
10 | export const runtime = 'edge'
11 |
12 | export const dynamic = 'force-dynamic'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/middleware.js:
--------------------------------------------------------------------------------
1 | import wasm from './add.wasm?module'
2 | const instance$ = WebAssembly.instantiate(wasm)
3 |
4 | async function increment(a) {
5 | const { instance } = await instance$
6 | return instance.exports.add_one(a)
7 | }
8 | export default async function middleware(request) {
9 | const input = Number(request.nextUrl.searchParams.get('input')) || 1
10 | const value = await increment(input)
11 | return new Response(null, { headers: { data: JSON.stringify({ input, value }) } })
12 | }
13 |
14 | export const config = {
15 | matcher: '/wasm',
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/pages/api/og-wrong-runtime.js:
--------------------------------------------------------------------------------
1 | // /pages/api/og.jsx
2 | import { ImageResponse } from '@vercel/og'
3 |
4 | export default function () {
5 | return new ImageResponse(
6 | (
7 |
18 | Hello!
19 |
20 | ),
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/pages/api/og.js:
--------------------------------------------------------------------------------
1 | // /pages/api/og.jsx
2 | import { ImageResponse } from '@vercel/og'
3 |
4 | export const config = {
5 | runtime: 'edge',
6 | }
7 |
8 | export default function () {
9 | return new ImageResponse(
10 | (
11 |
22 | Hello!
23 |
24 | ),
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm-src/src/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return hello world
3 | }
4 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/add.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/tests/fixtures/wasm/add.wasm
--------------------------------------------------------------------------------
/tests/fixtures/wasm/app/og-node/route.js:
--------------------------------------------------------------------------------
1 | import { ImageResponse } from '@vercel/og'
2 |
3 | export async function GET() {
4 | return new ImageResponse(hi
, {
5 | width: 1200,
6 | height: 630,
7 | })
8 | }
9 |
10 | export const dynamic = 'force-dynamic'
11 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/app/og/route.js:
--------------------------------------------------------------------------------
1 | import { ImageResponse } from '@vercel/og'
2 |
3 | export async function GET() {
4 | return new ImageResponse(hi
, {
5 | width: 1200,
6 | height: 630,
7 | })
8 | }
9 |
10 | export const runtime = 'edge'
11 |
12 | export const dynamic = 'force-dynamic'
13 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/middleware.js:
--------------------------------------------------------------------------------
1 | import wasm from './add.wasm?module'
2 | const instance$ = WebAssembly.instantiate(wasm)
3 |
4 | async function increment(a) {
5 | const { instance } = await instance$
6 | return instance.exports.add_one(a)
7 | }
8 | export default async function middleware(request) {
9 | const input = Number(request.nextUrl.searchParams.get('input')) || 1
10 | const value = await increment(input)
11 | return new Response(null, { headers: { data: JSON.stringify({ input, value }) } })
12 | }
13 |
14 | export const config = {
15 | matcher: '/wasm',
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "og-api",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "next build",
7 | "dev": "next dev",
8 | "build": "next build"
9 | },
10 | "dependencies": {
11 | "@vercel/og": "latest",
12 | "next": "latest",
13 | "react": "18.2.0",
14 | "react-dom": "18.2.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/pages/api/og-wrong-runtime.js:
--------------------------------------------------------------------------------
1 | // /pages/api/og.jsx
2 | import { ImageResponse } from '@vercel/og'
3 |
4 | export default function () {
5 | return new ImageResponse(
6 | (
7 |
18 | Hello!
19 |
20 | ),
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/pages/api/og.js:
--------------------------------------------------------------------------------
1 | // /pages/api/og.jsx
2 | import { ImageResponse } from '@vercel/og'
3 |
4 | export const config = {
5 | runtime: 'edge',
6 | }
7 |
8 | export default function () {
9 | return new ImageResponse(
10 | (
11 |
22 | Hello!
23 |
24 | ),
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/tests/fixtures/wasm/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return hello world
3 | }
4 |
--------------------------------------------------------------------------------
/tests/index.ts:
--------------------------------------------------------------------------------
1 | export * from './utils/index.js'
2 |
--------------------------------------------------------------------------------
/tests/netlify-e2e-legacy.json:
--------------------------------------------------------------------------------
1 | null
2 |
--------------------------------------------------------------------------------
/tests/netlify-e2e.cjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | const config = {
3 | version: 2,
4 | suites: {},
5 | rules: {
6 | include: ['test/e2e/**/*.test.{t,j}s{,x}'],
7 | /** @type {string[]} */
8 | exclude: [],
9 | },
10 | }
11 |
12 | const rules = require('./test-config.json')
13 |
14 | // Skip non-deploy tests
15 | config.rules.exclude.push(...rules.ignored)
16 |
17 | for (const rule of rules.skipped) {
18 | // Individually-skipped tests
19 | if (rule.tests?.length) {
20 | config.suites[rule.file] = {
21 | failed: rule.tests,
22 | }
23 | } else {
24 | // Entire suite skipped
25 | config.rules.exclude.push(rule.file)
26 | }
27 | }
28 |
29 | module.exports = config
30 |
--------------------------------------------------------------------------------
/tests/playwright-slack-conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "sendResults": "on-failure",
3 | "slackLogLevel": "debug",
4 | "sendUsingBot": {
5 | "channels": ["C020GQEKC13"]
6 | },
7 | "meta": [
8 | { "key": "version", "value": "__ENV_RESULTS_VERSION" },
9 | {
10 | "key": "results",
11 | "value": "__ENV_RESULTS_URL"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 | .yarn
8 |
9 | # Local env files
10 | .env
11 | .env.local
12 | .env.development.local
13 | .env.test.local
14 | .env.production.local
15 |
16 | # Testing
17 | coverage
18 |
19 | # Turbo
20 | .turbo
21 |
22 | # Vercel
23 | .vercel
24 |
25 | # Build Outputs
26 | .next/
27 | out/
28 | build
29 | dist
30 |
31 |
32 | # Debug
33 | npm-debug.log*
34 | yarn-debug.log*
35 | yarn-error.log*
36 |
37 | # Misc
38 | .DS_Store
39 | *.pem
40 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.0.3/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | eslint: {
4 | ignoreDuringBuilds: true,
5 | },
6 | }
7 |
8 | module.exports = nextConfig
9 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.0.3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-12.0.3",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "next": "12.0.3",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0"
12 | },
13 | "test": {
14 | "dependencies": {
15 | "next": "12.0.3"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.0.3/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Home({ ssr }) {
2 | return (
3 |
4 | SSR: {ssr ? 'yes' : 'no'}
5 |
6 | )
7 | }
8 |
9 | export const getServerSideProps = async () => {
10 | return {
11 | props: {
12 | ssr: true,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.1.0/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | eslint: {
4 | ignoreDuringBuilds: true,
5 | },
6 | }
7 |
8 | module.exports = nextConfig
9 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.1.0/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-12.1.0",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "next": "12.1.0",
10 | "react": "^17.0.2",
11 | "react-dom": "^17.0.2"
12 | },
13 | "test": {
14 | "dependencies": {
15 | "next": "12.1.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/next-12.1.0/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Home({ ssr }) {
2 | return (
3 |
4 | SSR: {ssr ? 'yes' : 'no'}
5 |
6 | )
7 | }
8 |
9 | export const getServerSideProps = async () => {
10 | return {
11 | props: {
12 | ssr: true,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/apps/site/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | base = ""
3 | command = "npm run build"
4 | publish = "apps/site/.next"
5 |
6 | [[plugins]]
7 | package = "@netlify/plugin-nextjs"
8 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "@packages/ui": "*",
10 | "next": "latest",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | import { TestElement } from '@packages/ui/test.jsx'
2 |
3 | export default function Home({ ssr }) {
4 | return (
5 |
6 | SSR: {ssr ? 'yes' : 'no'}
7 |
8 | )
9 | }
10 |
11 | export const getServerSideProps = async () => {
12 | return {
13 | props: {
14 | ssr: true,
15 | },
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-monorepo-empty-base",
3 | "private": true,
4 | "scripts": {
5 | "build": "cd apps/site && npm run build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "npm@10.2.3",
11 | "workspaces": [
12 | "apps/*",
13 | "packages/*"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@packages/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./test.jsx": "./src/test.jsx"
7 | },
8 | "devDependencies": {
9 | "react": "^18.2.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-empty-base/packages/ui/src/test.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const TestElement = ({ children, testid }) => {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/mock-download/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/mock-download/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "@packages/ui": "*",
10 | "next": "latest",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/mock-download/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | import { TestElement } from '@packages/ui/test.jsx'
2 |
3 | export default function Home({ ssr }) {
4 | return (
5 |
6 | SSR: {ssr ? 'yes' : 'no'}
7 |
8 | )
9 | }
10 |
11 | export const getServerSideProps = async () => {
12 | return {
13 | props: {
14 | ssr: true,
15 | },
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/mock-download/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@packages/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./test.jsx": "./src/test.jsx"
7 | },
8 | "devDependencies": {
9 | "react": "^18.2.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/mock-download/packages/ui/src/test.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const TestElement = ({ children, testid }) => {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "node setup-site.mjs && npm install && npm run build -w apps/site"
3 | publish = "./apps/site/.next"
4 |
5 | [[plugins]]
6 | package = "@netlify/plugin-nextjs"
7 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-monorepo-site-created-at-build",
3 | "private": true,
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "packageManager": "npm@10.2.3",
8 | "workspaces": [
9 | "apps/*",
10 | "packages/*"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/pre-deploy.mjs:
--------------------------------------------------------------------------------
1 | import { rm } from 'node:fs/promises'
2 |
3 | console.log('running pre-test.mjs')
4 | // ensure we don't have monorepo setup before starting deploy
5 | await rm('apps', { force: true, recursive: true })
6 | await rm('packages', { force: true, recursive: true })
7 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-monorepo-site-created-at-build/setup-site.mjs:
--------------------------------------------------------------------------------
1 | import { existsSync } from 'node:fs'
2 | import { cp, mkdir } from 'node:fs/promises'
3 |
4 | if (existsSync('apps/site')) {
5 | throw new Error('apps/site already exists. Run "node pre-test.mjs" to reset the test environment')
6 | }
7 |
8 | if (existsSync('packages/ui')) {
9 | throw new Error(
10 | 'packages/ui already exists. Run "node pre-test.mjs" to reset the test environment',
11 | )
12 | }
13 |
14 | await mkdir('apps', { recursive: true })
15 | await mkdir('packages', { recursive: true })
16 | await cp('mock-download/apps/', 'apps', { recursive: true })
17 | await cp('mock-download/packages/', 'packages', { recursive: true })
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-compatible/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-compatible/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-nested-site-multiple-next-version-site-compatible",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "next": "latest",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-compatible/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Home({ ssr }) {
2 | return (
3 |
4 | SSR: {ssr ? 'yes' : 'no'}
5 |
6 | )
7 | }
8 |
9 | export const getServerSideProps = async () => {
10 | return {
11 | props: {
12 | ssr: true,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-compatible/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "no-package-path-set",
3 | "private": true,
4 | "scripts": {
5 | "build": "cd apps/site && npm run build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "npm@10.2.3",
11 | "dependencies": {
12 | "next": "13.4.1"
13 | },
14 | "test": {
15 | "dependencies": {
16 | "next": "13.4.1"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-incompatible/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-incompatible/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "next": "13.4.1",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0"
12 | },
13 | "test": {
14 | "dependencies": {
15 | "next": "13.4.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-incompatible/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | export default function Home({ ssr }) {
2 | return (
3 |
4 | SSR: {ssr ? 'yes' : 'no'}
5 |
6 | )
7 | }
8 |
9 | export const getServerSideProps = async () => {
10 | return {
11 | props: {
12 | ssr: true,
13 | },
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/npm-nested-site-multiple-next-version-site-incompatible/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-nested-site-multiple-next-version-site-incompatible",
3 | "private": true,
4 | "scripts": {
5 | "build": "cd apps/site && npm run build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "npm@10.2.3",
11 | "dependencies": {
12 | "next": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "@packages/ui": "*",
10 | "next": "latest",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | import { TestElement } from '@packages/ui/test.jsx'
2 |
3 | export default function Home({ ssr }) {
4 | return (
5 |
6 | SSR: {ssr ? 'yes' : 'no'}
7 |
8 | )
9 | }
10 |
11 | export const getServerSideProps = async () => {
12 | return {
13 | props: {
14 | ssr: true,
15 | },
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yarn-monorepo-multiple-next-versions-site-compatible",
3 | "private": true,
4 | "scripts": {
5 | "build": "cd apps/site && npm run build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "yarn@1.22.21",
11 | "workspaces": [
12 | "apps/*",
13 | "packages/*"
14 | ],
15 | "dependencies": {
16 | "next": "13.4.1"
17 | },
18 | "test": {
19 | "dependencies": {
20 | "next": "13.4.1"
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@packages/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./test.jsx": "./src/test.jsx"
7 | },
8 | "devDependencies": {
9 | "react": "^18.2.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-compatible/packages/ui/src/test.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const TestElement = ({ children, testid }) => {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "@packages/ui": "*",
10 | "next": "13.4.1",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | },
14 | "test": {
15 | "dependencies": {
16 | "next": "13.4.1"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | import { TestElement } from '@packages/ui/test.jsx'
2 |
3 | export default function Home({ ssr }) {
4 | return (
5 |
6 | SSR: {ssr ? 'yes' : 'no'}
7 |
8 | )
9 | }
10 |
11 | export const getServerSideProps = async () => {
12 | return {
13 | props: {
14 | ssr: true,
15 | },
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yarn-monorepo-multiple-next-versions-site-incompatible",
3 | "private": true,
4 | "scripts": {
5 | "build": "cd apps/site && npm run build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "yarn@1.22.21",
11 | "workspaces": [
12 | "apps/*",
13 | "packages/*"
14 | ],
15 | "dependencies": {
16 | "next": "latest"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@packages/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./test.jsx": "./src/test.jsx"
7 | },
8 | "devDependencies": {
9 | "react": "^18.2.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-multiple-next-versions-site-incompatible/packages/ui/src/test.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const TestElement = ({ children, testid }) => {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: pnpm
2 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/apps/site/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'standalone',
4 | eslint: {
5 | ignoreDuringBuilds: true,
6 | },
7 | transpilePackages: ['@repo/ui'],
8 | }
9 |
10 | module.exports = nextConfig
11 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/apps/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@apps/site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build"
7 | },
8 | "dependencies": {
9 | "@packages/ui": "*",
10 | "next": "latest",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/apps/site/pages/index.js:
--------------------------------------------------------------------------------
1 | import { TestElement } from '@packages/ui/test.jsx'
2 |
3 | export default function Home({ ssr }) {
4 | return (
5 |
6 | SSR: {ssr ? 'yes' : 'no'}
7 |
8 | )
9 | }
10 |
11 | export const getServerSideProps = async () => {
12 | return {
13 | props: {
14 | ssr: true,
15 | },
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yarn-monorepo-with-pnpm-linker",
3 | "private": true,
4 | "scripts": {
5 | "build": "yarn workspace @apps/site build"
6 | },
7 | "engines": {
8 | "node": ">=18"
9 | },
10 | "packageManager": "yarn@3.2.4",
11 | "workspaces": [
12 | "apps/*",
13 | "packages/*"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@packages/ui",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./test.jsx": "./src/test.jsx"
7 | },
8 | "devDependencies": {
9 | "react": "^18.2.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/smoke/fixtures/yarn-monorepo-with-pnpm-linker/packages/ui/src/test.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const TestElement = ({ children, testid }) => {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tests/test-setup-e2e.ts:
--------------------------------------------------------------------------------
1 | import { execaCommand } from 'execa'
2 |
3 | // build the runtime before running tests
4 | export default async () => {
5 | console.log(`🔨 Building runtime...`, process.cwd())
6 | await execaCommand('npm run build')
7 | }
8 |
--------------------------------------------------------------------------------
/tests/test-setup.ts:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs'
2 | import { afterEach } from 'vitest'
3 | import { type FixtureTestContext } from './utils/contexts'
4 |
5 | export async function afterTestCleanup({ cleanup }: FixtureTestContext) {
6 | if ('reset' in fs) {
7 | ;(fs as any).reset()
8 | }
9 |
10 | const jobs = (cleanup ?? []).map((job) => job())
11 |
12 | await Promise.all(jobs)
13 | }
14 |
15 | // cleanup after each test as a fallback if someone forgot to call it
16 | afterEach(async (ctx) => {
17 | await afterTestCleanup(ctx)
18 | })
19 |
--------------------------------------------------------------------------------
/tests/utils/constants.mjs:
--------------------------------------------------------------------------------
1 | export const BLOB_TOKEN = 'secret-token'
2 |
--------------------------------------------------------------------------------
/tests/utils/contexts.ts:
--------------------------------------------------------------------------------
1 | import { type getStore } from '@netlify/blobs'
2 | import { BlobsServer } from '@netlify/blobs/server'
3 | import { type WriteStream } from 'node:fs'
4 | import { MockInstance, TestContext } from 'vitest'
5 |
6 | export interface FixtureTestContext extends TestContext {
7 | cwd: string
8 | siteID: string
9 | deployID: string
10 | blobStoreHost: string
11 | blobStorePort: number
12 | blobServer: BlobsServer
13 | blobServerGetSpy: MockInstance, ReturnType>
14 | blobStore: ReturnType
15 | functionDist: string
16 | edgeFunctionPort: number
17 | edgeFunctionOutput: WriteStream
18 | cleanup?: (() => Promise)[]
19 | }
20 |
--------------------------------------------------------------------------------
/tests/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './helpers.js'
2 | export * from './mock-file-system.js'
3 |
--------------------------------------------------------------------------------
/tools/vendor-deno-tools.js:
--------------------------------------------------------------------------------
1 | import { dirname, join } from 'node:path'
2 | import { fileURLToPath } from 'node:url'
3 |
4 | import { vendorDeno } from './build-helpers.js'
5 |
6 | const denoToolsDirectory = join(dirname(fileURLToPath(import.meta.url)), 'deno')
7 |
8 | await vendorDeno({
9 | vendorSource: join(denoToolsDirectory, 'eszip.ts'),
10 | cwd: denoToolsDirectory,
11 | wasmFilesToDownload: ['https://deno.land/x/eszip@v0.55.4/eszip_wasm_bg.wasm'],
12 | initEmptyDenoJson: true,
13 | })
14 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "resolveJsonModule": true,
7 | "outDir": "./dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "forceConsistentCasingInFileNames": true
12 | },
13 | "include": ["src/**/*"],
14 | "exclude": ["tests/**/*", "src/**/*.test.ts", "edge-runtime/**", "tests/netlify-deploy.ts"]
15 | }
16 |
--------------------------------------------------------------------------------
/turbofan/netlify.toml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-netlify/1f8ae92ac7110949ddbb49e943ffc56ac98d35bf/turbofan/netlify.toml
--------------------------------------------------------------------------------
/turbofan/netlify/edge-functions/turbofan.ts:
--------------------------------------------------------------------------------
1 | export { handleRequest as default } from 'https://deno.land/x/turbofan/mod.ts'
2 |
3 | export const config = {
4 | method: ['GET', 'PUT'],
5 | path: '/v8/artifacts/:hash',
6 | cache: 'manual',
7 | }
8 |
--------------------------------------------------------------------------------
/vitest.workspace.ts:
--------------------------------------------------------------------------------
1 | import { defineWorkspace } from 'vitest/config'
2 |
3 | export default defineWorkspace([
4 | {
5 | extends: './vitest.config.ts',
6 | test: {
7 | name: 'unit',
8 | include: ['src/**/*.test.ts'],
9 | },
10 | },
11 | {
12 | extends: './vitest.config.ts',
13 | test: {
14 | name: 'integration',
15 | include: ['tests/integration/**/*.test.ts'],
16 | },
17 | },
18 | {
19 | extends: './vitest.config.ts',
20 | test: {
21 | name: 'smoke',
22 | include: ['tests/smoke/**/*.test.ts'],
23 | },
24 | },
25 | ])
26 |
--------------------------------------------------------------------------------