[1]
diff --git a/plugin/test/fixtures/no-functions/README.md b/plugin/test/fixtures/no-functions/README.md
deleted file mode 100644
index c3f3061e..00000000
--- a/plugin/test/fixtures/no-functions/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
- Gatsby minimal starter
-
-
-## 🚀 Quick start
-
-1. **Create a Gatsby site.**
-
- Use the Gatsby CLI to create a new site, specifying the minimal starter.
-
- ```shell
- # create a new Gatsby site using the minimal starter
- npm init gatsby
- ```
-
-2. **Start developing.**
-
- Navigate into your new site’s directory and start it up.
-
- ```shell
- cd my-gatsby-site/
- npm run develop
- ```
-
-3. **Open the code and start customizing!**
-
- Your site is now running at http://localhost:8000!
-
- Edit `src/pages/index.js` to see your site update in real-time!
-
-4. **Learn more**
-
- - [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Tutorials](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Guides](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
-## 🚀 Quick start (Gatsby Cloud)
-
-Deploy this starter with one click on
-[Gatsby Cloud](https://www.gatsbyjs.com/cloud/):
-
-[ ](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-starter-minimal)
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.development b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.development
new file mode 100644
index 00000000..b72c5cd1
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.development
@@ -0,0 +1,4 @@
+pickle=word
+# @netlify/plugin-gatsby start
+GATSBY_PRECOMPILE_DEVELOP_FUNCTIONS=true
+# @netlify/plugin-gatsby end
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.production b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.production
new file mode 100644
index 00000000..72958bc0
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.env.production
@@ -0,0 +1 @@
+pickle=word
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/.gitignore b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.gitignore
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/.gitignore
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/.gitignore
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/.nvmrc b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/.nvmrc
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/.nvmrc
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/.nvmrc
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/functions.test.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/functions.test.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/functions.test.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/functions.test.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/test-helpers.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/test-helpers.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/test-helpers.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/e2e-tests/test-helpers.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/gatsby-config.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/gatsby-config.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/gatsby-config.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/gatsby-config.js
diff --git a/plugin/test/fixtures/with-no-plugins/netlify.toml b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/netlify.toml
similarity index 64%
rename from plugin/test/fixtures/with-no-plugins/netlify.toml
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/netlify.toml
index 7d3e889e..72865a74 100644
--- a/plugin/test/fixtures/with-no-plugins/netlify.toml
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/netlify.toml
@@ -3,4 +3,4 @@ command = "npm run build"
publish = "public/"
[[plugins]]
-package = "../../../src/index.ts"
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/package.json b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/package.json
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/package.json
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/package.json
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/function.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/function.js
new file mode 100644
index 00000000..537e4829
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/function.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am at a secondary-level`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/index.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/index.js
new file mode 100644
index 00000000..a646bc11
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/a-directory/index.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am an index.js in a sub-directory!`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cookie-me.ts b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cookie-me.ts
new file mode 100644
index 00000000..7f4664c9
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cookie-me.ts
@@ -0,0 +1,8 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ res.json(req.cookies)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cors.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cors.js
new file mode 100644
index 00000000..10dd8925
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/cors.js
@@ -0,0 +1,18 @@
+import Cors from 'cors'
+
+const cors = Cors()
+
+export default async function corsHandler(req, res) {
+ // Run Cors middleware and handle errors.
+ await new Promise((resolve, reject) => {
+ cors(req, res, (result) => {
+ if (result instanceof Error) {
+ reject(result)
+ }
+
+ resolve(result)
+ })
+ })
+
+ res.json(`Hi from Gatsby Functions`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/[...].js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/[...].js
new file mode 100644
index 00000000..e76f3038
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/[...].js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.json(req.params)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/function.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/function.js
new file mode 100644
index 00000000..b83f7110
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/dir/function.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am another sub-directory function`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/env-variables.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/env-variables.js
new file mode 100644
index 00000000..7d09b81f
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/env-variables.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(process.env.pickle)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/error-send-function-twice.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/error-send-function-twice.js
new file mode 100644
index 00000000..8e5b2582
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/error-send-function-twice.js
@@ -0,0 +1,4 @@
+export default function handler(req, res) {
+ res.send(`hi`)
+ res.json({ willCauseError: true })
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-ts.ts b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-ts.ts
new file mode 100644
index 00000000..37f90f86
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-ts.ts
@@ -0,0 +1,3 @@
+export default function handler(req, res) {
+ res.status(200).json({ hello: `world` })
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-world.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-world.js
new file mode 100644
index 00000000..37f90f86
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/hello-world.js
@@ -0,0 +1,3 @@
+export default function handler(req, res) {
+ res.status(200).json({ hello: `world` })
+}
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-false.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-false.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-false.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-false.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-json-too.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-json-too.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-json-too.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-json-too.js
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-json.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-json.js
new file mode 100644
index 00000000..ea5ffd15
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-json.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.json({ amIJSON: true })
+}
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-status.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-status.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-status.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-status.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-text.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-text.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/api/i-am-text.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-text.js
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-typescript.ts b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-typescript.ts
new file mode 100644
index 00000000..24b16d2a
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/i-am-typescript.ts
@@ -0,0 +1,10 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ if (req.method === `GET`) {
+ res.send(`I am typescript`)
+ }
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/parser.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/parser.js
new file mode 100644
index 00000000..66e2b10f
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/parser.js
@@ -0,0 +1,13 @@
+export default function topLevel(req, res) {
+ if (req.query && Object.keys(req.query).length !== 0) {
+ res.json(req.query)
+ } else if (req.files && req.files.length !== 0) {
+ res.json({ files: req.files, body: req.body })
+ } else if (req.body) {
+ res.json(req.body)
+ } else {
+ res.json({
+ message: `No body was sent. Try a POST request or query string`,
+ })
+ }
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/redirect-me.ts b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/redirect-me.ts
new file mode 100644
index 00000000..b141f7ab
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/redirect-me.ts
@@ -0,0 +1,8 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ res.redirect(`/`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some whitespace.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some whitespace.js
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some whitespace.js
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git "a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js" "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git "a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js" "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/status.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/status.js
new file mode 100644
index 00000000..edbe1f9f
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/status.js
@@ -0,0 +1,4 @@
+export default function topLevel(req, res) {
+ const status = req.query.code ? req.query.code : 200
+ res.status(status).send(`I am at the top-level`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/top-level.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/top-level.js
new file mode 100644
index 00000000..56d7d954
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/top-level.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am at the top-level`)
+}
diff --git a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js
new file mode 100644
index 00000000..583a404a
--- /dev/null
+++ b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js
@@ -0,0 +1,3 @@
+export default function userIdHandler(req, res) {
+ res.json(req.params)
+}
diff --git "a/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js" "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/no-functions/src/images/icon.png b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/images/icon.png
similarity index 100%
rename from plugin/test/fixtures/no-functions/src/images/icon.png
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/images/icon.png
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/pages/404.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/pages/404.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/pages/404.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/pages/404.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/src/pages/index.js b/plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/pages/index.js
similarity index 100%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/src/pages/index.js
rename to plugin/test/fixtures/v4/functions-without-gatsby-plugin/src/pages/index.js
diff --git a/plugin/test/fixtures/no-functions/.gitignore b/plugin/test/fixtures/v4/no-functions/.gitignore
similarity index 100%
rename from plugin/test/fixtures/no-functions/.gitignore
rename to plugin/test/fixtures/v4/no-functions/.gitignore
diff --git a/plugin/test/fixtures/no-functions/LICENSE b/plugin/test/fixtures/v4/no-functions/LICENSE
similarity index 100%
rename from plugin/test/fixtures/no-functions/LICENSE
rename to plugin/test/fixtures/v4/no-functions/LICENSE
diff --git a/plugin/test/fixtures/no-functions/e2e-tests/build.test.js b/plugin/test/fixtures/v4/no-functions/e2e-tests/build.test.js
similarity index 82%
rename from plugin/test/fixtures/no-functions/e2e-tests/build.test.js
rename to plugin/test/fixtures/v4/no-functions/e2e-tests/build.test.js
index edc89d44..55657bac 100644
--- a/plugin/test/fixtures/no-functions/e2e-tests/build.test.js
+++ b/plugin/test/fixtures/v4/no-functions/e2e-tests/build.test.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line node/no-unpublished-require
-const { buildSite } = require('../../../helpers')
+const { buildSite } = require('../../../../helpers')
jest.setTimeout(120_000)
describe('A site with no functions', () => {
diff --git a/plugin/test/fixtures/no-functions/gatsby-config.js b/plugin/test/fixtures/v4/no-functions/gatsby-config.js
similarity index 100%
rename from plugin/test/fixtures/no-functions/gatsby-config.js
rename to plugin/test/fixtures/v4/no-functions/gatsby-config.js
diff --git a/plugin/test/fixtures/functions-without-gatsby-plugin/netlify.toml b/plugin/test/fixtures/v4/no-functions/netlify.toml
similarity index 64%
rename from plugin/test/fixtures/functions-without-gatsby-plugin/netlify.toml
rename to plugin/test/fixtures/v4/no-functions/netlify.toml
index 7d3e889e..72865a74 100644
--- a/plugin/test/fixtures/functions-without-gatsby-plugin/netlify.toml
+++ b/plugin/test/fixtures/v4/no-functions/netlify.toml
@@ -3,4 +3,4 @@ command = "npm run build"
publish = "public/"
[[plugins]]
-package = "../../../src/index.ts"
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/no-functions/package.json b/plugin/test/fixtures/v4/no-functions/package.json
similarity index 95%
rename from plugin/test/fixtures/no-functions/package.json
rename to plugin/test/fixtures/v4/no-functions/package.json
index d8aa5237..2204b5c6 100644
--- a/plugin/test/fixtures/no-functions/package.json
+++ b/plugin/test/fixtures/v4/no-functions/package.json
@@ -17,7 +17,7 @@
},
"license": "0BSD",
"dependencies": {
- "gatsby": "next",
+ "gatsby": "^4.9.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/src/images/icon.png b/plugin/test/fixtures/v4/no-functions/src/images/icon.png
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/src/images/icon.png
rename to plugin/test/fixtures/v4/no-functions/src/images/icon.png
diff --git a/plugin/test/fixtures/no-functions/src/pages/404.js b/plugin/test/fixtures/v4/no-functions/src/pages/404.js
similarity index 100%
rename from plugin/test/fixtures/no-functions/src/pages/404.js
rename to plugin/test/fixtures/v4/no-functions/src/pages/404.js
diff --git a/plugin/test/fixtures/no-functions/src/pages/index.js b/plugin/test/fixtures/v4/no-functions/src/pages/index.js
similarity index 100%
rename from plugin/test/fixtures/no-functions/src/pages/index.js
rename to plugin/test/fixtures/v4/no-functions/src/pages/index.js
diff --git a/plugin/test/fixtures/with-no-gatsby-config/.gitignore b/plugin/test/fixtures/v4/with-no-gatsby-config/.gitignore
similarity index 100%
rename from plugin/test/fixtures/with-no-gatsby-config/.gitignore
rename to plugin/test/fixtures/v4/with-no-gatsby-config/.gitignore
diff --git a/plugin/test/fixtures/with-no-gatsby-config/LICENSE b/plugin/test/fixtures/v4/with-no-gatsby-config/LICENSE
similarity index 100%
rename from plugin/test/fixtures/with-no-gatsby-config/LICENSE
rename to plugin/test/fixtures/v4/with-no-gatsby-config/LICENSE
diff --git a/plugin/test/fixtures/with-no-gatsby-config/e2e-tests/build.test.js b/plugin/test/fixtures/v4/with-no-gatsby-config/e2e-tests/build.test.js
similarity index 82%
rename from plugin/test/fixtures/with-no-gatsby-config/e2e-tests/build.test.js
rename to plugin/test/fixtures/v4/with-no-gatsby-config/e2e-tests/build.test.js
index d968190e..7481fac9 100644
--- a/plugin/test/fixtures/with-no-gatsby-config/e2e-tests/build.test.js
+++ b/plugin/test/fixtures/v4/with-no-gatsby-config/e2e-tests/build.test.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line node/no-unpublished-require
-const { buildSite } = require('../../../helpers')
+const { buildSite } = require('../../../../helpers')
jest.setTimeout(120_000)
describe('A site with no Gatsby config', () => {
diff --git a/plugin/test/fixtures/no-functions/netlify.toml b/plugin/test/fixtures/v4/with-no-gatsby-config/netlify.toml
similarity index 64%
rename from plugin/test/fixtures/no-functions/netlify.toml
rename to plugin/test/fixtures/v4/with-no-gatsby-config/netlify.toml
index 7d3e889e..72865a74 100644
--- a/plugin/test/fixtures/no-functions/netlify.toml
+++ b/plugin/test/fixtures/v4/with-no-gatsby-config/netlify.toml
@@ -3,4 +3,4 @@ command = "npm run build"
publish = "public/"
[[plugins]]
-package = "../../../src/index.ts"
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/with-no-gatsby-config/package.json b/plugin/test/fixtures/v4/with-no-gatsby-config/package.json
similarity index 95%
rename from plugin/test/fixtures/with-no-gatsby-config/package.json
rename to plugin/test/fixtures/v4/with-no-gatsby-config/package.json
index a0efc234..0f42be3e 100644
--- a/plugin/test/fixtures/with-no-gatsby-config/package.json
+++ b/plugin/test/fixtures/v4/with-no-gatsby-config/package.json
@@ -17,7 +17,7 @@
},
"license": "0BSD",
"dependencies": {
- "gatsby": "next",
+ "gatsby": "^4.9.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
diff --git a/plugin/test/fixtures/with-no-gatsby-config/src/pages/404.js b/plugin/test/fixtures/v4/with-no-gatsby-config/src/pages/404.js
similarity index 100%
rename from plugin/test/fixtures/with-no-gatsby-config/src/pages/404.js
rename to plugin/test/fixtures/v4/with-no-gatsby-config/src/pages/404.js
diff --git a/plugin/test/fixtures/with-no-gatsby-config/src/pages/index.js b/plugin/test/fixtures/v4/with-no-gatsby-config/src/pages/index.js
similarity index 100%
rename from plugin/test/fixtures/with-no-gatsby-config/src/pages/index.js
rename to plugin/test/fixtures/v4/with-no-gatsby-config/src/pages/index.js
diff --git a/plugin/test/fixtures/with-no-plugins/.gitignore b/plugin/test/fixtures/v4/with-no-plugins/.gitignore
similarity index 100%
rename from plugin/test/fixtures/with-no-plugins/.gitignore
rename to plugin/test/fixtures/v4/with-no-plugins/.gitignore
diff --git a/plugin/test/fixtures/with-no-plugins/LICENSE b/plugin/test/fixtures/v4/with-no-plugins/LICENSE
similarity index 100%
rename from plugin/test/fixtures/with-no-plugins/LICENSE
rename to plugin/test/fixtures/v4/with-no-plugins/LICENSE
diff --git a/plugin/test/fixtures/with-no-plugins/e2e-tests/build.test.js b/plugin/test/fixtures/v4/with-no-plugins/e2e-tests/build.test.js
similarity index 82%
rename from plugin/test/fixtures/with-no-plugins/e2e-tests/build.test.js
rename to plugin/test/fixtures/v4/with-no-plugins/e2e-tests/build.test.js
index bbafe9f7..80a7640f 100644
--- a/plugin/test/fixtures/with-no-plugins/e2e-tests/build.test.js
+++ b/plugin/test/fixtures/v4/with-no-plugins/e2e-tests/build.test.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line node/no-unpublished-require
-const { buildSite } = require('../../../helpers')
+const { buildSite } = require('../../../../helpers')
jest.setTimeout(120_000)
describe('A site with no plugins', () => {
diff --git a/plugin/test/fixtures/with-no-plugins/gatsby-config.js b/plugin/test/fixtures/v4/with-no-plugins/gatsby-config.js
similarity index 100%
rename from plugin/test/fixtures/with-no-plugins/gatsby-config.js
rename to plugin/test/fixtures/v4/with-no-plugins/gatsby-config.js
diff --git a/plugin/test/fixtures/with-no-gatsby-config/netlify.toml b/plugin/test/fixtures/v4/with-no-plugins/netlify.toml
similarity index 64%
rename from plugin/test/fixtures/with-no-gatsby-config/netlify.toml
rename to plugin/test/fixtures/v4/with-no-plugins/netlify.toml
index 7d3e889e..72865a74 100644
--- a/plugin/test/fixtures/with-no-gatsby-config/netlify.toml
+++ b/plugin/test/fixtures/v4/with-no-plugins/netlify.toml
@@ -3,4 +3,4 @@ command = "npm run build"
publish = "public/"
[[plugins]]
-package = "../../../src/index.ts"
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/with-no-plugins/package.json b/plugin/test/fixtures/v4/with-no-plugins/package.json
similarity index 95%
rename from plugin/test/fixtures/with-no-plugins/package.json
rename to plugin/test/fixtures/v4/with-no-plugins/package.json
index 3b23f0ac..1ee943d1 100644
--- a/plugin/test/fixtures/with-no-plugins/package.json
+++ b/plugin/test/fixtures/v4/with-no-plugins/package.json
@@ -17,7 +17,7 @@
},
"license": "0BSD",
"dependencies": {
- "gatsby": "next",
+ "gatsby": "^4.9.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
diff --git a/plugin/test/fixtures/with-no-plugins/src/pages/404.js b/plugin/test/fixtures/v4/with-no-plugins/src/pages/404.js
similarity index 100%
rename from plugin/test/fixtures/with-no-plugins/src/pages/404.js
rename to plugin/test/fixtures/v4/with-no-plugins/src/pages/404.js
diff --git a/plugin/test/fixtures/with-no-plugins/src/pages/index.js b/plugin/test/fixtures/v4/with-no-plugins/src/pages/index.js
similarity index 100%
rename from plugin/test/fixtures/with-no-plugins/src/pages/index.js
rename to plugin/test/fixtures/v4/with-no-plugins/src/pages/index.js
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/.gitignore b/plugin/test/fixtures/v4/with-old-gatsby-plugin/.gitignore
similarity index 100%
rename from plugin/test/fixtures/with-old-gatsby-plugin/.gitignore
rename to plugin/test/fixtures/v4/with-old-gatsby-plugin/.gitignore
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/LICENSE b/plugin/test/fixtures/v4/with-old-gatsby-plugin/LICENSE
similarity index 100%
rename from plugin/test/fixtures/with-old-gatsby-plugin/LICENSE
rename to plugin/test/fixtures/v4/with-old-gatsby-plugin/LICENSE
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/e2e-tests/build.test.js b/plugin/test/fixtures/v4/with-old-gatsby-plugin/e2e-tests/build.test.js
similarity index 88%
rename from plugin/test/fixtures/with-old-gatsby-plugin/e2e-tests/build.test.js
rename to plugin/test/fixtures/v4/with-old-gatsby-plugin/e2e-tests/build.test.js
index 4357ab55..957efe82 100644
--- a/plugin/test/fixtures/with-old-gatsby-plugin/e2e-tests/build.test.js
+++ b/plugin/test/fixtures/v4/with-old-gatsby-plugin/e2e-tests/build.test.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line node/no-unpublished-require
-const { buildSite } = require('../../../helpers')
+const { buildSite } = require('../../../../helpers')
jest.setTimeout(120_000)
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/gatsby-config.js b/plugin/test/fixtures/v4/with-old-gatsby-plugin/gatsby-config.js
similarity index 100%
rename from plugin/test/fixtures/with-old-gatsby-plugin/gatsby-config.js
rename to plugin/test/fixtures/v4/with-old-gatsby-plugin/gatsby-config.js
diff --git a/plugin/test/fixtures/v4/with-old-gatsby-plugin/netlify.toml b/plugin/test/fixtures/v4/with-old-gatsby-plugin/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v4/with-old-gatsby-plugin/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/package.json b/plugin/test/fixtures/v4/with-old-gatsby-plugin/package.json
similarity index 96%
rename from plugin/test/fixtures/with-old-gatsby-plugin/package.json
rename to plugin/test/fixtures/v4/with-old-gatsby-plugin/package.json
index 5743b8df..e8fc4f48 100644
--- a/plugin/test/fixtures/with-old-gatsby-plugin/package.json
+++ b/plugin/test/fixtures/v4/with-old-gatsby-plugin/package.json
@@ -17,7 +17,7 @@
},
"license": "0BSD",
"dependencies": {
- "gatsby": "next",
+ "gatsby": "^4.9.0",
"gatsby-plugin-netlify-cache": "^1.2.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/.gitignore b/plugin/test/fixtures/v4/with-old-netlify-plugin/.gitignore
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/.gitignore
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/.gitignore
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/LICENSE b/plugin/test/fixtures/v4/with-old-netlify-plugin/LICENSE
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/LICENSE
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/LICENSE
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/e2e-tests/build.test.js b/plugin/test/fixtures/v4/with-old-netlify-plugin/e2e-tests/build.test.js
similarity index 88%
rename from plugin/test/fixtures/with-old-netlify-plugin/e2e-tests/build.test.js
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/e2e-tests/build.test.js
index edb87eb4..936987f1 100644
--- a/plugin/test/fixtures/with-old-netlify-plugin/e2e-tests/build.test.js
+++ b/plugin/test/fixtures/v4/with-old-netlify-plugin/e2e-tests/build.test.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line node/no-unpublished-require
-const { buildSite } = require('../../../helpers')
+const { buildSite } = require('../../../../helpers')
jest.setTimeout(120_000)
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/gatsby-config.js b/plugin/test/fixtures/v4/with-old-netlify-plugin/gatsby-config.js
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/gatsby-config.js
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/gatsby-config.js
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/netlify.toml b/plugin/test/fixtures/v4/with-old-netlify-plugin/netlify.toml
similarity index 76%
rename from plugin/test/fixtures/with-old-netlify-plugin/netlify.toml
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/netlify.toml
index 864951ca..b68939a6 100644
--- a/plugin/test/fixtures/with-old-netlify-plugin/netlify.toml
+++ b/plugin/test/fixtures/v4/with-old-netlify-plugin/netlify.toml
@@ -3,7 +3,7 @@ command = "npm run build"
publish = "public/"
[[plugins]]
-package = "../../../src/index.ts"
+package = "../../../../src/index.ts"
[[plugins]]
package = 'netlify-plugin-gatsby-cache'
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/package.json b/plugin/test/fixtures/v4/with-old-netlify-plugin/package.json
similarity index 96%
rename from plugin/test/fixtures/with-old-netlify-plugin/package.json
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/package.json
index bc326e12..5c5cf171 100644
--- a/plugin/test/fixtures/with-old-netlify-plugin/package.json
+++ b/plugin/test/fixtures/v4/with-old-netlify-plugin/package.json
@@ -17,7 +17,7 @@
},
"license": "0BSD",
"dependencies": {
- "gatsby": "next",
+ "gatsby": "^4.9.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
diff --git a/plugin/test/fixtures/v4/with-old-netlify-plugin/src/images/icon.png b/plugin/test/fixtures/v4/with-old-netlify-plugin/src/images/icon.png
new file mode 100644
index 00000000..38b2fb0e
Binary files /dev/null and b/plugin/test/fixtures/v4/with-old-netlify-plugin/src/images/icon.png differ
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/src/pages/404.js b/plugin/test/fixtures/v4/with-old-netlify-plugin/src/pages/404.js
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/src/pages/404.js
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/src/pages/404.js
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/src/pages/index.js b/plugin/test/fixtures/v4/with-old-netlify-plugin/src/pages/index.js
similarity index 100%
rename from plugin/test/fixtures/with-old-netlify-plugin/src/pages/index.js
rename to plugin/test/fixtures/v4/with-old-netlify-plugin/src/pages/index.js
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.development b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.development
new file mode 100644
index 00000000..b72c5cd1
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.development
@@ -0,0 +1,4 @@
+pickle=word
+# @netlify/plugin-gatsby start
+GATSBY_PRECOMPILE_DEVELOP_FUNCTIONS=true
+# @netlify/plugin-gatsby end
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.production b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.production
new file mode 100644
index 00000000..72958bc0
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.env.production
@@ -0,0 +1 @@
+pickle=word
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.gitignore b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.gitignore
new file mode 100644
index 00000000..459af46a
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.gitignore
@@ -0,0 +1,14 @@
+node_modules/
+.cache/
+public
+
+# Local Netlify folder
+.netlify
+netlify/functions/gatsby/functions
+deployment.json
+
+# @netlify/plugin-gatsby ignores start
+netlify/functions/gatsby
+# @netlify/plugin-gatsby ignores end
+
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.nvmrc b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.nvmrc
new file mode 100644
index 00000000..cab13a79
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/.nvmrc
@@ -0,0 +1 @@
+v14.17.0
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap
new file mode 100644
index 00000000..e7d04fe5
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/__snapshots__/functions.test.js.snap
@@ -0,0 +1,49 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Local functions can parse different ways of sending data file in multipart/form 1`] = `
+Object {
+ "body": Object {
+ "something": "here",
+ },
+ "files": Array [
+ Object {
+ "buffer": Object {
+ "data": Array [
+ 104,
+ 105,
+ ],
+ "type": "Buffer",
+ },
+ "encoding": "7bit",
+ "fieldname": "file",
+ "mimetype": "text/plain",
+ "originalname": "test.txt",
+ "size": 2,
+ },
+ ],
+}
+`;
+
+exports[`Local routing dynamic routes 1`] = `
+Object {
+ "super": "additional",
+ "userId": "23",
+}
+`;
+
+exports[`Local routing dynamic routes 2`] = `
+Object {
+ "*": "super",
+ "0": "super",
+}
+`;
+
+exports[`Local routing routes with special characters 1`] = `"I-Am-Capitalized.js"`;
+
+exports[`Local routing routes with special characters 2`] = `"some whitespace.js"`;
+
+exports[`Local routing routes with special characters 3`] = `"with-äöü-umlaut.js"`;
+
+exports[`Local routing routes with special characters 4`] = `"some-àè-french.js"`;
+
+exports[`Local routing routes with special characters 5`] = `"some-אודות.js"`;
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt
new file mode 100644
index 00000000..32f95c0d
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/fixtures/test.txt
@@ -0,0 +1 @@
+hi
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/functions.test.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/functions.test.js
new file mode 100644
index 00000000..4f0112b3
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/functions.test.js
@@ -0,0 +1,8 @@
+const { runTests } = require('./test-helpers')
+
+if (process.env.TEST_ENV === 'netlify') {
+ const { deploy_url } = require('../deployment.json')
+ runTests('Netlify', deploy_url)
+} else {
+ runTests('Local', 'http://localhost:8888')
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/test-helpers.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/test-helpers.js
new file mode 100644
index 00000000..f4a7d3d4
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/e2e-tests/test-helpers.js
@@ -0,0 +1,275 @@
+/* eslint-disable no-unused-vars */
+const fetch = require(`node-fetch`)
+const { readFileSync } = require('fs')
+const path = require('path')
+
+const FormData = require('form-data')
+// Based on Gatsby Functions integration tests
+// Source: https://github.com/gatsbyjs/gatsby/blob/master/integration-tests/functions/test-helpers.js
+
+exports.runTests = function runTests(env, host) {
+ jest.setTimeout(10_000)
+
+ async function fetchTwice(url, options) {
+ const result = await fetch(url, options)
+ if (!result.headers.has('x-forwarded-host')) {
+ return result
+ }
+ return fetch(url, options)
+ }
+
+ describe(env, () => {
+ describe(`routing`, () => {
+ test(`top-level API`, async () => {
+ const result = await fetchTwice(`${host}/api/top-level`).then((res) =>
+ res.text(),
+ )
+
+ expect(result).toEqual('I am at the top-level')
+ })
+ test(`secondary-level API`, async () => {
+ const result = await fetchTwice(
+ `${host}/api/a-directory/function`,
+ ).then((res) => res.text())
+
+ expect(result).toEqual('I am at a secondary-level')
+ })
+ test(`secondary-level API with index.js`, async () => {
+ const result = await fetchTwice(`${host}/api/a-directory`).then((res) =>
+ res.text(),
+ )
+
+ expect(result).toEqual('I am an index.js in a sub-directory!')
+ })
+ test(`secondary-level API`, async () => {
+ const result = await fetchTwice(`${host}/api/dir/function`).then(
+ (res) => res.text(),
+ )
+
+ expect(result).toEqual('I am another sub-directory function')
+ })
+ test(`routes with special characters`, async () => {
+ const routes = [
+ `${host}/api/I-Am-Capitalized`,
+ `${host}/api/some whitespace`,
+ `${host}/api/with-äöü-umlaut`,
+ `${host}/api/some-àè-french`,
+ encodeURI(`${host}/api/some-אודות`),
+ ]
+
+ for (const route of routes) {
+ const result = await fetchTwice(route).then((res) => res.text())
+
+ expect(result).toMatchSnapshot()
+ }
+ })
+
+ test(`dynamic routes`, async () => {
+ const routes = [
+ `${host}/api/users/23/additional`,
+ `${host}/api/dir/super`,
+ ]
+
+ for (const route of routes) {
+ const result = await fetchTwice(route).then((res) => res.json())
+
+ expect(result).toMatchSnapshot()
+ }
+ })
+ })
+
+ describe(`environment variables`, () => {
+ test(`can use inside functions`, async () => {
+ const result = await fetchTwice(`${host}/api/env-variables`).then(
+ (res) => res.text(),
+ )
+
+ expect(result).toEqual(`word`)
+ })
+ })
+
+ describe(`typescript`, () => {
+ test(`typescript functions work`, async () => {
+ const result = await fetchTwice(`${host}/api/i-am-typescript`).then(
+ (res) => res.text(),
+ )
+
+ expect(result).toEqual('I am typescript')
+ })
+ })
+
+ describe(`function errors don't crash the server`, () => {
+ // This test mainly just shows that the server doesn't crash.
+ test(`normal`, async () => {
+ const result = await fetchTwice(`${host}/api/error-send-function-twice`)
+
+ expect(result.status).toEqual(200)
+ })
+ })
+
+ describe(`response formats`, () => {
+ test(`returns json correctly`, async () => {
+ const res = await fetchTwice(`${host}/api/i-am-json`)
+ const result = await res.json()
+
+ expect(result).toEqual({
+ amIJSON: true,
+ })
+ expect(res.headers.get('content-type')).toEqual('application/json')
+ })
+ test(`returns json correctly via send`, async () => {
+ const res = await fetchTwice(`${host}/api/i-am-json-too`)
+ const result = await res.json()
+
+ expect(result).toEqual({
+ amIJSON: true,
+ })
+ expect(res.headers.get('content-type')).toEqual('application/json')
+ })
+ test(`returns boolean correctly via send`, async () => {
+ const res = await fetchTwice(`${host}/api/i-am-false`)
+ const result = await res.json()
+
+ expect(result).toEqual(false)
+ expect(res.headers.get('content-type')).toEqual('application/json')
+ })
+ test(`returns status correctly via send`, async () => {
+ const res = await fetchTwice(`${host}/api/i-am-status`)
+ const result = await res.text()
+
+ expect(result).toEqual('OK')
+ expect(res.headers.get('content-type')).toEqual(
+ 'text/plain; charset=utf-8',
+ )
+ })
+ test(`returns text correctly`, async () => {
+ const res = await fetchTwice(`${host}/api/i-am-text`)
+ const result = await res.text()
+
+ expect(result).toEqual('I am text')
+ expect(res.headers.get('content-type')).toEqual(
+ 'text/html; charset=utf-8',
+ )
+ })
+ })
+
+ describe(`functions can send custom statuses`, () => {
+ test(`can return 200 status`, async () => {
+ const res = await fetchTwice(`${host}/api/status`)
+
+ expect(res.status).toEqual(200)
+ })
+
+ test(`can return 404 status`, async () => {
+ const res = await fetchTwice(`${host}/api/status?code=404`)
+
+ expect(res.status).toEqual(404)
+ })
+
+ test(`can return 500 status`, async () => {
+ const res = await fetchTwice(`${host}/api/status?code=500`)
+
+ expect(res.status).toEqual(500)
+ })
+ })
+
+ describe(`functions can parse different ways of sending data`, () => {
+ test(`query string`, async () => {
+ const result = await fetchTwice(`${host}/api/parser?amIReal=true`).then(
+ (res) => res.json(),
+ )
+
+ expect(result).toEqual({
+ amIReal: 'true',
+ })
+ })
+
+ test(`form parameters`, async () => {
+ const { URLSearchParams } = require('url')
+ const params = new URLSearchParams()
+ params.append('a', `form parameters`)
+ const result = await fetchTwice(`${host}/api/parser`, {
+ method: `POST`,
+ body: params,
+ }).then((res) => res.json())
+
+ expect(result).toEqual({
+ a: 'form parameters',
+ })
+ })
+
+ test(`form data`, async () => {
+ const form = new FormData()
+ form.append('a', `form-data`)
+ const result = await fetchTwice(`${host}/api/parser`, {
+ method: `POST`,
+ body: form,
+ }).then((res) => res.json())
+
+ expect(result).toEqual({
+ a: 'form-data',
+ })
+ })
+
+ test(`json body`, async () => {
+ const body = { a: `json` }
+ const result = await fetchTwice(`${host}/api/parser`, {
+ method: `POST`,
+ body: JSON.stringify(body),
+ headers: { 'Content-Type': 'application/json' },
+ }).then((res) => res.json())
+
+ expect(result).toEqual({
+ a: 'json',
+ })
+ })
+
+ it(`file in multipart/form`, async () => {
+ const file = readFileSync(path.join(__dirname, './fixtures/test.txt'))
+
+ const form = new FormData()
+ form.append('file', file, {
+ filename: 'test.txt',
+ contentType: 'text/plain',
+ })
+ form.append('something', 'here')
+ const result = await fetchTwice(`${host}/api/parser`, {
+ method: `POST`,
+ body: form,
+ headers: form.getHeaders(),
+ }).then((res) => res.json())
+
+ expect(result).toMatchSnapshot()
+ })
+ })
+
+ describe(`functions get parsed cookies`, () => {
+ test(`cookie`, async () => {
+ const result = await fetchTwice(`${host}/api/cookie-me`, {
+ headers: { cookie: `foo=blue;` },
+ }).then((res) => res.json())
+
+ expect(result).toEqual({
+ foo: 'blue',
+ })
+ })
+ })
+
+ describe(`functions can redirect`, () => {
+ test(`normal`, async () => {
+ const result = await fetchTwice(`${host}/api/redirect-me`)
+
+ expect(result.url).toEqual(`${host}/`)
+ })
+ })
+
+ describe(`functions can have custom middleware`, () => {
+ test(`normal`, async () => {
+ const result = await fetchTwice(`${host}/api/cors`)
+
+ const headers = Object.fromEntries(result.headers)
+ expect(headers[`access-control-allow-origin`]).toEqual(`*`)
+ })
+ })
+ })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/gatsby-config.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/gatsby-config.js
new file mode 100644
index 00000000..af3a3453
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/gatsby-config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ flags: {
+ FUNCTIONS: true,
+ },
+ siteMetadata: {
+ title: 'Function test',
+ },
+ plugins: [],
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/netlify.toml b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/package.json b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/package.json
new file mode 100644
index 00000000..b137efd2
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "function-test",
+ "version": "1.0.0",
+ "private": true,
+ "description": "Function test",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "HOST=0.0.0.0 gatsby develop",
+ "start": "HOST=0.0.0.0 gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "build:netlify": "netlify build --offline",
+ "preview": "netlify dev --offline",
+ "test": "run-s build:netlify test:e2e",
+ "test:e2e": "start-server-and-test preview 8888 test:jest",
+ "test:jest": "jest"
+ },
+ "dependencies": {
+ "gatsby": "^5.2.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "form-data": "^4.0.0",
+ "jest": "^26.6.3",
+ "node-fetch": "^2.6.1",
+ "npm-run-all": "^4.1.5",
+ "start-server-and-test": "^1.12.2"
+ },
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.17.0"
+ }
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/I-Am-Capitalized.js
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/function.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/function.js
new file mode 100644
index 00000000..537e4829
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/function.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am at a secondary-level`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/index.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/index.js
new file mode 100644
index 00000000..a646bc11
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/a-directory/index.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am an index.js in a sub-directory!`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cookie-me.ts b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cookie-me.ts
new file mode 100644
index 00000000..7f4664c9
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cookie-me.ts
@@ -0,0 +1,8 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ res.json(req.cookies)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cors.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cors.js
new file mode 100644
index 00000000..10dd8925
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/cors.js
@@ -0,0 +1,18 @@
+import Cors from 'cors'
+
+const cors = Cors()
+
+export default async function corsHandler(req, res) {
+ // Run Cors middleware and handle errors.
+ await new Promise((resolve, reject) => {
+ cors(req, res, (result) => {
+ if (result instanceof Error) {
+ reject(result)
+ }
+
+ resolve(result)
+ })
+ })
+
+ res.json(`Hi from Gatsby Functions`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/[...].js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/[...].js
new file mode 100644
index 00000000..e76f3038
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/[...].js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.json(req.params)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/function.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/function.js
new file mode 100644
index 00000000..b83f7110
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/dir/function.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am another sub-directory function`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/env-variables.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/env-variables.js
new file mode 100644
index 00000000..7d09b81f
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/env-variables.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(process.env.pickle)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/error-send-function-twice.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/error-send-function-twice.js
new file mode 100644
index 00000000..8e5b2582
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/error-send-function-twice.js
@@ -0,0 +1,4 @@
+export default function handler(req, res) {
+ res.send(`hi`)
+ res.json({ willCauseError: true })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-ts.ts b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-ts.ts
new file mode 100644
index 00000000..37f90f86
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-ts.ts
@@ -0,0 +1,3 @@
+export default function handler(req, res) {
+ res.status(200).json({ hello: `world` })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-world.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-world.js
new file mode 100644
index 00000000..37f90f86
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/hello-world.js
@@ -0,0 +1,3 @@
+export default function handler(req, res) {
+ res.status(200).json({ hello: `world` })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-false.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-false.js
new file mode 100644
index 00000000..fea6703e
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-false.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(false)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json-too.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json-too.js
new file mode 100644
index 00000000..8909f045
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json-too.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send({ amIJSON: true })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json.js
new file mode 100644
index 00000000..ea5ffd15
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-json.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.json({ amIJSON: true })
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-status.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-status.js
new file mode 100644
index 00000000..374ebf13
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-status.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(200)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-text.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-text.js
new file mode 100644
index 00000000..30b66967
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-text.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send('I am text')
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-typescript.ts b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-typescript.ts
new file mode 100644
index 00000000..24b16d2a
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/i-am-typescript.ts
@@ -0,0 +1,10 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ if (req.method === `GET`) {
+ res.send(`I am typescript`)
+ }
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/parser.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/parser.js
new file mode 100644
index 00000000..66e2b10f
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/parser.js
@@ -0,0 +1,13 @@
+export default function topLevel(req, res) {
+ if (req.query && Object.keys(req.query).length !== 0) {
+ res.json(req.query)
+ } else if (req.files && req.files.length !== 0) {
+ res.json({ files: req.files, body: req.body })
+ } else if (req.body) {
+ res.json(req.body)
+ } else {
+ res.json({
+ message: `No body was sent. Try a POST request or query string`,
+ })
+ }
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/redirect-me.ts b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/redirect-me.ts
new file mode 100644
index 00000000..b141f7ab
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/redirect-me.ts
@@ -0,0 +1,8 @@
+import { GatsbyFunctionResponse, GatsbyFunctionRequest } from 'gatsby'
+
+export default function topLevel(
+ req: GatsbyFunctionRequest,
+ res: GatsbyFunctionResponse,
+) {
+ res.redirect(`/`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some whitespace.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some whitespace.js
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some whitespace.js
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git "a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js" "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\303\240\303\250-french.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git "a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js" "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/some-\327\220\327\225\327\223\327\225\327\252.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/status.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/status.js
new file mode 100644
index 00000000..edbe1f9f
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/status.js
@@ -0,0 +1,4 @@
+export default function topLevel(req, res) {
+ const status = req.query.code ? req.query.code : 200
+ res.status(status).send(`I am at the top-level`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/top-level.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/top-level.js
new file mode 100644
index 00000000..56d7d954
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/top-level.js
@@ -0,0 +1,3 @@
+export default function topLevel(req, res) {
+ res.send(`I am at the top-level`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js
new file mode 100644
index 00000000..583a404a
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/users/[userId]/[super].js
@@ -0,0 +1,3 @@
+export default function userIdHandler(req, res) {
+ res.json(req.params)
+}
diff --git "a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js" "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js"
new file mode 100644
index 00000000..32d09568
--- /dev/null
+++ "b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/api/with-\303\244\303\266\303\274-umlaut.js"
@@ -0,0 +1,4 @@
+const path = require(`path`)
+export default function topLevel(req, res) {
+ res.send(`${path.parse(__filename).name}${path.parse(__filename).ext}`)
+}
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/images/icon.png b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/images/icon.png
new file mode 100644
index 00000000..38b2fb0e
Binary files /dev/null and b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/images/icon.png differ
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/404.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/404.js
new file mode 100644
index 00000000..0697ec5a
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/404.js
@@ -0,0 +1,52 @@
+import { Link } from 'gatsby'
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: '96px',
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+
+// markup
+const NotFoundPage = () => (
+
+ Not found
+ Page not found
+
+ Sorry{' '}
+
+ 😔
+ {' '}
+ we couldn’t find what you were looking for.
+
+ {process.env.NODE_ENV === 'development' ? (
+ <>
+
+ Try creating a page in src/pages/
.
+
+ >
+ ) : null}
+
+ Go home.
+
+
+)
+
+export default NotFoundPage
diff --git a/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/index.js b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/index.js
new file mode 100644
index 00000000..75dcc278
--- /dev/null
+++ b/plugin/test/fixtures/v5/functions-without-gatsby-plugin/src/pages/index.js
@@ -0,0 +1,174 @@
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ paddingLeft: 60,
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+
+const listStyles = {
+ marginBottom: 96,
+ paddingLeft: 0,
+}
+const listItemStyles = {
+ fontWeight: 300,
+ fontSize: 24,
+ maxWidth: 560,
+ marginBottom: 10,
+}
+
+const linkStyle = {
+ color: '#8954A8',
+ fontWeight: 'bold',
+ fontSize: 16,
+ verticalAlign: '5%',
+}
+
+const descriptionStyle = {
+ color: '#232129',
+ fontSize: 14,
+ marginTop: 10,
+ marginBottom: 0,
+ lineHeight: 1.25,
+}
+
+// data
+const links = [
+ { text: 'Hello World', url: 'api/hello-world', description: '' },
+ {
+ text: 'I Am Capitalized',
+ url: 'api/I-Am-Capitalized',
+ description: 'Shows case-sensitive URLs',
+ },
+ {
+ text: 'Cookies',
+ url: 'api/cookie-me',
+ description: 'Reads browser cookies',
+ },
+ { text: 'Cors', url: 'api/cors', description: 'Uses custom middleware' },
+ {
+ text: 'env var',
+ url: 'api/env-variables',
+ description: 'Reads .env var from build',
+ },
+ {
+ text: 'Error caught',
+ url: 'api/error-send-function-twice',
+ description: "Doesn't crash the server on error",
+ },
+ {
+ text: 'JSON output',
+ url: 'api/i-am-json',
+ description: 'Uses json() helper',
+ },
+ {
+ text: 'I am TypeScript',
+ url: 'api/i-am-typescript',
+ description: 'Is a TypeScript function',
+ },
+ {
+ text: 'Value parser',
+ url: 'api/parser?message=These are query params&another=And so is this&hint=Try a form or JSON body POST',
+ description: 'Parses body. POST to me',
+ },
+ {
+ text: 'Redirect',
+ url: 'api/redirect-me',
+ description: 'Redirects back to this page',
+ },
+ { text: 'Whitespace in URL', url: 'api/some whitespace' },
+ { text: 'Accented characters', url: 'api/some-àè-french' },
+ { text: 'Non-latin characters', url: 'api/some-אודות' },
+ {
+ text: 'Status',
+ url: 'api/status?code=418',
+ description: 'Sets status code using status() helper',
+ },
+ { text: 'Directory index', url: 'api/a-directory' },
+ {
+ text: 'Directory subpage',
+ url: 'api/a-directory/function',
+ },
+ {
+ text: 'Directory catch-all',
+ url: 'api/dir/anything-here',
+ description: 'Change the catch-all value and see captured value',
+ },
+ {
+ text: 'Directory catch-all override',
+ url: 'api/dir/function',
+ description: 'A named function overrides the catch-all',
+ },
+ {
+ text: 'Named params',
+ url: 'api/users/123/hello world',
+ description: 'Captures named path params',
+ },
+]
+
+// markup
+const IndexPage = () => {
+ React.useEffect(() => {
+ document.cookie = 'thiscookie=was%20set%20on%20previous%20page'
+ })
+ return (
+
+ Home Page
+ Gatsby Functions demo
+
+ {links.map((link) => (
+
+
+
+ {link.text}
+
+ {link.description && (
+ {link.description}
+ )}
+
+
+ ))}
+
+
+ Form parser
+
+
+ A form posted to the parser. Also try using Postman or Insomnia to
+ send a JSON body.
+
+
+
+
+
+ Form parser
+
+ A file upload
+
+
+
+
+
+ )
+}
+
+export default IndexPage
diff --git a/plugin/test/fixtures/v5/no-functions/.gitignore b/plugin/test/fixtures/v5/no-functions/.gitignore
new file mode 100644
index 00000000..4137576c
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.cache/
+public
+.netlify/cache
+.netlify/functions
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/no-functions/LICENSE b/plugin/test/fixtures/v5/no-functions/LICENSE
new file mode 100644
index 00000000..7e964c1e
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/LICENSE
@@ -0,0 +1,14 @@
+The BSD Zero Clause License (0BSD)
+
+Copyright (c) 2020 Gatsby Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/plugin/test/fixtures/v5/no-functions/e2e-tests/build.test.js b/plugin/test/fixtures/v5/no-functions/e2e-tests/build.test.js
new file mode 100644
index 00000000..55657bac
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/e2e-tests/build.test.js
@@ -0,0 +1,10 @@
+// eslint-disable-next-line node/no-unpublished-require
+const { buildSite } = require('../../../../helpers')
+
+jest.setTimeout(120_000)
+describe('A site with no functions', () => {
+ it('successfully builds', async () => {
+ const { success } = await buildSite()
+ expect(success).toBeTruthy()
+ })
+})
diff --git a/plugin/test/fixtures/v5/no-functions/gatsby-config.js b/plugin/test/fixtures/v5/no-functions/gatsby-config.js
new file mode 100644
index 00000000..5ae66ab2
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/gatsby-config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ plugins: [],
+}
diff --git a/plugin/test/fixtures/v5/no-functions/netlify.toml b/plugin/test/fixtures/v5/no-functions/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/v5/no-functions/package.json b/plugin/test/fixtures/v5/no-functions/package.json
new file mode 100644
index 00000000..933e5173
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "no-functions",
+ "version": "1.0.0",
+ "private": true,
+ "description": "My Gatsby site",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "gatsby develop",
+ "start": "gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "test": "npm run build && jest"
+ },
+ "license": "0BSD",
+ "dependencies": {
+ "gatsby": "next",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "jest": "^27.0.4"
+ }
+}
diff --git a/plugin/test/fixtures/v5/no-functions/src/images/icon.png b/plugin/test/fixtures/v5/no-functions/src/images/icon.png
new file mode 100644
index 00000000..38b2fb0e
Binary files /dev/null and b/plugin/test/fixtures/v5/no-functions/src/images/icon.png differ
diff --git a/plugin/test/fixtures/v5/no-functions/src/pages/404.js b/plugin/test/fixtures/v5/no-functions/src/pages/404.js
new file mode 100644
index 00000000..0697ec5a
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/src/pages/404.js
@@ -0,0 +1,52 @@
+import { Link } from 'gatsby'
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: '96px',
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+
+// markup
+const NotFoundPage = () => (
+
+ Not found
+ Page not found
+
+ Sorry{' '}
+
+ 😔
+ {' '}
+ we couldn’t find what you were looking for.
+
+ {process.env.NODE_ENV === 'development' ? (
+ <>
+
+ Try creating a page in src/pages/
.
+
+ >
+ ) : null}
+
+ Go home.
+
+
+)
+
+export default NotFoundPage
diff --git a/plugin/test/fixtures/v5/no-functions/src/pages/index.js b/plugin/test/fixtures/v5/no-functions/src/pages/index.js
new file mode 100644
index 00000000..2dbe90ad
--- /dev/null
+++ b/plugin/test/fixtures/v5/no-functions/src/pages/index.js
@@ -0,0 +1,182 @@
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: 96,
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+const headingAccentStyles = {
+ color: '#663399',
+}
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+const listStyles = {
+ marginBottom: 96,
+ paddingLeft: 0,
+}
+const listItemStyles = {
+ fontWeight: 300,
+ fontSize: 24,
+ maxWidth: 560,
+ marginBottom: 30,
+}
+
+const linkStyle = {
+ color: '#8954A8',
+ fontWeight: 'bold',
+ fontSize: 16,
+ verticalAlign: '5%',
+}
+
+const docLinkStyle = {
+ ...linkStyle,
+ listStyleType: 'none',
+ marginBottom: 24,
+}
+
+const descriptionStyle = {
+ color: '#232129',
+ fontSize: 14,
+ marginTop: 10,
+ marginBottom: 0,
+ lineHeight: 1.25,
+}
+
+const docLink = {
+ text: 'Documentation',
+ url: 'https://www.gatsbyjs.com/docs/',
+ color: '#8954A8',
+}
+
+const badgeStyle = {
+ color: '#fff',
+ backgroundColor: '#088413',
+ border: '1px solid #088413',
+ fontSize: 11,
+ fontWeight: 'bold',
+ letterSpacing: 1,
+ borderRadius: 4,
+ padding: '4px 6px',
+ display: 'inline-block',
+ position: 'relative',
+ top: -2,
+ marginLeft: 10,
+ lineHeight: 1,
+}
+
+// data
+const links = [
+ {
+ text: 'Tutorial',
+ url: 'https://www.gatsbyjs.com/docs/tutorial/',
+ description:
+ "A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
+ color: '#E95800',
+ },
+ {
+ text: 'How to Guides',
+ url: 'https://www.gatsbyjs.com/docs/how-to/',
+ description:
+ "Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
+ color: '#1099A8',
+ },
+ {
+ text: 'Reference Guides',
+ url: 'https://www.gatsbyjs.com/docs/reference/',
+ description:
+ "Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
+ color: '#BC027F',
+ },
+ {
+ text: 'Conceptual Guides',
+ url: 'https://www.gatsbyjs.com/docs/conceptual/',
+ description:
+ 'Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.',
+ color: '#0D96F2',
+ },
+ {
+ text: 'Plugin Library',
+ url: 'https://www.gatsbyjs.com/plugins',
+ description:
+ 'Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.',
+ color: '#8EB814',
+ },
+ {
+ text: 'Build and Host',
+ url: 'https://www.gatsbyjs.com/cloud',
+ badge: true,
+ description:
+ 'Now you’re ready to show the world! Give your Gatsby site superpowers: Build and host on Gatsby Cloud. Get started for free!',
+ color: '#663399',
+ },
+]
+
+// markup
+const IndexPage = () => (
+
+ Home Page
+
+ Congratulations
+
+ — you just made a Gatsby site!
+
+ 🎉🎉🎉
+
+
+
+ Edit src/pages/index.js
to see this page
+ update in real-time.{' '}
+
+ 😎
+
+
+
+
+
+)
+
+export default IndexPage
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/.gitignore b/plugin/test/fixtures/v5/with-no-gatsby-config/.gitignore
new file mode 100644
index 00000000..4137576c
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.cache/
+public
+.netlify/cache
+.netlify/functions
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/LICENSE b/plugin/test/fixtures/v5/with-no-gatsby-config/LICENSE
new file mode 100644
index 00000000..7e964c1e
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/LICENSE
@@ -0,0 +1,14 @@
+The BSD Zero Clause License (0BSD)
+
+Copyright (c) 2020 Gatsby Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/e2e-tests/build.test.js b/plugin/test/fixtures/v5/with-no-gatsby-config/e2e-tests/build.test.js
new file mode 100644
index 00000000..7481fac9
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/e2e-tests/build.test.js
@@ -0,0 +1,10 @@
+// eslint-disable-next-line node/no-unpublished-require
+const { buildSite } = require('../../../../helpers')
+
+jest.setTimeout(120_000)
+describe('A site with no Gatsby config', () => {
+ it('successfully builds', async () => {
+ const { success } = await buildSite()
+ expect(success).toBeTruthy()
+ })
+})
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/netlify.toml b/plugin/test/fixtures/v5/with-no-gatsby-config/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/package.json b/plugin/test/fixtures/v5/with-no-gatsby-config/package.json
new file mode 100644
index 00000000..fa23b628
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "no-plugins",
+ "version": "1.0.0",
+ "private": true,
+ "description": "My Gatsby site",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "gatsby develop",
+ "start": "gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "test": "npm run build && jest"
+ },
+ "license": "0BSD",
+ "dependencies": {
+ "gatsby": "next",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "jest": "^27.0.4"
+ },
+ "peerDependencies": {
+ "execa": "^5.0.0"
+ }
+}
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/404.js b/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/404.js
new file mode 100644
index 00000000..0697ec5a
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/404.js
@@ -0,0 +1,52 @@
+import { Link } from 'gatsby'
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: '96px',
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+
+// markup
+const NotFoundPage = () => (
+
+ Not found
+ Page not found
+
+ Sorry{' '}
+
+ 😔
+ {' '}
+ we couldn’t find what you were looking for.
+
+ {process.env.NODE_ENV === 'development' ? (
+ <>
+
+ Try creating a page in src/pages/
.
+
+ >
+ ) : null}
+
+ Go home.
+
+
+)
+
+export default NotFoundPage
diff --git a/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/index.js b/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/index.js
new file mode 100644
index 00000000..2dbe90ad
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-gatsby-config/src/pages/index.js
@@ -0,0 +1,182 @@
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: 96,
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+const headingAccentStyles = {
+ color: '#663399',
+}
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+const listStyles = {
+ marginBottom: 96,
+ paddingLeft: 0,
+}
+const listItemStyles = {
+ fontWeight: 300,
+ fontSize: 24,
+ maxWidth: 560,
+ marginBottom: 30,
+}
+
+const linkStyle = {
+ color: '#8954A8',
+ fontWeight: 'bold',
+ fontSize: 16,
+ verticalAlign: '5%',
+}
+
+const docLinkStyle = {
+ ...linkStyle,
+ listStyleType: 'none',
+ marginBottom: 24,
+}
+
+const descriptionStyle = {
+ color: '#232129',
+ fontSize: 14,
+ marginTop: 10,
+ marginBottom: 0,
+ lineHeight: 1.25,
+}
+
+const docLink = {
+ text: 'Documentation',
+ url: 'https://www.gatsbyjs.com/docs/',
+ color: '#8954A8',
+}
+
+const badgeStyle = {
+ color: '#fff',
+ backgroundColor: '#088413',
+ border: '1px solid #088413',
+ fontSize: 11,
+ fontWeight: 'bold',
+ letterSpacing: 1,
+ borderRadius: 4,
+ padding: '4px 6px',
+ display: 'inline-block',
+ position: 'relative',
+ top: -2,
+ marginLeft: 10,
+ lineHeight: 1,
+}
+
+// data
+const links = [
+ {
+ text: 'Tutorial',
+ url: 'https://www.gatsbyjs.com/docs/tutorial/',
+ description:
+ "A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
+ color: '#E95800',
+ },
+ {
+ text: 'How to Guides',
+ url: 'https://www.gatsbyjs.com/docs/how-to/',
+ description:
+ "Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
+ color: '#1099A8',
+ },
+ {
+ text: 'Reference Guides',
+ url: 'https://www.gatsbyjs.com/docs/reference/',
+ description:
+ "Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
+ color: '#BC027F',
+ },
+ {
+ text: 'Conceptual Guides',
+ url: 'https://www.gatsbyjs.com/docs/conceptual/',
+ description:
+ 'Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.',
+ color: '#0D96F2',
+ },
+ {
+ text: 'Plugin Library',
+ url: 'https://www.gatsbyjs.com/plugins',
+ description:
+ 'Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.',
+ color: '#8EB814',
+ },
+ {
+ text: 'Build and Host',
+ url: 'https://www.gatsbyjs.com/cloud',
+ badge: true,
+ description:
+ 'Now you’re ready to show the world! Give your Gatsby site superpowers: Build and host on Gatsby Cloud. Get started for free!',
+ color: '#663399',
+ },
+]
+
+// markup
+const IndexPage = () => (
+
+ Home Page
+
+ Congratulations
+
+ — you just made a Gatsby site!
+
+ 🎉🎉🎉
+
+
+
+ Edit src/pages/index.js
to see this page
+ update in real-time.{' '}
+
+ 😎
+
+
+
+
+
+)
+
+export default IndexPage
diff --git a/plugin/test/fixtures/v5/with-no-plugins/.gitignore b/plugin/test/fixtures/v5/with-no-plugins/.gitignore
new file mode 100644
index 00000000..5b8ab449
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.cache/
+public
+.netlify
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/with-no-plugins/LICENSE b/plugin/test/fixtures/v5/with-no-plugins/LICENSE
new file mode 100644
index 00000000..7e964c1e
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/LICENSE
@@ -0,0 +1,14 @@
+The BSD Zero Clause License (0BSD)
+
+Copyright (c) 2020 Gatsby Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/plugin/test/fixtures/v5/with-no-plugins/e2e-tests/build.test.js b/plugin/test/fixtures/v5/with-no-plugins/e2e-tests/build.test.js
new file mode 100644
index 00000000..80a7640f
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/e2e-tests/build.test.js
@@ -0,0 +1,10 @@
+// eslint-disable-next-line node/no-unpublished-require
+const { buildSite } = require('../../../../helpers')
+
+jest.setTimeout(120_000)
+describe('A site with no plugins', () => {
+ it('successfully builds', async () => {
+ const { success } = await buildSite()
+ expect(success).toBeTruthy()
+ })
+})
diff --git a/plugin/test/fixtures/v5/with-no-plugins/gatsby-config.js b/plugin/test/fixtures/v5/with-no-plugins/gatsby-config.js
new file mode 100644
index 00000000..4ba52ba2
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/gatsby-config.js
@@ -0,0 +1 @@
+module.exports = {}
diff --git a/plugin/test/fixtures/v5/with-no-plugins/netlify.toml b/plugin/test/fixtures/v5/with-no-plugins/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/v5/with-no-plugins/package.json b/plugin/test/fixtures/v5/with-no-plugins/package.json
new file mode 100644
index 00000000..f90e1dba
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "no-plugins",
+ "version": "1.0.0",
+ "private": true,
+ "description": "My Gatsby site",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "gatsby develop",
+ "start": "gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "test": "npm run build && jest"
+ },
+ "license": "0BSD",
+ "dependencies": {
+ "gatsby": "next",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "jest": "^27.0.4"
+ }
+}
diff --git a/plugin/test/fixtures/v5/with-no-plugins/src/pages/404.js b/plugin/test/fixtures/v5/with-no-plugins/src/pages/404.js
new file mode 100644
index 00000000..0697ec5a
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/src/pages/404.js
@@ -0,0 +1,52 @@
+import { Link } from 'gatsby'
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: '96px',
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+
+// markup
+const NotFoundPage = () => (
+
+ Not found
+ Page not found
+
+ Sorry{' '}
+
+ 😔
+ {' '}
+ we couldn’t find what you were looking for.
+
+ {process.env.NODE_ENV === 'development' ? (
+ <>
+
+ Try creating a page in src/pages/
.
+
+ >
+ ) : null}
+
+ Go home.
+
+
+)
+
+export default NotFoundPage
diff --git a/plugin/test/fixtures/v5/with-no-plugins/src/pages/index.js b/plugin/test/fixtures/v5/with-no-plugins/src/pages/index.js
new file mode 100644
index 00000000..2dbe90ad
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-no-plugins/src/pages/index.js
@@ -0,0 +1,182 @@
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: 96,
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+const headingAccentStyles = {
+ color: '#663399',
+}
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+const listStyles = {
+ marginBottom: 96,
+ paddingLeft: 0,
+}
+const listItemStyles = {
+ fontWeight: 300,
+ fontSize: 24,
+ maxWidth: 560,
+ marginBottom: 30,
+}
+
+const linkStyle = {
+ color: '#8954A8',
+ fontWeight: 'bold',
+ fontSize: 16,
+ verticalAlign: '5%',
+}
+
+const docLinkStyle = {
+ ...linkStyle,
+ listStyleType: 'none',
+ marginBottom: 24,
+}
+
+const descriptionStyle = {
+ color: '#232129',
+ fontSize: 14,
+ marginTop: 10,
+ marginBottom: 0,
+ lineHeight: 1.25,
+}
+
+const docLink = {
+ text: 'Documentation',
+ url: 'https://www.gatsbyjs.com/docs/',
+ color: '#8954A8',
+}
+
+const badgeStyle = {
+ color: '#fff',
+ backgroundColor: '#088413',
+ border: '1px solid #088413',
+ fontSize: 11,
+ fontWeight: 'bold',
+ letterSpacing: 1,
+ borderRadius: 4,
+ padding: '4px 6px',
+ display: 'inline-block',
+ position: 'relative',
+ top: -2,
+ marginLeft: 10,
+ lineHeight: 1,
+}
+
+// data
+const links = [
+ {
+ text: 'Tutorial',
+ url: 'https://www.gatsbyjs.com/docs/tutorial/',
+ description:
+ "A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
+ color: '#E95800',
+ },
+ {
+ text: 'How to Guides',
+ url: 'https://www.gatsbyjs.com/docs/how-to/',
+ description:
+ "Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
+ color: '#1099A8',
+ },
+ {
+ text: 'Reference Guides',
+ url: 'https://www.gatsbyjs.com/docs/reference/',
+ description:
+ "Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
+ color: '#BC027F',
+ },
+ {
+ text: 'Conceptual Guides',
+ url: 'https://www.gatsbyjs.com/docs/conceptual/',
+ description:
+ 'Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.',
+ color: '#0D96F2',
+ },
+ {
+ text: 'Plugin Library',
+ url: 'https://www.gatsbyjs.com/plugins',
+ description:
+ 'Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.',
+ color: '#8EB814',
+ },
+ {
+ text: 'Build and Host',
+ url: 'https://www.gatsbyjs.com/cloud',
+ badge: true,
+ description:
+ 'Now you’re ready to show the world! Give your Gatsby site superpowers: Build and host on Gatsby Cloud. Get started for free!',
+ color: '#663399',
+ },
+]
+
+// markup
+const IndexPage = () => (
+
+ Home Page
+
+ Congratulations
+
+ — you just made a Gatsby site!
+
+ 🎉🎉🎉
+
+
+
+ Edit src/pages/index.js
to see this page
+ update in real-time.{' '}
+
+ 😎
+
+
+
+
+
+)
+
+export default IndexPage
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/.gitignore b/plugin/test/fixtures/v5/with-old-gatsby-plugin/.gitignore
new file mode 100644
index 00000000..5b8ab449
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.cache/
+public
+.netlify
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/LICENSE b/plugin/test/fixtures/v5/with-old-gatsby-plugin/LICENSE
new file mode 100644
index 00000000..7e964c1e
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/LICENSE
@@ -0,0 +1,14 @@
+The BSD Zero Clause License (0BSD)
+
+Copyright (c) 2020 Gatsby Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/e2e-tests/build.test.js b/plugin/test/fixtures/v5/with-old-gatsby-plugin/e2e-tests/build.test.js
new file mode 100644
index 00000000..957efe82
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/e2e-tests/build.test.js
@@ -0,0 +1,14 @@
+// eslint-disable-next-line node/no-unpublished-require
+const { buildSite } = require('../../../../helpers')
+
+jest.setTimeout(120_000)
+
+describe('A site using gatsby-plugin-netlify-cache', () => {
+ it('bails when running a build', async () => {
+ const { logs, success } = await buildSite()
+ expect(success).toBeFalsy()
+ expect(logs.stderr).toMatch(
+ "The plugin 'gatsby-plugin-netlify-cache' is not compatible with the Gatsby build plugin",
+ )
+ })
+})
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/gatsby-config.js b/plugin/test/fixtures/v5/with-old-gatsby-plugin/gatsby-config.js
new file mode 100644
index 00000000..20444695
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/gatsby-config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ plugins: [
+ {
+ resolve: 'gatsby-plugin-netlify-cache',
+ options: {
+ cachePublic: true,
+ },
+ },
+ ],
+}
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/netlify.toml b/plugin/test/fixtures/v5/with-old-gatsby-plugin/netlify.toml
new file mode 100644
index 00000000..72865a74
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/netlify.toml
@@ -0,0 +1,6 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
diff --git a/plugin/test/fixtures/v5/with-old-gatsby-plugin/package.json b/plugin/test/fixtures/v5/with-old-gatsby-plugin/package.json
new file mode 100644
index 00000000..a5baf472
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-gatsby-plugin/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "no-functions",
+ "version": "1.0.0",
+ "private": true,
+ "description": "My Gatsby site",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "gatsby develop",
+ "start": "gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "test": "npm run build && jest"
+ },
+ "license": "0BSD",
+ "dependencies": {
+ "gatsby": "next",
+ "gatsby-plugin-netlify-cache": "^1.2.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@netlify/build": "latest",
+ "jest": "^27.0.4"
+ },
+ "peerDependencies": {
+ "execa": "^5.0.0"
+ }
+}
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/.gitignore b/plugin/test/fixtures/v5/with-old-netlify-plugin/.gitignore
new file mode 100644
index 00000000..5b8ab449
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.cache/
+public
+.netlify
+package-lock.json
\ No newline at end of file
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/LICENSE b/plugin/test/fixtures/v5/with-old-netlify-plugin/LICENSE
new file mode 100644
index 00000000..7e964c1e
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/LICENSE
@@ -0,0 +1,14 @@
+The BSD Zero Clause License (0BSD)
+
+Copyright (c) 2020 Gatsby Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/e2e-tests/build.test.js b/plugin/test/fixtures/v5/with-old-netlify-plugin/e2e-tests/build.test.js
new file mode 100644
index 00000000..936987f1
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/e2e-tests/build.test.js
@@ -0,0 +1,14 @@
+// eslint-disable-next-line node/no-unpublished-require
+const { buildSite } = require('../../../../helpers')
+
+jest.setTimeout(120_000)
+
+describe('A site using netlify-plugin-gatsby-cache', () => {
+ it('warns when running a build', async () => {
+ const { logs, success } = await buildSite()
+ expect(success).toBeTruthy()
+ expect(logs.stderr).toMatch(
+ "The plugin 'netlify-plugin-gatsby-cache' is no longer required and should be removed.",
+ )
+ })
+})
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/gatsby-config.js b/plugin/test/fixtures/v5/with-old-netlify-plugin/gatsby-config.js
new file mode 100644
index 00000000..5ae66ab2
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/gatsby-config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ plugins: [],
+}
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/netlify.toml b/plugin/test/fixtures/v5/with-old-netlify-plugin/netlify.toml
new file mode 100644
index 00000000..b68939a6
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/netlify.toml
@@ -0,0 +1,9 @@
+[build]
+command = "npm run build"
+publish = "public/"
+
+[[plugins]]
+package = "../../../../src/index.ts"
+
+[[plugins]]
+package = 'netlify-plugin-gatsby-cache'
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/package.json b/plugin/test/fixtures/v5/with-old-netlify-plugin/package.json
new file mode 100644
index 00000000..5480f5a8
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "no-functions",
+ "version": "1.0.0",
+ "private": true,
+ "description": "My Gatsby site",
+ "author": "Matt Kane",
+ "keywords": [
+ "gatsby"
+ ],
+ "scripts": {
+ "develop": "gatsby develop",
+ "start": "gatsby develop",
+ "build": "gatsby build",
+ "serve": "gatsby serve",
+ "clean": "gatsby clean",
+ "test": "npm run build && jest"
+ },
+ "license": "0BSD",
+ "dependencies": {
+ "gatsby": "next",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@netlify/build": "latest",
+ "jest": "^27.0.4",
+ "netlify-plugin-gatsby-cache": "^0.3.2"
+ },
+ "peerDependencies": {
+ "execa": "^5.0.0"
+ }
+}
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/src/images/icon.png b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/images/icon.png
new file mode 100644
index 00000000..38b2fb0e
Binary files /dev/null and b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/images/icon.png differ
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/404.js b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/404.js
new file mode 100644
index 00000000..0697ec5a
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/404.js
@@ -0,0 +1,52 @@
+import { Link } from 'gatsby'
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: '96px',
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+
+// markup
+const NotFoundPage = () => (
+
+ Not found
+ Page not found
+
+ Sorry{' '}
+
+ 😔
+ {' '}
+ we couldn’t find what you were looking for.
+
+ {process.env.NODE_ENV === 'development' ? (
+ <>
+
+ Try creating a page in src/pages/
.
+
+ >
+ ) : null}
+
+ Go home.
+
+
+)
+
+export default NotFoundPage
diff --git a/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/index.js b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/index.js
new file mode 100644
index 00000000..2dbe90ad
--- /dev/null
+++ b/plugin/test/fixtures/v5/with-old-netlify-plugin/src/pages/index.js
@@ -0,0 +1,182 @@
+import * as React from 'react'
+
+// styles
+const pageStyles = {
+ color: '#232129',
+ padding: 96,
+ fontFamily: '-apple-system, Roboto, sans-serif, serif',
+}
+const headingStyles = {
+ marginTop: 0,
+ marginBottom: 64,
+ maxWidth: 320,
+}
+const headingAccentStyles = {
+ color: '#663399',
+}
+const paragraphStyles = {
+ marginBottom: 48,
+}
+const codeStyles = {
+ color: '#8A6534',
+ padding: 4,
+ backgroundColor: '#FFF4DB',
+ fontSize: '1.25rem',
+ borderRadius: 4,
+}
+const listStyles = {
+ marginBottom: 96,
+ paddingLeft: 0,
+}
+const listItemStyles = {
+ fontWeight: 300,
+ fontSize: 24,
+ maxWidth: 560,
+ marginBottom: 30,
+}
+
+const linkStyle = {
+ color: '#8954A8',
+ fontWeight: 'bold',
+ fontSize: 16,
+ verticalAlign: '5%',
+}
+
+const docLinkStyle = {
+ ...linkStyle,
+ listStyleType: 'none',
+ marginBottom: 24,
+}
+
+const descriptionStyle = {
+ color: '#232129',
+ fontSize: 14,
+ marginTop: 10,
+ marginBottom: 0,
+ lineHeight: 1.25,
+}
+
+const docLink = {
+ text: 'Documentation',
+ url: 'https://www.gatsbyjs.com/docs/',
+ color: '#8954A8',
+}
+
+const badgeStyle = {
+ color: '#fff',
+ backgroundColor: '#088413',
+ border: '1px solid #088413',
+ fontSize: 11,
+ fontWeight: 'bold',
+ letterSpacing: 1,
+ borderRadius: 4,
+ padding: '4px 6px',
+ display: 'inline-block',
+ position: 'relative',
+ top: -2,
+ marginLeft: 10,
+ lineHeight: 1,
+}
+
+// data
+const links = [
+ {
+ text: 'Tutorial',
+ url: 'https://www.gatsbyjs.com/docs/tutorial/',
+ description:
+ "A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
+ color: '#E95800',
+ },
+ {
+ text: 'How to Guides',
+ url: 'https://www.gatsbyjs.com/docs/how-to/',
+ description:
+ "Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
+ color: '#1099A8',
+ },
+ {
+ text: 'Reference Guides',
+ url: 'https://www.gatsbyjs.com/docs/reference/',
+ description:
+ "Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
+ color: '#BC027F',
+ },
+ {
+ text: 'Conceptual Guides',
+ url: 'https://www.gatsbyjs.com/docs/conceptual/',
+ description:
+ 'Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.',
+ color: '#0D96F2',
+ },
+ {
+ text: 'Plugin Library',
+ url: 'https://www.gatsbyjs.com/plugins',
+ description:
+ 'Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.',
+ color: '#8EB814',
+ },
+ {
+ text: 'Build and Host',
+ url: 'https://www.gatsbyjs.com/cloud',
+ badge: true,
+ description:
+ 'Now you’re ready to show the world! Give your Gatsby site superpowers: Build and host on Gatsby Cloud. Get started for free!',
+ color: '#663399',
+ },
+]
+
+// markup
+const IndexPage = () => (
+
+ Home Page
+
+ Congratulations
+
+ — you just made a Gatsby site!
+
+ 🎉🎉🎉
+
+
+
+ Edit src/pages/index.js
to see this page
+ update in real-time.{' '}
+
+ 😎
+
+
+
+
+
+)
+
+export default IndexPage
diff --git a/plugin/test/fixtures/with-no-gatsby-config/README.md b/plugin/test/fixtures/with-no-gatsby-config/README.md
deleted file mode 100644
index c3f3061e..00000000
--- a/plugin/test/fixtures/with-no-gatsby-config/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
- Gatsby minimal starter
-
-
-## 🚀 Quick start
-
-1. **Create a Gatsby site.**
-
- Use the Gatsby CLI to create a new site, specifying the minimal starter.
-
- ```shell
- # create a new Gatsby site using the minimal starter
- npm init gatsby
- ```
-
-2. **Start developing.**
-
- Navigate into your new site’s directory and start it up.
-
- ```shell
- cd my-gatsby-site/
- npm run develop
- ```
-
-3. **Open the code and start customizing!**
-
- Your site is now running at http://localhost:8000!
-
- Edit `src/pages/index.js` to see your site update in real-time!
-
-4. **Learn more**
-
- - [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Tutorials](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Guides](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
-## 🚀 Quick start (Gatsby Cloud)
-
-Deploy this starter with one click on
-[Gatsby Cloud](https://www.gatsbyjs.com/cloud/):
-
-[ ](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-starter-minimal)
diff --git a/plugin/test/fixtures/with-no-plugins/README.md b/plugin/test/fixtures/with-no-plugins/README.md
deleted file mode 100644
index c3f3061e..00000000
--- a/plugin/test/fixtures/with-no-plugins/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
- Gatsby minimal starter
-
-
-## 🚀 Quick start
-
-1. **Create a Gatsby site.**
-
- Use the Gatsby CLI to create a new site, specifying the minimal starter.
-
- ```shell
- # create a new Gatsby site using the minimal starter
- npm init gatsby
- ```
-
-2. **Start developing.**
-
- Navigate into your new site’s directory and start it up.
-
- ```shell
- cd my-gatsby-site/
- npm run develop
- ```
-
-3. **Open the code and start customizing!**
-
- Your site is now running at http://localhost:8000!
-
- Edit `src/pages/index.js` to see your site update in real-time!
-
-4. **Learn more**
-
- - [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Tutorials](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Guides](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
-## 🚀 Quick start (Gatsby Cloud)
-
-Deploy this starter with one click on
-[Gatsby Cloud](https://www.gatsbyjs.com/cloud/):
-
-[ ](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-starter-minimal)
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/README.md b/plugin/test/fixtures/with-old-gatsby-plugin/README.md
deleted file mode 100644
index c3f3061e..00000000
--- a/plugin/test/fixtures/with-old-gatsby-plugin/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
- Gatsby minimal starter
-
-
-## 🚀 Quick start
-
-1. **Create a Gatsby site.**
-
- Use the Gatsby CLI to create a new site, specifying the minimal starter.
-
- ```shell
- # create a new Gatsby site using the minimal starter
- npm init gatsby
- ```
-
-2. **Start developing.**
-
- Navigate into your new site’s directory and start it up.
-
- ```shell
- cd my-gatsby-site/
- npm run develop
- ```
-
-3. **Open the code and start customizing!**
-
- Your site is now running at http://localhost:8000!
-
- Edit `src/pages/index.js` to see your site update in real-time!
-
-4. **Learn more**
-
- - [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Tutorials](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Guides](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
-## 🚀 Quick start (Gatsby Cloud)
-
-Deploy this starter with one click on
-[Gatsby Cloud](https://www.gatsbyjs.com/cloud/):
-
-[ ](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-starter-minimal)
diff --git a/plugin/test/fixtures/with-old-gatsby-plugin/netlify.toml b/plugin/test/fixtures/with-old-gatsby-plugin/netlify.toml
deleted file mode 100644
index 7d3e889e..00000000
--- a/plugin/test/fixtures/with-old-gatsby-plugin/netlify.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[build]
-command = "npm run build"
-publish = "public/"
-
-[[plugins]]
-package = "../../../src/index.ts"
diff --git a/plugin/test/fixtures/with-old-netlify-plugin/README.md b/plugin/test/fixtures/with-old-netlify-plugin/README.md
deleted file mode 100644
index c3f3061e..00000000
--- a/plugin/test/fixtures/with-old-netlify-plugin/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
- Gatsby minimal starter
-
-
-## 🚀 Quick start
-
-1. **Create a Gatsby site.**
-
- Use the Gatsby CLI to create a new site, specifying the minimal starter.
-
- ```shell
- # create a new Gatsby site using the minimal starter
- npm init gatsby
- ```
-
-2. **Start developing.**
-
- Navigate into your new site’s directory and start it up.
-
- ```shell
- cd my-gatsby-site/
- npm run develop
- ```
-
-3. **Open the code and start customizing!**
-
- Your site is now running at http://localhost:8000!
-
- Edit `src/pages/index.js` to see your site update in real-time!
-
-4. **Learn more**
-
- - [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Tutorials](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Guides](https://www.gatsbyjs.com/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
- - [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter)
-
-## 🚀 Quick start (Gatsby Cloud)
-
-Deploy this starter with one click on
-[Gatsby Cloud](https://www.gatsbyjs.com/cloud/):
-
-[ ](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-starter-minimal)
diff --git a/plugin/test/e2e-test.sh b/plugin/test/v4-e2e-test.sh
similarity index 80%
rename from plugin/test/e2e-test.sh
rename to plugin/test/v4-e2e-test.sh
index 9fdb1ca4..77119289 100755
--- a/plugin/test/e2e-test.sh
+++ b/plugin/test/v4-e2e-test.sh
@@ -1,10 +1,10 @@
#!/bin/sh
set -e
-for dir in fixtures/*; do
+for dir in fixtures/v4/*; do
echo Running tests in "$dir"
cd "$dir"
npm i --no-package-lock --legacy-peer-deps
npm run test
cd -
-done
\ No newline at end of file
+done
diff --git a/plugin/test/v5-e2e-test.sh b/plugin/test/v5-e2e-test.sh
new file mode 100755
index 00000000..a0e45936
--- /dev/null
+++ b/plugin/test/v5-e2e-test.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+for dir in fixtures/v5/*; do
+ echo Running tests in "$dir"
+ cd "$dir"
+ npm i --no-package-lock --legacy-peer-deps
+ npm run test
+ cd -
+done