@carno.js/core 0.2.11 → 1.0.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 (314) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +188 -0
  3. package/dist/Carno.js +272 -333
  4. package/dist/Carno.mjs +268 -0
  5. package/dist/DefaultRoutes.js +51 -0
  6. package/dist/DefaultRoutes.mjs +34 -0
  7. package/dist/bun/index.js +183 -0
  8. package/dist/bun/index.js.map +86 -0
  9. package/dist/cache/CacheDriver.js +13 -0
  10. package/dist/cache/CacheDriver.mjs +0 -0
  11. package/dist/cache/CacheService.js +113 -0
  12. package/dist/cache/CacheService.mjs +93 -0
  13. package/dist/cache/MemoryDriver.js +66 -0
  14. package/dist/cache/MemoryDriver.mjs +46 -0
  15. package/dist/cache/RedisDriver.js +81 -0
  16. package/dist/cache/RedisDriver.mjs +61 -0
  17. package/dist/compiler/JITCompiler.js +111 -0
  18. package/dist/compiler/JITCompiler.mjs +89 -0
  19. package/dist/container/Container.js +99 -0
  20. package/dist/container/Container.mjs +78 -0
  21. package/dist/context/Context.js +97 -0
  22. package/dist/context/Context.mjs +77 -0
  23. package/dist/cors/CorsHandler.js +90 -0
  24. package/dist/cors/CorsHandler.mjs +68 -0
  25. package/dist/decorators/Controller.js +42 -0
  26. package/dist/decorators/Controller.mjs +22 -0
  27. package/dist/decorators/Inject.js +30 -0
  28. package/dist/decorators/Inject.mjs +10 -0
  29. package/dist/decorators/Middleware.js +35 -0
  30. package/dist/decorators/Middleware.mjs +15 -0
  31. package/dist/decorators/Service.js +31 -0
  32. package/dist/decorators/Service.mjs +12 -0
  33. package/dist/decorators/methods.js +60 -0
  34. package/dist/decorators/methods.mjs +34 -0
  35. package/dist/decorators/params.js +63 -0
  36. package/dist/decorators/params.mjs +37 -0
  37. package/dist/events/Lifecycle.js +69 -0
  38. package/dist/events/Lifecycle.mjs +41 -0
  39. package/dist/exceptions/HttpException.js +112 -26
  40. package/dist/exceptions/HttpException.mjs +82 -0
  41. package/dist/index.js +129 -31
  42. package/dist/index.mjs +94 -0
  43. package/dist/metadata.js +34 -0
  44. package/dist/metadata.mjs +9 -0
  45. package/dist/middleware/CarnoMiddleware.js +13 -0
  46. package/dist/middleware/CarnoMiddleware.mjs +0 -0
  47. package/dist/router/RadixRouter.js +121 -0
  48. package/dist/router/RadixRouter.mjs +101 -0
  49. package/dist/testing/TestHarness.js +81 -0
  50. package/dist/testing/TestHarness.mjs +60 -0
  51. package/dist/utils/Metadata.js +53 -0
  52. package/dist/utils/Metadata.mjs +31 -0
  53. package/dist/validation/ValibotAdapter.js +67 -0
  54. package/dist/validation/ValibotAdapter.mjs +48 -0
  55. package/dist/validation/ValidatorAdapter.js +35 -19
  56. package/dist/validation/ValidatorAdapter.mjs +14 -0
  57. package/dist/validation/ZodAdapter.js +80 -0
  58. package/dist/validation/ZodAdapter.mjs +59 -0
  59. package/package.json +21 -63
  60. package/src/Carno.ts +605 -0
  61. package/src/DefaultRoutes.ts +34 -0
  62. package/src/cache/CacheDriver.ts +50 -0
  63. package/src/cache/CacheService.ts +139 -0
  64. package/src/cache/MemoryDriver.ts +104 -0
  65. package/src/cache/RedisDriver.ts +116 -0
  66. package/src/compiler/JITCompiler.ts +167 -0
  67. package/src/container/Container.ts +168 -0
  68. package/src/context/Context.ts +128 -0
  69. package/src/cors/CorsHandler.ts +145 -0
  70. package/src/decorators/Controller.ts +63 -0
  71. package/src/decorators/Inject.ts +16 -0
  72. package/src/decorators/Middleware.ts +22 -0
  73. package/src/decorators/Service.ts +18 -0
  74. package/src/decorators/methods.ts +58 -0
  75. package/src/decorators/params.ts +47 -0
  76. package/src/events/Lifecycle.ts +97 -0
  77. package/src/exceptions/HttpException.ts +99 -0
  78. package/src/index.ts +92 -0
  79. package/src/metadata.ts +46 -0
  80. package/src/middleware/CarnoMiddleware.ts +14 -0
  81. package/src/router/RadixRouter.ts +225 -0
  82. package/src/testing/TestHarness.ts +177 -0
  83. package/src/utils/Metadata.ts +43 -0
  84. package/src/validation/ValibotAdapter.ts +95 -0
  85. package/src/validation/ValidatorAdapter.ts +69 -0
  86. package/src/validation/ZodAdapter.ts +102 -0
  87. package/dist/Carno.d.ts +0 -75
  88. package/dist/cache/bento-cache.driver.d.ts +0 -13
  89. package/dist/cache/bento-cache.driver.js +0 -55
  90. package/dist/cache/cache.service.d.ts +0 -8
  91. package/dist/cache/cache.service.js +0 -6
  92. package/dist/commons/decorators/Injectable.decorator.d.ts +0 -20
  93. package/dist/commons/decorators/Injectable.decorator.js +0 -33
  94. package/dist/commons/decorators/controller.decorator.d.ts +0 -8
  95. package/dist/commons/decorators/controller.decorator.js +0 -22
  96. package/dist/commons/decorators/http.decorators.d.ts +0 -13
  97. package/dist/commons/decorators/http.decorators.js +0 -63
  98. package/dist/commons/decorators/index.d.ts +0 -6
  99. package/dist/commons/decorators/index.js +0 -22
  100. package/dist/commons/decorators/inject.decorator.d.ts +0 -1
  101. package/dist/commons/decorators/inject.decorator.js +0 -5
  102. package/dist/commons/decorators/middleware.decorator.d.ts +0 -2
  103. package/dist/commons/decorators/middleware.decorator.js +0 -30
  104. package/dist/commons/decorators/service.decorator.d.ts +0 -2
  105. package/dist/commons/decorators/service.decorator.js +0 -7
  106. package/dist/commons/decorators/validation.decorator.d.ts +0 -32
  107. package/dist/commons/decorators/validation.decorator.js +0 -40
  108. package/dist/commons/http-code.enum.d.ts +0 -50
  109. package/dist/commons/http-code.enum.js +0 -54
  110. package/dist/commons/index.d.ts +0 -3
  111. package/dist/commons/index.js +0 -19
  112. package/dist/commons/registries/ProviderControl.d.ts +0 -77
  113. package/dist/commons/registries/ProviderControl.js +0 -112
  114. package/dist/commons/registries/ProviderRegistry.d.ts +0 -7
  115. package/dist/commons/registries/ProviderRegistry.js +0 -20
  116. package/dist/constants.d.ts +0 -8
  117. package/dist/constants.js +0 -11
  118. package/dist/container/ContainerConfiguration.d.ts +0 -45
  119. package/dist/container/ContainerConfiguration.js +0 -121
  120. package/dist/container/DependencyResolver.d.ts +0 -20
  121. package/dist/container/DependencyResolver.js +0 -85
  122. package/dist/container/InjectorService.d.ts +0 -58
  123. package/dist/container/InjectorService.js +0 -286
  124. package/dist/container/MethodInvoker.d.ts +0 -21
  125. package/dist/container/MethodInvoker.js +0 -83
  126. package/dist/container/RouteResolver.d.ts +0 -27
  127. package/dist/container/RouteResolver.js +0 -173
  128. package/dist/container/container.d.ts +0 -41
  129. package/dist/container/container.js +0 -71
  130. package/dist/container/createContainer.d.ts +0 -3
  131. package/dist/container/createContainer.js +0 -12
  132. package/dist/container/createInjector.d.ts +0 -2
  133. package/dist/container/createInjector.js +0 -7
  134. package/dist/container/index.d.ts +0 -6
  135. package/dist/container/index.js +0 -22
  136. package/dist/container/middleware.resolver.d.ts +0 -9
  137. package/dist/container/middleware.resolver.js +0 -35
  138. package/dist/default-routes-carno.d.ts +0 -3
  139. package/dist/default-routes-carno.js +0 -29
  140. package/dist/domain/BaseContext.d.ts +0 -15
  141. package/dist/domain/BaseContext.js +0 -2
  142. package/dist/domain/CarnoClosure.d.ts +0 -1
  143. package/dist/domain/CarnoClosure.js +0 -2
  144. package/dist/domain/CarnoMiddleware.d.ts +0 -5
  145. package/dist/domain/CarnoMiddleware.js +0 -2
  146. package/dist/domain/Context.d.ts +0 -58
  147. package/dist/domain/Context.js +0 -188
  148. package/dist/domain/FastContext.d.ts +0 -34
  149. package/dist/domain/FastContext.js +0 -59
  150. package/dist/domain/LocalsContainer.d.ts +0 -4
  151. package/dist/domain/LocalsContainer.js +0 -10
  152. package/dist/domain/Metadata.d.ts +0 -449
  153. package/dist/domain/Metadata.js +0 -511
  154. package/dist/domain/cors-config.d.ts +0 -12
  155. package/dist/domain/cors-config.js +0 -18
  156. package/dist/domain/cors-headers-cache.d.ts +0 -17
  157. package/dist/domain/cors-headers-cache.js +0 -101
  158. package/dist/domain/http-method.d.ts +0 -7
  159. package/dist/domain/http-method.js +0 -11
  160. package/dist/domain/index.d.ts +0 -10
  161. package/dist/domain/index.js +0 -26
  162. package/dist/domain/provider-scope.d.ts +0 -5
  163. package/dist/domain/provider-scope.js +0 -9
  164. package/dist/domain/provider-type.d.ts +0 -6
  165. package/dist/domain/provider-type.js +0 -10
  166. package/dist/domain/provider.d.ts +0 -37
  167. package/dist/domain/provider.js +0 -70
  168. package/dist/events/hooks.decorator.d.ts +0 -3
  169. package/dist/events/hooks.decorator.js +0 -29
  170. package/dist/events/index.d.ts +0 -2
  171. package/dist/events/index.js +0 -18
  172. package/dist/events/on-event.d.ts +0 -13
  173. package/dist/events/on-event.js +0 -11
  174. package/dist/exceptions/HttpException.d.ts +0 -9
  175. package/dist/exceptions/index.d.ts +0 -1
  176. package/dist/exceptions/index.js +0 -17
  177. package/dist/index.d.ts +0 -16
  178. package/dist/route/CompiledRoute.d.ts +0 -23
  179. package/dist/route/CompiledRoute.js +0 -9
  180. package/dist/route/FastPathExecutor.d.ts +0 -12
  181. package/dist/route/FastPathExecutor.js +0 -50
  182. package/dist/route/JITCompiler.d.ts +0 -28
  183. package/dist/route/JITCompiler.js +0 -245
  184. package/dist/route/Matcher.d.ts +0 -11
  185. package/dist/route/Matcher.js +0 -48
  186. package/dist/route/ParamResolverFactory.d.ts +0 -14
  187. package/dist/route/ParamResolverFactory.js +0 -49
  188. package/dist/route/RouteCompiler.d.ts +0 -28
  189. package/dist/route/RouteCompiler.js +0 -157
  190. package/dist/route/RouteExecutor.d.ts +0 -12
  191. package/dist/route/RouteExecutor.js +0 -84
  192. package/dist/route/memoirist.d.ts +0 -31
  193. package/dist/route/memoirist.js +0 -373
  194. package/dist/services/logger.service.d.ts +0 -23
  195. package/dist/services/logger.service.js +0 -47
  196. package/dist/testing/core-testing.d.ts +0 -24
  197. package/dist/testing/core-testing.js +0 -102
  198. package/dist/testing/index.d.ts +0 -1
  199. package/dist/testing/index.js +0 -17
  200. package/dist/utils/ValidationCache.d.ts +0 -5
  201. package/dist/utils/ValidationCache.js +0 -35
  202. package/dist/utils/ancestorOf.d.ts +0 -2
  203. package/dist/utils/ancestorOf.js +0 -10
  204. package/dist/utils/ancestorsOf.d.ts +0 -6
  205. package/dist/utils/ancestorsOf.js +0 -20
  206. package/dist/utils/classOf.d.ts +0 -13
  207. package/dist/utils/classOf.js +0 -21
  208. package/dist/utils/cleanObject.d.ts +0 -6
  209. package/dist/utils/cleanObject.js +0 -22
  210. package/dist/utils/constructorOf.d.ts +0 -11
  211. package/dist/utils/constructorOf.js +0 -18
  212. package/dist/utils/createInstance.d.ts +0 -1
  213. package/dist/utils/createInstance.js +0 -7
  214. package/dist/utils/decoratorTypeOf.d.ts +0 -11
  215. package/dist/utils/decoratorTypeOf.js +0 -32
  216. package/dist/utils/deepClone.d.ts +0 -6
  217. package/dist/utils/deepClone.js +0 -63
  218. package/dist/utils/deepMerge.d.ts +0 -9
  219. package/dist/utils/deepMerge.js +0 -62
  220. package/dist/utils/descriptorOf.d.ts +0 -8
  221. package/dist/utils/descriptorOf.js +0 -16
  222. package/dist/utils/formatValidationErrors.d.ts +0 -5
  223. package/dist/utils/formatValidationErrors.js +0 -80
  224. package/dist/utils/getClassOrSymbol.d.ts +0 -1
  225. package/dist/utils/getClassOrSymbol.js +0 -8
  226. package/dist/utils/getConstructorArgNames.d.ts +0 -1
  227. package/dist/utils/getConstructorArgNames.js +0 -12
  228. package/dist/utils/getMethodArgTypes.d.ts +0 -1
  229. package/dist/utils/getMethodArgTypes.js +0 -9
  230. package/dist/utils/getValue.d.ts +0 -32
  231. package/dist/utils/getValue.js +0 -47
  232. package/dist/utils/hasJsonMethod.d.ts +0 -1
  233. package/dist/utils/hasJsonMethod.js +0 -6
  234. package/dist/utils/index.d.ts +0 -15
  235. package/dist/utils/index.js +0 -31
  236. package/dist/utils/isArray.d.ts +0 -13
  237. package/dist/utils/isArray.js +0 -21
  238. package/dist/utils/isArrowFn.d.ts +0 -1
  239. package/dist/utils/isArrowFn.js +0 -7
  240. package/dist/utils/isBoolean.d.ts +0 -7
  241. package/dist/utils/isBoolean.js +0 -15
  242. package/dist/utils/isBuffer.d.ts +0 -7
  243. package/dist/utils/isBuffer.js +0 -19
  244. package/dist/utils/isClass.d.ts +0 -1
  245. package/dist/utils/isClass.js +0 -26
  246. package/dist/utils/isCollection.d.ts +0 -6
  247. package/dist/utils/isCollection.js +0 -20
  248. package/dist/utils/isDate.d.ts +0 -6
  249. package/dist/utils/isDate.js +0 -11
  250. package/dist/utils/isEmpty.d.ts +0 -6
  251. package/dist/utils/isEmpty.js +0 -12
  252. package/dist/utils/isFunction.d.ts +0 -1
  253. package/dist/utils/isFunction.js +0 -6
  254. package/dist/utils/isInheritedFrom.d.ts +0 -1
  255. package/dist/utils/isInheritedFrom.js +0 -24
  256. package/dist/utils/isMomentObject.d.ts +0 -1
  257. package/dist/utils/isMomentObject.js +0 -6
  258. package/dist/utils/isMongooseObject.d.ts +0 -2
  259. package/dist/utils/isMongooseObject.js +0 -11
  260. package/dist/utils/isNil.d.ts +0 -1
  261. package/dist/utils/isNil.js +0 -6
  262. package/dist/utils/isNumber.d.ts +0 -7
  263. package/dist/utils/isNumber.js +0 -15
  264. package/dist/utils/isObject.d.ts +0 -1
  265. package/dist/utils/isObject.js +0 -6
  266. package/dist/utils/isObservable.d.ts +0 -1
  267. package/dist/utils/isObservable.js +0 -6
  268. package/dist/utils/isPlainObject.d.ts +0 -7
  269. package/dist/utils/isPlainObject.js +0 -16
  270. package/dist/utils/isPrimitive.d.ts +0 -14
  271. package/dist/utils/isPrimitive.js +0 -28
  272. package/dist/utils/isPrimitiveType.d.ts +0 -1
  273. package/dist/utils/isPrimitiveType.js +0 -11
  274. package/dist/utils/isPromise.d.ts +0 -7
  275. package/dist/utils/isPromise.js +0 -14
  276. package/dist/utils/isProtectedKey.d.ts +0 -5
  277. package/dist/utils/isProtectedKey.js +0 -10
  278. package/dist/utils/isRegExp.d.ts +0 -1
  279. package/dist/utils/isRegExp.js +0 -6
  280. package/dist/utils/isRequestScope.d.ts +0 -11
  281. package/dist/utils/isRequestScope.js +0 -23
  282. package/dist/utils/isSerializable.d.ts +0 -1
  283. package/dist/utils/isSerializable.js +0 -11
  284. package/dist/utils/isStream.d.ts +0 -1
  285. package/dist/utils/isStream.js +0 -6
  286. package/dist/utils/isString.d.ts +0 -6
  287. package/dist/utils/isString.js +0 -14
  288. package/dist/utils/isSymbol.d.ts +0 -6
  289. package/dist/utils/isSymbol.js +0 -14
  290. package/dist/utils/methodsOf.d.ts +0 -9
  291. package/dist/utils/methodsOf.js +0 -24
  292. package/dist/utils/nameOf.d.ts +0 -14
  293. package/dist/utils/nameOf.js +0 -31
  294. package/dist/utils/objectKeys.d.ts +0 -1
  295. package/dist/utils/objectKeys.js +0 -7
  296. package/dist/utils/primitiveOf.d.ts +0 -1
  297. package/dist/utils/primitiveOf.js +0 -18
  298. package/dist/utils/prototypeOf.d.ts +0 -6
  299. package/dist/utils/prototypeOf.js +0 -12
  300. package/dist/utils/setValue.d.ts +0 -1
  301. package/dist/utils/setValue.js +0 -32
  302. package/dist/utils/toMap.d.ts +0 -3
  303. package/dist/utils/toMap.js +0 -34
  304. package/dist/utils/toStringConstructor.d.ts +0 -1
  305. package/dist/utils/toStringConstructor.js +0 -10
  306. package/dist/validation/ValidatorAdapter.d.ts +0 -66
  307. package/dist/validation/adapters/ClassValidatorAdapter.d.ts +0 -23
  308. package/dist/validation/adapters/ClassValidatorAdapter.js +0 -47
  309. package/dist/validation/adapters/ZodAdapter.d.ts +0 -14
  310. package/dist/validation/adapters/ZodAdapter.js +0 -56
  311. package/dist/validation/adapters/index.d.ts +0 -4
  312. package/dist/validation/adapters/index.js +0 -7
  313. package/dist/validation/index.d.ts +0 -3
  314. package/dist/validation/index.js +0 -20
