@scpxl/nodejs-framework 1.0.14 → 1.0.19

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 (192) hide show
  1. package/README.md +29 -0
  2. package/dist/api-requester/api-requester.d.ts +27 -6
  3. package/dist/api-requester/api-requester.d.ts.map +1 -1
  4. package/dist/api-requester/api-requester.js +188 -26
  5. package/dist/api-requester/api-requester.js.map +2 -2
  6. package/dist/api-requester/index.d.ts +1 -0
  7. package/dist/api-requester/index.d.ts.map +1 -1
  8. package/dist/api-requester/index.js.map +1 -1
  9. package/dist/application/base-application.d.ts +16 -20
  10. package/dist/application/base-application.d.ts.map +1 -1
  11. package/dist/application/base-application.js +152 -109
  12. package/dist/application/base-application.js.map +2 -2
  13. package/dist/application/command-application.d.ts.map +1 -1
  14. package/dist/application/command-application.js +3 -4
  15. package/dist/application/command-application.js.map +2 -2
  16. package/dist/application/web-application.d.ts.map +1 -1
  17. package/dist/application/web-application.js +9 -2
  18. package/dist/application/web-application.js.map +2 -2
  19. package/dist/cache/manager.d.ts +87 -6
  20. package/dist/cache/manager.d.ts.map +1 -1
  21. package/dist/cache/manager.js +77 -30
  22. package/dist/cache/manager.js.map +2 -2
  23. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  24. package/dist/cluster/cluster-manager.js +7 -9
  25. package/dist/cluster/cluster-manager.js.map +2 -2
  26. package/dist/config/env.d.ts +11 -0
  27. package/dist/config/env.d.ts.map +1 -0
  28. package/dist/config/env.js +103 -0
  29. package/dist/config/env.js.map +7 -0
  30. package/dist/config/index.d.ts +3 -0
  31. package/dist/config/index.d.ts.map +1 -0
  32. package/dist/config/index.js +3 -0
  33. package/dist/config/index.js.map +7 -0
  34. package/dist/config/schema.d.ts +408 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +218 -0
  37. package/dist/config/schema.js.map +7 -0
  38. package/dist/database/dynamic-entity.d.ts.map +1 -1
  39. package/dist/database/dynamic-entity.js +6 -2
  40. package/dist/database/dynamic-entity.js.map +2 -2
  41. package/dist/database/instance.d.ts.map +1 -1
  42. package/dist/database/instance.js +0 -8
  43. package/dist/database/instance.js.map +2 -2
  44. package/dist/database/manager.d.ts.map +1 -1
  45. package/dist/database/manager.js +71 -9
  46. package/dist/database/manager.js.map +2 -2
  47. package/dist/error/error-reporter.d.ts +96 -0
  48. package/dist/error/error-reporter.d.ts.map +1 -0
  49. package/dist/error/error-reporter.js +228 -0
  50. package/dist/error/error-reporter.js.map +7 -0
  51. package/dist/error/error.interface.d.ts +126 -0
  52. package/dist/error/error.interface.d.ts.map +1 -0
  53. package/dist/error/error.interface.js +45 -0
  54. package/dist/error/error.interface.js.map +7 -0
  55. package/dist/error/framework-errors.d.ts +113 -0
  56. package/dist/error/framework-errors.d.ts.map +1 -0
  57. package/dist/error/framework-errors.js +176 -0
  58. package/dist/error/framework-errors.js.map +7 -0
  59. package/dist/error/index.d.ts +6 -0
  60. package/dist/error/index.d.ts.map +1 -0
  61. package/dist/error/index.js +34 -0
  62. package/dist/error/index.js.map +7 -0
  63. package/dist/event/manager.d.ts.map +1 -1
  64. package/dist/event/manager.js +2 -9
  65. package/dist/event/manager.js.map +2 -2
  66. package/dist/index.d.ts +5 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -1
  69. package/dist/index.js.map +2 -2
  70. package/dist/lifecycle/exit.d.ts +11 -0
  71. package/dist/lifecycle/exit.d.ts.map +1 -0
  72. package/dist/lifecycle/exit.js +29 -0
  73. package/dist/lifecycle/exit.js.map +7 -0
  74. package/dist/lifecycle/index.d.ts +7 -0
  75. package/dist/lifecycle/index.d.ts.map +1 -0
  76. package/dist/lifecycle/index.js +12 -0
  77. package/dist/lifecycle/index.js.map +7 -0
  78. package/dist/lifecycle/lifecycle-manager.d.ts +66 -0
  79. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -0
  80. package/dist/lifecycle/lifecycle-manager.js +280 -0
  81. package/dist/lifecycle/lifecycle-manager.js.map +7 -0
  82. package/dist/lifecycle/shutdown-controller.d.ts +15 -0
  83. package/dist/lifecycle/shutdown-controller.d.ts.map +1 -0
  84. package/dist/lifecycle/shutdown-controller.js +38 -0
  85. package/dist/lifecycle/shutdown-controller.js.map +7 -0
  86. package/dist/lifecycle/types.d.ts +28 -0
  87. package/dist/lifecycle/types.d.ts.map +1 -0
  88. package/dist/lifecycle/types.js +13 -0
  89. package/dist/lifecycle/types.js.map +7 -0
  90. package/dist/logger/logger.d.ts +2 -1
  91. package/dist/logger/logger.d.ts.map +1 -1
  92. package/dist/logger/logger.js +35 -11
  93. package/dist/logger/logger.js.map +2 -2
  94. package/dist/performance/cache-performance.d.ts +6 -0
  95. package/dist/performance/cache-performance.d.ts.map +1 -1
  96. package/dist/performance/cache-performance.js +16 -0
  97. package/dist/performance/cache-performance.js.map +2 -2
  98. package/dist/performance/index.d.ts +1 -0
  99. package/dist/performance/index.d.ts.map +1 -1
  100. package/dist/performance/index.js +1 -0
  101. package/dist/performance/index.js.map +2 -2
  102. package/dist/performance/performance-monitor.d.ts.map +1 -1
  103. package/dist/performance/performance-monitor.js +47 -18
  104. package/dist/performance/performance-monitor.js.map +2 -2
  105. package/dist/performance/performance-monitor.plugin.d.ts +24 -0
  106. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -0
  107. package/dist/performance/performance-monitor.plugin.js +89 -0
  108. package/dist/performance/performance-monitor.plugin.js.map +7 -0
  109. package/dist/performance/webserver-performance.js +1 -1
  110. package/dist/performance/webserver-performance.js.map +2 -2
  111. package/dist/queue/manager.d.ts.map +1 -1
  112. package/dist/queue/manager.js +3 -10
  113. package/dist/queue/manager.js.map +2 -2
  114. package/dist/queue/worker.d.ts.map +1 -1
  115. package/dist/queue/worker.js +2 -2
  116. package/dist/queue/worker.js.map +2 -2
  117. package/dist/redis/manager.d.ts.map +1 -1
  118. package/dist/redis/manager.js +228 -33
  119. package/dist/redis/manager.js.map +2 -2
  120. package/dist/request-context/index.d.ts +3 -0
  121. package/dist/request-context/index.d.ts.map +1 -0
  122. package/dist/request-context/index.js +25 -0
  123. package/dist/request-context/index.js.map +7 -0
  124. package/dist/request-context/request-context.d.ts +108 -0
  125. package/dist/request-context/request-context.d.ts.map +1 -0
  126. package/dist/request-context/request-context.interface.d.ts +46 -0
  127. package/dist/request-context/request-context.interface.d.ts.map +1 -0
  128. package/dist/request-context/request-context.interface.js +1 -0
  129. package/dist/request-context/request-context.interface.js.map +7 -0
  130. package/dist/request-context/request-context.js +79 -0
  131. package/dist/request-context/request-context.js.map +7 -0
  132. package/dist/services/aws/s3.js +4 -6
  133. package/dist/services/aws/s3.js.map +2 -2
  134. package/dist/util/file.d.ts +13 -0
  135. package/dist/util/file.d.ts.map +1 -1
  136. package/dist/util/file.js +46 -9
  137. package/dist/util/file.js.map +2 -2
  138. package/dist/util/helper.d.ts +16 -1
  139. package/dist/util/helper.d.ts.map +1 -1
  140. package/dist/util/helper.js +19 -43
  141. package/dist/util/helper.js.map +2 -2
  142. package/dist/util/index.d.ts +1 -0
  143. package/dist/util/index.d.ts.map +1 -1
  144. package/dist/util/index.js +18 -16
  145. package/dist/util/index.js.map +2 -2
  146. package/dist/util/loader.d.ts.map +1 -1
  147. package/dist/util/loader.js +13 -2
  148. package/dist/util/loader.js.map +2 -2
  149. package/dist/util/os.d.ts.map +1 -1
  150. package/dist/util/os.js +8 -14
  151. package/dist/util/os.js.map +2 -2
  152. package/dist/util/time.d.ts +8 -2
  153. package/dist/util/time.d.ts.map +1 -1
  154. package/dist/util/time.js +12 -7
  155. package/dist/util/time.js.map +2 -2
  156. package/dist/util/timing.d.ts +36 -0
  157. package/dist/util/timing.d.ts.map +1 -0
  158. package/dist/util/timing.interface.d.ts +47 -0
  159. package/dist/util/timing.interface.d.ts.map +1 -0
  160. package/dist/util/timing.interface.js +1 -0
  161. package/dist/util/timing.interface.js.map +7 -0
  162. package/dist/util/timing.js +98 -0
  163. package/dist/util/timing.js.map +7 -0
  164. package/dist/util/url.js +1 -1
  165. package/dist/util/url.js.map +2 -2
  166. package/dist/webserver/controller/base.d.ts +3 -1
  167. package/dist/webserver/controller/base.d.ts.map +1 -1
  168. package/dist/webserver/controller/base.interface.d.ts +2 -0
  169. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  170. package/dist/webserver/controller/base.js +4 -1
  171. package/dist/webserver/controller/base.js.map +2 -2
  172. package/dist/webserver/controller/health.d.ts +8 -1
  173. package/dist/webserver/controller/health.d.ts.map +1 -1
  174. package/dist/webserver/controller/health.js +36 -22
  175. package/dist/webserver/controller/health.js.map +2 -2
  176. package/dist/webserver/webserver.d.ts +16 -2
  177. package/dist/webserver/webserver.d.ts.map +1 -1
  178. package/dist/webserver/webserver.interface.d.ts +37 -0
  179. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  180. package/dist/webserver/webserver.interface.js.map +2 -2
  181. package/dist/webserver/webserver.js +117 -20
  182. package/dist/webserver/webserver.js.map +2 -2
  183. package/dist/websocket/controllers/server/system.d.ts.map +1 -1
  184. package/dist/websocket/controllers/server/system.js.map +2 -2
  185. package/dist/websocket/websocket-base.d.ts.map +1 -1
  186. package/dist/websocket/websocket-base.js +2 -3
  187. package/dist/websocket/websocket-base.js.map +2 -2
  188. package/dist/websocket/websocket-server.d.ts +1 -1
  189. package/dist/websocket/websocket-server.d.ts.map +1 -1
  190. package/dist/websocket/websocket-server.js +7 -31
  191. package/dist/websocket/websocket-server.js.map +2 -2
  192. package/package.json +68 -25
