@visulima/connect 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## @visulima/connect [1.3.1](https://github.com/visulima/visulima/compare/@visulima/connect@1.3.0...@visulima/connect@1.3.1) (2022-12-01)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added correct folder to files key in package.json ([da9f987](https://github.com/visulima/visulima/commit/da9f9871462a0b2663046cde5f05e9a90df4c496))
7
+
1
8
  ## @visulima/connect [1.3.0](https://github.com/visulima/visulima/compare/@visulima/connect@1.2.0...@visulima/connect@1.3.0) (2022-11-16)
2
9
 
3
10
 
package/dist/index.js CHANGED
@@ -142,7 +142,7 @@ var Router = class {
142
142
  };
143
143
 
144
144
  // src/edge.ts
145
- var onNoMatch = async (request) => new Response(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : null, { status: 404 });
145
+ var onNoMatch = async (request) => new Response(request.method === "HEAD" ? null : `Route ${request.method} ${request.url} not found`, { status: 404 });
146
146
  var onError = async (error) => {
147
147
  console.error(error);
148
148
  return new Response("Internal Server Error", { status: 500 });
@@ -231,7 +231,7 @@ var express_default = expressWrapper;
231
231
  // src/node.ts
232
232
  var onNoMatch2 = async (request, response) => {
233
233
  response.statusCode = 404;
234
- response.end(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : void 0);
234
+ response.end(request.method === "HEAD" ? void 0 : `Route ${request.method} ${request.url} not found`);
235
235
  };
236
236
  var onError2 = async (error, _request, response) => {
237
237
  response.statusCode = 500;
@@ -240,7 +240,7 @@ var onError2 = async (error, _request, response) => {
240
240
  };
241
241
  function getPathname2(url) {
242
242
  const queryIndex = url.indexOf("?");
243
- return queryIndex !== -1 ? url.slice(0, Math.max(0, queryIndex)) : url;
243
+ return queryIndex === -1 ? url : url.slice(0, Math.max(0, queryIndex));
244
244
  }
245
245
  var NodeRouter = class {
246
246
  constructor(options = {}) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapter/with-zod.ts","../src/router.ts","../src/edge.ts","../src/adapter/express.ts","../src/node.ts","../src/utils/send-json.ts"],"names":["onNoMatch","onError","getPathname"],"mappings":";AAAA,OAAO,qBAAqB;AAE5B,SAAS,gBAA2B;AAIpC,IAAM,UAAU,CAMR,QACA,YACmF,OAAO,SAAkB,UAAoB,SAAS;AACzI,MAAI,qBAA8B;AAElC,MAAI;AACA,yBAAsB,MAAM,OAAO,WAAW,OAAO;AAAA,EACzD,SAAS,OAAP;AACE,QAAI,EAAE,QAAQ,IAAI;AAGlB,QAAI,iBAAiB,YAAY,OAAO,MAAM,WAAW,YAAY;AAEjE,gBAAU,MAAM,OAAO,IAAI,CAAC,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,OAAO,MAAM,SAAS,EAAE,KAAK,IAAI;AAAA,IACjG;AAEA,UAAM,gBAAgB,KAAK,OAAO;AAAA,EACtC;AAEA,SAAO,QAAQ,oBAAoB,UAAU,IAAI;AACrD;AAEJ,IAAO,mBAAQ;;;AC7Bf,SAAS,aAAa;AAkBf,IAAM,SAAN,MAAqC;AAAA,EACxC,YAAmB,OAAe,KAAY,SAA+B,CAAC,GAAG;AAA9D;AAA2B;AAAA,EAAoC;AAAA,EAE3E,IAAI,QAAyB,UAAoC,KAA0B;AAC9F,QAAI,OAAO,UAAU,YAAY;AAC7B,UAAI,QAAQ,KAAK;AAEjB,cAAQ;AAAA,IACZ;AAEA,QAAI,UAAU,IAAI;AACd,WAAK,OAAO,KAAK;AAAA,QACb,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAClB,CAAC;AAAA,IACL,OAAO;AACH,YAAM,EAAE,MAAM,QAAQ,IAAI,MAAM,KAAK;AAErC,WAAK,OAAO,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAClB,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACX;AAAA,EAEO,IAAI,SAA+C,KAAkC;AACxF,QAAI,OAAO,SAAS,cAAc,gBAAgB,QAAQ;AACtD,UAAI,QAAQ,IAAI;AAEhB,aAAO;AAAA,IACX;AAGA,UAAM,IAAI,IAAI,CAAC,cAAc;AACzB,UAAI,qBAAqB,QAAQ;AAC7B,YAAI,OAAO,SAAS;AAAU,iBAAO,UAAU,MAAM,IAAI;AACzD,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACvE;AACA,aAAO;AAAA,IACX,CAAC;AAED,UAAM,EAAE,MAAM,QAAQ,IAAI,MAAM,MAAM,IAAI;AAE1C,SAAK,OAAO,KAAK;AAAA,MACb;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,cAAc;AAAA,IAClB,CAAC;AAED,WAAO;AAAA,EACX;AAAA,EAEO,MAAM,MAAe;AACxB,WAAO,IAAI,OAAU,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC;AAAA,EAC/C;AAAA,EAEA,aAAa,KAA6B,QAAuB,YAA6C;AAC1G,QAAI,QAAQ;AAGZ,UAAM,OAAO,MAAO,IAAI,EAAE,OAAwB,GAAG,YAAY,IAAI;AAErE,WAAQ,IAAI,OAAwB,GAAG,YAAY,IAAI;AAAA,EAC3D;AAAA,EAGA,KAAK,QAAoB,UAAiC;AACtD,QAAI,aAAa;AAEjB,UAAM,MAAqB,CAAC;AAC5B,UAAM,aAAqC,CAAC;AAC5C,UAAM,SAAS,WAAW;AAG1B,WAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,UAAU;AAC1C,UACI,MAAM,WAAW,UAEd,MAAM,WAAW,MAEjB,EAAE,UAAU,MAAM,WAAW,QAClC;AACE;AAAA,MACJ;AAEA,UAAI,UAAU;AAEd,UAAI,cAAc,OAAO;AACrB,kBAAU;AAAA,MACd,WAAW,MAAM,SAAS,OAAO;AAE7B,cAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ;AAE3C,YAAI,YAAY,MAAM;AAClB;AAAA,QACJ;AAGA,YAAI,QAAQ,WAAW,QAAQ;AAC3B,iBAAO,KAAK,QAAQ,MAAM,EAAE,QAAQ,CAAC,QAAQ;AAEzC,uBAAW,OAAO,QAAQ,OAAO;AAAA,UACrC,CAAC;AAAA,QACL;AAEA,kBAAU;AAAA,MACd,WAAW,MAAM,KAAK,SAAS,GAAG;AAC9B,cAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ;AAE3C,YAAI,YAAY,MAAM;AAClB;AAAA,QACJ;AAEA,iBAAS,QAAQ,GAAG,QAAQ,MAAM,KAAK,UAAS;AAC5C,gBAAM,eAAe,MAAM,KAAK;AAIhC,qBAAW,gBAAgB,QAAQ,EAAE;AAAA,QACzC;AAEA,kBAAU;AAAA,MACd,WAAW,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACrC,kBAAU;AAAA,MACd;AAEA,UAAI,SAAS;AACT,YAAI;AAAA,UACA,GAAG,MAAM,IAAI,QAAQ,CAAC,cAAc;AAChC,gBAAI,qBAAqB,QAAQ;AAC7B,oBAAM,OAAO,UAAU;AAEvB,kBAAI,gBAAgB,SAAS,MAAM,KAAK,MAAM;AAI9C,kBAAI,cAAc,MAAM,KAAK;AACzB,gCAAgB,IAAI;AAAA,cACxB;AAGA,oBAAM,SAAS,UAAU,KAAK,QAAQ,aAAa;AAEnD,kBAAI,CAAC,OAAO,YAAY;AACpB,6BAAa;AAAA,cACjB;AAGA,qBAAO,OAAO,YAAY,OAAO,MAAM;AAEvC,qBAAO,OAAO;AAAA,YAClB;AAEA,mBAAO;AAAA,UACX,CAAC;AAAA,QACL;AACA,YAAI,CAAC,MAAM;AAAc,uBAAa;AAAA,MAC1C;AAAA,IACJ,CAAC;AAED,WAAO,EAAE,KAAK,QAAQ,YAAY,WAAW;AAAA,EACjD;AACJ;;;AChLA,IAAM,YAAY,OAAO,YAAqB,IAAI,SAAS,QAAQ,WAAW,SAAS,SAAS,QAAQ,UAAU,QAAQ,kBAAkB,MAAM,EAAE,QAAQ,IAAI,CAAC;AAEjK,IAAM,UAAU,OAAO,UAAmB;AAEtC,UAAQ,MAAM,KAAK;AACnB,SAAO,IAAI,SAAS,yBAAyB,EAAE,QAAQ,IAAI,CAAC;AAChE;AAEO,SAAS,YAAY,SAAsC;AAE9D,UAAQ,QAAQ,WAAW,IAAI,IAAI,QAAQ,GAAG,GAAG;AACrD;AAKO,IAAM,aAAN,MAAsJ;AAAA,EAUzJ,YAAY,UAAgH,CAAC,GAAG;AAThI,SAAQ,SAAS,IAAI,OAAmC;AA8CxD,SAAO,MAAqE,KAAK,IAAI,KAAK,MAAM,EAAE;AAElG,SAAO,MAAqE,KAAK,IAAI,KAAK,MAAM,KAAK;AAErG,SAAO,OAAsE,KAAK,IAAI,KAAK,MAAM,MAAM;AAEvG,SAAO,OAAsE,KAAK,IAAI,KAAK,MAAM,MAAM;AAEvG,SAAO,MAAqE,KAAK,IAAI,KAAK,MAAM,KAAK;AAErG,SAAO,QAAuE,KAAK,IAAI,KAAK,MAAM,OAAO;AAEzG,SAAO,SAAwE,KAAK,IAAI,KAAK,MAAM,QAAQ;AAhDvG,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,UAAU,QAAQ,WACf;AAAA,EAIZ;AAAA,EAEQ,IACJ,QACA,iBACA,yBACG,KACL;AACE,QAAI,OAAO,oBAAoB,YAAY,OAAO,yBAAyB,YAAY;AAEnF,YAAM,CAAC,oBAAoB;AAAA,IAC/B,WAAW,OAAO,yBAAyB,UAAU;AAEjD,UAAI,OAAO,oBAAoB,YAAY;AAEvC,cAAM,CAAC,iBAAkE,sBAAgC,eAAe,CAAC;AAAA,MAC7H,OAAO;AAEH,cAAM,IAAI,IAAI,CAAC,cAAc,iBAAkE,sBAAgC,SAAS,CAAC;AAAA,MAC7I;AAAA,IACJ,WAAW,OAAO,yBAAyB,YAAY;AAEnD,YAAM,CAAC,oBAAoB;AAAA,IAC/B;AAEA,SAAK,OAAO,IAAI,QAAQ,iBAAiB,GAAG,GAAG;AAE/C,WAAO;AAAA,EACX;AAAA,EAgBO,IACH,SACG,KACL;AACE,QAAI,OAAO,SAAS,cAAc,gBAAgB,YAAY;AAC1D,UAAI,QAAQ,IAAI;AAEhB,aAAO;AAAA,IACX;AAEA,SAAK,OAAO,IAAI,MAAM,GAAG,IAAI,IAAI,CAAC,cAAe,qBAAqB,aAAa,UAAU,SAAS,SAAU,CAAC;AAEjH,WAAO;AAAA,EACX;AAAA,EAGQ,eAAe,SAAmD,YAAoD;AAC1H,YAAQ,SAAS;AAAA,MACb,GAAG,WAAW;AAAA,MACd,GAAG,QAAQ;AAAA,IACf;AAAA,EACJ;AAAA,EAEO,QAAQ;AACX,UAAM,IAAI,IAAI,WAA0C,EAAE,WAAW,KAAK,WAAW,SAAS,KAAK,QAAQ,CAAC;AAE5G,MAAE,SAAS,KAAK,OAAO,MAAM;AAE7B,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,IAAI,SAAY,UAAmB;AAErC,UAAM,SAAS,KAAK,OAAO,KAAK,QAAQ,QAAsB,YAAY,OAAO,CAAC;AAElF,QAAI,OAAO,IAAI,WAAW,GAAG;AACzB;AAAA,IACJ;AAEA,SAAK,eAAe,SAAS,MAAM;AAGnC,WAAO,OAAO,KAAK,OAAO,KAAK,SAAS,QAAQ;AAAA,EACpD;AAAA,EAEA,UAAU;AACN,UAAM,EAAE,OAAO,IAAI,KAAK;AAExB,WAAO,OAAO,SAAY,aAAoC;AAE1D,YAAM,SAAS,KAAK,OAAO,KAAK,QAAQ,QAAsB,YAAY,OAAO,CAAC;AAElF,WAAK,eAAe,SAAS,MAAM;AAEnC,UAAI;AACA,eAAO,OAAO,OAAO,IAAI,WAAW,KAAK,OAAO,aAC1C,KAAK,UAAU,SAAS,UAAU,MAAM,IACxC,OAAO,KAAK,OAAO,KAAK,SAAS,QAAQ;AAAA,MACnD,SAAS,OAAP;AACE,eAAO,KAAK,QAAQ,OAAO,SAAS,UAAU,MAAM;AAAA,MACxD;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,SAAS,iBACZ,UAA+G,CAAC,GAClH;AACE,SAAO,IAAI,WAAiC,OAAO;AACvD;;;AC7JA,IAAM,iBAAiB,CACnB,cAE8C,CAAC,SAAS,UAAU,SAAS,IAAI,QAAc,CAAC,SAAS,WAAW;AAC9G,YAAU,SAAS,UAAU,CAAC,UAAW,QAAQ,OAAO,KAAK,IAAI,QAAQ,CAAE;AAE/E,CAAC,EAAE,KAAK,IAAI;AAIhB,IAAO,kBAAQ;;;ACEf,IAAMA,aAAY,OAAO,SAA0B,aAA6B;AAC5E,WAAS,aAAa;AACtB,WAAS,IAAI,QAAQ,WAAW,SAAS,SAAS,QAAQ,UAAU,QAAQ,kBAAkB,MAAS;AAC3G;AAEA,IAAMC,WAAU,OAAO,OAAgB,UAA2B,aAA6B;AAC3F,WAAS,aAAa;AAEtB,UAAQ,MAAM,KAAK;AAEnB,WAAS,IAAI,uBAAuB;AACxC;AAEO,SAASC,aAAY,KAAa;AACrC,QAAM,aAAa,IAAI,QAAQ,GAAG;AAElC,SAAO,eAAe,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI;AACvE;AAIO,IAAM,aAAN,MAIL;AAAA,EAUE,YAAY,UAAsH,CAAC,GAAG;AATtI,SAAQ,SAAS,IAAI,OAA0C;AA6C/D,SAAO,MAA4E,KAAK,IAAI,KAAK,MAAM,EAAE;AAEzG,SAAO,MAA4E,KAAK,IAAI,KAAK,MAAM,KAAK;AAE5G,SAAO,OAA6E,KAAK,IAAI,KAAK,MAAM,MAAM;AAE9G,SAAO,OAA6E,KAAK,IAAI,KAAK,MAAM,MAAM;AAE9G,SAAO,MAA4E,KAAK,IAAI,KAAK,MAAM,KAAK;AAE5G,SAAO,QAA8E,KAAK,IAAI,KAAK,MAAM,OAAO;AAEhH,SAAO,SAA+E,KAAK,IAAI,KAAK,MAAM,QAAQ;AA/C9G,SAAK,YAAY,QAAQ,aAAaF;AACtC,SAAK,UAAU,QAAQ,WAAWC;AAAA,EACtC;AAAA,EAEQ,IACJ,QACA,iBACA,yBACG,KACL;AACE,QAAI,OAAO,oBAAoB,YAAY,OAAO,yBAAyB,YAAY;AAEnF,YAAM,CAAC,oBAAoB;AAAA,IAC/B,WAAW,OAAO,yBAAyB,UAAU;AAEjD,UAAI,OAAO,oBAAoB,YAAY;AAEvC,cAAM,CAAC;AAAA,UACH;AAAA,UACA;AAAA,QACJ,CAAC;AAAA,MACL,OAAO;AAEH,cAAM,IAAI,IAAI,CAAC,cAAc,iBAAgF,sBAAgC,SAAS,CAAC;AAAA,MAC3J;AAAA,IACJ,WAAW,OAAO,yBAAyB,YAAY;AAEnD,YAAM,CAAC,oBAAoB;AAAA,IAC/B;AAEA,SAAK,OAAO,IAAI,QAAQ,iBAAiB,GAAG,GAAG;AAE/C,WAAO;AAAA,EACX;AAAA,EAgBO,IACH,SACG,KACL;AACE,QAAI,OAAO,SAAS,cAAc,gBAAgB,YAAY;AAC1D,UAAI,QAAQ,IAAI;AAEhB,aAAO;AAAA,IACX;AACA,SAAK,OAAO,IAAI,MAAM,GAAG,IAAI,IAAI,CAAC,cAAe,qBAAqB,aAAa,UAAU,SAAS,SAAU,CAAC;AAEjH,WAAO;AAAA,EACX;AAAA,EAGQ,eAAe,SAAyD,YAA2D;AACvI,YAAQ,SAAS;AAAA,MACb,GAAG,WAAW;AAAA,MACd,GAAG,QAAQ;AAAA,IACf;AAAA,EACJ;AAAA,EAEO,QAAQ;AACX,UAAM,IAAI,IAAI,WAAsC,EAAE,WAAW,KAAK,WAAW,SAAS,KAAK,QAAQ,CAAC;AAExG,MAAE,SAAS,KAAK,OAAO,MAAM;AAE7B,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,IAAI,SAAkB,UAAsC;AAE9D,UAAM,SAAS,KAAK,OAAO,KAAK,QAAQ,QAAsBC,aAAY,QAAQ,GAAa,CAAC;AAEhG,QAAI,OAAO,IAAI,WAAW,GAAG;AACzB;AAAA,IACJ;AAEA,SAAK,eAAe,SAAS,MAAM;AAGnC,WAAO,OAAO,KAAK,OAAO,KAAK,SAAS,QAAQ;AAAA,EACpD;AAAA,EAEA,UAAU;AACN,UAAM,EAAE,OAAO,IAAI,KAAK;AAExB,WAAO,OAAO,SAAkB,aAAuB;AAEnD,YAAM,SAAS,KAAK,OAAO,KAAK,QAAQ,QAAsBA,aAAY,QAAQ,GAAa,CAAC;AAEhG,WAAK,eAAe,SAAS,MAAM;AAEnC,UAAI;AACA,eAAO,OAAO,IAAI,WAAW,KAAK,OAAO,aAAa,KAAK,UAAU,SAAS,UAAU,MAAM,IAAI,OAAO,KAAK,OAAO,KAAK,SAAS,QAAQ;AAAA,MAC/I,SAAS,OAAP;AACE,cAAM,KAAK,QAAQ,OAAO,SAAS,UAAU,MAAM;AAAA,MACvD;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,IAAM,eAAe,CAKpB,UAAsH,CAAC,MACtH,IAAI,WAAsC,OAAO;;;ACpK1D,IAAM,WAAW,CAAC,UAA0B,YAAoB,aAAwB;AAEpF,WAAS,UAAU,gBAAgB,iCAAiC;AAEpE,WAAS,aAAa;AACtB,WAAS,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAClD;AAEA,IAAO,oBAAQ","sourcesContent":["import createHttpError from \"http-errors\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodError, ZodObject } from \"zod\";\n\nimport type { Nextable, NextHandler } from \"../types\";\n\nconst withZod = <\n Request extends object,\n Response extends unknown,\n Handler extends Nextable<any>,\n Schema extends ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n >(\n schema: Schema,\n handler: Handler,\n ): ((request: Request, response: Response, next: NextHandler) => Promise<Response>) => async (request: Request, response: Response, next) => {\n let transformedRequest: Request = request;\n\n try {\n transformedRequest = (await schema.parseAsync(request)) as Request;\n } catch (error: any) {\n let { message } = error;\n\n // eslint-disable-next-line unicorn/consistent-destructuring\n if (error instanceof ZodError && typeof error.format === \"function\") {\n // eslint-disable-next-line unicorn/consistent-destructuring\n message = error.issues.map((issue) => `${issue.path.join(\"/\")} - ${issue.message}`).join(\"/n\");\n }\n\n throw createHttpError(422, message);\n }\n\n return handler(transformedRequest, response, next);\n };\n\nexport default withZod;\n","/**\n * Agnostic router class\n * Adapted from lukeed/trouter library:\n * https://github.com/lukeed/trouter/blob/master/index.mjs\n */\nimport { parse } from \"regexparam\";\n\nimport type {\n FindResult, FunctionLike, HttpMethod, Nextable, RouteMatch,\n} from \"./types\";\n\nexport type Route<H> = {\n method: HttpMethod | \"\";\n fns: (H | Router<H extends FunctionLike ? H : never>)[];\n isMiddleware: boolean;\n} & (\n | {\n keys: string[] | false;\n pattern: RegExp;\n }\n | { matchAll: true }\n);\n\nexport class Router<H extends FunctionLike> {\n constructor(public base: string = \"/\", public routes: Route<Nextable<H>>[] = []) {}\n\n public add(method: HttpMethod | \"\", route: RouteMatch | Nextable<H>, ...fns: Nextable<H>[]): this {\n if (typeof route === \"function\") {\n fns.unshift(route);\n // eslint-disable-next-line no-param-reassign\n route = \"\";\n }\n\n if (route === \"\") {\n this.routes.push({\n matchAll: true,\n method,\n fns,\n isMiddleware: false,\n });\n } else {\n const { keys, pattern } = parse(route);\n\n this.routes.push({\n keys,\n pattern,\n method,\n fns,\n isMiddleware: false,\n });\n }\n\n return this;\n }\n\n public use(base: RouteMatch | Nextable<H> | Router<H>, ...fns: (Nextable<H> | Router<H>)[]) {\n if (typeof base === \"function\" || base instanceof Router) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n // mount subrouter\n // eslint-disable-next-line no-param-reassign\n fns = fns.map((function_) => {\n if (function_ instanceof Router) {\n if (typeof base === \"string\") return function_.clone(base);\n throw new Error(\"Mounting a router to RegExp base is not supported\");\n }\n return function_;\n });\n\n const { keys, pattern } = parse(base, true);\n\n this.routes.push({\n keys,\n pattern,\n method: \"\",\n fns,\n isMiddleware: true,\n });\n\n return this;\n }\n\n public clone(base?: string) {\n return new Router<H>(base, [...this.routes]);\n }\n\n static async exec<H extends FunctionLike>(fns: Nextable<H>[], ...arguments_: Parameters<H>): Promise<unknown> {\n let index = 0;\n\n // eslint-disable-next-line no-plusplus\n const next = () => (fns[++index] as FunctionLike)(...arguments_, next);\n\n return (fns[index] as FunctionLike)(...arguments_, next);\n }\n\n // eslint-disable-next-line radar/cognitive-complexity\n find(method: HttpMethod, pathname: string): FindResult<H> {\n let middleOnly = true;\n\n const fns: Nextable<H>[] = [];\n const parameters: Record<string, string> = {};\n const isHead = method === \"HEAD\";\n\n // eslint-disable-next-line radar/cognitive-complexity\n Object.values(this.routes).forEach((route) => {\n if (\n route.method !== method\n // matches any method\n && route.method !== \"\"\n // The HEAD method requests that the target resource transfer a representation of its state, as for a GET request...\n && !(isHead && route.method === \"GET\")\n ) {\n return;\n }\n\n let matched = false;\n\n if (\"matchAll\" in route) {\n matched = true;\n } else if (route.keys === false) {\n // routes.key is RegExp: https://github.com/lukeed/regexparam/blob/master/src/index.js#L2\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n // eslint-disable-next-line no-void\n if (matches.groups !== void 0) {\n Object.keys(matches.groups).forEach((key) => {\n // @ts-ignore @TODO: fix this\n parameters[key] = matches.groups[key] as string;\n });\n }\n\n matched = true;\n } else if (route.keys.length > 0) {\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n for (let index = 0; index < route.keys.length;) {\n const parameterKey = route.keys[index];\n\n // @ts-ignore @TODO: fix this\n // eslint-disable-next-line no-plusplus\n parameters[parameterKey] = matches[++index];\n }\n\n matched = true;\n } else if (route.pattern.test(pathname)) {\n matched = true;\n } // else not a match\n\n if (matched) {\n fns.push(\n ...route.fns.flatMap((function_) => {\n if (function_ instanceof Router) {\n const base = function_.base as string;\n\n let stripPathname = pathname.slice(base.length);\n\n // fix stripped pathname, not sure why this happens\n // eslint-disable-next-line eqeqeq\n if (stripPathname[0] != \"/\") {\n stripPathname = `/${stripPathname}`;\n }\n\n // eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n const result = function_.find(method, stripPathname);\n\n if (!result.middleOnly) {\n middleOnly = false;\n }\n\n // merge params\n Object.assign(parameters, result.params);\n\n return result.fns;\n }\n\n return function_;\n }),\n );\n if (!route.isMiddleware) middleOnly = false;\n }\n });\n\n return { fns, params: parameters, middleOnly };\n }\n}\n","import type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport { Route, Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\n// eslint-disable-next-line max-len\nconst onNoMatch = async (request: Request) => new Response(request.method !== \"HEAD\" ? `Route ${request.method} ${request.url} not found` : null, { status: 404 });\n\nconst onError = async (error: unknown) => {\n // eslint-disable-next-line no-console\n console.error(error);\n return new Response(\"Internal Server Error\", { status: 500 });\n};\n\nexport function getPathname(request: Request & { nextUrl?: URL }) {\n // eslint-disable-next-line compat/compat\n return (request.nextUrl || new URL(request.url)).pathname;\n}\n\n// eslint-disable-next-line max-len\nexport type RequestHandler<R extends Request, Context> = (request: R, context_: Context) => ValueOrPromise<Response | void>;\n\nexport class EdgeRouter<R extends Request = Request, Context = unknown, RResponse extends Response = Response, Schema extends AnyZodObject = ZodObject<any>> {\n private router = new Router<RequestHandler<R, Context>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch as unknown as RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n this.onError = options.onError\n || (onError as unknown as (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>);\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<R, Context>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<R, Context>>,\n ...fns: Nextable<RequestHandler<R, Context>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, routeOrFunction)];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>,\n ...fns: (Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>)[]\n ) {\n if (typeof base === \"function\" || base instanceof EdgeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n\n this.router.use(base, ...fns.map((function_) => (function_ instanceof EdgeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: R & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<R, Context>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new EdgeRouter<R, Context, RResponse, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: R, context_: Context) {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, context_);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: R, context_: Context): Promise<any> => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n this.prepareRequest(request, result);\n\n try {\n return await (result.fns.length === 0 || result.middleOnly\n ? this.onNoMatch(request, context_, routes)\n : Router.exec(result.fns, request, context_));\n } catch (error) {\n return this.onError(error, request, context_, routes);\n }\n };\n }\n}\n\nexport function createEdgeRouter<R extends Request, Context>(\n options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, Response, Route<Nextable<FunctionLike>>[]>> = {},\n) {\n return new EdgeRouter<R, Context, Response>(options);\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { RequestHandler } from \"../node\";\nimport type { Nextable } from \"../types\";\n\ntype NextFunction = (error?: any) => void;\n\nconst expressWrapper = <Request extends IncomingMessage, Response extends ServerResponse>(\n function_: ExpressRequestHandler<Request, Response>,\n // eslint-disable-next-line compat/compat\n): Nextable<RequestHandler<Request, Response>> => (request, response, next) => new Promise<void>((resolve, reject) => {\n function_(request, response, (error) => (error ? reject(error) : resolve()));\n // eslint-disable-next-line promise/no-callback-in-promise\n }).then(next);\n\nexport type ExpressRequestHandler<Request, Response> = (request: Request, response: Response, next: NextFunction) => void;\n\nexport default expressWrapper;\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport type { Route } from \"./router\";\nimport { Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\nconst onNoMatch = async (request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 404;\n response.end(request.method !== \"HEAD\" ? `Route ${request.method} ${request.url} not found` : undefined);\n};\n\nconst onError = async (error: unknown, _request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 500;\n // eslint-disable-next-line no-console\n console.error(error);\n\n response.end(\"Internal Server Error\");\n};\n\nexport function getPathname(url: string) {\n const queryIndex = url.indexOf(\"?\");\n\n return queryIndex !== -1 ? url.slice(0, Math.max(0, queryIndex)) : url;\n}\n\nexport type RequestHandler<Request extends IncomingMessage, Response extends ServerResponse> = (request: Request, response: Response) => ValueOrPromise<void>;\n\nexport class NodeRouter<\n Request extends IncomingMessage = IncomingMessage,\n Response extends ServerResponse = ServerResponse,\n Schema extends AnyZodObject = ZodObject<any>,\n> {\n private router = new Router<RequestHandler<Request, Response>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch;\n this.onError = options.onError || onError;\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<Request, Response>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<Request, Response>>,\n ...fns: Nextable<RequestHandler<Request, Response>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(\n zodOrRouteOrFunction as Schema,\n routeOrFunction,\n )];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>,\n ...fns: (Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>)[]\n ) {\n if (typeof base === \"function\" || base instanceof NodeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n this.router.use(base, ...fns.map((function_) => (function_ instanceof NodeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: Request & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<Request, Response>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new NodeRouter<Request, Response, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: Request, response: Response): Promise<unknown> {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, response);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: Request, response: Response) => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n this.prepareRequest(request, result);\n\n try {\n await (result.fns.length === 0 || result.middleOnly ? this.onNoMatch(request, response, routes) : Router.exec(result.fns, request, response));\n } catch (error) {\n await this.onError(error, request, response, routes);\n }\n };\n }\n}\n\nexport const createRouter = <\n Request extends IncomingMessage,\n Response extends ServerResponse,\n Schema extends AnyZodObject = ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n>(\n options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {},\n ) => new NodeRouter<Request, Response, Schema>(options);\n","import type { ServerResponse } from \"node:http\";\n\n/**\n * Send `JSON` object\n * @param {ServerResponse} response response object\n * @param {number} statusCode\n * @param {any} jsonBody of data\n */\nconst sendJson = (response: ServerResponse, statusCode: number, jsonBody: any): void => {\n // Set header to application/json\n response.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n\n response.statusCode = statusCode;\n response.end(JSON.stringify(jsonBody, null, 2));\n};\n\nexport default sendJson;\n"]}
1
+ {"version":3,"sources":["../src/adapter/with-zod.ts","../src/router.ts","../src/edge.ts","../src/adapter/express.ts","../src/node.ts","../src/utils/send-json.ts"],"names":["onNoMatch","onError","getPathname"],"mappings":"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","sourcesContent":["import createHttpError from \"http-errors\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodError, ZodObject } from \"zod\";\n\nimport type { Nextable, NextHandler } from \"../types\";\n\nconst withZod = <\n Request extends object,\n Response extends unknown,\n Handler extends Nextable<any>,\n Schema extends ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n >(\n schema: Schema,\n handler: Handler,\n ): ((request: Request, response: Response, next: NextHandler) => Promise<Response>) => async (request: Request, response: Response, next) => {\n let transformedRequest: Request = request;\n\n try {\n transformedRequest = (await schema.parseAsync(request)) as Request;\n } catch (error: any) {\n let { message } = error;\n\n // eslint-disable-next-line unicorn/consistent-destructuring\n if (error instanceof ZodError && typeof error.format === \"function\") {\n // eslint-disable-next-line unicorn/consistent-destructuring\n message = error.issues.map((issue) => `${issue.path.join(\"/\")} - ${issue.message}`).join(\"/n\");\n }\n\n throw createHttpError(422, message);\n }\n\n return handler(transformedRequest, response, next);\n };\n\nexport default withZod;\n","/**\n * Agnostic router class\n * Adapted from lukeed/trouter library:\n * https://github.com/lukeed/trouter/blob/master/index.mjs\n */\nimport { parse } from \"regexparam\";\n\nimport type {\n FindResult, FunctionLike, HttpMethod, Nextable, RouteMatch,\n} from \"./types\";\n\nexport type Route<H> = {\n method: HttpMethod | \"\";\n fns: (H | Router<H extends FunctionLike ? H : never>)[];\n isMiddleware: boolean;\n} & (\n | {\n keys: string[] | false;\n pattern: RegExp;\n }\n | { matchAll: true }\n);\n\nexport class Router<H extends FunctionLike> {\n constructor(public base: string = \"/\", public routes: Route<Nextable<H>>[] = []) {}\n\n public add(method: HttpMethod | \"\", route: RouteMatch | Nextable<H>, ...fns: Nextable<H>[]): this {\n if (typeof route === \"function\") {\n fns.unshift(route);\n // eslint-disable-next-line no-param-reassign\n route = \"\";\n }\n\n if (route === \"\") {\n this.routes.push({\n matchAll: true,\n method,\n fns,\n isMiddleware: false,\n });\n } else {\n const { keys, pattern } = parse(route);\n\n this.routes.push({\n keys,\n pattern,\n method,\n fns,\n isMiddleware: false,\n });\n }\n\n return this;\n }\n\n public use(base: RouteMatch | Nextable<H> | Router<H>, ...fns: (Nextable<H> | Router<H>)[]) {\n if (typeof base === \"function\" || base instanceof Router) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n // mount subrouter\n // eslint-disable-next-line no-param-reassign\n fns = fns.map((function_) => {\n if (function_ instanceof Router) {\n if (typeof base === \"string\") return function_.clone(base);\n throw new Error(\"Mounting a router to RegExp base is not supported\");\n }\n return function_;\n });\n\n const { keys, pattern } = parse(base, true);\n\n this.routes.push({\n keys,\n pattern,\n method: \"\",\n fns,\n isMiddleware: true,\n });\n\n return this;\n }\n\n public clone(base?: string) {\n return new Router<H>(base, [...this.routes]);\n }\n\n static async exec<H extends FunctionLike>(fns: Nextable<H>[], ...arguments_: Parameters<H>): Promise<unknown> {\n let index = 0;\n\n // eslint-disable-next-line no-plusplus\n const next = () => (fns[++index] as FunctionLike)(...arguments_, next);\n\n return (fns[index] as FunctionLike)(...arguments_, next);\n }\n\n // eslint-disable-next-line radar/cognitive-complexity\n find(method: HttpMethod, pathname: string): FindResult<H> {\n let middleOnly = true;\n\n const fns: Nextable<H>[] = [];\n const parameters: Record<string, string> = {};\n const isHead = method === \"HEAD\";\n\n // eslint-disable-next-line radar/cognitive-complexity\n Object.values(this.routes).forEach((route) => {\n if (\n route.method !== method\n // matches any method\n && route.method !== \"\"\n // The HEAD method requests that the target resource transfer a representation of its state, as for a GET request...\n && !(isHead && route.method === \"GET\")\n ) {\n return;\n }\n\n let matched = false;\n\n if (\"matchAll\" in route) {\n matched = true;\n } else if (route.keys === false) {\n // routes.key is RegExp: https://github.com/lukeed/regexparam/blob/master/src/index.js#L2\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n // eslint-disable-next-line no-void\n if (matches.groups !== void 0) {\n Object.keys(matches.groups).forEach((key) => {\n // @ts-ignore @TODO: fix this\n parameters[key] = matches.groups[key] as string;\n });\n }\n\n matched = true;\n } else if (route.keys.length > 0) {\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n for (let index = 0; index < route.keys.length;) {\n const parameterKey = route.keys[index];\n\n // @ts-ignore @TODO: fix this\n // eslint-disable-next-line no-plusplus\n parameters[parameterKey] = matches[++index];\n }\n\n matched = true;\n } else if (route.pattern.test(pathname)) {\n matched = true;\n } // else not a match\n\n if (matched) {\n fns.push(\n ...route.fns.flatMap((function_) => {\n if (function_ instanceof Router) {\n const base = function_.base as string;\n\n let stripPathname = pathname.slice(base.length);\n\n // fix stripped pathname, not sure why this happens\n // eslint-disable-next-line eqeqeq\n if (stripPathname[0] != \"/\") {\n stripPathname = `/${stripPathname}`;\n }\n\n // eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n const result = function_.find(method, stripPathname);\n\n if (!result.middleOnly) {\n middleOnly = false;\n }\n\n // merge params\n Object.assign(parameters, result.params);\n\n return result.fns;\n }\n\n return function_;\n }),\n );\n if (!route.isMiddleware) middleOnly = false;\n }\n });\n\n return { fns, params: parameters, middleOnly };\n }\n}\n","import type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport { Route, Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\n// eslint-disable-next-line max-len\nconst onNoMatch = async (request: Request) => new Response(request.method === \"HEAD\" ? null : `Route ${request.method} ${request.url} not found`, { status: 404 });\n\nconst onError = async (error: unknown) => {\n // eslint-disable-next-line no-console\n console.error(error);\n return new Response(\"Internal Server Error\", { status: 500 });\n};\n\nexport function getPathname(request: Request & { nextUrl?: URL }) {\n // eslint-disable-next-line compat/compat\n return (request.nextUrl || new URL(request.url)).pathname;\n}\n\n// eslint-disable-next-line max-len\nexport type RequestHandler<R extends Request, Context> = (request: R, context_: Context) => ValueOrPromise<Response | void>;\n\nexport class EdgeRouter<R extends Request = Request, Context = unknown, RResponse extends Response = Response, Schema extends AnyZodObject = ZodObject<any>> {\n private router = new Router<RequestHandler<R, Context>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch as unknown as RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n this.onError = options.onError\n || (onError as unknown as (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>);\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<R, Context>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<R, Context>>,\n ...fns: Nextable<RequestHandler<R, Context>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, routeOrFunction)];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>,\n ...fns: (Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>)[]\n ) {\n if (typeof base === \"function\" || base instanceof EdgeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n\n this.router.use(base, ...fns.map((function_) => (function_ instanceof EdgeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: R & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<R, Context>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new EdgeRouter<R, Context, RResponse, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: R, context_: Context) {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, context_);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: R, context_: Context): Promise<any> => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n this.prepareRequest(request, result);\n\n try {\n return await (result.fns.length === 0 || result.middleOnly\n ? this.onNoMatch(request, context_, routes)\n : Router.exec(result.fns, request, context_));\n } catch (error) {\n return this.onError(error, request, context_, routes);\n }\n };\n }\n}\n\nexport function createEdgeRouter<R extends Request, Context>(\n options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, Response, Route<Nextable<FunctionLike>>[]>> = {},\n) {\n return new EdgeRouter<R, Context, Response>(options);\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { RequestHandler } from \"../node\";\nimport type { Nextable } from \"../types\";\n\ntype NextFunction = (error?: any) => void;\n\nconst expressWrapper = <Request extends IncomingMessage, Response extends ServerResponse>(\n function_: ExpressRequestHandler<Request, Response>,\n // eslint-disable-next-line compat/compat\n): Nextable<RequestHandler<Request, Response>> => (request, response, next) => new Promise<void>((resolve, reject) => {\n function_(request, response, (error) => (error ? reject(error) : resolve()));\n // eslint-disable-next-line promise/no-callback-in-promise\n }).then(next);\n\nexport type ExpressRequestHandler<Request, Response> = (request: Request, response: Response, next: NextFunction) => void;\n\nexport default expressWrapper;\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport type { Route } from \"./router\";\nimport { Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\nconst onNoMatch = async (request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 404;\n response.end(request.method === \"HEAD\" ? undefined : `Route ${request.method} ${request.url} not found`);\n};\n\nconst onError = async (error: unknown, _request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 500;\n // eslint-disable-next-line no-console\n console.error(error);\n\n response.end(\"Internal Server Error\");\n};\n\nexport function getPathname(url: string) {\n const queryIndex = url.indexOf(\"?\");\n\n return queryIndex === -1 ? url : url.slice(0, Math.max(0, queryIndex));\n}\n\nexport type RequestHandler<Request extends IncomingMessage, Response extends ServerResponse> = (request: Request, response: Response) => ValueOrPromise<void>;\n\nexport class NodeRouter<\n Request extends IncomingMessage = IncomingMessage,\n Response extends ServerResponse = ServerResponse,\n Schema extends AnyZodObject = ZodObject<any>,\n> {\n private router = new Router<RequestHandler<Request, Response>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch;\n this.onError = options.onError || onError;\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<Request, Response>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<Request, Response>>,\n ...fns: Nextable<RequestHandler<Request, Response>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(\n zodOrRouteOrFunction as Schema,\n routeOrFunction,\n )];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>,\n ...fns: (Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>)[]\n ) {\n if (typeof base === \"function\" || base instanceof NodeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n this.router.use(base, ...fns.map((function_) => (function_ instanceof NodeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: Request & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<Request, Response>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new NodeRouter<Request, Response, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: Request, response: Response): Promise<unknown> {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, response);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: Request, response: Response) => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n this.prepareRequest(request, result);\n\n try {\n await (result.fns.length === 0 || result.middleOnly ? this.onNoMatch(request, response, routes) : Router.exec(result.fns, request, response));\n } catch (error) {\n await this.onError(error, request, response, routes);\n }\n };\n }\n}\n\nexport const createRouter = <\n Request extends IncomingMessage,\n Response extends ServerResponse,\n Schema extends AnyZodObject = ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n>(\n options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {},\n ) => new NodeRouter<Request, Response, Schema>(options);\n","import type { ServerResponse } from \"node:http\";\n\n/**\n * Send `JSON` object\n * @param {ServerResponse} response response object\n * @param {number} statusCode\n * @param {any} jsonBody of data\n */\nconst sendJson = (response: ServerResponse, statusCode: number, jsonBody: any): void => {\n // Set header to application/json\n response.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n\n response.statusCode = statusCode;\n response.end(JSON.stringify(jsonBody, null, 2));\n};\n\nexport default sendJson;\n"]}
package/dist/index.mjs CHANGED
@@ -142,7 +142,7 @@ var Router = class {
142
142
  };
143
143
 
144
144
  // src/edge.ts
145
- var onNoMatch = async (request) => new Response(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : null, { status: 404 });
145
+ var onNoMatch = async (request) => new Response(request.method === "HEAD" ? null : `Route ${request.method} ${request.url} not found`, { status: 404 });
146
146
  var onError = async (error) => {
147
147
  console.error(error);
148
148
  return new Response("Internal Server Error", { status: 500 });
@@ -231,7 +231,7 @@ var express_default = expressWrapper;
231
231
  // src/node.ts
232
232
  var onNoMatch2 = async (request, response) => {
233
233
  response.statusCode = 404;
234
- response.end(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : void 0);
234
+ response.end(request.method === "HEAD" ? void 0 : `Route ${request.method} ${request.url} not found`);
235
235
  };
236
236
  var onError2 = async (error, _request, response) => {
237
237
  response.statusCode = 500;
@@ -240,7 +240,7 @@ var onError2 = async (error, _request, response) => {
240
240
  };
241
241
  function getPathname2(url) {
242
242
  const queryIndex = url.indexOf("?");
243
- return queryIndex !== -1 ? url.slice(0, Math.max(0, queryIndex)) : url;
243
+ return queryIndex === -1 ? url : url.slice(0, Math.max(0, queryIndex));
244
244
  }
245
245
  var NodeRouter = class {
246
246
  constructor(options = {}) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapter/with-zod.ts","../src/router.ts","../src/edge.ts","../src/adapter/express.ts","../src/node.ts","../src/utils/send-json.ts"],"sourcesContent":["import createHttpError from \"http-errors\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodError, ZodObject } from \"zod\";\n\nimport type { Nextable, NextHandler } from \"../types\";\n\nconst withZod = <\n Request extends object,\n Response extends unknown,\n Handler extends Nextable<any>,\n Schema extends ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n >(\n schema: Schema,\n handler: Handler,\n ): ((request: Request, response: Response, next: NextHandler) => Promise<Response>) => async (request: Request, response: Response, next) => {\n let transformedRequest: Request = request;\n\n try {\n transformedRequest = (await schema.parseAsync(request)) as Request;\n } catch (error: any) {\n let { message } = error;\n\n // eslint-disable-next-line unicorn/consistent-destructuring\n if (error instanceof ZodError && typeof error.format === \"function\") {\n // eslint-disable-next-line unicorn/consistent-destructuring\n message = error.issues.map((issue) => `${issue.path.join(\"/\")} - ${issue.message}`).join(\"/n\");\n }\n\n throw createHttpError(422, message);\n }\n\n return handler(transformedRequest, response, next);\n };\n\nexport default withZod;\n","/**\n * Agnostic router class\n * Adapted from lukeed/trouter library:\n * https://github.com/lukeed/trouter/blob/master/index.mjs\n */\nimport { parse } from \"regexparam\";\n\nimport type {\n FindResult, FunctionLike, HttpMethod, Nextable, RouteMatch,\n} from \"./types\";\n\nexport type Route<H> = {\n method: HttpMethod | \"\";\n fns: (H | Router<H extends FunctionLike ? H : never>)[];\n isMiddleware: boolean;\n} & (\n | {\n keys: string[] | false;\n pattern: RegExp;\n }\n | { matchAll: true }\n);\n\nexport class Router<H extends FunctionLike> {\n constructor(public base: string = \"/\", public routes: Route<Nextable<H>>[] = []) {}\n\n public add(method: HttpMethod | \"\", route: RouteMatch | Nextable<H>, ...fns: Nextable<H>[]): this {\n if (typeof route === \"function\") {\n fns.unshift(route);\n // eslint-disable-next-line no-param-reassign\n route = \"\";\n }\n\n if (route === \"\") {\n this.routes.push({\n matchAll: true,\n method,\n fns,\n isMiddleware: false,\n });\n } else {\n const { keys, pattern } = parse(route);\n\n this.routes.push({\n keys,\n pattern,\n method,\n fns,\n isMiddleware: false,\n });\n }\n\n return this;\n }\n\n public use(base: RouteMatch | Nextable<H> | Router<H>, ...fns: (Nextable<H> | Router<H>)[]) {\n if (typeof base === \"function\" || base instanceof Router) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n // mount subrouter\n // eslint-disable-next-line no-param-reassign\n fns = fns.map((function_) => {\n if (function_ instanceof Router) {\n if (typeof base === \"string\") return function_.clone(base);\n throw new Error(\"Mounting a router to RegExp base is not supported\");\n }\n return function_;\n });\n\n const { keys, pattern } = parse(base, true);\n\n this.routes.push({\n keys,\n pattern,\n method: \"\",\n fns,\n isMiddleware: true,\n });\n\n return this;\n }\n\n public clone(base?: string) {\n return new Router<H>(base, [...this.routes]);\n }\n\n static async exec<H extends FunctionLike>(fns: Nextable<H>[], ...arguments_: Parameters<H>): Promise<unknown> {\n let index = 0;\n\n // eslint-disable-next-line no-plusplus\n const next = () => (fns[++index] as FunctionLike)(...arguments_, next);\n\n return (fns[index] as FunctionLike)(...arguments_, next);\n }\n\n // eslint-disable-next-line radar/cognitive-complexity\n find(method: HttpMethod, pathname: string): FindResult<H> {\n let middleOnly = true;\n\n const fns: Nextable<H>[] = [];\n const parameters: Record<string, string> = {};\n const isHead = method === \"HEAD\";\n\n // eslint-disable-next-line radar/cognitive-complexity\n Object.values(this.routes).forEach((route) => {\n if (\n route.method !== method\n // matches any method\n && route.method !== \"\"\n // The HEAD method requests that the target resource transfer a representation of its state, as for a GET request...\n && !(isHead && route.method === \"GET\")\n ) {\n return;\n }\n\n let matched = false;\n\n if (\"matchAll\" in route) {\n matched = true;\n } else if (route.keys === false) {\n // routes.key is RegExp: https://github.com/lukeed/regexparam/blob/master/src/index.js#L2\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n // eslint-disable-next-line no-void\n if (matches.groups !== void 0) {\n Object.keys(matches.groups).forEach((key) => {\n // @ts-ignore @TODO: fix this\n parameters[key] = matches.groups[key] as string;\n });\n }\n\n matched = true;\n } else if (route.keys.length > 0) {\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n for (let index = 0; index < route.keys.length;) {\n const parameterKey = route.keys[index];\n\n // @ts-ignore @TODO: fix this\n // eslint-disable-next-line no-plusplus\n parameters[parameterKey] = matches[++index];\n }\n\n matched = true;\n } else if (route.pattern.test(pathname)) {\n matched = true;\n } // else not a match\n\n if (matched) {\n fns.push(\n ...route.fns.flatMap((function_) => {\n if (function_ instanceof Router) {\n const base = function_.base as string;\n\n let stripPathname = pathname.slice(base.length);\n\n // fix stripped pathname, not sure why this happens\n // eslint-disable-next-line eqeqeq\n if (stripPathname[0] != \"/\") {\n stripPathname = `/${stripPathname}`;\n }\n\n // eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n const result = function_.find(method, stripPathname);\n\n if (!result.middleOnly) {\n middleOnly = false;\n }\n\n // merge params\n Object.assign(parameters, result.params);\n\n return result.fns;\n }\n\n return function_;\n }),\n );\n if (!route.isMiddleware) middleOnly = false;\n }\n });\n\n return { fns, params: parameters, middleOnly };\n }\n}\n","import type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport { Route, Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\n// eslint-disable-next-line max-len\nconst onNoMatch = async (request: Request) => new Response(request.method !== \"HEAD\" ? `Route ${request.method} ${request.url} not found` : null, { status: 404 });\n\nconst onError = async (error: unknown) => {\n // eslint-disable-next-line no-console\n console.error(error);\n return new Response(\"Internal Server Error\", { status: 500 });\n};\n\nexport function getPathname(request: Request & { nextUrl?: URL }) {\n // eslint-disable-next-line compat/compat\n return (request.nextUrl || new URL(request.url)).pathname;\n}\n\n// eslint-disable-next-line max-len\nexport type RequestHandler<R extends Request, Context> = (request: R, context_: Context) => ValueOrPromise<Response | void>;\n\nexport class EdgeRouter<R extends Request = Request, Context = unknown, RResponse extends Response = Response, Schema extends AnyZodObject = ZodObject<any>> {\n private router = new Router<RequestHandler<R, Context>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch as unknown as RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n this.onError = options.onError\n || (onError as unknown as (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>);\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<R, Context>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<R, Context>>,\n ...fns: Nextable<RequestHandler<R, Context>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, routeOrFunction)];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>,\n ...fns: (Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>)[]\n ) {\n if (typeof base === \"function\" || base instanceof EdgeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n\n this.router.use(base, ...fns.map((function_) => (function_ instanceof EdgeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: R & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<R, Context>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new EdgeRouter<R, Context, RResponse, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: R, context_: Context) {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, context_);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: R, context_: Context): Promise<any> => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n this.prepareRequest(request, result);\n\n try {\n return await (result.fns.length === 0 || result.middleOnly\n ? this.onNoMatch(request, context_, routes)\n : Router.exec(result.fns, request, context_));\n } catch (error) {\n return this.onError(error, request, context_, routes);\n }\n };\n }\n}\n\nexport function createEdgeRouter<R extends Request, Context>(\n options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, Response, Route<Nextable<FunctionLike>>[]>> = {},\n) {\n return new EdgeRouter<R, Context, Response>(options);\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { RequestHandler } from \"../node\";\nimport type { Nextable } from \"../types\";\n\ntype NextFunction = (error?: any) => void;\n\nconst expressWrapper = <Request extends IncomingMessage, Response extends ServerResponse>(\n function_: ExpressRequestHandler<Request, Response>,\n // eslint-disable-next-line compat/compat\n): Nextable<RequestHandler<Request, Response>> => (request, response, next) => new Promise<void>((resolve, reject) => {\n function_(request, response, (error) => (error ? reject(error) : resolve()));\n // eslint-disable-next-line promise/no-callback-in-promise\n }).then(next);\n\nexport type ExpressRequestHandler<Request, Response> = (request: Request, response: Response, next: NextFunction) => void;\n\nexport default expressWrapper;\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport type { Route } from \"./router\";\nimport { Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\nconst onNoMatch = async (request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 404;\n response.end(request.method !== \"HEAD\" ? `Route ${request.method} ${request.url} not found` : undefined);\n};\n\nconst onError = async (error: unknown, _request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 500;\n // eslint-disable-next-line no-console\n console.error(error);\n\n response.end(\"Internal Server Error\");\n};\n\nexport function getPathname(url: string) {\n const queryIndex = url.indexOf(\"?\");\n\n return queryIndex !== -1 ? url.slice(0, Math.max(0, queryIndex)) : url;\n}\n\nexport type RequestHandler<Request extends IncomingMessage, Response extends ServerResponse> = (request: Request, response: Response) => ValueOrPromise<void>;\n\nexport class NodeRouter<\n Request extends IncomingMessage = IncomingMessage,\n Response extends ServerResponse = ServerResponse,\n Schema extends AnyZodObject = ZodObject<any>,\n> {\n private router = new Router<RequestHandler<Request, Response>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch;\n this.onError = options.onError || onError;\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<Request, Response>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<Request, Response>>,\n ...fns: Nextable<RequestHandler<Request, Response>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(\n zodOrRouteOrFunction as Schema,\n routeOrFunction,\n )];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>,\n ...fns: (Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>)[]\n ) {\n if (typeof base === \"function\" || base instanceof NodeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n this.router.use(base, ...fns.map((function_) => (function_ instanceof NodeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: Request & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<Request, Response>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new NodeRouter<Request, Response, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: Request, response: Response): Promise<unknown> {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, response);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: Request, response: Response) => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n this.prepareRequest(request, result);\n\n try {\n await (result.fns.length === 0 || result.middleOnly ? this.onNoMatch(request, response, routes) : Router.exec(result.fns, request, response));\n } catch (error) {\n await this.onError(error, request, response, routes);\n }\n };\n }\n}\n\nexport const createRouter = <\n Request extends IncomingMessage,\n Response extends ServerResponse,\n Schema extends AnyZodObject = ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n>(\n options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {},\n ) => new NodeRouter<Request, Response, Schema>(options);\n","import type { ServerResponse } from \"node:http\";\n\n/**\n * Send `JSON` object\n * @param {ServerResponse} response response object\n * @param {number} statusCode\n * @param {any} jsonBody of data\n */\nconst sendJson = (response: ServerResponse, statusCode: number, jsonBody: any): void => {\n // Set header to application/json\n response.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n\n response.statusCode = statusCode;\n response.end(JSON.stringify(jsonBody, null, 2));\n};\n\nexport default sendJson;\n"],"mappings":"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","names":["onNoMatch","onError","getPathname"]}
1
+ {"version":3,"sources":["../src/adapter/with-zod.ts","../src/router.ts","../src/edge.ts","../src/adapter/express.ts","../src/node.ts","../src/utils/send-json.ts"],"sourcesContent":["import createHttpError from \"http-errors\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodError, ZodObject } from \"zod\";\n\nimport type { Nextable, NextHandler } from \"../types\";\n\nconst withZod = <\n Request extends object,\n Response extends unknown,\n Handler extends Nextable<any>,\n Schema extends ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n >(\n schema: Schema,\n handler: Handler,\n ): ((request: Request, response: Response, next: NextHandler) => Promise<Response>) => async (request: Request, response: Response, next) => {\n let transformedRequest: Request = request;\n\n try {\n transformedRequest = (await schema.parseAsync(request)) as Request;\n } catch (error: any) {\n let { message } = error;\n\n // eslint-disable-next-line unicorn/consistent-destructuring\n if (error instanceof ZodError && typeof error.format === \"function\") {\n // eslint-disable-next-line unicorn/consistent-destructuring\n message = error.issues.map((issue) => `${issue.path.join(\"/\")} - ${issue.message}`).join(\"/n\");\n }\n\n throw createHttpError(422, message);\n }\n\n return handler(transformedRequest, response, next);\n };\n\nexport default withZod;\n","/**\n * Agnostic router class\n * Adapted from lukeed/trouter library:\n * https://github.com/lukeed/trouter/blob/master/index.mjs\n */\nimport { parse } from \"regexparam\";\n\nimport type {\n FindResult, FunctionLike, HttpMethod, Nextable, RouteMatch,\n} from \"./types\";\n\nexport type Route<H> = {\n method: HttpMethod | \"\";\n fns: (H | Router<H extends FunctionLike ? H : never>)[];\n isMiddleware: boolean;\n} & (\n | {\n keys: string[] | false;\n pattern: RegExp;\n }\n | { matchAll: true }\n);\n\nexport class Router<H extends FunctionLike> {\n constructor(public base: string = \"/\", public routes: Route<Nextable<H>>[] = []) {}\n\n public add(method: HttpMethod | \"\", route: RouteMatch | Nextable<H>, ...fns: Nextable<H>[]): this {\n if (typeof route === \"function\") {\n fns.unshift(route);\n // eslint-disable-next-line no-param-reassign\n route = \"\";\n }\n\n if (route === \"\") {\n this.routes.push({\n matchAll: true,\n method,\n fns,\n isMiddleware: false,\n });\n } else {\n const { keys, pattern } = parse(route);\n\n this.routes.push({\n keys,\n pattern,\n method,\n fns,\n isMiddleware: false,\n });\n }\n\n return this;\n }\n\n public use(base: RouteMatch | Nextable<H> | Router<H>, ...fns: (Nextable<H> | Router<H>)[]) {\n if (typeof base === \"function\" || base instanceof Router) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n // mount subrouter\n // eslint-disable-next-line no-param-reassign\n fns = fns.map((function_) => {\n if (function_ instanceof Router) {\n if (typeof base === \"string\") return function_.clone(base);\n throw new Error(\"Mounting a router to RegExp base is not supported\");\n }\n return function_;\n });\n\n const { keys, pattern } = parse(base, true);\n\n this.routes.push({\n keys,\n pattern,\n method: \"\",\n fns,\n isMiddleware: true,\n });\n\n return this;\n }\n\n public clone(base?: string) {\n return new Router<H>(base, [...this.routes]);\n }\n\n static async exec<H extends FunctionLike>(fns: Nextable<H>[], ...arguments_: Parameters<H>): Promise<unknown> {\n let index = 0;\n\n // eslint-disable-next-line no-plusplus\n const next = () => (fns[++index] as FunctionLike)(...arguments_, next);\n\n return (fns[index] as FunctionLike)(...arguments_, next);\n }\n\n // eslint-disable-next-line radar/cognitive-complexity\n find(method: HttpMethod, pathname: string): FindResult<H> {\n let middleOnly = true;\n\n const fns: Nextable<H>[] = [];\n const parameters: Record<string, string> = {};\n const isHead = method === \"HEAD\";\n\n // eslint-disable-next-line radar/cognitive-complexity\n Object.values(this.routes).forEach((route) => {\n if (\n route.method !== method\n // matches any method\n && route.method !== \"\"\n // The HEAD method requests that the target resource transfer a representation of its state, as for a GET request...\n && !(isHead && route.method === \"GET\")\n ) {\n return;\n }\n\n let matched = false;\n\n if (\"matchAll\" in route) {\n matched = true;\n } else if (route.keys === false) {\n // routes.key is RegExp: https://github.com/lukeed/regexparam/blob/master/src/index.js#L2\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n // eslint-disable-next-line no-void\n if (matches.groups !== void 0) {\n Object.keys(matches.groups).forEach((key) => {\n // @ts-ignore @TODO: fix this\n parameters[key] = matches.groups[key] as string;\n });\n }\n\n matched = true;\n } else if (route.keys.length > 0) {\n const matches = route.pattern.exec(pathname);\n\n if (matches === null) {\n return;\n }\n\n for (let index = 0; index < route.keys.length;) {\n const parameterKey = route.keys[index];\n\n // @ts-ignore @TODO: fix this\n // eslint-disable-next-line no-plusplus\n parameters[parameterKey] = matches[++index];\n }\n\n matched = true;\n } else if (route.pattern.test(pathname)) {\n matched = true;\n } // else not a match\n\n if (matched) {\n fns.push(\n ...route.fns.flatMap((function_) => {\n if (function_ instanceof Router) {\n const base = function_.base as string;\n\n let stripPathname = pathname.slice(base.length);\n\n // fix stripped pathname, not sure why this happens\n // eslint-disable-next-line eqeqeq\n if (stripPathname[0] != \"/\") {\n stripPathname = `/${stripPathname}`;\n }\n\n // eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n const result = function_.find(method, stripPathname);\n\n if (!result.middleOnly) {\n middleOnly = false;\n }\n\n // merge params\n Object.assign(parameters, result.params);\n\n return result.fns;\n }\n\n return function_;\n }),\n );\n if (!route.isMiddleware) middleOnly = false;\n }\n });\n\n return { fns, params: parameters, middleOnly };\n }\n}\n","import type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport { Route, Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\n// eslint-disable-next-line max-len\nconst onNoMatch = async (request: Request) => new Response(request.method === \"HEAD\" ? null : `Route ${request.method} ${request.url} not found`, { status: 404 });\n\nconst onError = async (error: unknown) => {\n // eslint-disable-next-line no-console\n console.error(error);\n return new Response(\"Internal Server Error\", { status: 500 });\n};\n\nexport function getPathname(request: Request & { nextUrl?: URL }) {\n // eslint-disable-next-line compat/compat\n return (request.nextUrl || new URL(request.url)).pathname;\n}\n\n// eslint-disable-next-line max-len\nexport type RequestHandler<R extends Request, Context> = (request: R, context_: Context) => ValueOrPromise<Response | void>;\n\nexport class EdgeRouter<R extends Request = Request, Context = unknown, RResponse extends Response = Response, Schema extends AnyZodObject = ZodObject<any>> {\n private router = new Router<RequestHandler<R, Context>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch as unknown as RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;\n this.onError = options.onError\n || (onError as unknown as (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>);\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<R, Context>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<R, Context>>,\n ...fns: Nextable<RequestHandler<R, Context>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, routeOrFunction)];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>,\n ...fns: (Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>)[]\n ) {\n if (typeof base === \"function\" || base instanceof EdgeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n\n this.router.use(base, ...fns.map((function_) => (function_ instanceof EdgeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: R & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<R, Context>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new EdgeRouter<R, Context, RResponse, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: R, context_: Context) {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, context_);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: R, context_: Context): Promise<any> => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request));\n\n this.prepareRequest(request, result);\n\n try {\n return await (result.fns.length === 0 || result.middleOnly\n ? this.onNoMatch(request, context_, routes)\n : Router.exec(result.fns, request, context_));\n } catch (error) {\n return this.onError(error, request, context_, routes);\n }\n };\n }\n}\n\nexport function createEdgeRouter<R extends Request, Context>(\n options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, Response, Route<Nextable<FunctionLike>>[]>> = {},\n) {\n return new EdgeRouter<R, Context, Response>(options);\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { RequestHandler } from \"../node\";\nimport type { Nextable } from \"../types\";\n\ntype NextFunction = (error?: any) => void;\n\nconst expressWrapper = <Request extends IncomingMessage, Response extends ServerResponse>(\n function_: ExpressRequestHandler<Request, Response>,\n // eslint-disable-next-line compat/compat\n): Nextable<RequestHandler<Request, Response>> => (request, response, next) => new Promise<void>((resolve, reject) => {\n function_(request, response, (error) => (error ? reject(error) : resolve()));\n // eslint-disable-next-line promise/no-callback-in-promise\n }).then(next);\n\nexport type ExpressRequestHandler<Request, Response> = (request: Request, response: Response, next: NextFunction) => void;\n\nexport default expressWrapper;\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AnyZodObject } from \"zod\";\nimport { ZodObject } from \"zod\";\n\nimport withZod from \"./adapter/with-zod\";\nimport type { Route } from \"./router\";\nimport { Router } from \"./router\";\nimport type {\n FindResult,\n FunctionLike,\n HandlerOptions,\n HttpMethod,\n Nextable,\n RouteMatch,\n RoutesExtendedRequestHandler,\n RouteShortcutMethod,\n ValueOrPromise,\n} from \"./types\";\n\nconst onNoMatch = async (request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 404;\n response.end(request.method === \"HEAD\" ? undefined : `Route ${request.method} ${request.url} not found`);\n};\n\nconst onError = async (error: unknown, _request: IncomingMessage, response: ServerResponse) => {\n response.statusCode = 500;\n // eslint-disable-next-line no-console\n console.error(error);\n\n response.end(\"Internal Server Error\");\n};\n\nexport function getPathname(url: string) {\n const queryIndex = url.indexOf(\"?\");\n\n return queryIndex === -1 ? url : url.slice(0, Math.max(0, queryIndex));\n}\n\nexport type RequestHandler<Request extends IncomingMessage, Response extends ServerResponse> = (request: Request, response: Response) => ValueOrPromise<void>;\n\nexport class NodeRouter<\n Request extends IncomingMessage = IncomingMessage,\n Response extends ServerResponse = ServerResponse,\n Schema extends AnyZodObject = ZodObject<any>,\n> {\n private router = new Router<RequestHandler<Request, Response>>();\n\n private readonly onNoMatch: RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>;\n\n private readonly onError: (\n error: unknown,\n ...arguments_: Parameters<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>\n ) => ReturnType<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>;\n\n constructor(options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {}) {\n this.onNoMatch = options.onNoMatch || onNoMatch;\n this.onError = options.onError || onError;\n }\n\n private add(\n method: HttpMethod | \"\",\n routeOrFunction: RouteMatch | Nextable<RequestHandler<Request, Response>>,\n zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<Request, Response>>,\n ...fns: Nextable<RequestHandler<Request, Response>>[]\n ) {\n if (typeof routeOrFunction === \"string\" && typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n } else if (typeof zodOrRouteOrFunction === \"object\") {\n // eslint-disable-next-line unicorn/prefer-ternary\n if (typeof routeOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(\n zodOrRouteOrFunction as Schema,\n routeOrFunction,\n )];\n } else {\n // eslint-disable-next-line no-param-reassign,max-len\n fns = fns.map((function_) => withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(zodOrRouteOrFunction as Schema, function_));\n }\n } else if (typeof zodOrRouteOrFunction === \"function\") {\n // eslint-disable-next-line no-param-reassign\n fns = [zodOrRouteOrFunction];\n }\n\n this.router.add(method, routeOrFunction, ...fns);\n\n return this;\n }\n\n public all: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"\");\n\n public get: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"GET\");\n\n public head: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"HEAD\");\n\n public post: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"POST\");\n\n public put: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PUT\");\n\n public patch: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"PATCH\");\n\n public delete: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, \"DELETE\");\n\n public use(\n base: RouteMatch | Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>,\n ...fns: (Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>)[]\n ) {\n if (typeof base === \"function\" || base instanceof NodeRouter) {\n fns.unshift(base);\n // eslint-disable-next-line no-param-reassign\n base = \"/\";\n }\n this.router.use(base, ...fns.map((function_) => (function_ instanceof NodeRouter ? function_.router : function_)));\n\n return this;\n }\n\n // eslint-disable-next-line class-methods-use-this\n private prepareRequest(request: Request & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<Request, Response>>) {\n request.params = {\n ...findResult.params,\n ...request.params, // original params will take precedence\n };\n }\n\n public clone() {\n const r = new NodeRouter<Request, Response, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });\n\n r.router = this.router.clone();\n\n return r;\n }\n\n async run(request: Request, response: Response): Promise<unknown> {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n if (result.fns.length === 0) {\n return;\n }\n\n this.prepareRequest(request, result);\n\n // eslint-disable-next-line consistent-return\n return Router.exec(result.fns, request, response);\n }\n\n handler() {\n const { routes } = this.router as Router<FunctionLike>;\n\n return async (request: Request, response: Response) => {\n // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument\n const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));\n\n this.prepareRequest(request, result);\n\n try {\n await (result.fns.length === 0 || result.middleOnly ? this.onNoMatch(request, response, routes) : Router.exec(result.fns, request, response));\n } catch (error) {\n await this.onError(error, request, response, routes);\n }\n };\n }\n}\n\nexport const createRouter = <\n Request extends IncomingMessage,\n Response extends ServerResponse,\n Schema extends AnyZodObject = ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,\n>(\n options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {},\n ) => new NodeRouter<Request, Response, Schema>(options);\n","import type { ServerResponse } from \"node:http\";\n\n/**\n * Send `JSON` object\n * @param {ServerResponse} response response object\n * @param {number} statusCode\n * @param {any} jsonBody of data\n */\nconst sendJson = (response: ServerResponse, statusCode: number, jsonBody: any): void => {\n // Set header to application/json\n response.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n\n response.statusCode = statusCode;\n response.end(JSON.stringify(jsonBody, null, 2));\n};\n\nexport default sendJson;\n"],"mappings":"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","names":["onNoMatch","onError","getPathname"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/connect",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "The minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2 with support for zod validation.",
5
5
  "keywords": [
6
6
  "javascript",
@@ -52,8 +52,7 @@
52
52
  "source": "src/index.ts",
53
53
  "types": "dist/index.d.ts",
54
54
  "files": [
55
- "src",
56
- "dist",
55
+ "dist/**",
57
56
  "README.md",
58
57
  "CHANGELOG.md",
59
58
  "LICENSE.md"
@@ -64,7 +63,7 @@
64
63
  "clean": "rimraf node_modules dist",
65
64
  "coverage": "vitest run --coverage",
66
65
  "dev": "pnpm predev && pnpm run build --watch",
67
- "lint:eslint": "cross-env NO_LOGS=true eslint --ext js,jsx,ts,tsx --max-warnings=0 --config .eslintrc.cjs",
66
+ "lint:eslint": "cross-env NO_LOGS=true eslint . --ext js,jsx,ts,tsx --max-warnings=0 --config .eslintrc.cjs --cache --cache-strategy content .",
68
67
  "lint:eslint:fix": "pnpm run lint:eslint --fix",
69
68
  "test": "vitest"
70
69
  },
@@ -80,7 +79,7 @@
80
79
  "@types/node": "^18.11.5",
81
80
  "@typescript-eslint/eslint-plugin": "^5.41.0",
82
81
  "@typescript-eslint/parser": "^5.41.0",
83
- "@vitest/coverage-c8": "^0.24.3",
82
+ "@vitest/coverage-c8": "^0.25.0",
84
83
  "c8": "^7.12.0",
85
84
  "cross-env": "^7.0.3",
86
85
  "eslint": "^8.26.0",
@@ -101,7 +100,7 @@
101
100
  "eslint-plugin-simple-import-sort": "^8.0.0",
102
101
  "eslint-plugin-sort-keys-fix": "^1.1.2",
103
102
  "eslint-plugin-testing-library": "^5.9.1",
104
- "eslint-plugin-unicorn": "^44.0.2",
103
+ "eslint-plugin-unicorn": "^45.0.0",
105
104
  "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0",
106
105
  "eslint-plugin-you-dont-need-momentjs": "^1.6.0",
107
106
  "express": "^4.18.2",
@@ -113,7 +112,7 @@
113
112
  "semantic-release": "^19.0.5",
114
113
  "tsup": "^6.3.0",
115
114
  "typescript": "^4.8.4",
116
- "vitest": "^0.24.3",
115
+ "vitest": "^0.25.0",
117
116
  "zod": "^3.19.1"
118
117
  },
119
118
  "peerDependencies": {
@@ -1,18 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from "node:http";
2
-
3
- import type { RequestHandler } from "../node";
4
- import type { Nextable } from "../types";
5
-
6
- type NextFunction = (error?: any) => void;
7
-
8
- const expressWrapper = <Request extends IncomingMessage, Response extends ServerResponse>(
9
- function_: ExpressRequestHandler<Request, Response>,
10
- // eslint-disable-next-line compat/compat
11
- ): Nextable<RequestHandler<Request, Response>> => (request, response, next) => new Promise<void>((resolve, reject) => {
12
- function_(request, response, (error) => (error ? reject(error) : resolve()));
13
- // eslint-disable-next-line promise/no-callback-in-promise
14
- }).then(next);
15
-
16
- export type ExpressRequestHandler<Request, Response> = (request: Request, response: Response, next: NextFunction) => void;
17
-
18
- export default expressWrapper;
@@ -1,35 +0,0 @@
1
- import createHttpError from "http-errors";
2
- import type { AnyZodObject } from "zod";
3
- import { ZodError, ZodObject } from "zod";
4
-
5
- import type { Nextable, NextHandler } from "../types";
6
-
7
- const withZod = <
8
- Request extends object,
9
- Response extends unknown,
10
- Handler extends Nextable<any>,
11
- Schema extends ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,
12
- >(
13
- schema: Schema,
14
- handler: Handler,
15
- ): ((request: Request, response: Response, next: NextHandler) => Promise<Response>) => async (request: Request, response: Response, next) => {
16
- let transformedRequest: Request = request;
17
-
18
- try {
19
- transformedRequest = (await schema.parseAsync(request)) as Request;
20
- } catch (error: any) {
21
- let { message } = error;
22
-
23
- // eslint-disable-next-line unicorn/consistent-destructuring
24
- if (error instanceof ZodError && typeof error.format === "function") {
25
- // eslint-disable-next-line unicorn/consistent-destructuring
26
- message = error.issues.map((issue) => `${issue.path.join("/")} - ${issue.message}`).join("/n");
27
- }
28
-
29
- throw createHttpError(422, message);
30
- }
31
-
32
- return handler(transformedRequest, response, next);
33
- };
34
-
35
- export default withZod;
package/src/edge.ts DELETED
@@ -1,165 +0,0 @@
1
- import type { AnyZodObject } from "zod";
2
- import { ZodObject } from "zod";
3
-
4
- import withZod from "./adapter/with-zod";
5
- import { Route, Router } from "./router";
6
- import type {
7
- FindResult,
8
- FunctionLike,
9
- HandlerOptions,
10
- HttpMethod,
11
- Nextable,
12
- RouteMatch,
13
- RoutesExtendedRequestHandler,
14
- RouteShortcutMethod,
15
- ValueOrPromise,
16
- } from "./types";
17
-
18
- // eslint-disable-next-line max-len
19
- const onNoMatch = async (request: Request) => new Response(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : null, { status: 404 });
20
-
21
- const onError = async (error: unknown) => {
22
- // eslint-disable-next-line no-console
23
- console.error(error);
24
- return new Response("Internal Server Error", { status: 500 });
25
- };
26
-
27
- export function getPathname(request: Request & { nextUrl?: URL }) {
28
- // eslint-disable-next-line compat/compat
29
- return (request.nextUrl || new URL(request.url)).pathname;
30
- }
31
-
32
- // eslint-disable-next-line max-len
33
- export type RequestHandler<R extends Request, Context> = (request: R, context_: Context) => ValueOrPromise<Response | void>;
34
-
35
- export class EdgeRouter<R extends Request = Request, Context = unknown, RResponse extends Response = Response, Schema extends AnyZodObject = ZodObject<any>> {
36
- private router = new Router<RequestHandler<R, Context>>();
37
-
38
- private readonly onNoMatch: RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;
39
-
40
- private readonly onError: (
41
- error: unknown,
42
- ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>
43
- ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>;
44
-
45
- constructor(options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>> = {}) {
46
- this.onNoMatch = options.onNoMatch || onNoMatch as unknown as RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>;
47
- this.onError = options.onError
48
- || (onError as unknown as (
49
- error: unknown,
50
- ...arguments_: Parameters<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>
51
- ) => ReturnType<RoutesExtendedRequestHandler<R, Context, RResponse, Route<Nextable<FunctionLike>>[]>>);
52
- }
53
-
54
- private add(
55
- method: HttpMethod | "",
56
- routeOrFunction: RouteMatch | Nextable<RequestHandler<R, Context>>,
57
- zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<R, Context>>,
58
- ...fns: Nextable<RequestHandler<R, Context>>[]
59
- ) {
60
- if (typeof routeOrFunction === "string" && typeof zodOrRouteOrFunction === "function") {
61
- // eslint-disable-next-line no-param-reassign
62
- fns = [zodOrRouteOrFunction];
63
- } else if (typeof zodOrRouteOrFunction === "object") {
64
- // eslint-disable-next-line unicorn/prefer-ternary
65
- if (typeof routeOrFunction === "function") {
66
- // eslint-disable-next-line no-param-reassign
67
- fns = [withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, routeOrFunction)];
68
- } else {
69
- // eslint-disable-next-line no-param-reassign,max-len
70
- fns = fns.map((function_) => withZod<R, Context, Nextable<RequestHandler<R, Context>>, Schema>(zodOrRouteOrFunction as Schema, function_));
71
- }
72
- } else if (typeof zodOrRouteOrFunction === "function") {
73
- // eslint-disable-next-line no-param-reassign
74
- fns = [zodOrRouteOrFunction];
75
- }
76
-
77
- this.router.add(method, routeOrFunction, ...fns);
78
-
79
- return this;
80
- }
81
-
82
- public all: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "");
83
-
84
- public get: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "GET");
85
-
86
- public head: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "HEAD");
87
-
88
- public post: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "POST");
89
-
90
- public put: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "PUT");
91
-
92
- public patch: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "PATCH");
93
-
94
- public delete: RouteShortcutMethod<this, Schema, RequestHandler<R, Context>> = this.add.bind(this, "DELETE");
95
-
96
- public use(
97
- base: RouteMatch | Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>,
98
- ...fns: (Nextable<RequestHandler<R, Context>> | EdgeRouter<R, Context>)[]
99
- ) {
100
- if (typeof base === "function" || base instanceof EdgeRouter) {
101
- fns.unshift(base);
102
- // eslint-disable-next-line no-param-reassign
103
- base = "/";
104
- }
105
-
106
- this.router.use(base, ...fns.map((function_) => (function_ instanceof EdgeRouter ? function_.router : function_)));
107
-
108
- return this;
109
- }
110
-
111
- // eslint-disable-next-line class-methods-use-this
112
- private prepareRequest(request: R & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<R, Context>>) {
113
- request.params = {
114
- ...findResult.params,
115
- ...request.params, // original params will take precedence
116
- };
117
- }
118
-
119
- public clone() {
120
- const r = new EdgeRouter<R, Context, RResponse, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });
121
-
122
- r.router = this.router.clone();
123
-
124
- return r;
125
- }
126
-
127
- async run(request: R, context_: Context) {
128
- // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument
129
- const result = this.router.find(request.method as HttpMethod, getPathname(request));
130
-
131
- if (result.fns.length === 0) {
132
- return;
133
- }
134
-
135
- this.prepareRequest(request, result);
136
-
137
- // eslint-disable-next-line consistent-return
138
- return Router.exec(result.fns, request, context_);
139
- }
140
-
141
- handler() {
142
- const { routes } = this.router as Router<FunctionLike>;
143
-
144
- return async (request: R, context_: Context): Promise<any> => {
145
- // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument
146
- const result = this.router.find(request.method as HttpMethod, getPathname(request));
147
-
148
- this.prepareRequest(request, result);
149
-
150
- try {
151
- return await (result.fns.length === 0 || result.middleOnly
152
- ? this.onNoMatch(request, context_, routes)
153
- : Router.exec(result.fns, request, context_));
154
- } catch (error) {
155
- return this.onError(error, request, context_, routes);
156
- }
157
- };
158
- }
159
- }
160
-
161
- export function createEdgeRouter<R extends Request, Context>(
162
- options: HandlerOptions<RoutesExtendedRequestHandler<R, Context, Response, Route<Nextable<FunctionLike>>[]>> = {},
163
- ) {
164
- return new EdgeRouter<R, Context, Response>(options);
165
- }
package/src/index.ts DELETED
@@ -1,22 +0,0 @@
1
- export type { RequestHandler as EdgeRequestHandler } from "./edge";
2
- export { createEdgeRouter, EdgeRouter } from "./edge";
3
-
4
- export type { ExpressRequestHandler } from "./adapter/express";
5
- export { default as expressWrapper } from "./adapter/express";
6
-
7
- export type { RequestHandler as NodeRequestHandler } from "./node";
8
- export { createRouter as createNodeRouter, NodeRouter } from "./node";
9
-
10
- // @deprecated Use `createNodeRouter` instead
11
- export { createRouter } from "./node";
12
-
13
- export type { Route } from "./router";
14
- export { Router } from "./router";
15
-
16
- export { default as withZod } from "./adapter/with-zod";
17
-
18
- export type {
19
- HandlerOptions, NextHandler, FunctionLike, Nextable, ValueOrPromise, FindResult, RouteShortcutMethod, HttpMethod,
20
- } from "./types";
21
-
22
- export { default as sendJson } from "./utils/send-json";
package/src/node.ts DELETED
@@ -1,173 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from "node:http";
2
- import type { AnyZodObject } from "zod";
3
- import { ZodObject } from "zod";
4
-
5
- import withZod from "./adapter/with-zod";
6
- import type { Route } from "./router";
7
- import { Router } from "./router";
8
- import type {
9
- FindResult,
10
- FunctionLike,
11
- HandlerOptions,
12
- HttpMethod,
13
- Nextable,
14
- RouteMatch,
15
- RoutesExtendedRequestHandler,
16
- RouteShortcutMethod,
17
- ValueOrPromise,
18
- } from "./types";
19
-
20
- const onNoMatch = async (request: IncomingMessage, response: ServerResponse) => {
21
- response.statusCode = 404;
22
- response.end(request.method !== "HEAD" ? `Route ${request.method} ${request.url} not found` : undefined);
23
- };
24
-
25
- const onError = async (error: unknown, _request: IncomingMessage, response: ServerResponse) => {
26
- response.statusCode = 500;
27
- // eslint-disable-next-line no-console
28
- console.error(error);
29
-
30
- response.end("Internal Server Error");
31
- };
32
-
33
- export function getPathname(url: string) {
34
- const queryIndex = url.indexOf("?");
35
-
36
- return queryIndex !== -1 ? url.slice(0, Math.max(0, queryIndex)) : url;
37
- }
38
-
39
- export type RequestHandler<Request extends IncomingMessage, Response extends ServerResponse> = (request: Request, response: Response) => ValueOrPromise<void>;
40
-
41
- export class NodeRouter<
42
- Request extends IncomingMessage = IncomingMessage,
43
- Response extends ServerResponse = ServerResponse,
44
- Schema extends AnyZodObject = ZodObject<any>,
45
- > {
46
- private router = new Router<RequestHandler<Request, Response>>();
47
-
48
- private readonly onNoMatch: RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>;
49
-
50
- private readonly onError: (
51
- error: unknown,
52
- ...arguments_: Parameters<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>
53
- ) => ReturnType<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>>;
54
-
55
- constructor(options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {}) {
56
- this.onNoMatch = options.onNoMatch || onNoMatch;
57
- this.onError = options.onError || onError;
58
- }
59
-
60
- private add(
61
- method: HttpMethod | "",
62
- routeOrFunction: RouteMatch | Nextable<RequestHandler<Request, Response>>,
63
- zodOrRouteOrFunction?: RouteMatch | Schema | Nextable<RequestHandler<Request, Response>>,
64
- ...fns: Nextable<RequestHandler<Request, Response>>[]
65
- ) {
66
- if (typeof routeOrFunction === "string" && typeof zodOrRouteOrFunction === "function") {
67
- // eslint-disable-next-line no-param-reassign
68
- fns = [zodOrRouteOrFunction];
69
- } else if (typeof zodOrRouteOrFunction === "object") {
70
- // eslint-disable-next-line unicorn/prefer-ternary
71
- if (typeof routeOrFunction === "function") {
72
- // eslint-disable-next-line no-param-reassign
73
- fns = [withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(
74
- zodOrRouteOrFunction as Schema,
75
- routeOrFunction,
76
- )];
77
- } else {
78
- // eslint-disable-next-line no-param-reassign,max-len
79
- fns = fns.map((function_) => withZod<Request, Response, Nextable<RequestHandler<Request, Response>>, Schema>(zodOrRouteOrFunction as Schema, function_));
80
- }
81
- } else if (typeof zodOrRouteOrFunction === "function") {
82
- // eslint-disable-next-line no-param-reassign
83
- fns = [zodOrRouteOrFunction];
84
- }
85
-
86
- this.router.add(method, routeOrFunction, ...fns);
87
-
88
- return this;
89
- }
90
-
91
- public all: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "");
92
-
93
- public get: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "GET");
94
-
95
- public head: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "HEAD");
96
-
97
- public post: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "POST");
98
-
99
- public put: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "PUT");
100
-
101
- public patch: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "PATCH");
102
-
103
- public delete: RouteShortcutMethod<this, Schema, RequestHandler<Request, Response>> = this.add.bind(this, "DELETE");
104
-
105
- public use(
106
- base: RouteMatch | Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>,
107
- ...fns: (Nextable<RequestHandler<Request, Response>> | NodeRouter<Request, Response, Schema>)[]
108
- ) {
109
- if (typeof base === "function" || base instanceof NodeRouter) {
110
- fns.unshift(base);
111
- // eslint-disable-next-line no-param-reassign
112
- base = "/";
113
- }
114
- this.router.use(base, ...fns.map((function_) => (function_ instanceof NodeRouter ? function_.router : function_)));
115
-
116
- return this;
117
- }
118
-
119
- // eslint-disable-next-line class-methods-use-this
120
- private prepareRequest(request: Request & { params?: Record<string, unknown> }, findResult: FindResult<RequestHandler<Request, Response>>) {
121
- request.params = {
122
- ...findResult.params,
123
- ...request.params, // original params will take precedence
124
- };
125
- }
126
-
127
- public clone() {
128
- const r = new NodeRouter<Request, Response, Schema>({ onNoMatch: this.onNoMatch, onError: this.onError });
129
-
130
- r.router = this.router.clone();
131
-
132
- return r;
133
- }
134
-
135
- async run(request: Request, response: Response): Promise<unknown> {
136
- // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument
137
- const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));
138
-
139
- if (result.fns.length === 0) {
140
- return;
141
- }
142
-
143
- this.prepareRequest(request, result);
144
-
145
- // eslint-disable-next-line consistent-return
146
- return Router.exec(result.fns, request, response);
147
- }
148
-
149
- handler() {
150
- const { routes } = this.router as Router<FunctionLike>;
151
-
152
- return async (request: Request, response: Response) => {
153
- // eslint-disable-next-line unicorn/no-array-callback-reference,unicorn/no-array-method-this-argument
154
- const result = this.router.find(request.method as HttpMethod, getPathname(request.url as string));
155
-
156
- this.prepareRequest(request, result);
157
-
158
- try {
159
- await (result.fns.length === 0 || result.middleOnly ? this.onNoMatch(request, response, routes) : Router.exec(result.fns, request, response));
160
- } catch (error) {
161
- await this.onError(error, request, response, routes);
162
- }
163
- };
164
- }
165
- }
166
-
167
- export const createRouter = <
168
- Request extends IncomingMessage,
169
- Response extends ServerResponse,
170
- Schema extends AnyZodObject = ZodObject<{ body?: AnyZodObject; headers?: AnyZodObject; query?: AnyZodObject }>,
171
- >(
172
- options: HandlerOptions<RoutesExtendedRequestHandler<Request, Response, Response, Route<Nextable<FunctionLike>>[]>> = {},
173
- ) => new NodeRouter<Request, Response, Schema>(options);
@@ -1,10 +0,0 @@
1
- declare module "regexparam" {
2
- // eslint-disable-next-line import/prefer-default-export
3
- export function parse(
4
- route: string | RegExp,
5
- loose?: boolean,
6
- ): {
7
- keys: string[] | false;
8
- pattern: RegExp;
9
- };
10
- }
package/src/router.ts DELETED
@@ -1,195 +0,0 @@
1
- /**
2
- * Agnostic router class
3
- * Adapted from lukeed/trouter library:
4
- * https://github.com/lukeed/trouter/blob/master/index.mjs
5
- */
6
- import { parse } from "regexparam";
7
-
8
- import type {
9
- FindResult, FunctionLike, HttpMethod, Nextable, RouteMatch,
10
- } from "./types";
11
-
12
- export type Route<H> = {
13
- method: HttpMethod | "";
14
- fns: (H | Router<H extends FunctionLike ? H : never>)[];
15
- isMiddleware: boolean;
16
- } & (
17
- | {
18
- keys: string[] | false;
19
- pattern: RegExp;
20
- }
21
- | { matchAll: true }
22
- );
23
-
24
- export class Router<H extends FunctionLike> {
25
- constructor(public base: string = "/", public routes: Route<Nextable<H>>[] = []) {}
26
-
27
- public add(method: HttpMethod | "", route: RouteMatch | Nextable<H>, ...fns: Nextable<H>[]): this {
28
- if (typeof route === "function") {
29
- fns.unshift(route);
30
- // eslint-disable-next-line no-param-reassign
31
- route = "";
32
- }
33
-
34
- if (route === "") {
35
- this.routes.push({
36
- matchAll: true,
37
- method,
38
- fns,
39
- isMiddleware: false,
40
- });
41
- } else {
42
- const { keys, pattern } = parse(route);
43
-
44
- this.routes.push({
45
- keys,
46
- pattern,
47
- method,
48
- fns,
49
- isMiddleware: false,
50
- });
51
- }
52
-
53
- return this;
54
- }
55
-
56
- public use(base: RouteMatch | Nextable<H> | Router<H>, ...fns: (Nextable<H> | Router<H>)[]) {
57
- if (typeof base === "function" || base instanceof Router) {
58
- fns.unshift(base);
59
- // eslint-disable-next-line no-param-reassign
60
- base = "/";
61
- }
62
- // mount subrouter
63
- // eslint-disable-next-line no-param-reassign
64
- fns = fns.map((function_) => {
65
- if (function_ instanceof Router) {
66
- if (typeof base === "string") return function_.clone(base);
67
- throw new Error("Mounting a router to RegExp base is not supported");
68
- }
69
- return function_;
70
- });
71
-
72
- const { keys, pattern } = parse(base, true);
73
-
74
- this.routes.push({
75
- keys,
76
- pattern,
77
- method: "",
78
- fns,
79
- isMiddleware: true,
80
- });
81
-
82
- return this;
83
- }
84
-
85
- public clone(base?: string) {
86
- return new Router<H>(base, [...this.routes]);
87
- }
88
-
89
- static async exec<H extends FunctionLike>(fns: Nextable<H>[], ...arguments_: Parameters<H>): Promise<unknown> {
90
- let index = 0;
91
-
92
- // eslint-disable-next-line no-plusplus
93
- const next = () => (fns[++index] as FunctionLike)(...arguments_, next);
94
-
95
- return (fns[index] as FunctionLike)(...arguments_, next);
96
- }
97
-
98
- // eslint-disable-next-line radar/cognitive-complexity
99
- find(method: HttpMethod, pathname: string): FindResult<H> {
100
- let middleOnly = true;
101
-
102
- const fns: Nextable<H>[] = [];
103
- const parameters: Record<string, string> = {};
104
- const isHead = method === "HEAD";
105
-
106
- // eslint-disable-next-line radar/cognitive-complexity
107
- Object.values(this.routes).forEach((route) => {
108
- if (
109
- route.method !== method
110
- // matches any method
111
- && route.method !== ""
112
- // The HEAD method requests that the target resource transfer a representation of its state, as for a GET request...
113
- && !(isHead && route.method === "GET")
114
- ) {
115
- return;
116
- }
117
-
118
- let matched = false;
119
-
120
- if ("matchAll" in route) {
121
- matched = true;
122
- } else if (route.keys === false) {
123
- // routes.key is RegExp: https://github.com/lukeed/regexparam/blob/master/src/index.js#L2
124
- const matches = route.pattern.exec(pathname);
125
-
126
- if (matches === null) {
127
- return;
128
- }
129
-
130
- // eslint-disable-next-line no-void
131
- if (matches.groups !== void 0) {
132
- Object.keys(matches.groups).forEach((key) => {
133
- // @ts-ignore @TODO: fix this
134
- parameters[key] = matches.groups[key] as string;
135
- });
136
- }
137
-
138
- matched = true;
139
- } else if (route.keys.length > 0) {
140
- const matches = route.pattern.exec(pathname);
141
-
142
- if (matches === null) {
143
- return;
144
- }
145
-
146
- for (let index = 0; index < route.keys.length;) {
147
- const parameterKey = route.keys[index];
148
-
149
- // @ts-ignore @TODO: fix this
150
- // eslint-disable-next-line no-plusplus
151
- parameters[parameterKey] = matches[++index];
152
- }
153
-
154
- matched = true;
155
- } else if (route.pattern.test(pathname)) {
156
- matched = true;
157
- } // else not a match
158
-
159
- if (matched) {
160
- fns.push(
161
- ...route.fns.flatMap((function_) => {
162
- if (function_ instanceof Router) {
163
- const base = function_.base as string;
164
-
165
- let stripPathname = pathname.slice(base.length);
166
-
167
- // fix stripped pathname, not sure why this happens
168
- // eslint-disable-next-line eqeqeq
169
- if (stripPathname[0] != "/") {
170
- stripPathname = `/${stripPathname}`;
171
- }
172
-
173
- // eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument
174
- const result = function_.find(method, stripPathname);
175
-
176
- if (!result.middleOnly) {
177
- middleOnly = false;
178
- }
179
-
180
- // merge params
181
- Object.assign(parameters, result.params);
182
-
183
- return result.fns;
184
- }
185
-
186
- return function_;
187
- }),
188
- );
189
- if (!route.isMiddleware) middleOnly = false;
190
- }
191
- });
192
-
193
- return { fns, params: parameters, middleOnly };
194
- }
195
- }
package/src/types.d.ts DELETED
@@ -1,36 +0,0 @@
1
- import type { AnyZodObject } from "zod";
2
-
3
- export type HttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE";
4
-
5
- export type FunctionLike = (...arguments_: any[]) => unknown;
6
-
7
- export type RouteMatch = string | RegExp;
8
-
9
- export type NextHandler = () => ValueOrPromise<any>;
10
-
11
- export type Nextable<H extends FunctionLike> = (...arguments_: [...Parameters<H>, NextHandler]) => ValueOrPromise<any>;
12
-
13
- export type FindResult<H extends FunctionLike> = {
14
- fns: Nextable<H>[];
15
- params: Record<string, string>;
16
- middleOnly: boolean;
17
- };
18
-
19
- export type RoutesExtendedRequestHandler<Request extends object, Context extends unknown, RResponse extends unknown, Routes> = (
20
- request: Request,
21
- response: Context,
22
- routes: Routes,
23
- ) => ValueOrPromise<RResponse | void>;
24
-
25
- export interface HandlerOptions<Handler extends FunctionLike> {
26
- onNoMatch?: Handler;
27
- onError?: (error: unknown, ...arguments_: Parameters<Handler>) => ReturnType<Handler>;
28
- }
29
-
30
- export type ValueOrPromise<T> = T | Promise<T>;
31
-
32
- export type RouteShortcutMethod<This, Schema extends AnyZodObject, H extends FunctionLike> = (
33
- route: RouteMatch | Nextable<H>,
34
- zodSchemaOrRouteOrFns?: Schema | RouteMatch | Nextable<H> | string,
35
- ...fns: Nextable<H>[]
36
- ) => This;
@@ -1,17 +0,0 @@
1
- import type { ServerResponse } from "node:http";
2
-
3
- /**
4
- * Send `JSON` object
5
- * @param {ServerResponse} response response object
6
- * @param {number} statusCode
7
- * @param {any} jsonBody of data
8
- */
9
- const sendJson = (response: ServerResponse, statusCode: number, jsonBody: any): void => {
10
- // Set header to application/json
11
- response.setHeader("content-type", "application/json; charset=utf-8");
12
-
13
- response.statusCode = statusCode;
14
- response.end(JSON.stringify(jsonBody, null, 2));
15
- };
16
-
17
- export default sendJson;