diff --git a/src/lib/functions/netlify-function.mjs b/src/lib/functions/netlify-function.mjs index ad4bf94fb32..7280e3a180a 100644 --- a/src/lib/functions/netlify-function.mjs +++ b/src/lib/functions/netlify-function.mjs @@ -173,7 +173,8 @@ export default class NetlifyFunction { async matchURLPath(rawPath, method) { await this.buildQueue - const path = (rawPath.endsWith('/') ? rawPath.slice(0, -1) : rawPath).toLowerCase() + let path = rawPath !== '/' && rawPath.endsWith('/') ? rawPath.slice(0, -1) : rawPath + path = path.toLowerCase() const { routes = [] } = this.buildData return routes.find(({ expression, literal, methods }) => { if (methods.length !== 0 && !methods.includes(method)) { diff --git a/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-catchall.mjs b/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-catchall.mjs new file mode 100644 index 00000000000..7739408281a --- /dev/null +++ b/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-catchall.mjs @@ -0,0 +1,6 @@ +export default async (req) => new Response(`Catchall Path`) + +export const config = { + path: '/*', + method: 'PATCH', +} diff --git a/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-root.mjs b/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-root.mjs new file mode 100644 index 00000000000..b120081dae7 --- /dev/null +++ b/tests/integration/__fixtures__/dev-server-with-v2-functions/functions/custom-path-root.mjs @@ -0,0 +1,6 @@ +export default async (req) => new Response(`With literal path: ${req.url}`) + +export const config = { + path: '/', + method: 'GET' +} diff --git a/tests/integration/commands/dev/v2-api.test.ts b/tests/integration/commands/dev/v2-api.test.ts index 78c010c181a..7b1c695dabb 100644 --- a/tests/integration/commands/dev/v2-api.test.ts +++ b/tests/integration/commands/dev/v2-api.test.ts @@ -132,6 +132,21 @@ describe.runIf(gte(version, '18.13.0'))('v2 api', () => { expect(await response.text()).toBe(`With expression path: {"sku":"netlify"}`) }) + test('should serve the custom path ath the / route as specified in the in source config', async ({ + devServer, + }) => { + const url = `http://localhost:${devServer.port}/` + const response = await fetch(url) + expect(response.status).toBe(200) + expect(await response.text()).toBe(`With literal path: http://localhost:${devServer.port}/`) + }) + + test('catchall path applies to root path', async ({ devServer }) => { + const response = await fetch( `http://localhost:${devServer.port}/`, { method:"PATCH"}) + expect(response.status).toBe(200) + expect(await response.text()).toBe(`Catchall Path`) + }) + test('returns 404 when using the default function URL to access a function with custom routes', async ({ devServer, }) => {