@cinnabun/core 0.0.1 → 0.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 (260) hide show
  1. package/dist/__tests__/autowired.test.d.ts +1 -0
  2. package/dist/__tests__/autowired.test.js +109 -0
  3. package/dist/__tests__/autowired.test.js.map +1 -0
  4. package/dist/__tests__/cinnabun-application.test.d.ts +1 -0
  5. package/dist/__tests__/cinnabun-application.test.js +96 -0
  6. package/dist/__tests__/cinnabun-application.test.js.map +1 -0
  7. package/dist/__tests__/cinnabun-factory.test.d.ts +1 -0
  8. package/dist/__tests__/cinnabun-factory.test.js +269 -0
  9. package/dist/__tests__/cinnabun-factory.test.js.map +1 -0
  10. package/dist/__tests__/circular-dependency.test.d.ts +1 -0
  11. package/dist/__tests__/circular-dependency.test.js +318 -0
  12. package/dist/__tests__/circular-dependency.test.js.map +1 -0
  13. package/dist/__tests__/compression.test.d.ts +1 -0
  14. package/dist/__tests__/compression.test.js +459 -0
  15. package/dist/__tests__/compression.test.js.map +1 -0
  16. package/dist/__tests__/config.test.d.ts +1 -0
  17. package/dist/__tests__/config.test.js +86 -0
  18. package/dist/__tests__/config.test.js.map +1 -0
  19. package/dist/__tests__/cors.test.d.ts +1 -0
  20. package/dist/__tests__/cors.test.js +575 -0
  21. package/dist/__tests__/cors.test.js.map +1 -0
  22. package/dist/__tests__/env-config.test.d.ts +1 -0
  23. package/dist/__tests__/env-config.test.js +367 -0
  24. package/dist/__tests__/env-config.test.js.map +1 -0
  25. package/dist/__tests__/exception.test.d.ts +1 -0
  26. package/dist/__tests__/exception.test.js +207 -0
  27. package/dist/__tests__/exception.test.js.map +1 -0
  28. package/dist/__tests__/guards-interceptors.test.d.ts +1 -0
  29. package/dist/__tests__/guards-interceptors.test.js +660 -0
  30. package/dist/__tests__/guards-interceptors.test.js.map +1 -0
  31. package/dist/__tests__/health-check.test.d.ts +1 -0
  32. package/dist/__tests__/health-check.test.js +240 -0
  33. package/dist/__tests__/health-check.test.js.map +1 -0
  34. package/dist/__tests__/http.test.d.ts +1 -0
  35. package/dist/__tests__/http.test.js +629 -0
  36. package/dist/__tests__/http.test.js.map +1 -0
  37. package/dist/__tests__/integration/e2e.test.d.ts +1 -0
  38. package/dist/__tests__/integration/e2e.test.js +192 -0
  39. package/dist/__tests__/integration/e2e.test.js.map +1 -0
  40. package/dist/__tests__/integration/performance.bench.d.ts +1 -0
  41. package/dist/__tests__/integration/performance.bench.js +129 -0
  42. package/dist/__tests__/integration/performance.bench.js.map +1 -0
  43. package/dist/__tests__/integration/validation.test.d.ts +1 -0
  44. package/dist/__tests__/integration/validation.test.js +133 -0
  45. package/dist/__tests__/integration/validation.test.js.map +1 -0
  46. package/dist/__tests__/lifecycle-management.test.d.ts +1 -0
  47. package/dist/__tests__/lifecycle-management.test.js +688 -0
  48. package/dist/__tests__/lifecycle-management.test.js.map +1 -0
  49. package/dist/__tests__/lifecycle.test.d.ts +1 -0
  50. package/dist/__tests__/lifecycle.test.js +196 -0
  51. package/dist/__tests__/lifecycle.test.js.map +1 -0
  52. package/dist/__tests__/logger.test.d.ts +1 -0
  53. package/dist/__tests__/logger.test.js +109 -0
  54. package/dist/__tests__/logger.test.js.map +1 -0
  55. package/dist/__tests__/middleware.test.d.ts +1 -0
  56. package/dist/__tests__/middleware.test.js +329 -0
  57. package/dist/__tests__/middleware.test.js.map +1 -0
  58. package/dist/__tests__/module.test.d.ts +1 -0
  59. package/dist/__tests__/module.test.js +280 -0
  60. package/dist/__tests__/module.test.js.map +1 -0
  61. package/dist/__tests__/plugin.test.d.ts +1 -0
  62. package/dist/__tests__/plugin.test.js +283 -0
  63. package/dist/__tests__/plugin.test.js.map +1 -0
  64. package/dist/__tests__/request-logger.test.d.ts +1 -0
  65. package/dist/__tests__/request-logger.test.js +342 -0
  66. package/dist/__tests__/request-logger.test.js.map +1 -0
  67. package/dist/__tests__/request-mapping.test.d.ts +1 -0
  68. package/dist/__tests__/request-mapping.test.js +201 -0
  69. package/dist/__tests__/request-mapping.test.js.map +1 -0
  70. package/dist/__tests__/routes.test.d.ts +1 -0
  71. package/dist/__tests__/routes.test.js +119 -0
  72. package/dist/__tests__/routes.test.js.map +1 -0
  73. package/dist/__tests__/scan-fixtures/controllers/hello.controller.d.ts +4 -0
  74. package/dist/__tests__/scan-fixtures/controllers/hello.controller.js +28 -0
  75. package/dist/__tests__/scan-fixtures/controllers/hello.controller.js.map +1 -0
  76. package/dist/__tests__/scan-fixtures/modules/feature.module.d.ts +6 -0
  77. package/dist/__tests__/scan-fixtures/modules/feature.module.js +28 -0
  78. package/dist/__tests__/scan-fixtures/modules/feature.module.js.map +1 -0
  79. package/dist/__tests__/scan-fixtures/services/greeting.service.d.ts +4 -0
  80. package/dist/__tests__/scan-fixtures/services/greeting.service.js +18 -0
  81. package/dist/__tests__/scan-fixtures/services/greeting.service.js.map +1 -0
  82. package/dist/__tests__/scanner.test.d.ts +1 -0
  83. package/dist/__tests__/scanner.test.js +49 -0
  84. package/dist/__tests__/scanner.test.js.map +1 -0
  85. package/dist/__tests__/validation.test.d.ts +1 -0
  86. package/dist/__tests__/validation.test.js +561 -0
  87. package/dist/__tests__/validation.test.js.map +1 -0
  88. package/dist/__tests__/websocket-auth.test.d.ts +1 -0
  89. package/dist/__tests__/websocket-auth.test.js +431 -0
  90. package/dist/__tests__/websocket-auth.test.js.map +1 -0
  91. package/dist/__tests__/websocket-decorators.test.d.ts +1 -0
  92. package/dist/__tests__/websocket-decorators.test.js +173 -0
  93. package/dist/__tests__/websocket-decorators.test.js.map +1 -0
  94. package/dist/__tests__/websocket-validation.test.d.ts +1 -0
  95. package/dist/__tests__/websocket-validation.test.js +827 -0
  96. package/dist/__tests__/websocket-validation.test.js.map +1 -0
  97. package/dist/__tests__/websocket.test.d.ts +1 -0
  98. package/dist/__tests__/websocket.test.js +415 -0
  99. package/dist/__tests__/websocket.test.js.map +1 -0
  100. package/dist/config/config.module.d.ts +2 -0
  101. package/dist/config/config.module.js +18 -0
  102. package/dist/config/config.module.js.map +1 -0
  103. package/dist/config/config.service.d.ts +15 -0
  104. package/dist/config/config.service.js +58 -0
  105. package/dist/config/config.service.js.map +1 -0
  106. package/dist/config/schemas.d.ts +107 -0
  107. package/dist/config/schemas.js +87 -0
  108. package/dist/config/schemas.js.map +1 -0
  109. package/dist/core/app.d.ts +44 -0
  110. package/dist/core/app.js +178 -0
  111. package/dist/core/app.js.map +1 -0
  112. package/dist/core/cinnabun-factory.d.ts +5 -0
  113. package/dist/core/cinnabun-factory.js +130 -0
  114. package/dist/core/cinnabun-factory.js.map +1 -0
  115. package/dist/core/config-loader.d.ts +2 -0
  116. package/dist/core/config-loader.js +76 -0
  117. package/dist/core/config-loader.js.map +1 -0
  118. package/dist/core/config.d.ts +12 -0
  119. package/dist/core/config.js +27 -0
  120. package/dist/core/config.js.map +1 -0
  121. package/dist/core/container.d.ts +10 -0
  122. package/dist/core/container.js +82 -0
  123. package/dist/core/container.js.map +1 -0
  124. package/dist/core/dependency-validator.d.ts +12 -0
  125. package/dist/core/dependency-validator.js +76 -0
  126. package/dist/core/dependency-validator.js.map +1 -0
  127. package/dist/core/guard.d.ts +3 -0
  128. package/dist/core/guard.js +2 -0
  129. package/dist/core/guard.js.map +1 -0
  130. package/dist/core/interceptor.d.ts +4 -0
  131. package/dist/core/interceptor.js +2 -0
  132. package/dist/core/interceptor.js.map +1 -0
  133. package/dist/core/logger.d.ts +15 -0
  134. package/dist/core/logger.js +71 -0
  135. package/dist/core/logger.js.map +1 -0
  136. package/dist/core/module-resolver.d.ts +6 -0
  137. package/dist/core/module-resolver.js +67 -0
  138. package/dist/core/module-resolver.js.map +1 -0
  139. package/dist/core/plugin.d.ts +12 -0
  140. package/dist/core/plugin.js +2 -0
  141. package/dist/core/plugin.js.map +1 -0
  142. package/dist/core/router.d.ts +38 -0
  143. package/dist/core/router.js +406 -0
  144. package/dist/core/router.js.map +1 -0
  145. package/dist/core/scanner.d.ts +7 -0
  146. package/dist/core/scanner.js +83 -0
  147. package/dist/core/scanner.js.map +1 -0
  148. package/dist/core/shutdown-manager.d.ts +15 -0
  149. package/dist/core/shutdown-manager.js +68 -0
  150. package/dist/core/shutdown-manager.js.map +1 -0
  151. package/dist/core/websocket-handler.d.ts +41 -0
  152. package/dist/core/websocket-handler.js +242 -0
  153. package/dist/core/websocket-handler.js.map +1 -0
  154. package/dist/decorators/autowired.d.ts +3 -0
  155. package/dist/decorators/autowired.js +11 -0
  156. package/dist/decorators/autowired.js.map +1 -0
  157. package/dist/decorators/cinnabun-application.d.ts +14 -0
  158. package/dist/decorators/cinnabun-application.js +17 -0
  159. package/dist/decorators/cinnabun-application.js.map +1 -0
  160. package/dist/decorators/lifecycle.d.ts +2 -0
  161. package/dist/decorators/lifecycle.js +12 -0
  162. package/dist/decorators/lifecycle.js.map +1 -0
  163. package/dist/decorators/middleware.d.ts +2 -0
  164. package/dist/decorators/middleware.js +12 -0
  165. package/dist/decorators/middleware.js.map +1 -0
  166. package/dist/decorators/module.d.ts +10 -0
  167. package/dist/decorators/module.js +13 -0
  168. package/dist/decorators/module.js.map +1 -0
  169. package/dist/decorators/on-shutdown.d.ts +1 -0
  170. package/dist/decorators/on-shutdown.js +10 -0
  171. package/dist/decorators/on-shutdown.js.map +1 -0
  172. package/dist/decorators/params.d.ts +6 -0
  173. package/dist/decorators/params.js +31 -0
  174. package/dist/decorators/params.js.map +1 -0
  175. package/dist/decorators/request-mapping.d.ts +7 -0
  176. package/dist/decorators/request-mapping.js +34 -0
  177. package/dist/decorators/request-mapping.js.map +1 -0
  178. package/dist/decorators/response.d.ts +2 -0
  179. package/dist/decorators/response.js +17 -0
  180. package/dist/decorators/response.js.map +1 -0
  181. package/dist/decorators/rest-controller.d.ts +1 -0
  182. package/dist/decorators/rest-controller.js +19 -0
  183. package/dist/decorators/rest-controller.js.map +1 -0
  184. package/dist/decorators/routes.d.ts +5 -0
  185. package/dist/decorators/routes.js +19 -0
  186. package/dist/decorators/routes.js.map +1 -0
  187. package/dist/decorators/service.d.ts +1 -0
  188. package/dist/decorators/service.js +7 -0
  189. package/dist/decorators/service.js.map +1 -0
  190. package/dist/decorators/use-guard.d.ts +2 -0
  191. package/dist/decorators/use-guard.js +12 -0
  192. package/dist/decorators/use-guard.js.map +1 -0
  193. package/dist/decorators/use-interceptor.d.ts +2 -0
  194. package/dist/decorators/use-interceptor.js +12 -0
  195. package/dist/decorators/use-interceptor.js.map +1 -0
  196. package/dist/decorators/validate.d.ts +12 -0
  197. package/dist/decorators/validate.js +7 -0
  198. package/dist/decorators/validate.js.map +1 -0
  199. package/dist/decorators/websocket.d.ts +9 -0
  200. package/dist/decorators/websocket.js +38 -0
  201. package/dist/decorators/websocket.js.map +1 -0
  202. package/dist/decorators/ws-event.d.ts +28 -0
  203. package/dist/decorators/ws-event.js +37 -0
  204. package/dist/decorators/ws-event.js.map +1 -0
  205. package/dist/decorators/ws-gateway.d.ts +18 -0
  206. package/dist/decorators/ws-gateway.js +24 -0
  207. package/dist/decorators/ws-gateway.js.map +1 -0
  208. package/dist/dev/index.d.ts +6 -0
  209. package/dist/dev/index.js +28 -0
  210. package/dist/dev/index.js.map +1 -0
  211. package/dist/exceptions/circular-dependency-error.d.ts +5 -0
  212. package/dist/exceptions/circular-dependency-error.js +16 -0
  213. package/dist/exceptions/circular-dependency-error.js.map +1 -0
  214. package/dist/exceptions/http-exception.d.ts +41 -0
  215. package/dist/exceptions/http-exception.js +96 -0
  216. package/dist/exceptions/http-exception.js.map +1 -0
  217. package/dist/guards/jwt-websocket.guard.d.ts +11 -0
  218. package/dist/guards/jwt-websocket.guard.js +37 -0
  219. package/dist/guards/jwt-websocket.guard.js.map +1 -0
  220. package/dist/guards/websocket-auth.guard.d.ts +16 -0
  221. package/dist/guards/websocket-auth.guard.js +43 -0
  222. package/dist/guards/websocket-auth.guard.js.map +1 -0
  223. package/dist/health/health-check.service.d.ts +45 -0
  224. package/dist/health/health-check.service.js +95 -0
  225. package/dist/health/health-check.service.js.map +1 -0
  226. package/dist/health/health.controller.d.ts +15 -0
  227. package/dist/health/health.controller.js +63 -0
  228. package/dist/health/health.controller.js.map +1 -0
  229. package/dist/health/health.module.d.ts +2 -0
  230. package/dist/health/health.module.js +20 -0
  231. package/dist/health/health.module.js.map +1 -0
  232. package/dist/index.d.ts +74 -11
  233. package/dist/index.js +54 -0
  234. package/dist/index.js.map +1 -0
  235. package/dist/metadata/storage.d.ts +171 -0
  236. package/dist/metadata/storage.js +257 -0
  237. package/dist/metadata/storage.js.map +1 -0
  238. package/dist/middleware/compression.middleware.d.ts +32 -0
  239. package/dist/middleware/compression.middleware.js +113 -0
  240. package/dist/middleware/compression.middleware.js.map +1 -0
  241. package/dist/middleware/cors.middleware.d.ts +18 -0
  242. package/dist/middleware/cors.middleware.js +79 -0
  243. package/dist/middleware/cors.middleware.js.map +1 -0
  244. package/dist/middleware/performance-tracker.middleware.d.ts +35 -0
  245. package/dist/middleware/performance-tracker.middleware.js +79 -0
  246. package/dist/middleware/performance-tracker.middleware.js.map +1 -0
  247. package/dist/middleware/request-logger.middleware.d.ts +32 -0
  248. package/dist/middleware/request-logger.middleware.js +125 -0
  249. package/dist/middleware/request-logger.middleware.js.map +1 -0
  250. package/dist/types/index.d.ts +14 -0
  251. package/dist/types/index.js +5 -0
  252. package/dist/types/index.js.map +1 -0
  253. package/dist/validation/helpers.d.ts +36 -0
  254. package/dist/validation/helpers.js +27 -0
  255. package/dist/validation/helpers.js.map +1 -0
  256. package/dist/websocket/error.d.ts +27 -0
  257. package/dist/websocket/error.js +38 -0
  258. package/dist/websocket/error.js.map +1 -0
  259. package/package.json +38 -5
  260. package/LICENSE +0 -9
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Common environment variable transformations
4
+ */
5
+ export declare const EnvTransforms: {
6
+ /**
7
+ * Parse port number with validation
8
+ */
9
+ port: z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>, number, string | undefined>;
10
+ /**
11
+ * Parse boolean from string
12
+ */
13
+ boolean: z.ZodEffects<z.ZodDefault<z.ZodString>, boolean, string | undefined>;
14
+ /**
15
+ * Parse JSON from string
16
+ */
17
+ json: <T extends z.ZodTypeAny>(schema: T) => z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, T>;
18
+ /**
19
+ * Parse comma-separated list
20
+ */
21
+ list: z.ZodEffects<z.ZodString, string[], string>;
22
+ /**
23
+ * Parse number with validation
24
+ */
25
+ number: z.ZodEffects<z.ZodEffects<z.ZodString, number, string>, number, string>;
26
+ /**
27
+ * Require in production, optional in development
28
+ */
29
+ requiredInProduction: <T extends z.ZodTypeAny>(schema: T) => T | z.ZodOptional<T>;
30
+ };
31
+ /**
32
+ * Common environment schemas
33
+ */
34
+ export declare const CommonEnvSchema: z.ZodObject<{
35
+ NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "production", "test"]>>;
36
+ PORT: z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>, number, string | undefined>;
37
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ NODE_ENV: "production" | "development" | "test";
40
+ PORT: number;
41
+ LOG_LEVEL: "debug" | "info" | "warn" | "error";
42
+ }, {
43
+ NODE_ENV?: "production" | "development" | "test" | undefined;
44
+ PORT?: string | undefined;
45
+ LOG_LEVEL?: "debug" | "info" | "warn" | "error" | undefined;
46
+ }>;
47
+ /**
48
+ * Database environment schema
49
+ */
50
+ export declare const DatabaseEnvSchema: z.ZodObject<{
51
+ DATABASE_URL: z.ZodString;
52
+ DATABASE_POOL_SIZE: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodString, number, string>, number, string>>;
53
+ DATABASE_TIMEOUT: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodString, number, string>, number, string>>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ DATABASE_URL: string;
56
+ DATABASE_POOL_SIZE: number;
57
+ DATABASE_TIMEOUT: number;
58
+ }, {
59
+ DATABASE_URL: string;
60
+ DATABASE_POOL_SIZE?: string | undefined;
61
+ DATABASE_TIMEOUT?: string | undefined;
62
+ }>;
63
+ /**
64
+ * Redis environment schema
65
+ */
66
+ export declare const RedisEnvSchema: z.ZodObject<{
67
+ REDIS_URL: z.ZodString;
68
+ REDIS_PASSWORD: z.ZodOptional<z.ZodString>;
69
+ REDIS_DB: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodString, number, string>, number, string>>;
70
+ }, "strip", z.ZodTypeAny, {
71
+ REDIS_URL: string;
72
+ REDIS_DB: number;
73
+ REDIS_PASSWORD?: string | undefined;
74
+ }, {
75
+ REDIS_URL: string;
76
+ REDIS_PASSWORD?: string | undefined;
77
+ REDIS_DB?: string | undefined;
78
+ }>;
79
+ /**
80
+ * JWT environment schema
81
+ */
82
+ export declare const JwtEnvSchema: z.ZodObject<{
83
+ JWT_SECRET: z.ZodString;
84
+ JWT_EXPIRES_IN: z.ZodDefault<z.ZodString>;
85
+ JWT_REFRESH_SECRET: z.ZodOptional<z.ZodString>;
86
+ }, "strip", z.ZodTypeAny, {
87
+ JWT_SECRET: string;
88
+ JWT_EXPIRES_IN: string;
89
+ JWT_REFRESH_SECRET?: string | undefined;
90
+ }, {
91
+ JWT_SECRET: string;
92
+ JWT_EXPIRES_IN?: string | undefined;
93
+ JWT_REFRESH_SECRET?: string | undefined;
94
+ }>;
95
+ /**
96
+ * CORS environment schema
97
+ */
98
+ export declare const CorsEnvSchema: z.ZodObject<{
99
+ CORS_ORIGIN: z.ZodDefault<z.ZodEffects<z.ZodString, string[], string>>;
100
+ CORS_CREDENTIALS: z.ZodEffects<z.ZodDefault<z.ZodString>, boolean, string | undefined>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ CORS_ORIGIN: string[];
103
+ CORS_CREDENTIALS: boolean;
104
+ }, {
105
+ CORS_ORIGIN?: string | undefined;
106
+ CORS_CREDENTIALS?: string | undefined;
107
+ }>;
@@ -0,0 +1,87 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Common environment variable transformations
4
+ */
5
+ export const EnvTransforms = {
6
+ /**
7
+ * Parse port number with validation
8
+ */
9
+ port: z
10
+ .string()
11
+ .default("3000")
12
+ .transform((val) => parseInt(val, 10))
13
+ .refine((val) => val > 0 && val < 65536, "Port must be between 1 and 65535"),
14
+ /**
15
+ * Parse boolean from string
16
+ */
17
+ boolean: z
18
+ .string()
19
+ .default("false")
20
+ .transform((val) => val === "true" || val === "1"),
21
+ /**
22
+ * Parse JSON from string
23
+ */
24
+ json: (schema) => z
25
+ .string()
26
+ .transform((val) => JSON.parse(val))
27
+ .pipe(schema),
28
+ /**
29
+ * Parse comma-separated list
30
+ */
31
+ list: z
32
+ .string()
33
+ .transform((val) => val.split(",").map((v) => v.trim()).filter(Boolean)),
34
+ /**
35
+ * Parse number with validation
36
+ */
37
+ number: z
38
+ .string()
39
+ .transform((val) => parseFloat(val))
40
+ .refine((val) => !isNaN(val), "Must be a valid number"),
41
+ /**
42
+ * Require in production, optional in development
43
+ */
44
+ requiredInProduction: (schema) => process.env.NODE_ENV === "production" ? schema : schema.optional(),
45
+ };
46
+ /**
47
+ * Common environment schemas
48
+ */
49
+ export const CommonEnvSchema = z.object({
50
+ NODE_ENV: z
51
+ .enum(["development", "production", "test"])
52
+ .default("development"),
53
+ PORT: EnvTransforms.port,
54
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
55
+ });
56
+ /**
57
+ * Database environment schema
58
+ */
59
+ export const DatabaseEnvSchema = z.object({
60
+ DATABASE_URL: z.string().url("Invalid database URL"),
61
+ DATABASE_POOL_SIZE: EnvTransforms.number.default("10"),
62
+ DATABASE_TIMEOUT: EnvTransforms.number.default("30000"),
63
+ });
64
+ /**
65
+ * Redis environment schema
66
+ */
67
+ export const RedisEnvSchema = z.object({
68
+ REDIS_URL: z.string().url("Invalid Redis URL"),
69
+ REDIS_PASSWORD: z.string().optional(),
70
+ REDIS_DB: EnvTransforms.number.default("0"),
71
+ });
72
+ /**
73
+ * JWT environment schema
74
+ */
75
+ export const JwtEnvSchema = z.object({
76
+ JWT_SECRET: z.string().min(32, "JWT secret must be at least 32 characters"),
77
+ JWT_EXPIRES_IN: z.string().default("1h"),
78
+ JWT_REFRESH_SECRET: z.string().min(32).optional(),
79
+ });
80
+ /**
81
+ * CORS environment schema
82
+ */
83
+ export const CorsEnvSchema = z.object({
84
+ CORS_ORIGIN: EnvTransforms.list.default("*"),
85
+ CORS_CREDENTIALS: EnvTransforms.boolean,
86
+ });
87
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/config/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Container } from "./container.js";
2
+ import { type Middleware } from "./router.js";
3
+ import { WebSocketHandler } from "./websocket-handler.js";
4
+ import type { Constructor } from "../metadata/storage.js";
5
+ import type { CinnabunPlugin, PluginContext } from "./plugin.js";
6
+ export interface ApplicationConfig {
7
+ controllers: Constructor[];
8
+ providers?: Constructor[];
9
+ middleware?: (Constructor | Middleware)[];
10
+ plugins?: CinnabunPlugin[];
11
+ preRegister?: (container: Container) => void;
12
+ websocket?: WebSocketHandler;
13
+ timeout?: number;
14
+ shutdownTimeout?: number;
15
+ }
16
+ export declare class CinnabunApplication {
17
+ private server;
18
+ private container;
19
+ private router;
20
+ private wsHandler;
21
+ private plugins;
22
+ private pluginContext;
23
+ private logger;
24
+ private isClosing;
25
+ private shutdownManager;
26
+ private shutdownTimeout;
27
+ private timeout;
28
+ private constructor();
29
+ static create(config: ApplicationConfig): Promise<CinnabunApplication>;
30
+ setPluginContext(context: PluginContext): void;
31
+ onShutdown(name: string, handler: () => Promise<void> | void, timeout?: number): void;
32
+ private printBanner;
33
+ listen(port: number): Promise<void>;
34
+ close(): Promise<void>;
35
+ getContainer(): Container;
36
+ getPort(): number;
37
+ getRoutes(): Array<{
38
+ method: string;
39
+ path: string;
40
+ }>;
41
+ getProviders(): Array<{
42
+ name: string;
43
+ }>;
44
+ }
@@ -0,0 +1,178 @@
1
+ import { Container } from "./container.js";
2
+ import { Router } from "./router.js";
3
+ import { Logger } from "./logger.js";
4
+ import { ShutdownManager } from "./shutdown-manager.js";
5
+ export class CinnabunApplication {
6
+ server = null;
7
+ container;
8
+ router;
9
+ wsHandler;
10
+ plugins;
11
+ pluginContext = null;
12
+ logger;
13
+ isClosing = false;
14
+ shutdownManager = new ShutdownManager();
15
+ shutdownTimeout;
16
+ timeout;
17
+ constructor(container, router, wsHandler, plugins, shutdownTimeout, timeout) {
18
+ this.container = container;
19
+ this.router = router;
20
+ this.wsHandler = wsHandler;
21
+ this.plugins = plugins;
22
+ this.shutdownTimeout = shutdownTimeout;
23
+ this.timeout = timeout;
24
+ this.logger = new Logger("CinnabunApplication");
25
+ }
26
+ static async create(config) {
27
+ const container = new Container();
28
+ if (config.preRegister) {
29
+ config.preRegister(container);
30
+ }
31
+ for (const provider of config.providers ?? []) {
32
+ container.resolve(provider);
33
+ }
34
+ // Resolve middleware constructors so they're available in the container
35
+ // Instances are passed through directly to the router
36
+ for (const mw of config.middleware ?? []) {
37
+ if (typeof mw === "function") {
38
+ container.resolve(mw);
39
+ }
40
+ }
41
+ const controllerInstances = config.controllers.map((ctrl) => ({
42
+ constructor: ctrl,
43
+ instance: container.resolve(ctrl),
44
+ }));
45
+ const router = new Router();
46
+ router.setContainer(container);
47
+ router.setGlobalMiddleware(config.middleware ?? []);
48
+ router.setTimeout(config.timeout ?? 30000);
49
+ for (const { constructor, instance } of controllerInstances) {
50
+ router.registerController(constructor, instance);
51
+ }
52
+ // Register WebSocket message mappings
53
+ const wsHandler = config.websocket ?? null;
54
+ if (wsHandler) {
55
+ wsHandler.setContainer(container);
56
+ for (const { constructor, instance } of controllerInstances) {
57
+ wsHandler.registerController(constructor, instance);
58
+ }
59
+ }
60
+ return new CinnabunApplication(container, router, wsHandler, config.plugins ?? [], config.shutdownTimeout ?? 5000, config.timeout ?? 30000);
61
+ }
62
+ setPluginContext(context) {
63
+ this.pluginContext = context;
64
+ }
65
+ onShutdown(name, handler, timeout) {
66
+ this.shutdownManager.registerHook({
67
+ name,
68
+ execute: handler,
69
+ timeout,
70
+ });
71
+ }
72
+ printBanner(port) {
73
+ const version = "1.0.0";
74
+ console.log(`
75
+ ╔═══════════════════════════════════════════════╗
76
+ ║ ║
77
+ ║ Cinnabun Framework v${version.padEnd(19)}║
78
+ ║ ║
79
+ ║ ║
80
+ ╚═══════════════════════════════════════════════╝
81
+
82
+ Environment: ${process.env.NODE_ENV || "development"}
83
+ Port: ${port}
84
+ Timeout: ${this.timeout}ms
85
+ PID: ${process.pid}
86
+ Node: ${process.version}
87
+ Platform: ${process.platform}
88
+
89
+ Features:
90
+ ✓ Request timeouts
91
+ ✓ Input validation
92
+ ✓ Error handling
93
+ ✓ Graceful shutdown
94
+
95
+ Ready to accept connections!
96
+ `);
97
+ }
98
+ async listen(port) {
99
+ const router = this.router;
100
+ const wsHandler = this.wsHandler;
101
+ if (wsHandler) {
102
+ this.server = Bun.serve({
103
+ port,
104
+ async fetch(req, server) {
105
+ const url = new URL(req.url);
106
+ if (wsHandler.isUpgradeEndpoint(url.pathname)) {
107
+ // Check authentication if guard is configured
108
+ const authResult = await wsHandler.checkAuth(req);
109
+ if (!authResult.allowed) {
110
+ return new Response("Unauthorized", { status: 401 });
111
+ }
112
+ const upgraded = server.upgrade(req, {
113
+ data: {
114
+ subscribedTopics: new Set(),
115
+ user: authResult.user,
116
+ },
117
+ });
118
+ if (upgraded)
119
+ return undefined;
120
+ }
121
+ return router.handle(req);
122
+ },
123
+ websocket: wsHandler.getHandler(),
124
+ });
125
+ wsHandler.setServer(this.server);
126
+ }
127
+ else {
128
+ this.server = Bun.serve({
129
+ port,
130
+ fetch(req) {
131
+ return router.handle(req);
132
+ },
133
+ });
134
+ }
135
+ this.printBanner(this.server.port || port);
136
+ }
137
+ async close() {
138
+ if (this.isClosing)
139
+ return;
140
+ this.isClosing = true;
141
+ this.logger.info("Shutdown signal received");
142
+ // Stop accepting new connections first
143
+ if (this.server) {
144
+ this.server.stop();
145
+ this.server = null;
146
+ }
147
+ // Register plugin shutdown hooks
148
+ if (this.pluginContext) {
149
+ for (const plugin of this.plugins) {
150
+ if (plugin.onShutdown) {
151
+ this.shutdownManager.registerHook({
152
+ name: `Plugin: ${plugin.name}`,
153
+ execute: () => plugin.onShutdown(this.pluginContext),
154
+ });
155
+ }
156
+ }
157
+ }
158
+ // Execute all shutdown hooks (including container PreDestroy)
159
+ await this.shutdownManager.shutdown(this.container, this.shutdownTimeout);
160
+ this.logger.info("Application stopped");
161
+ }
162
+ getContainer() {
163
+ return this.container;
164
+ }
165
+ getPort() {
166
+ if (!this.server) {
167
+ throw new Error("Server is not running. Call listen() first.");
168
+ }
169
+ return this.server.port;
170
+ }
171
+ getRoutes() {
172
+ return this.router.getRoutes();
173
+ }
174
+ getProviders() {
175
+ return this.container.getProviders();
176
+ }
177
+ }
178
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/core/app.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAmB,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAexD,MAAM,OAAO,mBAAmB;IACtB,MAAM,GAA0B,IAAI,CAAC;IACrC,SAAS,CAAY;IACrB,MAAM,CAAS;IACf,SAAS,CAA0B;IACnC,OAAO,CAAmB;IAC1B,aAAa,GAAyB,IAAI,CAAC;IAC3C,MAAM,CAAS;IACf,SAAS,GAAG,KAAK,CAAC;IAClB,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IACxC,eAAe,CAAS;IACxB,OAAO,CAAS;IAExB,YACE,SAAoB,EACpB,MAAc,EACd,SAAkC,EAClC,OAAyB,EACzB,eAAuB,EACvB,OAAe;QAEf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAyB;QAC3C,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAElC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YAC9C,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAED,wEAAwE;QACxE,sDAAsD;QACtD,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5D,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;QAE3C,KAAK,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,mBAAmB,EAAE,CAAC;YAC5D,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACnD,CAAC;QAED,sCAAsC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;QAC3C,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAClC,KAAK,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,mBAAmB,EAAE,CAAC;gBAC5D,SAAS,CAAC,kBAAkB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,OAAO,IAAI,mBAAmB,CAC5B,SAAS,EACT,MAAM,EACN,SAAS,EACT,MAAM,CAAC,OAAO,IAAI,EAAE,EACpB,MAAM,CAAC,eAAe,IAAI,IAAI,EAC9B,MAAM,CAAC,OAAO,IAAI,KAAK,CACxB,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,OAAsB;QACrC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED,UAAU,CACR,IAAY,EACZ,OAAmC,EACnC,OAAgB;QAEhB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC;YAChC,IAAI;YACJ,OAAO,EAAE,OAAO;YAChB,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,IAAY;QAC9B,MAAM,OAAO,GAAG,OAAO,CAAC;QAExB,OAAO,CAAC,GAAG,CAAC;;;8BAGc,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;;;;;gBAKhC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;gBACrC,IAAI;gBACJ,IAAI,CAAC,OAAO;gBACZ,OAAO,CAAC,GAAG;gBACX,OAAO,CAAC,OAAO;gBACf,OAAO,CAAC,QAAQ;;;;;;;;;KAS3B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;gBACtB,IAAI;gBACJ,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM;oBACrB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC7B,IAAI,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC9C,8CAA8C;wBAC9C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;wBAClD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;4BACxB,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;wBACvD,CAAC;wBAED,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;4BACnC,IAAI,EAAE;gCACJ,gBAAgB,EAAE,IAAI,GAAG,EAAE;gCAC3B,IAAI,EAAE,UAAU,CAAC,IAAI;6BACtB;yBACF,CAAC,CAAC;wBACH,IAAI,QAAQ;4BAAE,OAAO,SAAgB,CAAC;oBACxC,CAAC;oBACD,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,CAAC;gBACD,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE;aAClC,CAAC,CAAC;YACH,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;gBACtB,IAAI;gBACJ,KAAK,CAAC,GAAG;oBACP,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAE7C,uCAAuC;QACvC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC;wBAChC,IAAI,EAAE,WAAW,MAAM,CAAC,IAAI,EAAE;wBAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAW,CAAC,IAAI,CAAC,aAAc,CAAC;qBACvD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAE1E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC1C,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAK,CAAC;IAC3B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import { type Constructor } from "../metadata/storage.js";
2
+ import { CinnabunApplication } from "./app.js";
3
+ export declare class CinnabunFactory {
4
+ static run(appClass: Constructor): Promise<CinnabunApplication>;
5
+ }
@@ -0,0 +1,130 @@
1
+ import { metadataStorage } from "../metadata/storage.js";
2
+ import { scanComponents } from "./scanner.js";
3
+ import { CinnabunApplication } from "./app.js";
4
+ import { resolveModuleTree } from "./module-resolver.js";
5
+ import { WebSocketHandler } from "./websocket-handler.js";
6
+ import { FileConfigService } from "./config.js";
7
+ import { loadConfig } from "./config-loader.js";
8
+ import { Logger } from "./logger.js";
9
+ import { validateDependencies } from "./dependency-validator.js";
10
+ export class CinnabunFactory {
11
+ static async run(appClass) {
12
+ const logger = new Logger("CinnabunFactory");
13
+ // 1. Read @CinnabunApplication metadata
14
+ const meta = metadataStorage.getAppMetadata(appClass);
15
+ if (!meta) {
16
+ throw new Error(`${appClass.name} is not decorated with @CinnabunApplication(). ` +
17
+ `Add @CinnabunApplication() to your main class.`);
18
+ }
19
+ // 2. Load configuration
20
+ const rawConfig = await loadConfig();
21
+ const configService = new FileConfigService(rawConfig);
22
+ // 3. Scan for components
23
+ logger.info("Scanning components...");
24
+ const scanned = await scanComponents(meta.scanPaths);
25
+ // 4. Resolve module imports
26
+ const moduleProviders = [];
27
+ const moduleControllers = [];
28
+ for (const mod of [...meta.imports, ...scanned.modules]) {
29
+ const resolved = await resolveModuleTree(mod);
30
+ moduleProviders.push(...resolved.providers);
31
+ moduleControllers.push(...resolved.controllers);
32
+ }
33
+ // 5. Collect all components
34
+ const controllers = [...moduleControllers, ...scanned.controllers];
35
+ const providers = [...moduleProviders, ...scanned.providers];
36
+ // If the main class itself is a @RestController, include it
37
+ if (metadataStorage.controllerPaths.has(appClass)) {
38
+ controllers.push(appClass);
39
+ }
40
+ // Collect all @WsGateway classes and add them to providers
41
+ const wsGateways = Array.from(metadataStorage.getAllWsGateways().keys());
42
+ for (const gateway of wsGateways) {
43
+ if (!providers.includes(gateway) && !controllers.includes(gateway)) {
44
+ providers.push(gateway);
45
+ }
46
+ }
47
+ logger.info(`Found ${controllers.length} controllers, ${providers.length} providers, ` +
48
+ `${meta.imports.length + scanned.modules.length} modules`);
49
+ // 6. Validate dependencies for circular references
50
+ logger.info("Validating dependencies...");
51
+ try {
52
+ validateDependencies(providers);
53
+ logger.info("✓ No circular dependencies detected");
54
+ }
55
+ catch (error) {
56
+ logger.error("✗ Dependency validation failed");
57
+ throw error;
58
+ }
59
+ // 7. Check for WebSocket broker configuration
60
+ let wsHandler;
61
+ const wsMeta = metadataStorage.getWsBrokerMetadata(appClass);
62
+ if (wsMeta) {
63
+ wsHandler = new WebSocketHandler();
64
+ wsHandler.configure(wsMeta.brokerPrefixes, wsMeta.appDestinationPrefixes, wsMeta.endpoints);
65
+ logger.info(`WebSocket enabled: endpoints=${wsMeta.endpoints.join(",")}, ` +
66
+ `broker=${wsMeta.brokerPrefixes.join(",")}, app=${wsMeta.appDestinationPrefixes.join(",")}`);
67
+ // Set up WebSocket authentication if configured
68
+ if (meta.websocketAuth) {
69
+ logger.info(`WebSocket authentication enabled: ${meta.websocketAuth.name}`);
70
+ }
71
+ }
72
+ // 8. Create the application, pre-register FileConfigService
73
+ const plugins = meta.plugins ?? [];
74
+ const app = await CinnabunApplication.create({
75
+ controllers,
76
+ providers,
77
+ middleware: meta.middleware,
78
+ websocket: wsHandler,
79
+ plugins,
80
+ timeout: meta.timeout,
81
+ shutdownTimeout: meta.shutdownTimeout,
82
+ preRegister: (container) => {
83
+ container.registerInstance(FileConfigService, configService);
84
+ // Resolve and set WebSocket auth guard if configured
85
+ if (wsHandler && meta.websocketAuth) {
86
+ const authGuard = container.resolve(meta.websocketAuth);
87
+ wsHandler.setAuthGuard(authGuard);
88
+ }
89
+ // Register @WsGateway classes with WebSocketHandler
90
+ if (wsHandler) {
91
+ for (const gatewayClass of wsGateways) {
92
+ const instance = container.resolve(gatewayClass);
93
+ wsHandler.registerController(gatewayClass, instance);
94
+ }
95
+ }
96
+ },
97
+ });
98
+ // 9. Run plugin onInit hooks
99
+ const pluginContext = {
100
+ container: app.getContainer(),
101
+ config: configService,
102
+ };
103
+ app.setPluginContext(pluginContext);
104
+ for (const plugin of plugins) {
105
+ if (plugin.onInit) {
106
+ logger.info(`Plugin "${plugin.name}" initializing...`);
107
+ await plugin.onInit(pluginContext);
108
+ }
109
+ }
110
+ // 10. Start listening
111
+ const port = configService.get("port") ?? meta.port;
112
+ await app.listen(port);
113
+ // 11. Run plugin onReady hooks
114
+ for (const plugin of plugins) {
115
+ if (plugin.onReady) {
116
+ await plugin.onReady(pluginContext);
117
+ }
118
+ }
119
+ // 12. Register signal handlers for graceful shutdown
120
+ const shutdown = async (signal) => {
121
+ logger.info(`Received ${signal}, shutting down...`);
122
+ await app.close();
123
+ process.exit(0);
124
+ };
125
+ process.on("SIGINT", () => shutdown("SIGINT"));
126
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
127
+ return app;
128
+ }
129
+ }
130
+ //# sourceMappingURL=cinnabun-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cinnabun-factory.js","sourceRoot":"","sources":["../../src/core/cinnabun-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function loadConfig(): Promise<Record<string, any>>;
2
+ export declare function parseEnvVars(env: Record<string, string | undefined>): Record<string, any>;
@@ -0,0 +1,76 @@
1
+ import { resolve, relative } from "path";
2
+ export async function loadConfig() {
3
+ // 1. Try loading cinnabun.config.ts
4
+ let fileConfig = {};
5
+ const cwd = process.cwd();
6
+ const configPath = resolve(cwd, "cinnabun.config.ts");
7
+ // Prevent path traversal
8
+ const relativePath = relative(cwd, configPath);
9
+ if (relativePath.startsWith("..") || relativePath.startsWith("/")) {
10
+ throw new Error("Config file must be within project directory");
11
+ }
12
+ try {
13
+ const mod = await import(configPath);
14
+ fileConfig = mod.default ?? mod;
15
+ }
16
+ catch (error) {
17
+ if (error.code === "ERR_MODULE_NOT_FOUND") {
18
+ // No config file — use empty defaults
19
+ }
20
+ else {
21
+ throw new Error(`Failed to load config: ${error.message}`);
22
+ }
23
+ }
24
+ // 2. Apply env var overrides (CINNABUN_ prefix)
25
+ const envConfig = parseEnvVars(process.env);
26
+ // 3. Merge: env overrides file
27
+ return deepMerge(fileConfig, envConfig);
28
+ }
29
+ export function parseEnvVars(env) {
30
+ const result = {};
31
+ const prefix = "CINNABUN_";
32
+ for (const [key, value] of Object.entries(env)) {
33
+ if (!key.startsWith(prefix) || value === undefined)
34
+ continue;
35
+ const path = key.slice(prefix.length).toLowerCase().split("__");
36
+ setNestedValue(result, path, coerceValue(value));
37
+ }
38
+ return result;
39
+ }
40
+ function setNestedValue(obj, path, value) {
41
+ let current = obj;
42
+ for (let i = 0; i < path.length - 1; i++) {
43
+ if (!(path[i] in current)) {
44
+ current[path[i]] = {};
45
+ }
46
+ current = current[path[i]];
47
+ }
48
+ current[path[path.length - 1]] = value;
49
+ }
50
+ function coerceValue(value) {
51
+ if (value === "true")
52
+ return true;
53
+ if (value === "false")
54
+ return false;
55
+ const num = Number(value);
56
+ if (!isNaN(num) && value.trim() !== "")
57
+ return num;
58
+ return value;
59
+ }
60
+ function deepMerge(base, override) {
61
+ const result = { ...base };
62
+ for (const [key, value] of Object.entries(override)) {
63
+ if (value &&
64
+ typeof value === "object" &&
65
+ !Array.isArray(value) &&
66
+ result[key] &&
67
+ typeof result[key] === "object") {
68
+ result[key] = deepMerge(result[key], value);
69
+ }
70
+ else {
71
+ result[key] = value;
72
+ }
73
+ }
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/core/config-loader.ts"],"names":[],"mappings":"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"}