diff --git a/lib/internals/parseRequestUrl.spec.ts b/lib/internals/parseRequestUrl.spec.ts index 6f94d2e2..dac63697 100644 --- a/lib/internals/parseRequestUrl.spec.ts +++ b/lib/internals/parseRequestUrl.spec.ts @@ -40,7 +40,7 @@ describe('parseRequestUrl', () => { parseRequestUrl({ url: '/api/articles' }, '/next-api-decorators/.next/server/pages/api', 'articles.js') ).toStrictEqual('/')); - it('Should return "/" when the file name starts with "[..."', () => + it('Should return "/" when the file name starts with a single bracket and three dots', () => expect( parseRequestUrl( // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -50,4 +50,37 @@ describe('parseRequestUrl', () => { '[...id].js' ) ).toStrictEqual('/')); + + it('Should return "/" when the file name starts with a double bracket and three dots', () => + expect( + parseRequestUrl( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + { url: '/api/article/1', query: { id: '1' } }, + '/next-api-decorators/.next/server/pages/api/article', + '[[...id]].js' + ) + ).toStrictEqual('/1')); + + it('Should return "/" when the file name starts with a double bracket and three dots in a nested folder', () => + expect( + parseRequestUrl( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + { url: '/api/article/comments/1', query: { id: '1' } }, + '/next-api-decorators/.next/server/pages/api/article/comments', + '[[...id]].js' + ) + ).toStrictEqual('/1')); + + it('Should return "/" when the file name starts with a single bracket', () => + expect( + parseRequestUrl( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + { url: '/api/article/1', query: { id: '1' } }, + '/next-api-decorators/.next/server/pages/api/article', + '[id].js' + ) + ).toStrictEqual('/')); }); diff --git a/lib/internals/parseRequestUrl.ts b/lib/internals/parseRequestUrl.ts index df1e2189..4bfc9cf6 100644 --- a/lib/internals/parseRequestUrl.ts +++ b/lib/internals/parseRequestUrl.ts @@ -6,22 +6,18 @@ export function parseRequestUrl(req: NextApiRequest, directoryPath?: string, fil const url = req.url!; let path = url.split('?')[0].split('/').slice(3).join('/'); - // In order for the main method (e.g: `@Get()`) to be matched, - // the path for catch all routes should be set to "/" - if (fileName?.startsWith('[...')) { - const qsKey = basename(fileName.replace('[...', '').replace(']', ''), extname(fileName)); - /* istanbul ignore else */ - if (req.query[qsKey]) { - path = ''; - } + // The path for parametererized routes should be set to "/", in order for the methods to be matched. + if (fileName?.startsWith('[')) { + path = '/'; } if (directoryPath && !fileName?.startsWith('[...')) { const pathRegExp = new RegExp( // "pages/api/articles/index.ts" is compiled into "pages/api/articles.js" which has to be appended to the directory path for parsing - (directoryPath + (fileName && !fileName.startsWith('[') ? basename(fileName, extname(fileName)) : '')) - .split('/.next/server/pages')[1] - .replace(/(\[\w+\])/, '(\\w+)') + directoryPath.split('/.next/server/pages')[1].replace(/(\[\w+\])/, '(\\w+)') + + (fileName && !fileName.startsWith('[...') && !fileName.startsWith('[[...') + ? `/${basename(fileName, extname(fileName))}` + : '') ); /* istanbul ignore else */ if (pathRegExp.test(url)) {