package/dist/Carno.js CHANGED
@@ -1,338 +1,277 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Carno = void 0;
7
- const node_process_1 = __importDefault(require("node:process"));
8
- const ZodAdapter_1 = require("./validation/adapters/ZodAdapter");
9
- const ValidationCache_1 = require("./utils/ValidationCache");
10
- const index_1 = require("./commons/index");
11
- const constants_1 = require("./constants");
12
- const createContainer_1 = require("./container/createContainer");
13
- const createInjector_1 = require("./container/createInjector");
14
- const domain_1 = require("./domain");
15
- const Context_1 = require("./domain/Context");
16
- const LocalsContainer_1 = require("./domain/LocalsContainer");
17
- const cors_headers_cache_1 = require("./domain/cors-headers-cache");
18
- const on_event_1 = require("./events/on-event");
19
- const HttpException_1 = require("./exceptions/HttpException");
20
- const RouteExecutor_1 = require("./route/RouteExecutor");
21
- const memoirist_1 = __importDefault(require("./route/memoirist"));
22
- const CompiledRoute_1 = require("./route/CompiledRoute");
23
- const logger_service_1 = require("./services/logger.service");
24
- const METHOD_MAP = {
25
- GET: 'get',
26
- POST: 'post',
27
- PUT: 'put',
28
- DELETE: 'delete',
29
- PATCH: 'patch',
30
- HEAD: 'head',
31
- OPTIONS: 'options'
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: !0 });
8
+ }, __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from == "object" || typeof from == "function")
10
+ for (let key of __getOwnPropNames(from))
11
+ !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ return to;
32
13
  };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
