@kaito-http/core 2.0.2 → 2.2.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.
@@ -0,0 +1,6 @@
1
+ export declare class WrappedError<T> extends Error {
2
+ readonly data: T;
3
+ static maybe<T>(maybeError: T): (T & Error) | WrappedError<T>;
4
+ static from<T>(data: T): WrappedError<T>;
5
+ private constructor();
6
+ }
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ import { IncomingMessage } from 'http';
3
+ import { Method } from './util';
4
+ export declare class KaitoRequest {
5
+ readonly raw: IncomingMessage;
6
+ constructor(raw: IncomingMessage);
7
+ get fullURL(): string;
8
+ get url(): URL;
9
+ get method(): Method;
10
+ get protocol(): 'http' | 'https';
11
+ get headers(): import("http").IncomingHttpHeaders;
12
+ get hostname(): string;
13
+ }
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import { ServerResponse } from 'http';
3
+ export declare type ErroredAPIResponse = {
4
+ success: false;
5
+ data: null;
6
+ message: string;
7
+ };
8
+ export declare type SuccessfulAPIResponse<T> = {
9
+ success: true;
10
+ data: T;
11
+ message: 'OK';
12
+ };
13
+ export declare type APIResponse<T> = ErroredAPIResponse | SuccessfulAPIResponse<T>;
14
+ export declare type AnyResponse = APIResponse<unknown>;
15
+ export declare class KaitoResponse<T = unknown> {
16
+ readonly raw: ServerResponse;
17
+ constructor(raw: ServerResponse);
18
+ header(key: string, value: string | readonly string[]): this;
19
+ status(code: number): this;
20
+ json(data: APIResponse<T>): this;
21
+ }
@@ -1,13 +1,10 @@
1
1
  /// <reference types="node" />
2
- import { FastifyReply, FastifyRequest } from 'fastify';
2
+ import http from 'http';
3
3
  import { z, ZodTypeAny } from 'zod';
4
- export declare enum Method {
5
- GET = "GET",
6
- POST = "POST",
7
- PATCH = "PATCH",
8
- DELETE = "DELETE"
9
- }
10
- export declare type GetContext<T> = (req: FastifyRequest, res: FastifyReply) => Promise<T>;
4
+ import { KaitoRequest } from './req';
5
+ import { KaitoResponse } from './res';
6
+ import { Method, NormalizePath } from './util';
7
+ export declare type GetContext<T> = (req: KaitoRequest, res: KaitoResponse) => Promise<T>;
11
8
  declare type Never = [never];
12
9
  export declare function createGetContext<T>(getContext: GetContext<T>): GetContext<T>;
13
10
  export declare type InferContext<T> = T extends GetContext<infer Value> ? Value : never;
@@ -16,86 +13,130 @@ export declare type ContextWithInput<Ctx, Input> = {
16
13
  input: Input;
17
14
  };
18
15
  declare type Values<T> = T[keyof T];
