From c6c8818840b905e7d554def340f4b638082d1ff2 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 17 Mar 2023 14:30:32 +0000 Subject: [PATCH] feat: support route handlers (#106) * feat: function entry matcher utility * test: function entry matcher * chore: changeset * chore: prefer forEach over test.each * chore: clearer parameter names --- .changeset/wise-camels-sleep.md | 5 +++++ src/index.ts | 7 ++----- src/utils/index.ts | 3 ++- src/utils/transform/index.ts | 1 + src/utils/transform/manifest.ts | 19 +++++++++++++++++++ tests/manifest.test.ts | 21 +++++++++++++++++++++ 6 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 .changeset/wise-camels-sleep.md create mode 100644 src/utils/transform/index.ts create mode 100644 src/utils/transform/manifest.ts create mode 100644 tests/manifest.test.ts diff --git a/.changeset/wise-camels-sleep.md b/.changeset/wise-camels-sleep.md new file mode 100644 index 000000000..0def81d90 --- /dev/null +++ b/.changeset/wise-camels-sleep.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/next-on-pages": patch +--- + +Handle route handler function entries. diff --git a/src/index.ts b/src/index.ts index b791f37fd..aa8a71108 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { watch } from "chokidar"; import pLimit from "p-limit"; import acorn, { parse, Node } from "acorn"; import { generate } from "astring"; -import { normalizePath } from "./utils"; +import { matchFunctionEntry, normalizePath } from "./utils"; import { version as nextOnPagesVersion } from "../package.json"; @@ -400,10 +400,7 @@ const transform = async ({ } for (const entry of functionsEntries) { - if ( - `pages/${name}` === entry?.name || - `app${name !== "index" ? `/${name}` : ""}/page` === entry?.name - ) { + if (matchFunctionEntry(entry.name, name)) { hydratedFunctions.set(name, { matchers: entry.matchers, filepath }); } } diff --git a/src/utils/index.ts b/src/utils/index.ts index 3f26a6dfb..44118f987 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ -export { normalizePath } from "./paths"; \ No newline at end of file +export { normalizePath } from './paths'; +export { matchFunctionEntry } from './transform'; \ No newline at end of file diff --git a/src/utils/transform/index.ts b/src/utils/transform/index.ts new file mode 100644 index 000000000..2ca78cd67 --- /dev/null +++ b/src/utils/transform/index.ts @@ -0,0 +1 @@ +export { matchFunctionEntry } from './manifest'; diff --git a/src/utils/transform/manifest.ts b/src/utils/transform/manifest.ts new file mode 100644 index 000000000..561692b2e --- /dev/null +++ b/src/utils/transform/manifest.ts @@ -0,0 +1,19 @@ +/** + * Check if a function file name matches an entry in the manifest. + * + * @param entryName Manifest entry name. + * @param fileName Function file name. + * @returns Whether the function file name matches the manifest entry name. + */ +export const matchFunctionEntry = (entryName: string, fileName: string) => { + // app directory + if (entryName.startsWith('app/')) { + const type = entryName.endsWith('/route') ? '/route' : '/page'; + return ( + `app${fileName !== 'index' ? `/${fileName}` : ''}${type}` === entryName + ); + } + + // pages directory + return entryName.startsWith('pages/') && `pages/${fileName}` === entryName; +}; diff --git a/tests/manifest.test.ts b/tests/manifest.test.ts new file mode 100644 index 000000000..3d44f4344 --- /dev/null +++ b/tests/manifest.test.ts @@ -0,0 +1,21 @@ +import { describe, test, expect, suite } from 'vitest'; +import { matchFunctionEntry } from '../src/utils'; + +const manifestEntries = [ + { name: 'app dir - normal page', entry: 'app/test/page', file: 'test' }, + { name: 'app dir - dynamic page', entry: 'app/[id]/page', file: '[id]' }, + { name: 'app dir - nested page', entry: 'app/1/2/3/page', file: '1/2/3' }, + { name: 'app dir - index page', entry: 'app/page', file: 'index' }, + { name: 'app dir - route handler', entry: 'app/test/route', file: 'test' }, + { name: 'pages dir - page', entry: 'pages/api/hello', file: 'api/hello' }, +]; + +suite('manifest utils', () => { + describe('match function entries', () => { + manifestEntries.forEach(({ name, entry, file }) => { + test(name, () => { + expect(matchFunctionEntry(entry, file)).toEqual(true); + }); + }); + }); +});