15
+ var Carno_exports = {};
16
+ __export(Carno_exports, {
17
+ Carno: () => Carno
18
+ });
19
+ module.exports = __toCommonJS(Carno_exports);
20
+ var import_reflect_metadata = require("reflect-metadata"), import_metadata = require('./metadata.js'), import_JITCompiler = require('./compiler/JITCompiler.js'), import_Context = require('./context/Context.js'), import_Container = require('./container/Container.js'), import_CorsHandler = require('./cors/CorsHandler.js'), import_HttpException = require('./exceptions/HttpException.js'), import_ZodAdapter = require('./validation/ZodAdapter.js'), import_Lifecycle = require('./events/Lifecycle.js'), import_CacheService = require('./cache/CacheService.js'), import_DefaultRoutes = require('./DefaultRoutes.js'), import_ZodAdapter2 = require('./validation/ZodAdapter.js');
21
+ const NOT_FOUND_RESPONSE = new Response("Not Found", { status: 404 }), TEXT_OPTS = Object.freeze({
22
+ status: 200,
23
+ headers: { "Content-Type": "text/plain" }
24
+ }), JSON_OPTS = Object.freeze({
25
+ status: 200,
26
+ headers: { "Content-Type": "application/json" }
27
+ }), INTERNAL_ERROR_RESPONSE = new Response(
28
+ '{"statusCode":500,"message":"Internal Server Error"}',
29
+ { status: 500, headers: { "Content-Type": "application/json" } }
30
+ );
33
31
  class Carno {
34
- constructor(config = {}) {
35
- this.config = config;
36
- this.router = new memoirist_1.default();
37
- this.injector = (0, createInjector_1.createInjector)();
38
- this.emptyLocals = new LocalsContainer_1.LocalsContainer();
39
- this.corsEnabled = false;
40
- this.hasOnRequestHook = false;
41
- this.fetch = (request, server) => {
42
- const method = request.method;
43
- if (this.corsEnabled) {
44
- const origin = request.headers.get("origin");
45
- if (method === "OPTIONS" && origin) {
46
- return this.handlePreflightRequest(request);
47
- }
48
- }
49
- const url = request.url;
50
- const startIndex = url.indexOf('/', 12);
51
- const queryIndex = url.indexOf('?', startIndex);
52
- const pathname = queryIndex === -1
53
- ? (startIndex === -1 ? '/' : url.slice(startIndex))
54
- : url.slice(startIndex, queryIndex);
55
- const methodLower = METHOD_MAP[method] || method.toLowerCase();
56
- const route = this.router.find(methodLower, pathname);
57
- if (!route) {
58
- return this.errorResponse(request, "Method not allowed", 404);
59
- }
60
- const compiled = route.store;
61
- const isCompiledRoute = compiled.routeType !== undefined;
62
- const isSimpleRoute = isCompiledRoute && compiled.routeType === CompiledRoute_1.RouteType.SIMPLE;
63
- const isGetOrHead = method === 'GET' || method === 'HEAD';
64
- const hasQuery = queryIndex !== -1;
65
- if (isSimpleRoute && isGetOrHead && !this.corsEnabled && !hasQuery && !compiled.isAsync) {
66
- const context = Context_1.Context.createFastContext(request, route.params);
67
- return compiled.boundHandler(context);
68
- }
69
- return this.fetcherAsync(request, server, route, compiled, isSimpleRoute, hasQuery, queryIndex, url);
70
- };
71
- this.catcher = (error) => {
72
- this.resolveLogger().error("Unhandled error", error);
73
- return new Response("Internal Server Error", { status: 500 });
74
- };
75
- this.validatorAdapter = this.resolveValidatorAdapter();
76
- if (config.cors) {
77
- this.corsCache = new cors_headers_cache_1.CorsHeadersCache(config.cors);
78
- }
79
- void this.bootstrapApplication();
80
- }
81
- resolveValidatorAdapter() {
82
- const config = this.config.validation;
83
- if (!config?.adapter) {
84
- return new ZodAdapter_1.ZodAdapter();
85
- }
86
- const AdapterClass = config.adapter;
87
- const options = config.options || {};
88
- return new AdapterClass(options);
89
- }
90
- /**
91
- * Use the Carno plugin.
92
- *
93
- * @param plugin
94
- */
95
- use(plugin) {
96
- if (!this.config.providers) {
97
- this.config.providers = [];
98
- }
99
- if (!this.config.globalMiddlewares) {
100
- this.config.globalMiddlewares = [];
101
- }
102
- for (const exportProvider of plugin.config.exports || []) {
103
- const existingProvider = this.findProviderInConfig(plugin, exportProvider);
104
- const providerToAdd = this.shouldCloneProvider(existingProvider)
105
- ? this.cloneProvider(existingProvider)
106
- : exportProvider;
107
- this.config.providers.push(providerToAdd);
108
- }
109
- if (plugin.config.globalMiddlewares) {
110
- this.config.globalMiddlewares.push(...plugin.config.globalMiddlewares);
111
- }
112
- return this;
113
- }
114
- findProviderInConfig(plugin, exportProvider) {
115
- return plugin.config.providers?.find((p) => this.getProviderToken(p) === this.getProviderToken(exportProvider));
116
- }
117
- getProviderToken(provider) {
118
- return provider?.provide || provider;
119
- }
120
- shouldCloneProvider(provider) {
121
- return !!(provider?.useValue !== undefined || provider?.useClass);
122
- }
123
- cloneProvider(provider) {
124
- return { ...provider };
125
- }
126
- /**
127
- * Set the custom logger provider.
128
- * The provider must be a class with the @Service() decorator.
129
- * The provider must extend the LoggerService class.
130
- *
131
- * @param provider
132
- */
133
- useLogger(provider) {
134
- (0, index_1.registerProvider)({ provide: logger_service_1.LoggerService, useClass: provider });
135
- return this;
136
- }
137
- loadProvidersAndControllers() {
138
- const providers = domain_1.Metadata.get(constants_1.PROVIDER, Reflect) || [];
139
- const controllers = domain_1.Metadata.get(constants_1.CONTROLLER, Reflect) || [];
140
- this.registerControllers(controllers);
141
- this.registerMetadataProviders(providers);
142
- this.registerConfigProviders();
143
- }
144
- registerControllers(controllers) {
145
- for (const controller of controllers) {
146
- (0, index_1.registerController)(controller);
147
- controller.options?.children &&
148
- controller.options.children.forEach((child) => {
149
- (0, index_1.registerController)({ provide: child, parent: controller.provide });
150
- });
151
- }
152
- }
153
- registerMetadataProviders(providers) {
154
- for (const provider of providers) {
155
- (0, index_1.registerProvider)(provider);
156
- }
157
- }
158
- registerConfigProviders() {
159
- if (!this.config.providers) {
160
- return;
161
- }
162
- for (const provider of this.config.providers) {
163
- const normalized = this.normalizeProvider(provider);
164
- (0, index_1.registerProvider)(normalized);
165
- }
166
- }
167
- normalizeProvider(provider) {
168
- if (provider?.provide) {
169
- return provider;
170
- }
171
- return {
172
- provide: provider,
173
- useClass: provider,
174
- };
175
- }
176
- async init() {
177
- (0, ValidationCache_1.setValidatorAdapter)(this.validatorAdapter);
178
- this.loadProvidersAndControllers();
179
- await this.injector.loadModule((0, createContainer_1.createContainer)(), this.config, this.router, this.validatorAdapter);
180
- this.corsEnabled = !!this.config.cors;
181
- this.hasOnRequestHook = this.injector.hasOnRequestHook();
182
- }
183
- async listen(port = 3000) {
184
- this.registerShutdownHandlers();
185
- await this.init();
186
- this.createHttpServer(port);
187
- }
188
- registerShutdownHandlers() {
189
- const shutdown = async (signal) => {
190
- this.resolveLogger().info(`Received ${signal}, starting graceful shutdown...`);
191
- await this.handleShutdownHook();
192
- };
193
- node_process_1.default.on("SIGTERM", () => shutdown("SIGTERM"));
194
- node_process_1.default.on("SIGINT", () => shutdown("SIGINT"));
195
- }
196
- getHttpServer() {
197
- return this.server;
198
- }
199
- getInjector() {
200
- return this.injector;
201
- }
202
- createHttpServer(port) {
203
- this.server = Bun.serve({ port, fetch: this.fetch, error: this.catcher });
204
- if (!this.config.disableStartupLog) {
205
- this.resolveLogger().info(`Server running on port ${port}`);
206
- }
207
- }
208
- async fetcherAsync(request, server, route, compiled, isSimpleRoute, hasQuery, queryIndex, url) {
209
- try {
210
- let response;
211
- const query = hasQuery ? url.slice(queryIndex + 1) : undefined;
212
- const context = Context_1.Context.createFromRequestSync({ query }, request, server);
213
- context.param = route.params;
214
- if (isSimpleRoute) {
215
- response = compiled.isAsync
216
- ? await compiled.boundHandler(context)
217
- : compiled.boundHandler(context);
218
- }
219
- else {
220
- const needsLocalsContainer = compiled.routeType !== undefined
221
- ? compiled.needsLocalsContainer
222
- : true;
223
- const locals = this.resolveLocalsContainer(needsLocalsContainer, context);
224
- if (this.hasOnRequestHook) {
225
- await this.injector.callHook(on_event_1.EventType.OnRequest, { context });
226
- }
227
- response = await RouteExecutor_1.RouteExecutor.executeRoute(compiled, this.injector, context, locals);
228
- }
229
- if (this.corsEnabled) {
230
- const origin = request.headers.get("origin");
231
- if (origin && this.corsCache.isOriginAllowed(origin)) {
232
- if (!(response instanceof Response)) {
233
- response = RouteExecutor_1.RouteExecutor.mountResponse(response, context);
234
- }
235
- return this.applyCorsHeaders(response, origin);
236
- }
237
- }
238
- return response;
239
- }
240
- catch (error) {
241
- if (error instanceof HttpException_1.HttpException) {
242
- return this.errorResponse(request, error.getResponse(), error.getStatus());
243
- }
244
- throw error;
245
- }
246
- }
247
- async bootstrapApplication() {
248
- try {
249
- await this.injector.callHook(on_event_1.EventType.OnApplicationBoot, {});
250
- }
251
- catch (error) {
252
- this.reportHookFailure(on_event_1.EventType.OnApplicationBoot, error);
253
- }
254
- }
255
- async handleShutdownHook() {
256
- try {
257
- await this.injector.callHook(on_event_1.EventType.OnApplicationShutdown);
258
- this.closeHttpServer();
259
- this.exitProcess();
260
- }
261
- catch (error) {
262
- this.reportHookFailure(on_event_1.EventType.OnApplicationShutdown, error);
263
- this.exitProcess(1);
264
- }
265
- }
266
- closeHttpServer() {
267
- if (this.server) {
268
- this.resolveLogger().info("Closing HTTP server...");
269
- this.server.stop(true);
270
- }
271
- }
272
- exitProcess(code = 0) {
273
- this.resolveLogger().info("Shutdown complete.");
274
- node_process_1.default.exit(code);
275
- }
276
- reportHookFailure(event, error) {
277
- this.resolveLogger().error(`Lifecycle hook ${event} failed`, error);
278
- }
279
- resolveLogger() {
280
- const provider = this.injector.get(logger_service_1.LoggerService);
281
- const instance = provider?.instance;
282
- return instance ?? new logger_service_1.LoggerService(this.injector);
283
- }
284
- isCorsEnabled() {
285
- return !!this.config.cors;
286
- }
287
- errorResponse(request, message, statusCode) {
288
- let response = new Response(JSON.stringify({
289
- message,
290
- statusCode,
291
- }), {
292
- status: statusCode,
293
- headers: { "Content-Type": "application/json" },
294
- });
295
- if (this.corsEnabled) {
296
- const origin = request.headers.get("origin");
297
- if (origin && this.corsCache.isOriginAllowed(origin)) {
298
- response = this.applyCorsHeaders(response, origin);
299
- }
300
- }
301
- return response;
302
- }
303
- handlePreflightRequest(request) {
304
- const origin = request.headers.get("origin");
305
- if (!origin || !this.corsCache.isOriginAllowed(origin)) {
306
- return new Response(null, { status: 403 });
32
+ constructor(config = {}) {
33
+ this.config = config;
34
+ this._controllers = [];
35
+ this._services = [];
36
+ this._middlewares = [];
37
+ this.routes = {};
38
+ this.container = new import_Container.Container();
39
+ this.corsHandler = null;
40
+ this.hasCors = !1;
41
+ this.validator = null;
42
+ // Cached lifecycle event flags - checked once at startup
43
+ this.hasInitHooks = !1;
44
+ this.hasBootHooks = !1;
45
+ this.hasShutdownHooks = !1;
46
+ if (this.config.exports = this.config.exports || [], this.config.globalMiddlewares = this.config.globalMiddlewares || [], this.config.cors && (this.corsHandler = new import_CorsHandler.CorsHandler(this.config.cors), this.hasCors = !0), this.config.validation === void 0 || this.config.validation === !0)
47
+ this.validator = new import_ZodAdapter2.ZodAdapter();
48
+ else if (typeof this.config.validation == "function") {
49
+ const AdapterClass = this.config.validation;
50
+ this.validator = new AdapterClass();
51
+ } else this.config.validation && (this.validator = this.config.validation);
52
+ }
53
+ /**
54
+ * Use a Carno plugin.
55
+ * Imports controllers, services and global middlewares from another Carno instance.
56
+ */
57
+ use(plugin) {
58
+ plugin._controllers.length > 0 && this._controllers.push(...plugin._controllers);
59
+ for (const exported of plugin.config.exports || []) {
60
+ const existingService = this.findServiceInPlugin(plugin, exported), serviceToAdd = this.shouldCloneService(existingService) ? { ...existingService } : exported;
61
+ this._services.push(serviceToAdd);
62
+ }
63
+ return plugin._services.length > 0 && this._services.push(...plugin._services), plugin.config.globalMiddlewares && this._middlewares.push(...plugin.config.globalMiddlewares), plugin._middlewares.length > 0 && this._middlewares.push(...plugin._middlewares), this;
64
+ }
65
+ findServiceInPlugin(plugin, exported) {
66
+ return plugin._services.find(
67
+ (s) => this.getServiceToken(s) === this.getServiceToken(exported)
68
+ );
69
+ }
70
+ getServiceToken(service) {
71
+ return service?.token || service;
72
+ }
73
+ shouldCloneService(service) {
74
+ return !!(service?.useValue !== void 0 || service?.useClass);
75
+ }
76
+ /**
77
+ * Register one or more services/providers.
78
+ */
79
+ services(serviceClass) {
80
+ const items = Array.isArray(serviceClass) ? serviceClass : [serviceClass];
81
+ return this._services.push(...items), this;
82
+ }
83
+ /**
84
+ * Register one or more global middlewares.
85
+ */
86
+ middlewares(handler) {
87
+ const items = Array.isArray(handler) ? handler : [handler];
88
+ return this._middlewares.push(...items), this;
89
+ }
90
+ /**
91
+ * Register one or more controllers.
92
+ */
93
+ controllers(controllerClass) {
94
+ const items = Array.isArray(controllerClass) ? controllerClass : [controllerClass];
95
+ return this._controllers.push(...items), this;
96
+ }
97
+ /**
98
+ * Get a service instance from the container.
99
+ */
100
+ get(token) {
101
+ return this.container.get(token);
102
+ }
103
+ listen(port = 3e3) {
104
+ this.bootstrap(), this.compileRoutes();
105
+ const config = {
106
+ port,
107
+ fetch: this.handleNotFound.bind(this),
108
+ error: this.handleError.bind(this),
109
+ routes: {
110
+ ...import_DefaultRoutes.DEFAULT_STATIC_ROUTES,
111
+ ...this.routes
112
+ }
113
+ };
114
+ this.server = Bun.serve(config), this.hasBootHooks && this.executeLifecycleHooks(import_Lifecycle.EventType.BOOT), this.hasShutdownHooks && this.registerShutdownHandlers(), this.config.disableStartupLog || console.log(`Carno running on port ${port}`);
115
+ }
116
+ bootstrap() {
117
+ this.hasInitHooks = (0, import_Lifecycle.hasEventHandlers)(import_Lifecycle.EventType.INIT), this.hasBootHooks = (0, import_Lifecycle.hasEventHandlers)(import_Lifecycle.EventType.BOOT), this.hasShutdownHooks = (0, import_Lifecycle.hasEventHandlers)(import_Lifecycle.EventType.SHUTDOWN), this.container.register({
118
+ token: import_Container.Container,
119
+ useValue: this.container
120
+ });
121
+ const cacheConfig = typeof this.config.cache == "object" ? this.config.cache : {};
122
+ this.container.register({
123
+ token: import_CacheService.CacheService,
124
+ useValue: new import_CacheService.CacheService(cacheConfig)
125
+ });
126
+ for (const service of this._services)
127
+ this.container.register(service);
128
+ for (const ControllerClass of this._controllers)
129
+ this.container.register(ControllerClass);
130
+ this.hasInitHooks && this.executeLifecycleHooks(import_Lifecycle.EventType.INIT);
131
+ for (const service of this._services) {
132
+ const token = typeof service == "function" ? service : service.token, serviceConfig = typeof service == "function" ? null : service;
133
+ (!serviceConfig || serviceConfig.scope !== import_Container.Scope.REQUEST) && this.container.get(token);
134
+ }
135
+ }
136
+ compileRoutes() {
137
+ for (const ControllerClass of this._controllers)
138
+ this.compileController(ControllerClass);
139
+ }
140
+ compileController(ControllerClass, parentPath = "", inheritedMiddlewares = []) {
141
+ const meta = Reflect.getMetadata(import_metadata.CONTROLLER_META, ControllerClass) || { path: "" }, basePath = parentPath + (meta.path || ""), routes = Reflect.getMetadata(import_metadata.ROUTES_META, ControllerClass) || [], middlewares = Reflect.getMetadata(import_metadata.MIDDLEWARE_META, ControllerClass) || [], instance = this.container.get(ControllerClass), controllerMiddlewares = middlewares.filter((m) => !m.target).map((m) => m.handler), scopedMiddlewares = [...inheritedMiddlewares, ...controllerMiddlewares];
142
+ for (const route of routes) {
143
+ const fullPath = this.normalizePath(basePath + route.path), params = Reflect.getMetadata(import_metadata.PARAMS_META, ControllerClass, route.handlerName) || [], routeMiddlewares = middlewares.filter((m) => m.target === route.handlerName).map((m) => m.handler), paramTypes = Reflect.getMetadata("design:paramtypes", ControllerClass.prototype, route.handlerName) || [];
144
+ let bodyDtoType = null;
145
+ for (const param of params)
146
+ if (param.type === "body" && !param.key) {
147
+ const dtoType = paramTypes[param.index];
148
+ dtoType && this.validator?.hasValidation(dtoType) && (bodyDtoType = dtoType);
307
149
  }
308
- const corsHeaders = this.corsCache.get(origin);
309
- return new Response(null, {
310
- status: 204,
311
- headers: corsHeaders,
312
- });
313
- }
314
- applyCorsHeaders(response, origin) {
315
- return this.corsCache.applyToResponse(response, origin);
316
- }
317
- close(closeActiveConnections = false) {
318
- this.server?.stop(closeActiveConnections);
319
- }
320
- resolveLocalsContainer(needsLocalsContainer, context) {
321
- if (!needsLocalsContainer) {
322
- return this.emptyLocals;
150
+ const compiled = (0, import_JITCompiler.compileHandler)(instance, route.handlerName, params), resolvedMiddlewares = [
151
+ ...this.config.globalMiddlewares || [],
152
+ ...this._middlewares,
153
+ ...scopedMiddlewares,
154
+ ...routeMiddlewares
155
+ ].map((m) => this.resolveMiddleware(m)), hasMiddlewares = resolvedMiddlewares.length > 0, method = route.method.toUpperCase();
156
+ compiled.isStatic && !hasMiddlewares ? this.registerRoute(fullPath, method, this.createStaticResponse(compiled.staticValue)) : this.registerRoute(fullPath, method, this.createHandler(compiled, params, resolvedMiddlewares, bodyDtoType));
157
+ }
158
+ if (meta.children)
159
+ for (const ChildController of meta.children)
160
+ this.container.has(ChildController) || this.container.register(ChildController), this.compileController(ChildController, basePath, scopedMiddlewares);
161
+ }
162
+ /**
163
+ * Register a route with Bun's native router format.
164
+ * Path: "/users/:id", Method: "GET", Handler: Function or Response
165
+ */
166
+ registerRoute(path, method, handler) {
167
+ this.routes[path] || (this.routes[path] = {}), this.routes[path][method] = handler;
168
+ }
169
+ createStaticResponse(value) {
170
+ const isString = typeof value == "string", body = isString ? value : JSON.stringify(value), opts = isString ? TEXT_OPTS : JSON_OPTS;
171
+ return new Response(body, opts);
172
+ }
173
+ createHandler(compiled, params, middlewares, bodyDtoType) {
174
+ const handler = compiled.fn, hasMiddlewares = middlewares.length > 0, hasParams = params.length > 0, applyCors = this.hasCors ? this.applyCors.bind(this) : null, validator = bodyDtoType ? this.validator : null, hasMiddlewaresOrValidation = hasMiddlewares || !!validator;
175
+ return !hasMiddlewaresOrValidation && !hasParams ? compiled.isAsync ? async (req) => {
176
+ const ctx = new import_Context.Context(req), result = await handler(ctx), response = this.buildResponse(result);
177
+ return applyCors ? applyCors(response, req) : response;
178
+ } : (req) => {
179
+ const ctx = new import_Context.Context(req), result = handler(ctx), response = this.buildResponse(result);
180
+ return applyCors ? applyCors(response, req) : response;
181
+ } : !hasMiddlewaresOrValidation && hasParams ? compiled.isAsync ? async (req) => {
182
+ const ctx = new import_Context.Context(req, req.params), result = await handler(ctx), response = this.buildResponse(result);
183
+ return applyCors ? applyCors(response, req) : response;
184
+ } : (req) => {
185
+ const ctx = new import_Context.Context(req, req.params), result = handler(ctx), response = this.buildResponse(result);
186
+ return applyCors ? applyCors(response, req) : response;
187
+ } : async (req) => {
188
+ const ctx = new import_Context.Context(req, req.params || {});
189
+ for (const middleware of middlewares) {
190
+ const result2 = await middleware(ctx);
191
+ if (result2 instanceof Response)
192
+ return applyCors ? applyCors(result2, req) : result2;
193
+ }
194
+ validator && bodyDtoType && (await ctx.parseBody(), validator.validateOrThrow(bodyDtoType, ctx.body));
195
+ const result = compiled.isAsync ? await handler(ctx) : handler(ctx), response = this.buildResponse(result);
196
+ return applyCors ? applyCors(response, req) : response;
197
+ };
198
+ }
199
+ resolveMiddleware(middleware) {
200
+ if (typeof middleware == "function" && middleware.prototype?.handle) {
201
+ const instance = this.container.get(middleware);
202
+ return (ctx) => instance.handle(ctx, () => {
203
+ });
204
+ }
205
+ return middleware;
206
+ }
207
+ /**
208
+ * Apply CORS headers to a response.
209
+ */
210
+ applyCors(response, req) {
211
+ const origin = req.headers.get("origin");
212
+ return origin && this.corsHandler ? this.corsHandler.apply(response, origin) : response;
213
+ }
214
+ /**
215
+ * Fallback handler - only called for unmatched routes.
216
+ * All matched routes go through Bun's native router.
217
+ */
218
+ handleNotFound(req) {
219
+ if (this.hasCors && req.method === "OPTIONS") {
220
+ const origin = req.headers.get("origin");
221
+ if (origin)
222
+ return this.corsHandler.preflight(origin);
223
+ }
224
+ return NOT_FOUND_RESPONSE;
225
+ }
226
+ buildResponse(result) {
227
+ return result instanceof Response ? result : typeof result == "string" ? new Response(result, TEXT_OPTS) : result === void 0 ? new Response(null, { status: 204 }) : Response.json(result);
228
+ }
229
+ normalizePath(path) {
230
+ return path.startsWith("/") || (path = "/" + path), path !== "/" && path.endsWith("/") && (path = path.slice(0, -1)), path.replace(/\/+/g, "/");
231
+ }
232
+ hasParams(path) {
233
+ return path.includes(":") || path.includes("*");
234
+ }
235
+ stop() {
236
+ this.server?.stop?.();
237
+ }
238
+ /**
239
+ * Error handler for Bun.serve.
240
+ * Converts exceptions to proper HTTP responses.
241
+ */
242
+ handleError(error) {
243
+ let response;
244
+ return error instanceof import_HttpException.HttpException || error instanceof import_ZodAdapter.ValidationException ? response = error.toResponse() : (console.error("Unhandled error:", error), response = INTERNAL_ERROR_RESPONSE), this.hasCors && this.corsHandler ? this.corsHandler.apply(response, "*") : response;
245
+ }
246
+ /**
247
+ * Execute lifecycle hooks for a specific event type.
248
+ */
249
+ executeLifecycleHooks(type) {
250
+ const handlers = (0, import_Lifecycle.getEventHandlers)(type);
251
+ for (const handler of handlers)
252
+ try {
253
+ const instance = this.container.has(handler.target) ? this.container.get(handler.target) : null;
254
+ if (instance && typeof instance[handler.methodName] == "function") {
255
+ const result = instance[handler.methodName]();
256
+ result instanceof Promise && result.catch(
257
+ (err) => console.error(`Error in ${type} hook ${handler.methodName}:`, err)
258
+ );
323
259
  }
324
- return this.buildLocalsContainer(context);
325
- }
326
- buildLocalsContainer(context) {
327
- const locals = new LocalsContainer_1.LocalsContainer();
328
- locals.set(Context_1.Context, context);
329
- return locals;
330
- }
331
- discoverRoutePath(url) {
332
- if (typeof url === 'string') {
333
- return url;
334
- }
335
- return url?.pathname || url?.path || '/';
336
- }
260
+ } catch (err) {
261
+ console.error(`Error in ${type} hook ${handler.methodName}:`, err);
262
+ }
263
+ }
264
+ /**
265
+ * Register SIGTERM/SIGINT handlers for graceful shutdown.
266
+ */
267
+ registerShutdownHandlers() {
268
+ const shutdown = () => {
269
+ this.executeLifecycleHooks(import_Lifecycle.EventType.SHUTDOWN), this.stop(), process.exit(0);
270
+ };
271
+ process.on("SIGTERM", shutdown), process.on("SIGINT", shutdown);
272
+ }
337
273
  }
338
- exports.Carno = Carno;
274
+ // Annotate the CommonJS export names for ESM import in node:
275
+ 0 && (module.exports = {
276
+ Carno
277
+ });