19
- declare type Proc<Ctx, Result, Input extends z.ZodTypeAny | Never = Never> = Readonly<{
16
+ export declare type Proc<Ctx, Result, Input extends z.ZodTypeAny | Never = Never> = Readonly<{
20
17
  input?: Input;
21
18
  run(arg: ContextWithInput<Ctx, Input extends ZodTypeAny ? z.infer<Input> : undefined>): Promise<Result>;
22
19
  }>;
23
- declare type ProcsInit<Ctx> = {
24
- [Key in string]: Proc<Ctx, unknown, z.ZodTypeAny> & {
25
- method: Method;
26
- name: Key;
27
- };
20
+ export interface RouterProc<Path extends string, M extends Method> {
21
+ method: M;
22
+ path: Path;
23
+ pattern: RegExp;
24
+ }
25
+ export declare type AnyProcs<Ctx> = {
26
+ [Path in string]: Proc<Ctx, unknown, z.ZodTypeAny> & RouterProc<Path, Method>;
28
27
  };
29
- declare type AnyRouter<Ctx> = Router<Ctx, ProcsInit<Ctx>>;
30
- export declare class Router<Ctx, Procs extends ProcsInit<Ctx>> {
28
+ export declare type AnyRouter<Ctx> = Router<Ctx, AnyProcs<Ctx>>;
29
+ export declare class Router<Ctx, Procs extends AnyProcs<Ctx>> {
31
30
  private readonly procs;
31
+ private readonly _procsArray;
32
32
  constructor(procs: Procs);
33
33
  getProcs(): Procs;
34
+ find(method: Method, url: string): (Readonly<{
35
+ input?: z.ZodTypeAny | undefined;
36
+ run(arg: ContextWithInput<Ctx, any>): Promise<unknown>;
37
+ }> & RouterProc<string, Method>) | null;
34
38
  private readonly create;
35
- readonly merge: <Prefix extends string, NewCtx, NewProcs extends ProcsInit<NewCtx>>(prefix: Prefix, router: Router<NewCtx, NewProcs>) => Router<NewCtx & Ctx, Procs & { [Key in `${Prefix}${Extract<keyof NewProcs, string>}`]: Omit<NewProcs[Key extends `${Prefix}${infer Rest}` ? Rest : never], "name"> & {
36
- name: Key;
39
+ readonly merge: <Prefix extends string, NewCtx, NewProcs extends AnyProcs<NewCtx>>(_prefix: (Prefix extends `${infer U}/` ? U : Prefix) extends `/${infer U_1}` ? `/${U_1}` : `/${Prefix extends `${infer U}/` ? U : Prefix}`, router: Router<NewCtx, NewProcs>) => Router<NewCtx & Ctx, Procs & { [P in `/${Prefix}${Extract<keyof NewProcs, string>}`]: Omit<NewProcs[P extends `/${Prefix}${infer Rest}` ? Rest : never], "path"> & {
40
+ path: P;
37
41
  }; }>;
38
- readonly get: <Name extends string, Result, Input extends z.ZodTypeAny>(name: Name, proc: Readonly<{
42
+ readonly get: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
43
+ input?: Input | undefined;
44
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
45
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
46
+ input?: Input | undefined;
47
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
48
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "GET">>>;
49
+ readonly post: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
50
+ input?: Input | undefined;
51
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
52
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
53
+ input?: Input | undefined;
54
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
55
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "POST">>>;
56
+ readonly put: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
57
+ input?: Input | undefined;
58
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
59
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
60
+ input?: Input | undefined;
61
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
62
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "PUT">>>;
63
+ readonly patch: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
64
+ input?: Input | undefined;
65
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
66
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
67
+ input?: Input | undefined;
68
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
69
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "PATCH">>>;
70
+ readonly delete: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
71
+ input?: Input | undefined;
72
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
73
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
74
+ input?: Input | undefined;
75
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
76
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "DELETE">>>;
77
+ readonly head: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
78
+ input?: Input | undefined;
79
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
80
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
81
+ input?: Input | undefined;
82
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
83
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "HEAD">>>;
84
+ readonly options: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
85
+ input?: Input | undefined;
86
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
87
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
88
+ input?: Input | undefined;
89
+ run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
90
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "OPTIONS">>>;
91
+ readonly connect: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
39
92
  input?: Input | undefined;
40
93
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
41
- }>) => Router<Ctx, Procs & Record<Name, Readonly<{
94
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
42
95
  input?: Input | undefined;
43
96
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
44
- }> & {
45
- method: Method.GET;
46
- name: Name;
47
- }>>;
48
- readonly post: <Name extends string, Result, Input extends z.ZodTypeAny>(name: Name, proc: Readonly<{
97
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "CONNECT">>>;
98
+ readonly trace: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
49
99
  input?: Input | undefined;
50
100
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
51
- }>) => Router<Ctx, Procs & Record<Name, Readonly<{
101
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
52
102
  input?: Input | undefined;
53
103
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
54
- }> & {
55
- method: Method.POST;
56
- name: Name;
57
- }>>;
58
- readonly patch: <Name extends string, Result, Input extends z.ZodTypeAny>(name: Name, proc: Readonly<{
104
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "TRACE">>>;
105
+ readonly acl: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
59
106
  input?: Input | undefined;
60
107
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
61
- }>) => Router<Ctx, Procs & Record<Name, Readonly<{
108
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
62
109
  input?: Input | undefined;
63
110
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
64
- }> & {
65
- method: Method.PATCH;
66
- name: Name;
67
- }>>;
68
- readonly delete: <Name extends string, Result, Input extends z.ZodTypeAny>(name: Name, proc: Readonly<{
111
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "ACL">>>;
112
+ readonly bind: <Path extends string, Result, Input extends z.ZodTypeAny>(path: (Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, proc: Readonly<{
69
113
  input?: Input | undefined;
70
114
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
71
- }>) => Router<Ctx, Procs & Record<Name, Readonly<{
115
+ }>) => Router<Ctx, Procs & Record<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, Readonly<{
72
116
  input?: Input | undefined;
73
117
  run(arg: ContextWithInput<Ctx, Input extends z.ZodTypeAny ? z.TypeOf<Input> : undefined>): Promise<Result>;
74
- }> & {
75
- method: Method.DELETE;
76
- name: Name;
77
- }>>;
118
+ }> & RouterProc<(Path extends `${infer U}/` ? U : Path) extends `/${infer U_1}` ? `/${U_1}` : `/${Path extends `${infer U}/` ? U : Path}`, "BIND">>>;
78
119
  }
79
120
  export declare class KaitoError extends Error {
80
- readonly code: number;
121
+ readonly status: number;
81
122
  readonly cause?: Error | undefined;
82
- constructor(code: number, message: string, cause?: Error | undefined);
123
+ constructor(status: number, message: string, cause?: Error | undefined);
83
124
  }
84
125
  export declare function createRouter<Ctx>(): Router<Ctx, {}>;
85
- export declare type InferApiResponseType<R extends AnyRouter<unknown>, M extends Method, Path extends Extract<Values<ReturnType<R['getProcs']>>, {
126
+ export declare type InferAPIResponseType<R extends AnyRouter<unknown>, M extends Method, Path extends Extract<Values<ReturnType<R['getProcs']>>, {
86
127
  method: M;
87
- }>['name']> = ReturnType<ReturnType<R['getProcs']>[Path]['run']> extends Promise<infer V> ? V : never;
88
- export declare function createServer<Ctx, R extends Router<Ctx, ProcsInit<Ctx>>>(config: {
128
+ }>['path']> = ReturnType<ReturnType<R['getProcs']>[Path]['run']> extends Promise<infer V> ? V : never;
129
+ export declare function createServer<Ctx, R extends Router<Ctx, AnyProcs<Ctx>>>(config: {
89
130
  getContext: GetContext<Ctx>;
90
131
  router: R;
91
132
  onError(error: {
92
133
  error: Error;
93
- req: FastifyRequest;
94
- res: FastifyReply;
134
+ req: KaitoRequest;
135
+ res: KaitoResponse;
95
136
  }): Promise<{
96
- code: number;
137
+ status: number;
97
138
  message: string;
98
139
  }>;
99
140
  log?: ((message: string) => unknown) | false;
100
- }): import("fastify").FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance> & PromiseLike<import("fastify").FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance>>;
141
+ }): http.Server;
101
142
  export {};
@@ -0,0 +1,9 @@
1
+ import { KaitoRequest } from './req';
2
+ export declare function getLastEntryInMultiHeaderValue(headerValue: string | string[]): string;
3
+ declare type RemoveEndSlashes<T extends string> = T extends `${infer U}/` ? U : T;
4
+ declare type AddStartSlashes<T extends string> = T extends `/${infer U}` ? `/${U}` : `/${T}`;
5
+ export declare type NormalizePath<T extends string> = AddStartSlashes<RemoveEndSlashes<T>>;
6
+ export declare function normalizePath<T extends string>(path: T): NormalizePath<T>;
7
+ export declare type Method = 'ACL' | 'BIND' | 'CHECKOUT' | 'CONNECT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LINK' | 'LOCK' | 'M-SEARCH' | 'MERGE' | 'MKACTIVITY' | 'MKCALENDAR' | 'MKCOL' | 'MOVE' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PRI' | 'PROPFIND' | 'PROPPATCH' | 'PURGE' | 'PUT' | 'REBIND' | 'REPORT' | 'SEARCH' | 'SOURCE' | 'SUBSCRIBE' | 'TRACE' | 'UNBIND' | 'UNLINK' | 'UNLOCK' | 'UNSUBSCRIBE';
8
+ export declare function getInput(req: KaitoRequest): Promise<unknown>;
9
+ export {};
@@ -2,11 +2,14 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var fastify = require('fastify');
5
+ var http = require('http');
6
+ var tls = require('tls');
7
+ var getRawBody = require('raw-body');
6
8
 
7
9
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
8
10
 
9
- var fastify__default = /*#__PURE__*/_interopDefault(fastify);
11
+ var http__default = /*#__PURE__*/_interopDefault(http);
12
+ var getRawBody__default = /*#__PURE__*/_interopDefault(getRawBody);
10
13
 
11
14
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
12
15
  try {
@@ -97,35 +100,174 @@ function _objectSpread2(target) {
97
100
  return target;
98
101
  }
99
102
 
100
- exports.Method = void 0;
103
+ class WrappedError extends Error {
104
+ static maybe(maybeError) {
105
+ if (maybeError instanceof Error) {
106
+ return maybeError;
107
+ }
108
+
109
+ return WrappedError.from(maybeError);
110
+ }
111
+
112
+ static from(data) {
113
+ return new WrappedError(data);
114
+ }
115
+
116
+ constructor(data) {
117
+ super('Something was thrown, but it was not an instance of Error, so a WrappedError was created.');
118
+ this.data = data;
119
+ }
120
+
121
+ }
122
+
123
+ function getLastEntryInMultiHeaderValue(headerValue) {
124
+ var normalized = Array.isArray(headerValue) ? headerValue.join(',') : headerValue;
125
+ var lastIndex = normalized.lastIndexOf(',');
126
+ return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
127
+ }
128
+ function normalizePath(path) {
129
+ var result = path;
130
+
131
+ if (!result.startsWith('/')) {
132
+ result = "/".concat(result);
133
+ }
134
+
135
+ if (result.endsWith('/')) {
136
+ result = result.slice(-1);
137
+ }
138
+
139
+ return result;
140
+ } // Type for import('http').METHODS
141
+
142
+ function getInput(_x) {
143
+ return _getInput.apply(this, arguments);
144
+ }
145
+
146
+ function _getInput() {
147
+ _getInput = _asyncToGenerator(function* (req) {
148
+ if (req.method === 'GET') {
149
+ var input = req.url.searchParams.get('input');
150
+
151
+ if (!input) {
152
+ return null;
153
+ }
154
+
155
+ return JSON.parse(input);
156
+ }
157
+
158
+ var buffer = yield getRawBody__default["default"](req.raw);
159
+
160
+ switch (req.headers['content-type']) {
161
+ case 'application/json':
162
+ {
163
+ return JSON.parse(buffer.toString());
164
+ }
165
+
166
+ default:
167
+ {
168
+ return null;
169
+ }
170
+ }
171
+ });
172
+ return _getInput.apply(this, arguments);
173
+ }
174
+
175
+ class KaitoRequest {
176
+ constructor(raw) {
177
+ this.raw = raw;
178
+ }
179
+
180
+ get fullURL() {
181
+ var _this$raw$url;
182
+
183
+ return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
184
+ }
185
+
186
+ get url() {
187
+ return new URL(this.fullURL);
188
+ }
189
+
190
+ get method() {
191
+ if (!this.raw.method) {
192
+ throw new Error('Request method is not defined, somehow...');
193
+ }
194
+
195
+ return this.raw.method;
196
+ }
197
+
198
+ get protocol() {
199
+ if (this.raw.socket instanceof tls.TLSSocket) {
200
+ return this.raw.socket.encrypted ? 'https' : 'http';
201
+ }
202
+
203
+ return 'http';
204
+ }
205
+
206
+ get headers() {
207
+ return this.raw.headers;
208
+ }
209
+
210
+ get hostname() {
211
+ var _this$raw$headers$hos, _this$raw$headers$Au;
212
+
213
+ return (_this$raw$headers$hos = this.raw.headers.host) !== null && _this$raw$headers$hos !== void 0 ? _this$raw$headers$hos : getLastEntryInMultiHeaderValue((_this$raw$headers$Au = this.raw.headers[':authority']) !== null && _this$raw$headers$Au !== void 0 ? _this$raw$headers$Au : []);
214
+ }
215
+
216
+ }
101
217
 
102
- (function (Method) {
103
- Method["GET"] = "GET";
104
- Method["POST"] = "POST";
105
- Method["PATCH"] = "PATCH";
106
- Method["DELETE"] = "DELETE";
107
- })(exports.Method || (exports.Method = {}));
218
+ class KaitoResponse {
219
+ constructor(raw) {
220
+ this.raw = raw;
221
+ }
222
+
223
+ header(key, value) {
224
+ this.raw.setHeader(key, value);
225
+ return this;
226
+ }
227
+
228
+ status(code) {
229
+ this.raw.statusCode = code;
230
+ return this;
231
+ }
232
+
233
+ json(data) {
234
+ var json = JSON.stringify(data);
235
+ this.raw.setHeader('Content-Type', 'application/json');
236
+ this.raw.setHeader('Content-Length', Buffer.byteLength(json));
237
+ this.raw.end(json);
238
+ return this;
239
+ }
240
+
241
+ }
108
242
 
109
243
  function createGetContext(getContext) {
110
244
  return getContext;
111
245
  }
112
246
  class Router {
113
247
  constructor(procs) {
114
- _defineProperty(this, "create", method => (name, proc) => {
115
- return new Router(_objectSpread2(_objectSpread2({}, this.procs), {}, {
116
- [name]: _objectSpread2(_objectSpread2({}, proc), {}, {
248
+ _defineProperty(this, "create", method => (path, proc) => {
249
+ var stripped = normalizePath(path);
250
+ var pattern = new RegExp("^".concat(stripped, "/?$"), 'i');
251
+
252
+ var merged = _objectSpread2(_objectSpread2({}, this.procs), {}, {
253
+ [path]: _objectSpread2(_objectSpread2({}, proc), {}, {
117
254
  method,
118
- name
255
+ path,
256
+ pattern
119
257
  })
120
- }));
258
+ });
259
+
260
+ return new Router(merged);
121
261
  });
122
262
 
123
- _defineProperty(this, "merge", (prefix, router) => {
263
+ _defineProperty(this, "merge", (_prefix, router) => {
264
+ var prefix = normalizePath(_prefix);
124
265
  var newProcs = Object.entries(router.getProcs()).reduce((all, entry) => {
125
- var [name, proc] = entry;
266
+ var [_path, proc] = entry;
267
+ var path = normalizePath(_path);
126
268
  return _objectSpread2(_objectSpread2({}, all), {}, {
127
- ["".concat(prefix).concat(name)]: _objectSpread2(_objectSpread2({}, proc), {}, {
128
- name: "".concat(prefix).concat(name)
269
+ ["".concat(prefix).concat(path)]: _objectSpread2(_objectSpread2({}, proc), {}, {
270
+ path: "".concat(prefix).concat(path)
129
271
  })
130
272
  });
131
273
  }, {});
@@ -135,26 +277,55 @@ class Router {
135
277
  return new Router(mergedProcs);
136
278
  });
137
279
 
138
- _defineProperty(this, "get", this.create(exports.Method.GET));
280
+ _defineProperty(this, "get", this.create('GET'));
281
+
282
+ _defineProperty(this, "post", this.create('POST'));
139
283
 
140
- _defineProperty(this, "post", this.create(exports.Method.POST));
284
+ _defineProperty(this, "put", this.create('PUT'));
141
285
 
142
- _defineProperty(this, "patch", this.create(exports.Method.PATCH));
286
+ _defineProperty(this, "patch", this.create('PATCH'));
143
287
 
144
- _defineProperty(this, "delete", this.create(exports.Method.DELETE));
288
+ _defineProperty(this, "delete", this.create('DELETE'));
289
+
290
+ _defineProperty(this, "head", this.create('HEAD'));
291
+
292
+ _defineProperty(this, "options", this.create('OPTIONS'));
293
+
294
+ _defineProperty(this, "connect", this.create('CONNECT'));
295
+
296
+ _defineProperty(this, "trace", this.create('TRACE'));
297
+
298
+ _defineProperty(this, "acl", this.create('ACL'));
299
+
300
+ _defineProperty(this, "bind", this.create('BIND'));
145
301
 
146
302
  this.procs = procs;
303
+ this._procsArray = Object.values(procs);
147
304
  }
148
305
 
149
306
  getProcs() {
150
307
  return this.procs;
151
308
  }
152
309
 
310
+ find(method, url) {
311
+ for (var proc of this._procsArray) {
312
+ if (proc.method !== method) {
313
+ continue;
314
+ }
315
+
316
+ if (proc.pattern.test(url)) {
317
+ return proc;
318
+ }
319
+ }
320
+
321
+ return null;
322
+ }
323
+
153
324
  }
154
325
  class KaitoError extends Error {
155
- constructor(code, message, cause) {
326
+ constructor(status, message, cause) {
156
327
  super(message);
157
- this.code = code;
328
+ this.status = status;
158
329
  this.cause = cause;
159
330
  }
160
331
 
@@ -163,79 +334,76 @@ function createRouter() {
163
334
  return new Router({});
164
335
  }
165
336
  function createServer(config) {
166
- var tree = config.router.getProcs();
167
- var app = fastify__default["default"]();
168
- app.setErrorHandler( /*#__PURE__*/function () {
169
- var _ref = _asyncToGenerator(function* (error, req, res) {
170
- if (error instanceof KaitoError) {
171
- yield res.status(error.code).send({
172
- success: false,
173
- data: null,
174
- message: error.message
175
- });
176
- return;
177
- }
178
-
179
- var {
180
- code,
181
- message
182
- } = yield config.onError({
183
- error,
184
- req,
185
- res
186
- }).catch(() => ({
187
- code: 500,
188
- message: 'Something went wrong'
189
- }));
190
- yield res.status(code).send({
191
- success: false,
192
- data: null,
193
- message
194
- });
195
- });
196
-
197
- return function (_x, _x2, _x3) {
198
- return _ref.apply(this, arguments);
199
- };
200
- }());
201
- app.all('*', /*#__PURE__*/function () {
202
- var _ref2 = _asyncToGenerator(function* (req, res) {
203
- var _handler$input$parse, _handler$input;
204
-
205
- var logMessage = "".concat(req.hostname, " ").concat(req.method, " ").concat(req.url);
337
+ var log = message => {
338
+ if (config.log === undefined) {
339
+ console.log(message);
340
+ } else if (config.log) {
341
+ config.log(message);
342
+ }
343
+ };
206
344
 
207
- if (config.log === undefined) {
208
- console.log(logMessage);
209
- } else if (config.log) {
210
- config.log(logMessage);
211
- }
345
+ return http__default["default"].createServer( /*#__PURE__*/function () {
346
+ var _ref = _asyncToGenerator(function* (incomingMessage, serverResponse) {
347
+ var start = Date.now();
348
+ var req = new KaitoRequest(incomingMessage);
349
+ var res = new KaitoResponse(serverResponse);
212
350
 
213
- var url = new URL("".concat(req.protocol, "://").concat(req.hostname).concat(req.url));
214
- var handler = tree[url.pathname];
351
+ try {
352
+ var _handler$input, _yield$getInput;
215
353
 
216
- if (!handler) {
217
- throw new KaitoError(404, "Cannot ".concat(req.method, " this route."));
218
- }
354
+ var handler = config.router.find(req.method, req.url.pathname);
219
355
 
220
- var context = yield config.getContext(req, res); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
356
+ if (!handler) {
357
+ throw new KaitoError(404, "Cannot ".concat(req.method, " this route."));
358
+ }
221
359
 
222
- var input = (_handler$input$parse = (_handler$input = handler.input) === null || _handler$input === void 0 ? void 0 : _handler$input.parse(req.method === 'GET' ? req.query : req.body)) !== null && _handler$input$parse !== void 0 ? _handler$input$parse : null;
223
- yield res.send({
224
- success: true,
225
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
226
- data: yield handler.run({
360
+ var input = (_handler$input = handler.input) === null || _handler$input === void 0 ? void 0 : _handler$input.parse((_yield$getInput = yield getInput(req)) !== null && _yield$getInput !== void 0 ? _yield$getInput : undefined);
361
+ var context = yield config.getContext(req, res);
362
+ var data = yield handler.run({
227
363
  ctx: context,
228
364
  input
229
- }),
230
- message: 'OK'
231
- });
365
+ });
366
+ res.json({
367
+ success: true,
368
+ data,
369
+ message: 'OK'
370
+ });
371
+ } catch (error) {
372
+ if (error instanceof KaitoError) {
373
+ res.status(error.status).json({
374
+ success: false,
375
+ data: null,
376
+ message: error.message
377
+ });
378
+ return;
379
+ }
380
+
381
+ var {
382
+ status: _status,
383
+ message: _message
384
+ } = yield config.onError({
385
+ error: WrappedError.maybe(error),
386
+ req,
387
+ res
388
+ }).catch(() => ({
389
+ status: 500,
390
+ message: 'Something went wrong'
391
+ }));
392
+ res.status(_status).json({
393
+ success: false,
394
+ data: null,
395
+ message: _message
396
+ });
397
+ } finally {
398
+ var finish = Date.now();
399
+ log("".concat(req.method, " ").concat(req.fullURL, " ").concat(res.raw.statusCode, " ").concat(finish - start, "ms"));
400
+ }
232
401
  });
233
402
 
234
- return function (_x4, _x5) {
235
- return _ref2.apply(this, arguments);
403
+ return function (_x, _x2) {
404
+ return _ref.apply(this, arguments);
236
405
  };
237
406
  }());
238
- return app;
239
407
  }
240
408
 
241
409
  exports.KaitoError = KaitoError;