elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
10.25k stars 219 forks source link

when first param is dynamic, and second param is optional, it returns 404 #876

Open ozdevi opened 5 days ago

ozdevi commented 5 days ago

What version of Elysia is running?

1.1.20

What platform is your computer?

Darwin 23.6.0 arm64 arm

What steps can reproduce the bug?

bun version: 1.1.29

write simple Elysia application index.ts

import { Elysia } from "elysia";

const app = new Elysia()
  .get("/:first/:second?", async ({ params }) => {
    const { first, second } = params;
    console.log("first parameter", first, "second parameter", second);
    return "ok";
  })
  .listen(7777);

console.log(
  `🦊 Elysia is running at http://${app.server?.hostname}:${app.server?.port}`,
);

bun run index.ts open a browser and type url, fill only first parameter http://localhost:7777/elysia it throws NOT_FOUND

What is the expected behavior?

browser: status: 200 response: "ok" cli: first parameter, elysia, second parameter, undefined

What do you see instead?

browser: status: 404 response "NOT_FOUND" cli

{
  request: Request (0 KB) {
    method: "GET",
    url: "http://localhost:7777/elysia",
    headers: Headers {
      "host": "localhost:7777",
      "connection": "keep-alive",
      "pragma": "no-cache",
      "cache-control": "no-cache",
      "dnt": "1",
      "upgrade-insecure-requests": "1",
      "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
      "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
      "sec-fetch-mode": "navigate",
      "sec-fetch-dest": "document",
      "accept-encoding": "gzip, deflate, br, zstd",
      "accept-language": "en-US,en;q=0.9",
      "cookie": "theme=light; session=e62f6xwgfdbx5mgc5rlif7g4c3cxxhfytmo2h7ki",
      "sec-ch-ua": "\"Chromium\";v=\"129\", \"Not=A?Brand\";v=\"8\"",
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": "\"macOS\"",
      "sec-fetch-site": "none",
      "sec-fetch-user": "?1",
    }
  },
  store: {},
  qi: -1,
  path: "/elysia",
  url: "http://localhost:7777/elysia",
  redirect: [Function: d0],
  set: {
    headers: {},
    status: 200,
  },
  error: 2 | var L1=Object.create;var{getPrototypeOf:T1,defineProperty:k2,getOwnPropertyNames:E1}=Object;var q1=Object.prototype.hasOwnProperty;var U2=($,W,X)=>{X=$!=null?L1(T1($)):{};const Z=W||!$||!$.__esModule?k2(X,"default",{value:$,enumerable:!0}):X;for(let j of E1($))if(!q1.call(Z,j))k2(Z,j,{get:()=>$[j],enumerable:!0});return Z};var H1=($,W)=>()=>(W||$((W={exports:{}}).exports,W),W.exports);var o0=H1((G8,$1)=>{function _3($){var W=$.indexOf("%");if(W===-1)return $;var X=$.length,Z="",j=0,J=0,Y=W,G=o2;while(W>-1&&W<X){var K=e2($[W+1],4),B=e2($[W+2],0),U=K|B,w=N2[U];if(G=N2[256+G+w],J=J<<6|U&N2[364+w],G===o2)Z+=$.slice(j,Y),Z+=J<=65535?String.fromCharCode(J):String.fromCharCode(55232+(J>>10),56320+(J&1023)),J=0,j=W+3,W=Y=$.indexOf("%",j);else if(G===w3)return null;else{if(W+=3,W<X&&$.charCodeAt(W)===37)continue;return null}}return Z+$.slice(j)}function e2($,W){var X=F3[$];return X===void 0?255:X<<W}var o2=12,w3=0,N2=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ... truncated 
3 |  * cookie
4 |  * Copyright(c) 2012-2014 Roman Shtylman
5 |  * Copyright(c) 2015 Douglas Christopher Wilson
6 |  * MIT Licensed
7 |  */var z2=Q3,D2=Y3;var J3=Object.prototype.toString,a0=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;var X1=U2(o0(),1);class w0{$;W;X;constructor($,W,X={}){this.name=$;this.jar=W;this.initial=X}get cookie(){if(!(this.name in this.jar))this.jar[this.name]=this.initial;return this.jar[this.name]}set cookie($){if(!(this.name in this.jar))this.jar[this.name]=this.initial;this.jar[this.name]=$}get value(){return this.cookie.value}set value($){this.cookie.value=$}get expires(){return this.cookie.expires}set expires($){this.cookie.expires=$,console.log(this.cookie)}get maxAge(){return this.cookie.maxAge}set maxAge($){this.cookie.maxAge=$}get domain(){return this.cookie.domain}set domain($){this.cookie.domain=$}get path(){return this.cookie.path}set path($){this.cookie.path=$}get secure(){return this.cookie.secure}set secure($){this.cookie.secure=$}get httpOnly(){return this.cookie.httpOnly}set httpOnly($){this.cookie.httpOnly=$}get sameSite(){return this.cookie.sameSite}set sameSite($){this.cookie.sameSite=$}get priority( | ... truncated 

error: NOT_FOUND
 code: "NOT_FOUND"

      at new A0 (/elysia-test/node_modules/elysia/dist/bun/index.js:7:29678)
      at anonymous (file:///elysia-test/node_modules/elysia/dist/bun/index.js:23:36)
      at compile (/elysia-test/node_modules/elysia/src/index.ts:5894:6)
      at /elysia-test/node_modules/elysia/src/index.ts:5973:8
      at module code (/elysia-test/src/index.tsx:11:4)
,
  server: [Getter],
  code: "NOT_FOUND",
}

Additional information

No response

Have you try removing the node_modules and bun.lockb and try again yet?

yes

K4leri commented 5 days ago

there is no issue here.

Your app can still have with one patameter endpoint .get("/:first, ...) that will dont understand behaviour of the previous

U can use query instead to set up additional keys

ozdevi commented 5 days ago

there is no issue here.

Your app can still have with one patameter endpoint .get("/:first, ...) that will dont understand behaviour of the previous

U can use query instead to set up additional keys

sorry. i didn't get your point. yes i can use query, wouldn't be just a workaround if api needs to utilise params? urls doesn't have one purpose that just carry data, some of needs more memorable, readable etc. your suggestion solves only carrying the data.