@ozanarslan/corpus 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +96 -52
  2. package/dist/index.js +220 -209
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export type ConfigEnvKey = OrString<keyof Env>;
13
13
  export type ConfigValueParser<T> = (value: string) => T;
14
14
  export declare class Config {
15
15
  static get runtime(): string;
16
+ static get nodeEnv(): OrString<"development" | "production" | "test">;
16
17
  static get env(): NodeJS.ProcessEnv;
17
18
  static cwd(): string;
18
19
  static resolvePath(...paths: string[]): string;
@@ -20,7 +21,7 @@ export declare class Config {
20
21
  parser?: ConfigValueParser<T>;
21
22
  fallback?: T;
22
23
  }): T;
23
- static set(key: string, value: string): void;
24
+ static set(key: string, value: string | number | boolean): void;
24
25
  }
25
26
  export type CookieOptions = {
26
27
  name: string;
@@ -36,15 +37,13 @@ export type CookieOptions = {
36
37
  partitioned?: boolean;
37
38
  maxAge?: number;
38
39
  };
39
- export type CookiesInit = Cookies | [
40
- string,
41
- string
42
- ][] | Record<string, string>;
40
+ export type CookiesInit = CookiesAbstract | CookieOptions | CookieOptions[];
43
41
  declare abstract class CookiesAbstract {
44
42
  abstract set(opts: CookieOptions): void;
45
43
  abstract get(name: string): string | null;
46
44
  abstract has(name: string): boolean;
47
- abstract delete(opts: Pick<CookieOptions, "name" | "domain" | "path">): void;
45
+ abstract get count(): number;
46
+ abstract delete(name: string): void;
48
47
  abstract entries(): IterableIterator<[
49
48
  string,
50
49
  string
@@ -52,18 +51,18 @@ declare abstract class CookiesAbstract {
52
51
  abstract values(): Array<string>;
53
52
  abstract keys(): Array<string>;
54
53
  abstract toSetCookieHeaders(): Array<string>;
54
+ abstract setMany(optsArr: Array<CookieOptions>): void;
55
55
  applyInit(init: CookiesInit): void;
56
- decodeValue(cookieString: string): string | null;
57
- createHeader(opts: CookieOptions): string;
58
56
  }
59
- /** Simple cookie map/jar to collect and manipulate cookies. */
60
57
  export declare class Cookies extends CookiesAbstract {
61
58
  private instance;
62
59
  constructor(init?: CookiesInit);
63
60
  set(opts: CookieOptions): void;
61
+ setMany(optsArr: Array<CookieOptions>): void;
64
62
  get(name: string): string | null;
65
63
  has(name: string): boolean;
66
- delete(opts: Pick<CookieOptions, "name" | "path" | "domain">): void;
64
+ get count(): number;
65
+ delete(name: string): void;
67
66
  entries(): IterableIterator<[
68
67
  string,
69
68
  string
@@ -129,18 +128,24 @@ type HttpHeadersInit = Headers | HttpHeaders | [
129
128
  string,
130
129
  string
131
130
  ][] | (Record<string, string> & Partial<Record<HttpHeaderKey, string>>);
131
+ /** Headers is extended to include helpers and intellisense for common header names. */
132
132
  declare class HttpHeaders extends Headers {
133
133
  constructor(init?: HttpHeadersInit);
134
134
  append(name: HttpHeaderKey, value: string): void;
135
135
  set(name: HttpHeaderKey, value: string): void;
136
- get(name: string): string | null;
137
- has(name: string): boolean;
138
- combine(source: HttpHeaders, target: HttpHeaders): HttpHeaders;
139
- innerCombine(source: HttpHeaders): HttpHeaders;
140
- setMany(init: HttpHeadersInit): void;
136
+ get(name: HttpHeaderKey): string | null;
137
+ has(name: HttpHeaderKey): boolean;
138
+ delete(name: HttpHeaderKey): void;
139
+ static combine(source: HttpHeaders, target: HttpHeaders): HttpHeaders;
140
+ innerCombine(source: HttpHeaders): void;
141
+ setMany(init: [
142
+ string,
143
+ string
144
+ ][] | (Record<string, string> & Partial<Record<HttpHeaderKey, string>>)): void;
145
+ /** @deprecated */
141
146
  static findHeaderInInit(init: HttpHeadersInit, name: HttpHeaderKey): string | null;
142
147
  }
143
- type HttpRequestInfo = Request | string | HttpRequest;
148
+ type HttpRequestInfo = Request | string | HttpRequest | URL;
144
149
  /** Commonly used HTTP verbs. */
145
150
  export declare const Method: {
146
151
  readonly GET: "GET";
@@ -160,14 +165,18 @@ type HttpRequestInit = Omit<RequestInit, "headers" | "method"> & {
160
165
  };
161
166
  /** HttpRequest includes a cookie jar, better headers, and some utilities. */
162
167
  declare class HttpRequest extends Request {
163
- readonly input: HttpRequestInfo;
168
+ readonly info: HttpRequestInfo;
164
169
  readonly init?: HttpRequestInit | undefined;
165
- constructor(input: HttpRequestInfo, init?: HttpRequestInit | undefined);
166
- get urlObject(): URL;
167
- get headers(): HttpHeaders;
170
+ constructor(info: HttpRequestInfo, init?: HttpRequestInit | undefined);
171
+ readonly urlObject: URL;
172
+ readonly isPreflight: boolean;
173
+ readonly cookies: Cookies;
174
+ headers: HttpHeaders;
175
+ private resolveUrlObject;
176
+ private resolveHeaders;
168
177
  /** Gets cookie header and collects cookies for the jar */
169
- get cookies(): Cookies;
170
- get isPreflight(): boolean;
178
+ private resolveCookies;
179
+ private resolveIsPreflight;
171
180
  }
172
181
  export type OrNumber<T> = T | (number & {});
173
182
  /** Commonly used HTTP status codes. */
@@ -605,7 +614,8 @@ declare class HttpError extends Error {
605
614
  status: Status;
606
615
  data?: unknown | undefined;
607
616
  constructor(message: string, status: Status, data?: unknown | undefined);
608
- static isStatusOf(err: unknown, status: Status): boolean;
617
+ toResponse(): HttpResponse;
618
+ isStatusOf(status: Status): boolean;
609
619
  static internalServerError(msg?: string): HttpError;
610
620
  static badRequest(msg?: string): HttpError;
611
621
  static notFound(msg?: string): HttpError;
@@ -650,12 +660,13 @@ export declare class Parser {
650
660
  static getSearch<S = UnknownObject>(url: URL, validate?: SchemaValidator<S>): Promise<S>;
651
661
  static getBody<B = UnknownObject>(r: HttpRequest | HttpResponse | Response, validate?: SchemaValidator<B>): Promise<B>;
652
662
  static getParams<P = UnknownObject>(endpoint: string, url: URL, validate?: SchemaValidator<P>): Promise<P>;
663
+ private static getUnknownBody;
653
664
  private static getJsonBody;
654
665
  private static getFormUrlEncodedBody;
655
666
  private static getFormDataBody;
656
667
  private static getTextBody;
657
668
  static getNormalizedContentType(input: Request | Response): string;
658
- private static processString;
669
+ static processString(value: string): string | boolean | number;
659
670
  }
660
671
  /** Abstract class for repository implementations */
661
672
  declare abstract class RepositoryAbstract {
@@ -701,29 +712,67 @@ declare class Cors {
701
712
  }
702
713
  export type ErrorHandler<R = unknown> = (err: Error) => MaybePromise<HttpResponse<R>>;
703
714
  export type RequestHandler<R = unknown> = (req: HttpRequest) => MaybePromise<HttpResponse<R>>;
704
- declare abstract class ServerAbstract {
715
+ export type AfterResponseHandler = ((res: HttpResponse) => MaybePromise<HttpResponse>) | undefined;
716
+ export interface ServerInterface {
717
+ serve(options: ServeOptions): void;
718
+ close(): Promise<void>;
719
+ setGlobalPrefix(value: string): void;
720
+ setCors(cors: CorsOptions): void;
721
+ /**
722
+ *
723
+ * Default error handler response will have a status of C.Error or 500 and json:
724
+ *
725
+ * ```typescript
726
+ * { error: unknown | true, message: string }
727
+ * ```
728
+ *
729
+ * If throw something other than an Error instance, you should probably handle it.
730
+ * However the default response will have a status of 500 and json:
731
+ *
732
+ * ```typescript
733
+ * { error: Instance, message: "Unknown" }
734
+ * ```
735
+ */
736
+ setOnError(handler: ErrorHandler): void;
737
+ /**
738
+ *
739
+ * Default not found handler response will have a status of 404 and json:
740
+ *
741
+ * ```typescript
742
+ * { error: true, message: `${req.method} on ${req.url} does not exist.` }
743
+ * ```
744
+ */
745
+ setOnNotFound(handler: RequestHandler): void;
746
+ setOnBeforeListen(handler: () => MaybePromise<void>): void;
747
+ setOnBeforeClose(handler: () => MaybePromise<void>): void;
748
+ setOnAfterResponse(handler: AfterResponseHandler): void;
749
+ listen(port: ServeOptions["port"], hostname: ServeOptions["hostname"]): Promise<void>;
750
+ handle(request: Request): Promise<Response>;
751
+ }
752
+ declare abstract class ServerAbstract implements ServerInterface {
705
753
  abstract serve(options: ServeOptions): void;
706
- abstract exit(): Promise<void>;
754
+ abstract close(): Promise<void>;
707
755
  protected cors: Cors | undefined;
708
- protected handleBeforeListen: (() => MaybePromise<void>) | undefined;
709
- protected handleBeforeExit: (() => MaybePromise<void>) | undefined;
710
- protected handleAfterResponse: ((res: HttpResponse) => MaybePromise<HttpResponse>) | undefined;
756
+ get routes(): Array<[
757
+ string,
758
+ string
759
+ ]>;
711
760
  setGlobalPrefix(value: string): void;
712
761
  setCors(cors: CorsOptions): void;
713
762
  setOnError(handler: ErrorHandler): void;
714
763
  setOnNotFound(handler: RequestHandler): void;
715
764
  setOnBeforeListen(handler: () => MaybePromise<void>): void;
716
- setOnBeforeExit(handler: () => MaybePromise<void>): void;
717
- setOnAfterResponse(handler: (res: HttpResponse) => MaybePromise<HttpResponse>): void;
765
+ setOnBeforeClose(handler: () => MaybePromise<void>): void;
766
+ setOnAfterResponse(handler: AfterResponseHandler): void;
718
767
  listen(port: ServeOptions["port"], hostname?: ServeOptions["hostname"]): Promise<void>;
719
768
  handle(request: Request): Promise<Response>;
720
- private prepare;
721
- private handleError;
722
- private handleNotFound;
723
- private handleMethodNotAllowed;
724
- private handlePreflight;
725
- private handleRoute;
726
769
  private getResponse;
770
+ protected handleBeforeListen: (() => MaybePromise<void>) | undefined;
771
+ protected handleBeforeClose: (() => MaybePromise<void>) | undefined;
772
+ protected handleAfterResponse: AfterResponseHandler;
773
+ protected handleError: ErrorHandler;
774
+ protected handleNotFound: RequestHandler;
775
+ protected handleMethodNotAllowed: RequestHandler;
727
776
  }
728
777
  /**
729
778
  * Server is the entrypoint to the app. It must be initialized before registering routes and middlewares.
@@ -733,23 +782,12 @@ export declare class Server extends ServerAbstract {
733
782
  private instance;
734
783
  constructor();
735
784
  serve(options: ServeOptions): void;
736
- exit(): Promise<void>;
785
+ close(): Promise<void>;
737
786
  }
738
- export type MiddlewareRegistryData = {
739
- handler: MiddlewareHandler;
740
- order: number;
741
- routeId: RouteId | "*";
742
- };
743
787
  declare class MiddlewareRegistry {
744
- readonly compiledCache: Map<`[${string}:${string}]`, MiddlewareHandler>;
745
- readonly handlerMap: Map<number, MiddlewareHandler>;
746
- readonly data: Array<MiddlewareRegistryData>;
747
- readonly compiledMap: Map<string, MiddlewareHandler>;
788
+ private readonly map;
748
789
  add(item: Middleware): void;
749
790
  find(routeId: RouteId): MiddlewareHandler;
750
- private internMiddlewareHandler;
751
- private push;
752
- private findInsertIndex;
753
791
  private compile;
754
792
  }
755
793
  export type AnyRouteModel = RouteModel<any, any, any, any>;
@@ -763,7 +801,10 @@ declare class ModelRegistry {
763
801
  export type RouteRegistryData = Pick<AnyRoute, "id" | "endpoint" | "method" | "pattern" | "handler">;
764
802
  declare class RouteRegistry {
765
803
  private store;
766
- list(): string;
804
+ list(): Array<[
805
+ string,
806
+ string
807
+ ]>;
767
808
  add(r: AnyRoute): void;
768
809
  find(req: HttpRequest): RouteRegistryData;
769
810
  private checkPossibleCollision;
@@ -778,7 +819,10 @@ declare class Router {
778
819
  setGlobalPrefix(value: string): void;
779
820
  routeRegistryInstance: RouteRegistry | undefined;
780
821
  get routeRegistry(): RouteRegistry;
781
- getRouteList(): string;
822
+ getRouteList(): Array<[
823
+ string,
824
+ string
825
+ ]>;
782
826
  addRoute(r: AnyRoute): void;
783
827
  addController(c: ControllerAbstract): void;
784
828
  findRoute(req: HttpRequest): RouteRegistryData;
package/dist/index.js CHANGED
@@ -4,25 +4,43 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
19
37
  var __export = (target, all) => {
20
38
  for (var name in all)
21
39
  __defProp(target, name, {
22
40
  get: all[name],
23
41
  enumerable: true,
24
42
  configurable: true,
25
- set: (newValue) => all[name] = () => newValue
43
+ set: __exportSetter.bind(all, name)
26
44
  });
27
45
  };
28
46
  var __require = import.meta.require;
@@ -168778,6 +168796,11 @@ var RuntimeOptions = {
168778
168796
  node: "node"
168779
168797
  };
168780
168798
 
168799
+ // src/utils/strIsDefined.ts
168800
+ function strIsDefined(input) {
168801
+ return !!input?.trim() && typeof input === "string";
168802
+ }
168803
+
168781
168804
  // src/Config/Config.ts
168782
168805
  import path from "path";
168783
168806
 
@@ -168789,8 +168812,12 @@ class Config {
168789
168812
  if (typeof process !== "undefined" && process?.env) {
168790
168813
  return RuntimeOptions.node;
168791
168814
  }
168815
+ console.warn("\u26A0\uFE0F Runtime isn't Bun or NodeJS. Features may not be available. App might not start.");
168792
168816
  return "unknown";
168793
168817
  }
168818
+ static get nodeEnv() {
168819
+ return this.env.NODE_ENV ?? "development";
168820
+ }
168794
168821
  static get env() {
168795
168822
  switch (this.runtime) {
168796
168823
  case RuntimeOptions.bun:
@@ -168798,6 +168825,7 @@ class Config {
168798
168825
  case RuntimeOptions.node:
168799
168826
  return process.env;
168800
168827
  default:
168828
+ console.warn("\u26A0\uFE0F process.env wasn't available. Your environment variables are in memory.");
168801
168829
  return {};
168802
168830
  }
168803
168831
  }
@@ -168809,7 +168837,7 @@ class Config {
168809
168837
  }
168810
168838
  static get(key, opts) {
168811
168839
  const value = this.env[key];
168812
- if (value !== undefined && value !== "") {
168840
+ if (strIsDefined(value)) {
168813
168841
  return opts?.parser ? opts?.parser(value) : value;
168814
168842
  }
168815
168843
  if (opts?.fallback !== undefined) {
@@ -168819,6 +168847,14 @@ class Config {
168819
168847
  return;
168820
168848
  }
168821
168849
  static set(key, value) {
168850
+ if (typeof value === "number") {
168851
+ this.env[key] = value.toString();
168852
+ return;
168853
+ }
168854
+ if (typeof value === "boolean") {
168855
+ this.env[key] = value ? "true" : "false";
168856
+ return;
168857
+ }
168822
168858
  this.env[key] = value;
168823
168859
  }
168824
168860
  }
@@ -168934,87 +168970,32 @@ var CommonHeaders = {
168934
168970
  Cookie: "Cookie"
168935
168971
  };
168936
168972
 
168937
- // src/utils/strAfterMark.ts
168938
- function strAfterMark(mark, input) {
168939
- const index = input.indexOf(mark);
168940
- return index === -1 ? "" : input.slice(index + mark.length);
168941
- }
168942
-
168943
- // src/utils/strCapitalize.ts
168944
- function strCapitalize(input) {
168945
- return input.length > 0 ? input.split(" ").map((part) => part.charAt(0).toLocaleUpperCase() + input.slice(1)).join(" ") : input;
168946
- }
168947
-
168948
- // src/utils/strIsDefined.ts
168949
- function strIsDefined(input) {
168950
- return !!input?.trim() && typeof input === "string";
168951
- }
168952
-
168953
168973
  // src/Cookies/CookiesAbstract.ts
168954
168974
  class CookiesAbstract {
168955
168975
  applyInit(init) {
168956
168976
  if (init instanceof CookiesAbstract) {
168957
- for (const [name, value] of init.entries()) {
168977
+ for (const name of init.keys()) {
168978
+ const value = init.get(name) ?? "";
168958
168979
  this.set({ name, value });
168959
168980
  }
168960
168981
  } else if (Array.isArray(init)) {
168961
- for (const [name, value] of init) {
168962
- if (!name || !value)
168963
- continue;
168964
- this.set({ name, value });
168982
+ for (const opts of init) {
168983
+ this.set(opts);
168965
168984
  }
168966
168985
  } else {
168967
- for (const [name, value] of Object.entries(init)) {
168968
- this.set({ name, value });
168969
- }
168986
+ this.set(init);
168970
168987
  }
168971
168988
  }
168972
- decodeValue(cookieString) {
168973
- const encodedValue = strAfterMark("=", cookieString);
168974
- if (!encodedValue)
168975
- return null;
168976
- return decodeURIComponent(encodedValue);
168977
- }
168978
- createHeader(opts) {
168979
- let result = `${encodeURIComponent(opts.name)}=${encodeURIComponent(opts.value)}`;
168980
- if (strIsDefined(opts.domain)) {
168981
- result += `; Domain=${opts.domain}`;
168982
- }
168983
- if (strIsDefined(opts.path)) {
168984
- result += `; Path=${opts.path}`;
168985
- } else {
168986
- result += `; Path=/`;
168987
- }
168988
- if (opts.expires) {
168989
- if (typeof opts.expires === "number") {
168990
- result += `; Expires=${new Date(opts.expires).toUTCString()}`;
168991
- } else {
168992
- result += `; Expires=${opts.expires.toUTCString()}`;
168993
- }
168994
- }
168995
- if (opts.maxAge && Number.isInteger(opts.maxAge)) {
168996
- result += `; Max-Age=${opts.maxAge}`;
168997
- }
168998
- if (opts.secure === true) {
168999
- result += "; Secure";
169000
- }
169001
- if (opts.httpOnly === true) {
169002
- result += "; HttpOnly";
169003
- }
169004
- if (opts.partitioned === true) {
169005
- result += "; Partitioned";
169006
- }
169007
- if (strIsDefined(opts.sameSite)) {
169008
- result += `; SameSite=${strCapitalize(opts.sameSite)}`;
169009
- } else {
169010
- result += `; SameSite=Lax`;
169011
- }
169012
- return result;
169013
- }
169014
168989
  }
169015
168990
 
169016
168991
  // src/Cookies/CookiesUsingBun.ts
169017
168992
  class CookiesUsingBun extends CookiesAbstract {
168993
+ constructor(init) {
168994
+ super();
168995
+ if (init) {
168996
+ this.applyInit(init);
168997
+ }
168998
+ }
169018
168999
  map = new Bun.CookieMap;
169019
169000
  toSetCookieHeaders() {
169020
169001
  return this.map.toSetCookieHeaders();
@@ -169022,14 +169003,22 @@ class CookiesUsingBun extends CookiesAbstract {
169022
169003
  set(opts) {
169023
169004
  this.map.set(opts.name, opts.value, opts);
169024
169005
  }
169006
+ setMany(optsArr) {
169007
+ for (const opts of optsArr) {
169008
+ this.set(opts);
169009
+ }
169010
+ }
169025
169011
  get(name) {
169026
169012
  return this.map.get(name);
169027
169013
  }
169028
169014
  has(name) {
169029
169015
  return this.map.has(name);
169030
169016
  }
169031
- delete(opts) {
169032
- this.map.delete(opts);
169017
+ get count() {
169018
+ return this.values().length;
169019
+ }
169020
+ delete(name) {
169021
+ this.map.delete(name);
169033
169022
  }
169034
169023
  entries() {
169035
169024
  return this.map.entries();
@@ -169044,24 +169033,28 @@ class CookiesUsingBun extends CookiesAbstract {
169044
169033
 
169045
169034
  // src/Cookies/Cookies.ts
169046
169035
  class Cookies extends CookiesAbstract {
169047
- instance = new CookiesUsingBun;
169036
+ instance;
169048
169037
  constructor(init) {
169049
169038
  super();
169050
- if (init) {
169051
- this.applyInit(init);
169052
- }
169039
+ this.instance = new CookiesUsingBun(init);
169053
169040
  }
169054
169041
  set(opts) {
169055
169042
  return this.instance.set(opts);
169056
169043
  }
169044
+ setMany(optsArr) {
169045
+ return this.instance.setMany(optsArr);
169046
+ }
169057
169047
  get(name) {
169058
169048
  return this.instance.get(name);
169059
169049
  }
169060
169050
  has(name) {
169061
169051
  return this.instance.has(name);
169062
169052
  }
169063
- delete(opts) {
169064
- return this.instance.delete(opts);
169053
+ get count() {
169054
+ return this.instance.count;
169055
+ }
169056
+ delete(name) {
169057
+ return this.instance.delete(name);
169065
169058
  }
169066
169059
  entries() {
169067
169060
  return this.instance.entries();
@@ -169094,7 +169087,10 @@ class HttpHeaders extends Headers {
169094
169087
  has(name) {
169095
169088
  return super.has(name) || super.has(name.toLowerCase());
169096
169089
  }
169097
- combine(source, target) {
169090
+ delete(name) {
169091
+ return super.delete(name);
169092
+ }
169093
+ static combine(source, target) {
169098
169094
  source.forEach((value, key) => {
169099
169095
  if (key.toLowerCase() === "set-cookie") {
169100
169096
  target.append(key, value);
@@ -169105,10 +169101,11 @@ class HttpHeaders extends Headers {
169105
169101
  return target;
169106
169102
  }
169107
169103
  innerCombine(source) {
169108
- return this.combine(source, this);
169104
+ HttpHeaders.combine(source, this);
169109
169105
  }
169110
169106
  setMany(init) {
169111
- for (const [key, value] of Object.entries(init)) {
169107
+ const entries = Array.isArray(init) ? init : Object.entries(init);
169108
+ for (const [key, value] of entries) {
169112
169109
  if (!strIsDefined(value))
169113
169110
  continue;
169114
169111
  this.set(key, value);
@@ -169206,7 +169203,7 @@ class HttpResponse {
169206
169203
  const res = new HttpResponse(undefined, {
169207
169204
  ...init,
169208
169205
  status: init?.status ?? Status.FOUND,
169209
- statusText: init?.statusText
169206
+ statusText: init?.statusText ?? DefaultStatusTexts[Status.FOUND]
169210
169207
  });
169211
169208
  const urlString = url instanceof URL ? url.toString() : url;
169212
169209
  res.headers.set(CommonHeaders.Location, urlString);
@@ -169250,11 +169247,11 @@ class HttpError extends Error {
169250
169247
  this.status = status;
169251
169248
  this.data = data;
169252
169249
  }
169253
- static isStatusOf(err, status) {
169254
- if (err instanceof HttpError) {
169255
- return err.status === status;
169256
- }
169257
- return Status.INTERNAL_SERVER_ERROR === status;
169250
+ toResponse() {
169251
+ return new HttpResponse(this.data ? { error: this.data, message: this.message } : { error: true, message: this.message }, { status: this.status });
169252
+ }
169253
+ isStatusOf(status) {
169254
+ return this.status === status;
169258
169255
  }
169259
169256
  static internalServerError(msg) {
169260
169257
  const status = Status.INTERNAL_SERVER_ERROR;
@@ -169347,13 +169344,15 @@ class Parser {
169347
169344
  case "text":
169348
169345
  data = await this.getTextBody(input);
169349
169346
  break;
169347
+ case "unknown":
169348
+ data = await this.getUnknownBody(input);
169349
+ break;
169350
169350
  case "xml":
169351
169351
  case "binary":
169352
169352
  case "pdf":
169353
169353
  case "image":
169354
169354
  case "audio":
169355
169355
  case "video":
169356
- case "unknown":
169357
169356
  throw new HttpError("unprocessable.contentType", Status.UNPROCESSABLE_ENTITY);
169358
169357
  case "no-body-allowed":
169359
169358
  default:
@@ -169383,11 +169382,21 @@ class Parser {
169383
169382
  }
169384
169383
  return await this.parse(data, validate);
169385
169384
  }
169385
+ static async getUnknownBody(input, validate) {
169386
+ if (!validate) {
169387
+ return await this.getTextBody(input);
169388
+ }
169389
+ try {
169390
+ return await this.getJsonBody(input);
169391
+ } catch {
169392
+ return await this.getTextBody(input);
169393
+ }
169394
+ }
169386
169395
  static async getJsonBody(req) {
169387
169396
  return await req.json();
169388
169397
  }
169389
- static async getFormUrlEncodedBody(req) {
169390
- const text = await req.text();
169398
+ static async getFormUrlEncodedBody(input) {
169399
+ const text = await input.text();
169391
169400
  if (!text || text.trim().length === 0) {
169392
169401
  throw new SyntaxError("Body is empty");
169393
169402
  }
@@ -169398,8 +169407,8 @@ class Parser {
169398
169407
  }
169399
169408
  return body;
169400
169409
  }
169401
- static async getFormDataBody(req) {
169402
- const formData = await req.formData();
169410
+ static async getFormDataBody(input) {
169411
+ const formData = await input.formData();
169403
169412
  const entries = formData.entries();
169404
169413
  const body = {};
169405
169414
  for (const [key, value] of entries) {
@@ -169411,15 +169420,15 @@ class Parser {
169411
169420
  }
169412
169421
  return body;
169413
169422
  }
169414
- static async getTextBody(req) {
169415
- const contentLength = req.headers.get("content-length");
169423
+ static async getTextBody(input) {
169424
+ const contentLength = input.headers.get(CommonHeaders.ContentLength);
169416
169425
  const length = contentLength ? parseInt(contentLength) : 0;
169417
169426
  if (length > 0 && length < 1024 * 1024) {
169418
- const text2 = await req.text();
169427
+ const text2 = await input.text();
169419
169428
  return this.processString(text2);
169420
169429
  }
169421
- const buffer = await req.arrayBuffer();
169422
- const contentType = req.headers.get("content-type") || "";
169430
+ const buffer = await input.arrayBuffer();
169431
+ const contentType = input.headers.get(CommonHeaders.ContentType) || "";
169423
169432
  const match = contentType.match(/charset=([^;]+)/i);
169424
169433
  const charset = match?.[1] ? match[1].trim() : null;
169425
169434
  const decoder = new TextDecoder(charset || "utf-8");
@@ -169463,6 +169472,8 @@ class Parser {
169463
169472
  }
169464
169473
  static processString(value) {
169465
169474
  let processedValue = value;
169475
+ if (!strIsDefined(value))
169476
+ return "";
169466
169477
  if (/^-?\d+(\.\d+)?$/.test(value)) {
169467
169478
  processedValue = Number(value);
169468
169479
  } else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
@@ -169704,6 +169715,7 @@ class StaticRoute extends RouteAbstract {
169704
169715
  htm: "text/html",
169705
169716
  css: "text/css",
169706
169717
  js: "application/javascript",
169718
+ ts: "application/javascript",
169707
169719
  mjs: "application/javascript",
169708
169720
  json: "application/json",
169709
169721
  png: "image/png",
@@ -169793,33 +169805,77 @@ class RepositoryAbstract {
169793
169805
  this.db = db;
169794
169806
  }
169795
169807
  }
169808
+ // src/utils/assert.ts
169809
+ function assert(condition, message) {
169810
+ const conditionName = String(condition);
169811
+ if (!condition) {
169812
+ if (!message) {
169813
+ message = `Assertion failed for ${conditionName}`;
169814
+ } else {
169815
+ message = `${conditionName}: ${message}`;
169816
+ }
169817
+ throw new Error(message);
169818
+ }
169819
+ }
169820
+
169796
169821
  // src/utils/strSplit.ts
169797
- function strSplit(mark, input) {
169798
- return input.split(mark).map((part) => part.trim()).filter(Boolean);
169822
+ function strSplit(mark, input, minLength) {
169823
+ const parts = input.split(mark).map((part) => part.trim()).filter(Boolean);
169824
+ if (minLength) {
169825
+ assert(parts.length >= minLength);
169826
+ return parts;
169827
+ }
169828
+ return parts;
169799
169829
  }
169800
169830
 
169801
169831
  // src/Request/HttpRequest.ts
169802
169832
  class HttpRequest extends Request {
169803
- input;
169833
+ info;
169804
169834
  init;
169805
- constructor(input, init) {
169806
- super(input, init);
169807
- this.input = input;
169835
+ constructor(info, init) {
169836
+ super(info, init);
169837
+ this.info = info;
169808
169838
  this.init = init;
169839
+ this.urlObject = this.resolveUrlObject();
169840
+ this.headers = this.resolveHeaders();
169841
+ this.cookies = this.resolveCookies();
169842
+ this.isPreflight = this.resolveIsPreflight();
169809
169843
  }
169810
- get urlObject() {
169811
- return new URL(this.url);
169844
+ urlObject;
169845
+ isPreflight;
169846
+ cookies;
169847
+ headers;
169848
+ resolveUrlObject() {
169849
+ let urlObject;
169850
+ switch (true) {
169851
+ case this.info instanceof URL:
169852
+ urlObject = this.info;
169853
+ break;
169854
+ case this.info instanceof HttpRequest:
169855
+ urlObject = this.info.urlObject;
169856
+ break;
169857
+ case this.info instanceof Request:
169858
+ urlObject = new URL(this.info.url);
169859
+ break;
169860
+ default:
169861
+ urlObject = new URL(this.info);
169862
+ break;
169863
+ }
169864
+ if (!urlObject.pathname) {
169865
+ urlObject.pathname += "/";
169866
+ }
169867
+ return urlObject;
169812
169868
  }
169813
- get headers() {
169814
- if (this.input instanceof Request) {
169815
- return new HttpHeaders(this.input.headers);
169816
- } else if (this.init?.headers !== undefined) {
169869
+ resolveHeaders() {
169870
+ if (this.init?.headers !== undefined) {
169817
169871
  return new HttpHeaders(this.init.headers);
169818
- } else {
169819
- return new HttpHeaders;
169820
169872
  }
169873
+ if (this.info instanceof Request || this.info instanceof HttpRequest) {
169874
+ return new HttpHeaders(this.info.headers);
169875
+ }
169876
+ return new HttpHeaders;
169821
169877
  }
169822
- get cookies() {
169878
+ resolveCookies() {
169823
169879
  const jar = new Cookies;
169824
169880
  const cookieHeader = this.headers.get(CommonHeaders.Cookie);
169825
169881
  if (cookieHeader) {
@@ -169833,93 +169889,52 @@ class HttpRequest extends Request {
169833
169889
  }
169834
169890
  return jar;
169835
169891
  }
169836
- get isPreflight() {
169892
+ resolveIsPreflight() {
169837
169893
  const accessControlRequestMethodHeader = this.headers.has(CommonHeaders.AccessControlRequestMethod);
169838
169894
  return this.method === Method.OPTIONS && accessControlRequestMethodHeader;
169839
169895
  }
169840
169896
  }
169841
169897
  // src/Middleware/MiddlewareRegistry.ts
169842
169898
  class MiddlewareRegistry {
169843
- compiledCache = new Map;
169844
- handlerMap = new Map;
169845
- data = [];
169846
- compiledMap = new Map;
169899
+ map = new Map;
169847
169900
  add(item) {
169848
- const order = this.data.length + 1;
169849
169901
  const useOn = item.useOn;
169850
169902
  if (useOn === "*") {
169851
169903
  const arr = [];
169852
- const globals = this.compiledMap.get("*");
169904
+ const globals = this.map.get("*");
169853
169905
  if (globals) {
169854
169906
  arr.push(globals);
169855
169907
  }
169856
169908
  arr.push(item.handler);
169857
- this.compiledMap.set("*", this.compile(arr));
169909
+ this.map.set("*", this.compile(arr));
169858
169910
  return;
169859
169911
  }
169860
169912
  const targets = Array.isArray(useOn) ? useOn : [useOn];
169861
169913
  for (const target of targets) {
169862
169914
  const routeIds = target instanceof Route ? [target.id] : target instanceof ControllerAbstract ? Array.from(target.routeIds) : [];
169863
169915
  for (const routeId of routeIds) {
169864
- console.log("adding mw to", routeId);
169865
169916
  const arr = [];
169866
- const locals = this.compiledMap.get(routeId);
169917
+ const locals = this.map.get(routeId);
169867
169918
  if (locals) {
169868
169919
  arr.push(locals);
169869
169920
  }
169870
169921
  arr.push(item.handler);
169871
- this.compiledMap.set(routeId, this.compile(arr));
169922
+ this.map.set(routeId, this.compile(arr));
169872
169923
  }
169873
169924
  }
169874
169925
  }
169875
169926
  find(routeId) {
169876
169927
  const arr = [];
169877
- const globals = this.compiledMap.get("*");
169928
+ const globals = this.map.get("*");
169878
169929
  if (globals) {
169879
169930
  arr.push(globals);
169880
169931
  }
169881
- const locals = this.compiledMap.get(routeId);
169932
+ const locals = this.map.get(routeId);
169882
169933
  if (locals) {
169883
169934
  arr.push(locals);
169884
169935
  }
169885
- console.log(routeId, arr);
169886
169936
  return this.compile(arr);
169887
169937
  }
169888
- internMiddlewareHandler(order, fn) {
169889
- const existing = this.handlerMap.get(order);
169890
- if (existing)
169891
- return existing;
169892
- this.handlerMap.set(order, fn);
169893
- return fn;
169894
- }
169895
- push(data) {
169896
- if (data.routeId === "*") {
169897
- this.compiledCache.clear();
169898
- } else {
169899
- this.compiledCache.delete(data.routeId);
169900
- }
169901
- const insertIndex = this.findInsertIndex(data.order);
169902
- this.data.splice(insertIndex, 0, {
169903
- order: data.order,
169904
- routeId: data.routeId,
169905
- handler: this.internMiddlewareHandler(data.order, data.handler)
169906
- });
169907
- console.log(this.data);
169908
- console.log(this.compiledCache);
169909
- }
169910
- findInsertIndex(order) {
169911
- let left = 0;
169912
- let right = this.data.length;
169913
- while (left < right) {
169914
- const mid = left + right >> 1;
169915
- if (this.data[mid].order < order) {
169916
- left = mid + 1;
169917
- } else {
169918
- right = mid;
169919
- }
169920
- }
169921
- return left;
169922
- }
169923
169938
  compile(handlers) {
169924
169939
  return async (ctx) => {
169925
169940
  for (const h of handlers) {
@@ -169987,8 +170002,7 @@ function strIsEqual(source, target, modifier) {
169987
170002
  class RouteRegistry {
169988
170003
  store = new Map;
169989
170004
  list() {
169990
- return Array.from(this.store.values()).map((r) => `${r.method} : ${r.endpoint}`).join(`
169991
- `);
170005
+ return Array.from(this.store.values()).map((r) => [r.method, r.endpoint]);
169992
170006
  }
169993
170007
  add(r) {
169994
170008
  this.checkPossibleCollision(r);
@@ -170204,9 +170218,9 @@ class Cors {
170204
170218
  // src/Server/ServerAbstract.ts
170205
170219
  class ServerAbstract {
170206
170220
  cors;
170207
- handleBeforeListen;
170208
- handleBeforeExit;
170209
- handleAfterResponse;
170221
+ get routes() {
170222
+ return getRouterInstance().getRouteList();
170223
+ }
170210
170224
  setGlobalPrefix(value) {
170211
170225
  Config.set(_globalPrefixEnvKey, value);
170212
170226
  }
@@ -170222,15 +170236,17 @@ class ServerAbstract {
170222
170236
  setOnBeforeListen(handler) {
170223
170237
  this.handleBeforeListen = handler;
170224
170238
  }
170225
- setOnBeforeExit(handler) {
170226
- this.handleBeforeExit = handler;
170239
+ setOnBeforeClose(handler) {
170240
+ this.handleBeforeClose = handler;
170227
170241
  }
170228
170242
  setOnAfterResponse(handler) {
170229
170243
  this.handleAfterResponse = handler;
170230
170244
  }
170231
170245
  async listen(port, hostname = "0.0.0.0") {
170232
170246
  try {
170233
- await this.prepare(port, hostname);
170247
+ process.on("SIGINT", () => this.close());
170248
+ process.on("SIGTERM", () => this.close());
170249
+ console.log(`Listening on ${hostname}:${port}`);
170234
170250
  await this.handleBeforeListen?.();
170235
170251
  this.serve({
170236
170252
  port,
@@ -170239,7 +170255,7 @@ class ServerAbstract {
170239
170255
  });
170240
170256
  } catch (err) {
170241
170257
  console.error("Server unable to start:", err);
170242
- await this.exit();
170258
+ await this.close();
170243
170259
  }
170244
170260
  }
170245
170261
  async handle(request) {
@@ -170253,51 +170269,43 @@ class ServerAbstract {
170253
170269
  }
170254
170270
  return res.response;
170255
170271
  }
170256
- async prepare(port, hostname) {
170257
- process.on("SIGINT", () => this.exit());
170258
- process.on("SIGTERM", () => this.exit());
170259
- const routes = getRouterInstance().getRouteList();
170260
- console.log(`Listening on ${hostname}:${port}
170261
- ${routes}`);
170272
+ async getResponse(req) {
170273
+ try {
170274
+ if (req.isPreflight) {
170275
+ return new HttpResponse("Departed");
170276
+ }
170277
+ const handler = getRouterInstance().getRouteHandler(req);
170278
+ return await handler();
170279
+ } catch (err) {
170280
+ if (err instanceof HttpError) {
170281
+ if (err.isStatusOf(Status.NOT_FOUND)) {
170282
+ return await this.handleNotFound(req);
170283
+ }
170284
+ if (err.isStatusOf(Status.METHOD_NOT_ALLOWED)) {
170285
+ return await this.handleMethodNotAllowed(req);
170286
+ }
170287
+ }
170288
+ return await this.handleError(err);
170289
+ }
170262
170290
  }
170291
+ handleBeforeListen;
170292
+ handleBeforeClose;
170293
+ handleAfterResponse;
170263
170294
  handleError = async (err) => {
170264
- let body = err;
170265
- let status = Status.INTERNAL_SERVER_ERROR;
170295
+ if (!(err instanceof Error)) {
170296
+ return new HttpResponse({ error: err, message: "Unknown" }, { status: Status.INTERNAL_SERVER_ERROR });
170297
+ }
170266
170298
  if (err instanceof HttpError) {
170267
- body = err.data ?? err.message;
170268
- status = err.status;
170299
+ return err.toResponse();
170269
170300
  }
170270
- return new HttpResponse({ error: body }, { status });
170301
+ return new HttpResponse({ error: err, message: err.message }, { status: Status.INTERNAL_SERVER_ERROR });
170271
170302
  };
170272
170303
  handleNotFound = async (req) => {
170273
- return new HttpResponse({ error: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
170304
+ return new HttpResponse({ error: true, message: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
170274
170305
  };
170275
170306
  handleMethodNotAllowed = async (req) => {
170276
170307
  return new HttpResponse({ error: `${req.method} does not exist.` }, { status: Status.METHOD_NOT_ALLOWED });
170277
170308
  };
170278
- handlePreflight = async () => {
170279
- return new HttpResponse("Departed");
170280
- };
170281
- handleRoute = async (req) => {
170282
- const handler = getRouterInstance().getRouteHandler(req);
170283
- return await handler();
170284
- };
170285
- async getResponse(req) {
170286
- try {
170287
- if (req.isPreflight) {
170288
- return await this.handlePreflight();
170289
- }
170290
- return await this.handleRoute(req);
170291
- } catch (err) {
170292
- if (HttpError.isStatusOf(err, Status.NOT_FOUND)) {
170293
- return await this.handleNotFound(req);
170294
- }
170295
- if (HttpError.isStatusOf(err, Status.METHOD_NOT_ALLOWED)) {
170296
- return await this.handleMethodNotAllowed(req);
170297
- }
170298
- return await this.handleError(err);
170299
- }
170300
- }
170301
170309
  }
170302
170310
 
170303
170311
  // src/Server/ServerUsingBun.ts
@@ -170306,9 +170314,8 @@ class ServerUsingBun extends ServerAbstract {
170306
170314
  serve(options) {
170307
170315
  this.app = this.createApp(options);
170308
170316
  }
170309
- async exit() {
170317
+ async close() {
170310
170318
  await this.app?.stop();
170311
- process.exit(0);
170312
170319
  }
170313
170320
  createApp(options) {
170314
170321
  return Bun.serve({
@@ -170329,9 +170336,13 @@ class Server extends ServerAbstract {
170329
170336
  serve(options) {
170330
170337
  return this.instance.serve(options);
170331
170338
  }
170332
- async exit() {
170333
- await this.handleBeforeExit?.();
170334
- return await this.instance.exit();
170339
+ async close() {
170340
+ await this.handleBeforeClose?.();
170341
+ console.log("Closing...");
170342
+ await this.instance.close();
170343
+ if (Config.nodeEnv !== "test") {
170344
+ process.exit(0);
170345
+ }
170335
170346
  }
170336
170347
  }
170337
170348
  // src/index.ts
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@ozanarslan/corpus",
3
3
  "type": "module",
4
4
  "module": "index.ts",
5
- "version": "0.1.0",
5
+ "version": "0.1.2",
6
6
  "description": "Small Typescript backend framework with only core utilities",
7
7
  "author": "Ozan Arslan <ozanarslanwork@gmail.com>",
8
8
  "license": "MIT",