package/README.md CHANGED
@@ -100,6 +100,35 @@ class UserService {
100
100
  }
101
101
  ```
102
102
 
103
+ ## Examples
104
+
105
+ The `examples/` directory contains working examples demonstrating the framework:
106
+
107
+ ### Hello World Example
108
+
109
+ A simple full-stack example with:
110
+
111
+ - Backend: PXL WebApplication with TypeScript
112
+ - Frontend: Vue 3 + TypeScript + Vite
113
+
114
+ **Run the example:**
115
+
116
+ ```bash
117
+ # Install dependencies for the example (one-time setup)
118
+ npm run example:install
119
+
120
+ # Run backend + frontend together with hot-reload
121
+ npm run example:hello-world
122
+
123
+ # Or run individually
124
+ npm run example:hello-world:backend
125
+ npm run example:hello-world:frontend
126
+ ```
127
+
128
+ Then open http://localhost:5173 to see the app.
129
+
130
+ See [examples/README.md](examples/README.md) for more details.
131
+
103
132
  ## When Not to Use
104
133
 
105
134
  If you only need a single HTTP server or minimal script, this framework may be heavier than needed.
@@ -1,11 +1,32 @@
1
- import { type AxiosRequestConfig, type AxiosResponse } from 'axios';
1
+ export interface ApiRequestConfig extends Omit<RequestInit, 'method' | 'body' | 'headers'> {
2
+ headers?: Record<string, string | undefined>;
3
+ params?: Record<string, string | number | boolean | null | undefined>;
4
+ responseType?: 'json' | 'text';
5
+ }
6
+ export interface ApiResponse<T> {
7
+ data: T;
8
+ status: number;
9
+ statusText: string;
10
+ headers: Record<string, string>;
11
+ }
2
12
  export default class ApiRequester {
3
- private axiosInstance;
13
+ private readonly baseURL;
14
+ private readonly defaultHeaders;
4
15
  constructor(baseURL: string, headers?: Record<string, string>);
5
- get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T> | undefined>;
6
- post<T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<AxiosResponse<R> | undefined>;
7
- put<T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<AxiosResponse<R> | undefined>;
8
- delete<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T> | undefined>;
16
+ get<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T> | undefined>;
17
+ post<T, R>(url: string, data: T, config?: ApiRequestConfig): Promise<ApiResponse<R> | undefined>;
18
+ put<T, R>(url: string, data: T, config?: ApiRequestConfig): Promise<ApiResponse<R> | undefined>;
19
+ delete<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T> | undefined>;
20
+ private request;
21
+ private mergeHeaders;
22
+ private prepareBody;
23
+ private shouldSerializeAsJson;
24
+ private headersToRecord;
25
+ private buildUrl;
26
+ private isAbsoluteUrl;
27
+ private combineWithBase;
28
+ private parseResponse;
29
+ private createHttpError;
9
30
  private handleError;
10
31
  }
11
32
  //# sourceMappingURL=api-requester.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-requester.d.ts","sourceRoot":"","sources":["../../src/api-requester/api-requester.ts"],"names":[],"mappings":"AAAA,OAAc,EAAsB,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAE/F,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOhD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IASvF,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IASpG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IASnG,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IASvG,OAAO,CAAC,WAAW;CAUpB"}
1
+ {"version":3,"file":"api-requester.d.ts","sourceRoot":"","sources":["../../src/api-requester/api-requester.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AA0BD,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE5C,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAKpD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAInF,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAIhG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAI/F,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;YAIrF,OAAO;IAsCrB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,WAAW;IA4BnB,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,eAAe;YAUT,aAAa;YAkBb,eAAe;IAoC7B,OAAO,CAAC,WAAW;CAapB"}
@@ -1,52 +1,214 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import axios from "axios";
3
+ class ApiRequesterHttpError extends Error {
4
+ static {
5
+ __name(this, "ApiRequesterHttpError");
6
+ }
7
+ status;
8
+ statusText;
9
+ data;
10
+ headers;
11
+ constructor(message, options) {
12
+ super(message);
13
+ this.name = "ApiRequesterHttpError";
14
+ this.status = options.status;
15
+ this.statusText = options.statusText;
16
+ this.data = options.data;
17
+ this.headers = options.headers;
18
+ }
19
+ }
4
20
  class ApiRequester {
5
21
  static {
6
22
  __name(this, "ApiRequester");
7
23
  }
8
- axiosInstance;
9
- constructor(baseURL, headers) {
10
- this.axiosInstance = axios.create({
11
- baseURL,
12
- headers
13
- });
24
+ baseURL;
25
+ defaultHeaders;
26
+ constructor(baseURL, headers = {}) {
27
+ this.baseURL = baseURL;
28
+ this.defaultHeaders = { ...headers };
14
29
  }
15
30
  async get(url, config) {
16
- try {
17
- const response = await this.axiosInstance.get(url, config);
18
- return response;
19
- } catch (error) {
20
- this.handleError(error);
21
- }
31
+ return this.request("GET", url, void 0, config);
22
32
  }
23
33
  async post(url, data, config) {
34
+ return this.request("POST", url, data, config);
35
+ }
36
+ async put(url, data, config) {
37
+ return this.request("PUT", url, data, config);
38
+ }
39
+ async delete(url, config) {
40
+ return this.request("DELETE", url, void 0, config);
41
+ }
42
+ async request(method, url, data, config) {
24
43
  try {
25
- const response = await this.axiosInstance.post(url, data, config);
26
- return response;
44
+ const { headers: configHeaders, params, responseType = "json", ...init } = config ?? {};
45
+ const finalUrl = this.buildUrl(url, params);
46
+ const headers = this.mergeHeaders(configHeaders, data);
47
+ const body = this.prepareBody(method, data);
48
+ const response = await fetch(finalUrl, {
49
+ ...init,
50
+ method,
51
+ headers,
52
+ body
53
+ });
54
+ if (!response.ok) {
55
+ throw await this.createHttpError(response);
56
+ }
57
+ const parsed = await this.parseResponse(response, responseType);
58
+ return {
59
+ data: parsed,
60
+ status: response.status,
61
+ statusText: response.statusText,
62
+ headers: this.headersToRecord(response.headers)
63
+ };
27
64
  } catch (error) {
28
65
  this.handleError(error);
29
66
  }
30
67
  }
31
- async put(url, data, config) {
68
+ mergeHeaders(headers, body) {
69
+ const merged = new Headers();
70
+ for (const [key, value] of Object.entries(this.defaultHeaders)) {
71
+ if (value !== void 0) {
72
+ merged.set(key, value);
73
+ }
74
+ }
75
+ if (headers) {
76
+ for (const [key, value] of Object.entries(headers)) {
77
+ if (value !== void 0) {
78
+ merged.set(key, value);
79
+ } else {
80
+ merged.delete(key);
81
+ }
82
+ }
83
+ }
84
+ if (body !== void 0 && this.shouldSerializeAsJson(body) && !merged.has("content-type")) {
85
+ merged.set("content-type", "application/json");
86
+ }
87
+ return merged;
88
+ }
89
+ prepareBody(method, data) {
90
+ if (method === "GET" || method === "HEAD" || data === void 0) {
91
+ return void 0;
92
+ }
93
+ if (typeof data === "string" || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
94
+ return data;
95
+ }
96
+ if (typeof Blob !== "undefined" && data instanceof Blob) {
97
+ return data;
98
+ }
99
+ if (typeof FormData !== "undefined" && data instanceof FormData) {
100
+ return data;
101
+ }
102
+ if (typeof URLSearchParams !== "undefined" && data instanceof URLSearchParams) {
103
+ return data;
104
+ }
105
+ if (typeof ReadableStream !== "undefined" && data instanceof ReadableStream) {
106
+ return data;
107
+ }
108
+ return JSON.stringify(data);
109
+ }
110
+ shouldSerializeAsJson(data) {
111
+ if (data === null) {
112
+ return true;
113
+ }
114
+ if (Array.isArray(data)) {
115
+ return true;
116
+ }
117
+ const primitiveTypes = ["string", "number", "boolean", "bigint"];
118
+ if (primitiveTypes.includes(typeof data)) {
119
+ return false;
120
+ }
121
+ if (typeof data === "object") {
122
+ return !(data instanceof ArrayBuffer || ArrayBuffer.isView(data) || typeof Blob !== "undefined" && data instanceof Blob || typeof FormData !== "undefined" && data instanceof FormData || typeof URLSearchParams !== "undefined" && data instanceof URLSearchParams || typeof ReadableStream !== "undefined" && data instanceof ReadableStream || typeof Buffer !== "undefined" && Buffer.isBuffer(data));
123
+ }
124
+ return false;
125
+ }
126
+ headersToRecord(headers) {
127
+ const result = {};
128
+ headers.forEach((value, key) => {
129
+ result[key] = value;
130
+ });
131
+ return result;
132
+ }
133
+ buildUrl(path, params) {
134
+ const absolute = this.isAbsoluteUrl(path) ? path : this.combineWithBase(path);
135
+ if (!params) {
136
+ return absolute;
137
+ }
138
+ const url = new URL(absolute);
139
+ for (const [key, rawValue] of Object.entries(params)) {
140
+ if (rawValue === void 0 || rawValue === null) {
141
+ continue;
142
+ }
143
+ url.searchParams.set(key, String(rawValue));
144
+ }
145
+ return url.toString();
146
+ }
147
+ isAbsoluteUrl(url) {
148
+ return /^https?:\/\//i.test(url);
149
+ }
150
+ combineWithBase(path) {
151
+ if (!this.baseURL) {
152
+ return path;
153
+ }
154
+ const normalizedBase = this.baseURL.endsWith("/") ? this.baseURL.slice(0, -1) : this.baseURL;
155
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
156
+ return `${normalizedBase}${normalizedPath}`;
157
+ }
158
+ async parseResponse(response, responseType) {
159
+ if (responseType === "text") {
160
+ return await response.text();
161
+ }
162
+ const body = await response.text();
163
+ if (!body) {
164
+ return void 0;
165
+ }
32
166
  try {
33
- const response = await this.axiosInstance.put(url, data, config);
34
- return response;
167
+ return JSON.parse(body);
35
168
  } catch (error) {
36
- this.handleError(error);
169
+ const reason = error instanceof Error ? error.message : String(error);
170
+ throw new Error(`Failed to parse JSON response: ${reason}`);
37
171
  }
38
172
  }
39
- async delete(url, config) {
173
+ async createHttpError(response) {
174
+ const headers = this.headersToRecord(response.headers);
175
+ let data = void 0;
176
+ let message = `Request failed with status ${response.status}`;
40
177
  try {
41
- const response = await this.axiosInstance.delete(url, config);
42
- return response;
43
- } catch (error) {
44
- this.handleError(error);
178
+ const text = await response.text();
179
+ if (text) {
180
+ const contentType = headers["content-type"] ?? "";
181
+ if (contentType.includes("application/json")) {
182
+ data = JSON.parse(text);
183
+ if (data && typeof data === "object" && "message" in data) {
184
+ const potentialMessage = data.message;
185
+ if (typeof potentialMessage === "string") {
186
+ message = potentialMessage;
187
+ }
188
+ }
189
+ } else {
190
+ data = text;
191
+ message = text;
192
+ }
193
+ }
194
+ } catch {
195
+ data = void 0;
196
+ message = `Request failed with status ${response.status}`;
45
197
  }
198
+ return new ApiRequesterHttpError(message, {
199
+ status: response.status,
200
+ statusText: response.statusText,
201
+ data,
202
+ headers
203
+ });
46
204
  }
47
205
  handleError(error) {
48
- if (axios.isAxiosError(error)) {
49
- console.error("Axios error:", error.response?.data);
206
+ if (error instanceof ApiRequesterHttpError) {
207
+ console.error("HTTP error:", {
208
+ status: error.status,
209
+ statusText: error.statusText,
210
+ data: error.data
211
+ });
50
212
  } else {
51
213
  console.error("Unexpected error:", error);
52
214
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/api-requester/api-requester.ts"],
4
- "sourcesContent": ["import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';\n\nexport default class ApiRequester {\n private axiosInstance: AxiosInstance;\n\n constructor(baseURL: string, headers?: Record<string, string>) {\n this.axiosInstance = axios.create({\n baseURL,\n headers,\n });\n }\n\n public async get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T> | undefined> {\n try {\n const response = await this.axiosInstance.get<T>(url, config);\n return response;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n public async post<T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<AxiosResponse<R> | undefined> {\n try {\n const response = await this.axiosInstance.post<R>(url, data, config);\n return response;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n public async put<T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<AxiosResponse<R> | undefined> {\n try {\n const response = await this.axiosInstance.put<R>(url, data, config);\n return response;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n public async delete<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T> | undefined> {\n try {\n const response = await this.axiosInstance.delete<T>(url, config);\n return response;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private handleError(error: any): void {\n if (axios.isAxiosError(error)) {\n // Handle Axios-specific errors here\n console.error('Axios error:', error.response?.data);\n } else {\n // Handle non-Axios errors here\n console.error('Unexpected error:', error);\n }\n throw error;\n }\n}\n"],
5
- "mappings": ";;AAAA,OAAO,WAAgF;AAEvF,MAAO,aAA2B;AAAA,EAFlC,OAEkC;AAAA;AAAA;AAAA,EACxB;AAAA,EAER,YAAY,SAAiB,SAAkC;AAC7D,SAAK,gBAAgB,MAAM,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,IAAO,KAAa,QAAoE;AACnG,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,cAAc,IAAO,KAAK,MAAM;AAC5D,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAa,KAAW,KAAa,MAAS,QAAoE;AAChH,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,cAAc,KAAQ,KAAK,MAAM,MAAM;AACnE,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAa,IAAU,KAAa,MAAS,QAAoE;AAC/G,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,cAAc,IAAO,KAAK,MAAM,MAAM;AAClE,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAa,OAAU,KAAa,QAAoE;AACtG,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,cAAc,OAAU,KAAK,MAAM;AAC/D,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,YAAY,OAAkB;AACpC,QAAI,MAAM,aAAa,KAAK,GAAG;AAE7B,cAAQ,MAAM,gBAAgB,MAAM,UAAU,IAAI;AAAA,IACpD,OAAO;AAEL,cAAQ,MAAM,qBAAqB,KAAK;AAAA,IAC1C;AACA,UAAM;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["export interface ApiRequestConfig extends Omit<RequestInit, 'method' | 'body' | 'headers'> {\n headers?: Record<string, string | undefined>;\n params?: Record<string, string | number | boolean | null | undefined>;\n responseType?: 'json' | 'text';\n}\n\nexport interface ApiResponse<T> {\n data: T;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n}\n\nclass ApiRequesterHttpError extends Error {\n public readonly status: number;\n public readonly statusText: string;\n public readonly data: unknown;\n public readonly headers: Record<string, string>;\n\n constructor(\n message: string,\n options: {\n status: number;\n statusText: string;\n data: unknown;\n headers: Record<string, string>;\n },\n ) {\n super(message);\n this.name = 'ApiRequesterHttpError';\n this.status = options.status;\n this.statusText = options.statusText;\n this.data = options.data;\n this.headers = options.headers;\n }\n}\n\nexport default class ApiRequester {\n private readonly baseURL: string;\n private readonly defaultHeaders: Record<string, string>;\n\n constructor(baseURL: string, headers: Record<string, string> = {}) {\n this.baseURL = baseURL;\n this.defaultHeaders = { ...headers };\n }\n\n public async get<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T> | undefined> {\n return this.request<T>('GET', url, undefined, config);\n }\n\n public async post<T, R>(url: string, data: T, config?: ApiRequestConfig): Promise<ApiResponse<R> | undefined> {\n return this.request<R>('POST', url, data, config);\n }\n\n public async put<T, R>(url: string, data: T, config?: ApiRequestConfig): Promise<ApiResponse<R> | undefined> {\n return this.request<R>('PUT', url, data, config);\n }\n\n public async delete<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T> | undefined> {\n return this.request<T>('DELETE', url, undefined, config);\n }\n\n private async request<T>(\n method: string,\n url: string,\n data?: unknown,\n config?: ApiRequestConfig,\n ): Promise<ApiResponse<T> | undefined> {\n try {\n const { headers: configHeaders, params, responseType = 'json', ...init } = config ?? {};\n const finalUrl = this.buildUrl(url, params);\n const headers = this.mergeHeaders(configHeaders, data);\n const body = this.prepareBody(method, data);\n\n // fetch is a global in Node.js 18+\n // eslint-disable-next-line no-undef\n const response = await fetch(finalUrl, {\n ...init,\n method,\n headers,\n body,\n });\n\n if (!response.ok) {\n throw await this.createHttpError(response);\n }\n\n const parsed = await this.parseResponse<T>(response, responseType);\n\n return {\n data: parsed,\n status: response.status,\n statusText: response.statusText,\n headers: this.headersToRecord(response.headers),\n };\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private mergeHeaders(headers?: Record<string, string | undefined>, body?: unknown): Headers {\n const merged = new Headers();\n\n for (const [key, value] of Object.entries(this.defaultHeaders)) {\n if (value !== undefined) {\n merged.set(key, value);\n }\n }\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n merged.set(key, value);\n } else {\n merged.delete(key);\n }\n }\n }\n\n if (body !== undefined && this.shouldSerializeAsJson(body) && !merged.has('content-type')) {\n merged.set('content-type', 'application/json');\n }\n\n return merged;\n }\n\n private prepareBody(method: string, data?: unknown): BodyInit | null | undefined {\n if (method === 'GET' || method === 'HEAD' || data === undefined) {\n return undefined;\n }\n\n if (typeof data === 'string' || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {\n return data as BodyInit;\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n return data;\n }\n\n if (typeof FormData !== 'undefined' && data instanceof FormData) {\n return data;\n }\n\n if (typeof URLSearchParams !== 'undefined' && data instanceof URLSearchParams) {\n return data;\n }\n\n if (typeof ReadableStream !== 'undefined' && data instanceof ReadableStream) {\n return data;\n }\n\n return JSON.stringify(data);\n }\n\n private shouldSerializeAsJson(data: unknown): boolean {\n if (data === null) {\n return true;\n }\n\n if (Array.isArray(data)) {\n return true;\n }\n\n const primitiveTypes = ['string', 'number', 'boolean', 'bigint'];\n if (primitiveTypes.includes(typeof data)) {\n return false;\n }\n\n if (typeof data === 'object') {\n return !(\n data instanceof ArrayBuffer ||\n ArrayBuffer.isView(data) ||\n (typeof Blob !== 'undefined' && data instanceof Blob) ||\n (typeof FormData !== 'undefined' && data instanceof FormData) ||\n (typeof URLSearchParams !== 'undefined' && data instanceof URLSearchParams) ||\n (typeof ReadableStream !== 'undefined' && data instanceof ReadableStream) ||\n (typeof Buffer !== 'undefined' && Buffer.isBuffer(data))\n );\n }\n\n return false;\n }\n\n private headersToRecord(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n // Safe: key comes from Headers iterator, not user input\n // eslint-disable-next-line security/detect-object-injection\n result[key] = value;\n });\n return result;\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | null | undefined>): string {\n const absolute = this.isAbsoluteUrl(path) ? path : this.combineWithBase(path);\n if (!params) {\n return absolute;\n }\n\n const url = new URL(absolute);\n for (const [key, rawValue] of Object.entries(params)) {\n if (rawValue === undefined || rawValue === null) {\n continue;\n }\n url.searchParams.set(key, String(rawValue));\n }\n return url.toString();\n }\n\n private isAbsoluteUrl(url: string): boolean {\n return /^https?:\\/\\//i.test(url);\n }\n\n private combineWithBase(path: string): string {\n if (!this.baseURL) {\n return path;\n }\n\n const normalizedBase = this.baseURL.endsWith('/') ? this.baseURL.slice(0, -1) : this.baseURL;\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n return `${normalizedBase}${normalizedPath}`;\n }\n\n private async parseResponse<T>(response: Response, responseType: 'json' | 'text'): Promise<T> {\n if (responseType === 'text') {\n return (await response.text()) as T;\n }\n\n const body = await response.text();\n if (!body) {\n return undefined as T;\n }\n\n try {\n return JSON.parse(body) as T;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse JSON response: ${reason}`);\n }\n }\n\n private async createHttpError(response: Response): Promise<ApiRequesterHttpError> {\n const headers = this.headersToRecord(response.headers);\n let data: unknown = undefined;\n let message = `Request failed with status ${response.status}`;\n\n try {\n const text = await response.text();\n if (text) {\n const contentType = headers['content-type'] ?? '';\n if (contentType.includes('application/json')) {\n data = JSON.parse(text);\n if (data && typeof data === 'object' && 'message' in (data as Record<string, unknown>)) {\n const potentialMessage = (data as Record<string, unknown>).message;\n if (typeof potentialMessage === 'string') {\n message = potentialMessage;\n }\n }\n } else {\n data = text;\n message = text;\n }\n }\n } catch {\n // If parsing fails, use defaults set above\n data = undefined;\n message = `Request failed with status ${response.status}`;\n }\n\n return new ApiRequesterHttpError(message, {\n status: response.status,\n statusText: response.statusText,\n data,\n headers,\n });\n }\n\n private handleError(error: unknown): never {\n if (error instanceof ApiRequesterHttpError) {\n console.error('HTTP error:', {\n status: error.status,\n statusText: error.statusText,\n data: error.data,\n });\n } else {\n console.error('Unexpected error:', error);\n }\n\n throw error;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,3 @@
1
1
  export { default as ApiRequester } from './api-requester.js';
2
+ export type { ApiRequestConfig, ApiResponse } from './api-requester.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api-requester/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api-requester/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/api-requester/index.ts"],
4
- "sourcesContent": ["export { default as ApiRequester } from './api-requester.js';\n"],
4
+ "sourcesContent": ["export { default as ApiRequester } from './api-requester.js';\nexport type { ApiRequestConfig, ApiResponse } from './api-requester.js';\n"],
5
5
  "mappings": "AAAA,SAAoB,WAAXA,gBAA+B;",
6
6
  "names": ["default"]
7
7
  }
@@ -1,21 +1,18 @@
1
1
  import { type DatabaseInstance, DatabaseManager } from '../database/index.js';
2
2
  import QueueManager from '../queue/manager.js';
3
3
  import RedisManager from '../redis/manager.js';
4
- import type { ApplicationConfig } from './base-application.interface.js';
4
+ import type { ApplicationConfig, ApplicationStopInstanceOptions } from './base-application.interface.js';
5
5
  import type RedisInstance from '../redis/instance.js';
6
6
  import CacheManager from '../cache/manager.js';
7
7
  import EventManager from '../event/manager.js';
8
- import { PerformanceMonitor } from '../performance/performance-monitor.js';
8
+ import type { PerformanceMonitor } from '../performance/performance-monitor.js';
9
+ import { LifecycleManager, ShutdownController } from '../lifecycle/index.js';
9
10
  export type { ApplicationConfig } from './base-application.interface.js';
10
11
  export default abstract class BaseApplication {
11
12
  /** Unique instance ID */
12
13
  uniqueInstanceId: string;
13
- /** Shutdown signals */
14
- protected shutdownSignals: NodeJS.Signals[];
15
14
  /** Application start time */
16
- protected startTime: [number, number];
17
- /** Whether application is stopping */
18
- protected isStopping: boolean;
15
+ protected startTime: number;
19
16
  /** Shutdown timeout (30 seconds) */
20
17
  protected shutdownTimeout: number;
21
18
  /** Cache for application version to avoid repeated imports */
@@ -38,6 +35,10 @@ export default abstract class BaseApplication {
38
35
  eventManager?: EventManager;
39
36
  /** Performance monitor */
40
37
  performanceMonitor?: PerformanceMonitor;
38
+ /** Lifecycle manager */
39
+ lifecycle: LifecycleManager;
40
+ /** Shutdown controller */
41
+ shutdownController: ShutdownController;
41
42
  get Name(): string;
42
43
  /**
43
44
  * Application constructor
@@ -67,10 +68,6 @@ export default abstract class BaseApplication {
67
68
  protected onStopped({ runtime: _runtime }: {
68
69
  runtime: number;
69
70
  }): void;
70
- /**
71
- * Before application stop event
72
- */
73
- private onBeforeStop;
74
71
  /**
75
72
  * Start application instance
76
73
  */
@@ -88,23 +85,22 @@ export default abstract class BaseApplication {
88
85
  /**
89
86
  * Initialize performance monitor
90
87
  */
91
- private initializePerformanceMonitor;
92
88
  private setupGlobalErrorHandlers;
89
+ /**
90
+ * Register shutdown hooks for proper cleanup
91
+ */
92
+ private registerShutdownHooks;
93
93
  /**
94
94
  * Initiate graceful shutdown
95
95
  */
96
96
  private initiateGracefulShutdown;
97
97
  /**
98
- * Handle shutdown
98
+ * Stop application using lifecycle manager
99
99
  */
100
- handleShutdown({ onStopped }: {
101
- onStopped?: ({ runtime }: {
102
- runtime: number;
103
- }) => void;
104
- }): void;
100
+ stop({ onStopped }?: ApplicationStopInstanceOptions): Promise<void>;
105
101
  /**
106
- * Stop application
102
+ * Finalize exit: during tests, suppress actual process exit to avoid failing vitest runs.
107
103
  */
108
- private stop;
104
+ private finalizeExit;
109
105
  }
110
106
  //# sourceMappingURL=base-application.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-application.d.ts","sourceRoot":"","sources":["../../src/application/base-application.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-application.d.ts","sourceRoot":"","sources":["../../src/application/base-application.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EACV,iBAAiB,EAEjB,8BAA8B,EAC/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAwB,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAKnG,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,eAAe;IAC3C,yBAAyB;IAClB,gBAAgB,EAAE,MAAM,CAAC;IAEhC,6BAA6B;IAC7B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAK;IAEhC,oCAAoC;IACpC,SAAS,CAAC,eAAe,SAAS;IAElC,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAqB;IAE3D,wBAAwB;IACxB,SAAS,CAAC,QAAQ,gBAAiE;IAEnF,yBAAyB;IACzB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,0BAA0B;IAC1B,SAAS,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAEtC,oBAAoB;IACb,YAAY,EAAE,YAAY,CAAC;IAElC,oBAAoB;IACb,YAAY,EAAE,YAAY,CAAC;IAElC,uBAAuB;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAEzC,oBAAoB;IACb,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC,oBAAoB;IACb,YAAY,CAAC,EAAE,YAAY,CAAC;IAEnC,0BAA0B;IACnB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAE/C,wBAAwB;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAEnC,0BAA0B;IACnB,kBAAkB,EAAE,kBAAkB,CAAC;IAE9C,IAAW,IAAI,WAEd;IAED;;OAEG;gBACS,MAAM,EAAE,iBAAiB;IA4ErC;;OAEG;IACU,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBrD;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmCnC;;OAEG;YACW,aAAa;IAuE3B;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAEjF;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAErE;;OAEG;YACW,aAAa;IA0D3B,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC9B,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,EAAE;QACD,aAAa,EAAE,aAAa,CAAC;QAC7B,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAC3C,YAAY,EAAE,YAAY,CAAC;QAC3B,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;KACpC,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjB,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI;IAEvC;;OAEG;IACH;;OAEG;IAIH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;OAEG;YACW,wBAAwB;IA6BtC;;OAEG;IACU,IAAI,CAAC,EAAE,SAAS,EAAE,GAAE,8BAAmC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCpF;;OAEG;IACH,OAAO,CAAC,YAAY;CAerB"}