@bloomneo/appkit 1.2.9

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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +902 -0
  3. package/bin/appkit.js +71 -0
  4. package/bin/commands/generate.js +1050 -0
  5. package/bin/templates/backend/README.md.template +39 -0
  6. package/bin/templates/backend/api.http.template +0 -0
  7. package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
  8. package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
  9. package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
  10. package/bin/templates/backend/package.json.template +34 -0
  11. package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
  12. package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
  13. package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
  14. package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
  15. package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
  16. package/bin/templates/backend/src/api/server.ts.template +188 -0
  17. package/bin/templates/backend/tsconfig.api.json.template +24 -0
  18. package/bin/templates/backend/tsconfig.json.template +40 -0
  19. package/bin/templates/feature/feature.http.template +63 -0
  20. package/bin/templates/feature/feature.route.ts.template +36 -0
  21. package/bin/templates/feature/feature.service.ts.template +81 -0
  22. package/bin/templates/feature/feature.types.ts.template +23 -0
  23. package/bin/templates/feature-db/feature.http.template +63 -0
  24. package/bin/templates/feature-db/feature.model.ts.template +74 -0
  25. package/bin/templates/feature-db/feature.route.ts.template +58 -0
  26. package/bin/templates/feature-db/feature.service.ts.template +231 -0
  27. package/bin/templates/feature-db/feature.types.ts.template +25 -0
  28. package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
  29. package/bin/templates/feature-db/seeding/README.md.template +57 -0
  30. package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
  31. package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
  32. package/bin/templates/feature-user/user.http.template +157 -0
  33. package/bin/templates/feature-user/user.model.ts.template +244 -0
  34. package/bin/templates/feature-user/user.route.ts.template +379 -0
  35. package/bin/templates/feature-user/user.seed.js.template +182 -0
  36. package/bin/templates/feature-user/user.service.ts.template +426 -0
  37. package/bin/templates/feature-user/user.types.ts.template +127 -0
  38. package/dist/auth/auth.d.ts +182 -0
  39. package/dist/auth/auth.d.ts.map +1 -0
  40. package/dist/auth/auth.js +477 -0
  41. package/dist/auth/auth.js.map +1 -0
  42. package/dist/auth/defaults.d.ts +104 -0
  43. package/dist/auth/defaults.d.ts.map +1 -0
  44. package/dist/auth/defaults.js +374 -0
  45. package/dist/auth/defaults.js.map +1 -0
  46. package/dist/auth/index.d.ts +70 -0
  47. package/dist/auth/index.d.ts.map +1 -0
  48. package/dist/auth/index.js +94 -0
  49. package/dist/auth/index.js.map +1 -0
  50. package/dist/cache/cache.d.ts +118 -0
  51. package/dist/cache/cache.d.ts.map +1 -0
  52. package/dist/cache/cache.js +249 -0
  53. package/dist/cache/cache.js.map +1 -0
  54. package/dist/cache/defaults.d.ts +63 -0
  55. package/dist/cache/defaults.d.ts.map +1 -0
  56. package/dist/cache/defaults.js +193 -0
  57. package/dist/cache/defaults.js.map +1 -0
  58. package/dist/cache/index.d.ts +101 -0
  59. package/dist/cache/index.d.ts.map +1 -0
  60. package/dist/cache/index.js +203 -0
  61. package/dist/cache/index.js.map +1 -0
  62. package/dist/cache/strategies/memory.d.ts +138 -0
  63. package/dist/cache/strategies/memory.d.ts.map +1 -0
  64. package/dist/cache/strategies/memory.js +348 -0
  65. package/dist/cache/strategies/memory.js.map +1 -0
  66. package/dist/cache/strategies/redis.d.ts +105 -0
  67. package/dist/cache/strategies/redis.d.ts.map +1 -0
  68. package/dist/cache/strategies/redis.js +318 -0
  69. package/dist/cache/strategies/redis.js.map +1 -0
  70. package/dist/config/config.d.ts +62 -0
  71. package/dist/config/config.d.ts.map +1 -0
  72. package/dist/config/config.js +107 -0
  73. package/dist/config/config.js.map +1 -0
  74. package/dist/config/defaults.d.ts +44 -0
  75. package/dist/config/defaults.d.ts.map +1 -0
  76. package/dist/config/defaults.js +217 -0
  77. package/dist/config/defaults.js.map +1 -0
  78. package/dist/config/index.d.ts +105 -0
  79. package/dist/config/index.d.ts.map +1 -0
  80. package/dist/config/index.js +163 -0
  81. package/dist/config/index.js.map +1 -0
  82. package/dist/database/adapters/mongoose.d.ts +106 -0
  83. package/dist/database/adapters/mongoose.d.ts.map +1 -0
  84. package/dist/database/adapters/mongoose.js +480 -0
  85. package/dist/database/adapters/mongoose.js.map +1 -0
  86. package/dist/database/adapters/prisma.d.ts +106 -0
  87. package/dist/database/adapters/prisma.d.ts.map +1 -0
  88. package/dist/database/adapters/prisma.js +494 -0
  89. package/dist/database/adapters/prisma.js.map +1 -0
  90. package/dist/database/defaults.d.ts +87 -0
  91. package/dist/database/defaults.d.ts.map +1 -0
  92. package/dist/database/defaults.js +271 -0
  93. package/dist/database/defaults.js.map +1 -0
  94. package/dist/database/index.d.ts +137 -0
  95. package/dist/database/index.d.ts.map +1 -0
  96. package/dist/database/index.js +490 -0
  97. package/dist/database/index.js.map +1 -0
  98. package/dist/email/defaults.d.ts +100 -0
  99. package/dist/email/defaults.d.ts.map +1 -0
  100. package/dist/email/defaults.js +400 -0
  101. package/dist/email/defaults.js.map +1 -0
  102. package/dist/email/email.d.ts +139 -0
  103. package/dist/email/email.d.ts.map +1 -0
  104. package/dist/email/email.js +316 -0
  105. package/dist/email/email.js.map +1 -0
  106. package/dist/email/index.d.ts +176 -0
  107. package/dist/email/index.d.ts.map +1 -0
  108. package/dist/email/index.js +251 -0
  109. package/dist/email/index.js.map +1 -0
  110. package/dist/email/strategies/console.d.ts +90 -0
  111. package/dist/email/strategies/console.d.ts.map +1 -0
  112. package/dist/email/strategies/console.js +268 -0
  113. package/dist/email/strategies/console.js.map +1 -0
  114. package/dist/email/strategies/resend.d.ts +84 -0
  115. package/dist/email/strategies/resend.d.ts.map +1 -0
  116. package/dist/email/strategies/resend.js +266 -0
  117. package/dist/email/strategies/resend.js.map +1 -0
  118. package/dist/email/strategies/smtp.d.ts +77 -0
  119. package/dist/email/strategies/smtp.d.ts.map +1 -0
  120. package/dist/email/strategies/smtp.js +286 -0
  121. package/dist/email/strategies/smtp.js.map +1 -0
  122. package/dist/error/defaults.d.ts +40 -0
  123. package/dist/error/defaults.d.ts.map +1 -0
  124. package/dist/error/defaults.js +75 -0
  125. package/dist/error/defaults.js.map +1 -0
  126. package/dist/error/error.d.ts +140 -0
  127. package/dist/error/error.d.ts.map +1 -0
  128. package/dist/error/error.js +200 -0
  129. package/dist/error/error.js.map +1 -0
  130. package/dist/error/index.d.ts +145 -0
  131. package/dist/error/index.d.ts.map +1 -0
  132. package/dist/error/index.js +145 -0
  133. package/dist/error/index.js.map +1 -0
  134. package/dist/event/defaults.d.ts +111 -0
  135. package/dist/event/defaults.d.ts.map +1 -0
  136. package/dist/event/defaults.js +378 -0
  137. package/dist/event/defaults.js.map +1 -0
  138. package/dist/event/event.d.ts +171 -0
  139. package/dist/event/event.d.ts.map +1 -0
  140. package/dist/event/event.js +391 -0
  141. package/dist/event/event.js.map +1 -0
  142. package/dist/event/index.d.ts +173 -0
  143. package/dist/event/index.d.ts.map +1 -0
  144. package/dist/event/index.js +302 -0
  145. package/dist/event/index.js.map +1 -0
  146. package/dist/event/strategies/memory.d.ts +122 -0
  147. package/dist/event/strategies/memory.d.ts.map +1 -0
  148. package/dist/event/strategies/memory.js +331 -0
  149. package/dist/event/strategies/memory.js.map +1 -0
  150. package/dist/event/strategies/redis.d.ts +115 -0
  151. package/dist/event/strategies/redis.d.ts.map +1 -0
  152. package/dist/event/strategies/redis.js +434 -0
  153. package/dist/event/strategies/redis.js.map +1 -0
  154. package/dist/index.d.ts +58 -0
  155. package/dist/index.d.ts.map +1 -0
  156. package/dist/index.js +72 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/logger/defaults.d.ts +67 -0
  159. package/dist/logger/defaults.d.ts.map +1 -0
  160. package/dist/logger/defaults.js +213 -0
  161. package/dist/logger/defaults.js.map +1 -0
  162. package/dist/logger/index.d.ts +84 -0
  163. package/dist/logger/index.d.ts.map +1 -0
  164. package/dist/logger/index.js +101 -0
  165. package/dist/logger/index.js.map +1 -0
  166. package/dist/logger/logger.d.ts +165 -0
  167. package/dist/logger/logger.d.ts.map +1 -0
  168. package/dist/logger/logger.js +843 -0
  169. package/dist/logger/logger.js.map +1 -0
  170. package/dist/logger/transports/console.d.ts +102 -0
  171. package/dist/logger/transports/console.d.ts.map +1 -0
  172. package/dist/logger/transports/console.js +276 -0
  173. package/dist/logger/transports/console.js.map +1 -0
  174. package/dist/logger/transports/database.d.ts +153 -0
  175. package/dist/logger/transports/database.d.ts.map +1 -0
  176. package/dist/logger/transports/database.js +539 -0
  177. package/dist/logger/transports/database.js.map +1 -0
  178. package/dist/logger/transports/file.d.ts +146 -0
  179. package/dist/logger/transports/file.d.ts.map +1 -0
  180. package/dist/logger/transports/file.js +464 -0
  181. package/dist/logger/transports/file.js.map +1 -0
  182. package/dist/logger/transports/http.d.ts +128 -0
  183. package/dist/logger/transports/http.d.ts.map +1 -0
  184. package/dist/logger/transports/http.js +401 -0
  185. package/dist/logger/transports/http.js.map +1 -0
  186. package/dist/logger/transports/webhook.d.ts +152 -0
  187. package/dist/logger/transports/webhook.d.ts.map +1 -0
  188. package/dist/logger/transports/webhook.js +485 -0
  189. package/dist/logger/transports/webhook.js.map +1 -0
  190. package/dist/queue/defaults.d.ts +66 -0
  191. package/dist/queue/defaults.d.ts.map +1 -0
  192. package/dist/queue/defaults.js +205 -0
  193. package/dist/queue/defaults.js.map +1 -0
  194. package/dist/queue/index.d.ts +124 -0
  195. package/dist/queue/index.d.ts.map +1 -0
  196. package/dist/queue/index.js +116 -0
  197. package/dist/queue/index.js.map +1 -0
  198. package/dist/queue/queue.d.ts +156 -0
  199. package/dist/queue/queue.d.ts.map +1 -0
  200. package/dist/queue/queue.js +387 -0
  201. package/dist/queue/queue.js.map +1 -0
  202. package/dist/queue/transports/database.d.ts +165 -0
  203. package/dist/queue/transports/database.d.ts.map +1 -0
  204. package/dist/queue/transports/database.js +595 -0
  205. package/dist/queue/transports/database.js.map +1 -0
  206. package/dist/queue/transports/memory.d.ts +143 -0
  207. package/dist/queue/transports/memory.d.ts.map +1 -0
  208. package/dist/queue/transports/memory.js +415 -0
  209. package/dist/queue/transports/memory.js.map +1 -0
  210. package/dist/queue/transports/redis.d.ts +203 -0
  211. package/dist/queue/transports/redis.d.ts.map +1 -0
  212. package/dist/queue/transports/redis.js +744 -0
  213. package/dist/queue/transports/redis.js.map +1 -0
  214. package/dist/security/defaults.d.ts +64 -0
  215. package/dist/security/defaults.d.ts.map +1 -0
  216. package/dist/security/defaults.js +159 -0
  217. package/dist/security/defaults.js.map +1 -0
  218. package/dist/security/index.d.ts +110 -0
  219. package/dist/security/index.d.ts.map +1 -0
  220. package/dist/security/index.js +160 -0
  221. package/dist/security/index.js.map +1 -0
  222. package/dist/security/security.d.ts +138 -0
  223. package/dist/security/security.d.ts.map +1 -0
  224. package/dist/security/security.js +419 -0
  225. package/dist/security/security.js.map +1 -0
  226. package/dist/storage/defaults.d.ts +79 -0
  227. package/dist/storage/defaults.d.ts.map +1 -0
  228. package/dist/storage/defaults.js +358 -0
  229. package/dist/storage/defaults.js.map +1 -0
  230. package/dist/storage/index.d.ts +153 -0
  231. package/dist/storage/index.d.ts.map +1 -0
  232. package/dist/storage/index.js +242 -0
  233. package/dist/storage/index.js.map +1 -0
  234. package/dist/storage/storage.d.ts +151 -0
  235. package/dist/storage/storage.d.ts.map +1 -0
  236. package/dist/storage/storage.js +439 -0
  237. package/dist/storage/storage.js.map +1 -0
  238. package/dist/storage/strategies/local.d.ts +117 -0
  239. package/dist/storage/strategies/local.d.ts.map +1 -0
  240. package/dist/storage/strategies/local.js +368 -0
  241. package/dist/storage/strategies/local.js.map +1 -0
  242. package/dist/storage/strategies/r2.d.ts +130 -0
  243. package/dist/storage/strategies/r2.d.ts.map +1 -0
  244. package/dist/storage/strategies/r2.js +470 -0
  245. package/dist/storage/strategies/r2.js.map +1 -0
  246. package/dist/storage/strategies/s3.d.ts +121 -0
  247. package/dist/storage/strategies/s3.d.ts.map +1 -0
  248. package/dist/storage/strategies/s3.js +461 -0
  249. package/dist/storage/strategies/s3.js.map +1 -0
  250. package/dist/util/defaults.d.ts +77 -0
  251. package/dist/util/defaults.d.ts.map +1 -0
  252. package/dist/util/defaults.js +193 -0
  253. package/dist/util/defaults.js.map +1 -0
  254. package/dist/util/index.d.ts +97 -0
  255. package/dist/util/index.d.ts.map +1 -0
  256. package/dist/util/index.js +165 -0
  257. package/dist/util/index.js.map +1 -0
  258. package/dist/util/util.d.ts +145 -0
  259. package/dist/util/util.d.ts.map +1 -0
  260. package/dist/util/util.js +481 -0
  261. package/dist/util/util.js.map +1 -0
  262. package/package.json +234 -0
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Core error class with semantic HTTP status codes and middleware
3
+ * @module @bloomneo/appkit/error
4
+ * @file src/error/error.ts
5
+ *
6
+ * @llm-rule WHEN: Building apps that need semantic HTTP error handling
7
+ * @llm-rule AVOID: Using directly - always get instance via errorClass.get()
8
+ * @llm-rule NOTE: Provides semantic error creation (badRequest, unauthorized) and Express middleware
9
+ */
10
+ /**
11
+ * Error class with semantic HTTP status codes and middleware functionality
12
+ */
13
+ export class ErrorClass {
14
+ config;
15
+ constructor(config) {
16
+ this.config = config;
17
+ }
18
+ /**
19
+ * Creates a 400 Bad Request error
20
+ * @llm-rule WHEN: Client sends invalid input data (missing fields, wrong format)
21
+ * @llm-rule AVOID: Using for server-side validation errors - use conflict() instead
22
+ * @llm-rule NOTE: EXAMPLES: missing email, invalid JSON, malformed request body
23
+ * @llm-rule NOTE: PATTERN: if (!req.body.email) throw error.badRequest('Email required');
24
+ */
25
+ badRequest(message) {
26
+ const error = new Error(message || this.config.messages.badRequest);
27
+ error.statusCode = 400;
28
+ error.type = 'BAD_REQUEST';
29
+ return error;
30
+ }
31
+ /**
32
+ * Creates a 401 Unauthorized error
33
+ * @llm-rule WHEN: Authentication is required but missing or invalid
34
+ * @llm-rule AVOID: Using for permission issues - use forbidden() for access control
35
+ * @llm-rule NOTE: EXAMPLES: missing token, invalid token, expired session
36
+ * @llm-rule NOTE: PATTERN: if (!token) throw error.unauthorized('Token required');
37
+ */
38
+ unauthorized(message) {
39
+ const error = new Error(message || this.config.messages.unauthorized);
40
+ error.statusCode = 401;
41
+ error.type = 'UNAUTHORIZED';
42
+ return error;
43
+ }
44
+ /**
45
+ * Creates a 403 Forbidden error
46
+ * @llm-rule WHEN: User is authenticated but lacks permission for the action
47
+ * @llm-rule AVOID: Using for authentication issues - use unauthorized() instead
48
+ * @llm-rule NOTE: EXAMPLES: insufficient role, blocked user, admin-only endpoint
49
+ * @llm-rule NOTE: PATTERN: if (!user.isAdmin) throw error.forbidden('Admin access required');
50
+ */
51
+ forbidden(message) {
52
+ const error = new Error(message || this.config.messages.forbidden);
53
+ error.statusCode = 403;
54
+ error.type = 'FORBIDDEN';
55
+ return error;
56
+ }
57
+ /**
58
+ * Creates a 404 Not Found error
59
+ * @llm-rule WHEN: Requested resource does not exist
60
+ * @llm-rule AVOID: Using for business logic failures - use conflict() instead
61
+ * @llm-rule NOTE: EXAMPLES: user not found, post not found, missing file
62
+ * @llm-rule NOTE: PATTERN: if (!user) throw error.notFound('User not found');
63
+ */
64
+ notFound(message) {
65
+ const error = new Error(message || this.config.messages.notFound);
66
+ error.statusCode = 404;
67
+ error.type = 'NOT_FOUND';
68
+ return error;
69
+ }
70
+ /**
71
+ * Creates a 409 Conflict error
72
+ * @llm-rule WHEN: Business logic conflicts or resource already exists
73
+ * @llm-rule AVOID: Using for validation errors - use badRequest() for input validation
74
+ * @llm-rule NOTE: EXAMPLES: email already exists, duplicate username, state conflicts
75
+ * @llm-rule NOTE: PATTERN: if (existingUser) throw error.conflict('Email already registered');
76
+ */
77
+ conflict(message) {
78
+ const error = new Error(message || this.config.messages.conflict);
79
+ error.statusCode = 409;
80
+ error.type = 'CONFLICT';
81
+ return error;
82
+ }
83
+ /**
84
+ * Creates a 500 Server Error
85
+ * @llm-rule WHEN: Internal server failures like database errors, external API failures
86
+ * @llm-rule AVOID: Using for business logic issues - use appropriate 4xx errors instead
87
+ * @llm-rule NOTE: EXAMPLES: database connection failure, external API timeout, file system errors
88
+ * @llm-rule NOTE: PATTERN: catch (dbError) { throw error.serverError('Database unavailable'); }
89
+ */
90
+ serverError(message) {
91
+ const error = new Error(message || this.config.messages.serverError);
92
+ error.statusCode = 500;
93
+ error.type = 'SERVER_ERROR';
94
+ return error;
95
+ }
96
+ /**
97
+ * Creates a custom error with any status code
98
+ * @llm-rule WHEN: Need custom HTTP status codes not covered by semantic methods
99
+ * @llm-rule AVOID: Using for standard HTTP codes - use semantic methods instead
100
+ * @llm-rule NOTE: EXAMPLES: 429 rate limit, 503 service unavailable, 418 teapot
101
+ * @llm-rule NOTE: PATTERN: error.createError(429, 'Rate limit exceeded', 'RATE_LIMIT');
102
+ */
103
+ createError(statusCode, message, type) {
104
+ const error = new Error(message);
105
+ error.statusCode = statusCode;
106
+ error.type = type || `HTTP_${statusCode}`;
107
+ return error;
108
+ }
109
+ /**
110
+ * Creates production-ready Express error handling middleware
111
+ * @llm-rule WHEN: Setting up Express app error handling - use as last middleware
112
+ * @llm-rule AVOID: Using multiple error handlers - this should be the final middleware
113
+ * @llm-rule NOTE: MIDDLEWARE SETUP: app.use(error.handleErrors()); // Must be LAST
114
+ * @llm-rule NOTE: AUTO-FEATURES: dev vs prod responses, stack trace hiding, error logging
115
+ */
116
+ handleErrors(options = {}) {
117
+ // Use instance config as defaults, allow options to override
118
+ const showStack = options.showStack !== undefined
119
+ ? options.showStack
120
+ : this.config.middleware.showStack;
121
+ const logErrors = options.logErrors !== undefined
122
+ ? options.logErrors
123
+ : this.config.middleware.logErrors;
124
+ return (error, req, res, next) => {
125
+ // Log errors if enabled
126
+ if (logErrors) {
127
+ console.error('Error:', error.message);
128
+ if (showStack && error.stack) {
129
+ console.error('Stack:', error.stack);
130
+ }
131
+ }
132
+ // Determine status code
133
+ const statusCode = error.statusCode || 500;
134
+ // Determine error type
135
+ const errorType = error.type || (statusCode >= 500 ? 'SERVER_ERROR' : 'CLIENT_ERROR');
136
+ // Build response object
137
+ const response = {
138
+ error: errorType,
139
+ message: error.message || 'An error occurred',
140
+ };
141
+ // Include stack trace in development
142
+ if (showStack && error.stack) {
143
+ response.stack = error.stack;
144
+ }
145
+ // Send error response
146
+ res.status(statusCode).json(response);
147
+ };
148
+ }
149
+ /**
150
+ * Wraps async route handlers to catch errors automatically
151
+ * @llm-rule WHEN: Creating async Express route handlers that might throw errors
152
+ * @llm-rule AVOID: Manual try/catch in every route - this handles it automatically
153
+ * @llm-rule NOTE: ASYNC PATTERN: app.post('/route', error.asyncRoute(async (req, res) => {...}));
154
+ * @llm-rule NOTE: ERROR FLOW: thrown errors → automatically caught → sent to handleErrors middleware
155
+ */
156
+ asyncRoute(fn) {
157
+ return (req, res, next) => {
158
+ Promise.resolve(fn(req, res, next)).catch(next);
159
+ };
160
+ }
161
+ /**
162
+ * Checks if error is a 4xx client error
163
+ * @llm-rule WHEN: Need to categorize errors for logging or metrics
164
+ * @llm-rule AVOID: Manual status code checking - this handles the logic
165
+ * @llm-rule NOTE: CLIENT ERRORS: 400-499 status codes (user's fault)
166
+ */
167
+ isClientError(error) {
168
+ return error.statusCode >= 400 && error.statusCode < 500;
169
+ }
170
+ /**
171
+ * Checks if error is a 5xx server error
172
+ * @llm-rule WHEN: Need to categorize errors for monitoring or alerting
173
+ * @llm-rule AVOID: Manual status code checking - this handles the logic
174
+ * @llm-rule NOTE: SERVER ERRORS: 500-599 status codes (server's fault)
175
+ */
176
+ isServerError(error) {
177
+ return error.statusCode >= 500;
178
+ }
179
+ /**
180
+ * Gets current environment detection info
181
+ * @llm-rule WHEN: Need to check current environment configuration
182
+ * @llm-rule AVOID: Direct process.env access - this provides parsed config
183
+ */
184
+ getEnvironmentInfo() {
185
+ return {
186
+ isDevelopment: this.config.environment.isDevelopment,
187
+ isProduction: this.config.environment.isProduction,
188
+ nodeEnv: this.config.environment.nodeEnv,
189
+ };
190
+ }
191
+ /**
192
+ * Gets current error configuration
193
+ * @llm-rule WHEN: Debugging error setup or inspecting current settings
194
+ * @llm-rule AVOID: Accessing config directly - this provides clean interface
195
+ */
196
+ getConfig() {
197
+ return { ...this.config };
198
+ }
199
+ }
200
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error/error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwCH;;GAEG;AACH,MAAM,OAAO,UAAU;IACd,MAAM,CAAc;IAE3B,YAAY,MAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,OAAgB;QACzB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAa,CAAC;QAChF,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,OAAgB;QAC3B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAa,CAAC;QAClF,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,cAAc,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,OAAgB;QACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAa,CAAC;QAC/E,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,OAAgB;QACvB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAa,CAAC;QAC9E,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,OAAgB;QACvB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAa,CAAC;QAC9E,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,OAAgB;QAC1B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAa,CAAC;QACjF,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,cAAc,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,UAAkB,EAAE,OAAe,EAAE,IAAa;QAC5D,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAa,CAAC;QAC7C,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC9B,KAAK,CAAC,IAAI,GAAG,IAAI,IAAI,QAAQ,UAAU,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,UAA+B,EAAE;QAC5C,6DAA6D;QAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS;YAC/C,CAAC,CAAC,OAAO,CAAC,SAAS;YACnB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAErC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS;YAC/C,CAAC,CAAC,OAAO,CAAC,SAAS;YACnB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAErC,OAAO,CAAC,KAAe,EAAE,GAAmB,EAAE,GAAoB,EAAE,IAAyB,EAAQ,EAAE;YACrG,wBAAwB;YACxB,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvC,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;YAED,wBAAwB;YACxB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;YAE3C,uBAAuB;YACvB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YAEtF,wBAAwB;YACxB,MAAM,QAAQ,GAAQ;gBACpB,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,mBAAmB;aAC9C,CAAC;YAEF,qCAAqC;YACrC,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC7B,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC/B,CAAC;YAED,sBAAsB;YACtB,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,EAAqB;QAC9B,OAAO,CAAC,GAAmB,EAAE,GAAoB,EAAE,IAAyB,EAAQ,EAAE;YACpF,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,KAAe;QAC3B,OAAO,KAAK,CAAC,UAAU,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,KAAe;QAC3B,OAAO,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,kBAAkB;QAChB,OAAO;YACL,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa;YACpD,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY;YAClD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO;SACzC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Ultra-simple semantic error handling that just works
3
+ * @module @bloomneo/appkit/error
4
+ * @file src/error/index.ts
5
+ *
6
+ * @llm-rule WHEN: Building apps that need semantic HTTP error handling
7
+ * @llm-rule AVOID: Complex error setups with multiple libraries - this handles everything in one API
8
+ * @llm-rule NOTE: Provides semantic error creation (badRequest, unauthorized) and Express middleware
9
+ * @llm-rule NOTE: Common pattern - errorClass.get() → throw error.badRequest() → app.use(error.handleErrors())
10
+ * @llm-rule NOTE: COMPLETE SETUP: const error = errorClass.get(); app.use(error.handleErrors()); // Done!
11
+ */
12
+ import { ErrorClass } from './error.js';
13
+ import { type ErrorConfig } from './defaults.js';
14
+ export interface AppError extends Error {
15
+ statusCode: number;
16
+ type: string;
17
+ }
18
+ export interface ExpressRequest {
19
+ [key: string]: any;
20
+ }
21
+ export interface ExpressResponse {
22
+ status: (code: number) => ExpressResponse;
23
+ json: (data: any) => void;
24
+ }
25
+ export interface ExpressNextFunction {
26
+ (error?: any): void;
27
+ }
28
+ export type ExpressErrorHandler = (error: AppError, req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
29
+ export type AsyncRouteHandler = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => Promise<any>;
30
+ export interface ErrorHandlerOptions {
31
+ showStack?: boolean;
32
+ logErrors?: boolean;
33
+ }
34
+ /**
35
+ * Get error instance - the only function you need to learn
36
+ * Environment variables parsed once for performance
37
+ * @llm-rule WHEN: Starting any error operation - this is your main entry point
38
+ * @llm-rule AVOID: Calling new ErrorClass() directly - always use this function
39
+ * @llm-rule NOTE: USAGE FLOW: get() → create errors → setup middleware → done
40
+ * @llm-rule NOTE: TYPICAL SETUP: const error = errorClass.get(); app.use(error.handleErrors());
41
+ */
42
+ declare function get(overrides?: Partial<ErrorConfig>): ErrorClass;
43
+ /**
44
+ * Reset global instance (useful for testing or config changes)
45
+ * @llm-rule WHEN: Testing error logic with different configurations
46
+ * @llm-rule AVOID: Using in production - only for tests and development
47
+ * @llm-rule NOTE: TEST PATTERN: const error = errorClass.reset({showStack: false}); // Clean slate
48
+ */
49
+ declare function reset(newConfig?: Partial<ErrorConfig>): ErrorClass;
50
+ /**
51
+ * Clear global instance cache (for testing)
52
+ * @llm-rule WHEN: Testing error configurations or between test suites
53
+ * @llm-rule AVOID: Using in production - only for tests
54
+ */
55
+ declare function clearCache(): void;
56
+ /**
57
+ * Single error export with semantic methods and Express integration
58
+ * @llm-rule NOTE: TWO USAGE PATTERNS: errorClass.get().badRequest() OR errorClass.badRequest() (shortcuts)
59
+ * @llm-rule NOTE: MIDDLEWARE PATTERN: app.use(error.handleErrors()); // Global error handling
60
+ */
61
+ export declare const errorClass: {
62
+ readonly get: typeof get;
63
+ readonly reset: typeof reset;
64
+ readonly clearCache: typeof clearCache;
65
+ /**
66
+ * Creates 400 Bad Request error
67
+ * @llm-rule WHEN: Client input validation failures (missing/invalid data)
68
+ * @llm-rule NOTE: EXAMPLES: missing email, invalid JSON, malformed request
69
+ * @llm-rule NOTE: PATTERN: if (!email) throw error.badRequest('Email required');
70
+ */
71
+ readonly badRequest: (message?: string) => import("./error.js").AppError;
72
+ /**
73
+ * Creates 401 Unauthorized error
74
+ * @llm-rule WHEN: Authentication required but missing or invalid
75
+ * @llm-rule NOTE: EXAMPLES: missing token, expired session, invalid credentials
76
+ * @llm-rule NOTE: PATTERN: if (!token) throw error.unauthorized('Login required');
77
+ */
78
+ readonly unauthorized: (message?: string) => import("./error.js").AppError;
79
+ /**
80
+ * Creates 403 Forbidden error
81
+ * @llm-rule WHEN: User authenticated but lacks permission for action
82
+ * @llm-rule NOTE: EXAMPLES: insufficient role, admin-only endpoint, blocked user
83
+ * @llm-rule NOTE: PATTERN: if (!user.isAdmin) throw error.forbidden('Admin only');
84
+ */
85
+ readonly forbidden: (message?: string) => import("./error.js").AppError;
86
+ /**
87
+ * Creates 404 Not Found error
88
+ * @llm-rule WHEN: Requested resource does not exist in database/system
89
+ * @llm-rule NOTE: EXAMPLES: user not found, post not found, file missing
90
+ * @llm-rule NOTE: PATTERN: if (!user) throw error.notFound('User not found');
91
+ */
92
+ readonly notFound: (message?: string) => import("./error.js").AppError;
93
+ /**
94
+ * Creates 409 Conflict error
95
+ * @llm-rule WHEN: Business logic conflicts or duplicate resources
96
+ * @llm-rule NOTE: EXAMPLES: email already exists, username taken, state conflicts
97
+ * @llm-rule NOTE: PATTERN: if (existingUser) throw error.conflict('Email exists');
98
+ */
99
+ readonly conflict: (message?: string) => import("./error.js").AppError;
100
+ /**
101
+ * Creates 500 Server Error
102
+ * @llm-rule WHEN: Internal failures like database/API errors
103
+ * @llm-rule NOTE: EXAMPLES: database down, external API timeout, file system errors
104
+ * @llm-rule NOTE: PATTERN: catch (dbError) { throw error.serverError('DB unavailable'); }
105
+ */
106
+ readonly serverError: (message?: string) => import("./error.js").AppError;
107
+ /**
108
+ * Creates custom error with any status code
109
+ * @llm-rule WHEN: Need non-standard HTTP status codes
110
+ * @llm-rule NOTE: EXAMPLES: 429 rate limit, 503 maintenance, 418 teapot
111
+ * @llm-rule NOTE: PATTERN: error.createError(429, 'Rate limited', 'RATE_LIMIT');
112
+ */
113
+ readonly createError: (statusCode: number, message: string, type?: string) => import("./error.js").AppError;
114
+ /**
115
+ * Express error handling middleware - handles all thrown errors
116
+ * @llm-rule WHEN: Setting up Express app - use as LAST middleware
117
+ * @llm-rule AVOID: Multiple error handlers - this should be the final one
118
+ * @llm-rule NOTE: EXPRESS SETUP: app.use(error.handleErrors()); // Must be last!
119
+ * @llm-rule NOTE: AUTO-FEATURES: dev vs prod responses, stack hiding, error logging
120
+ */
121
+ readonly handleErrors: (options?: ErrorHandlerOptions) => import("./error.js").ExpressErrorHandler;
122
+ /**
123
+ * Async route wrapper - automatically catches thrown errors
124
+ * @llm-rule WHEN: Creating async Express routes that might throw errors
125
+ * @llm-rule AVOID: Manual try/catch in routes - this handles it automatically
126
+ * @llm-rule NOTE: ASYNC PATTERN: app.post('/api', error.asyncRoute(async (req, res) => {...}));
127
+ * @llm-rule NOTE: ERROR FLOW: throw error → asyncRoute catches → handleErrors processes
128
+ */
129
+ readonly asyncRoute: (fn: AsyncRouteHandler) => (req: import("./error.js").ExpressRequest, res: import("./error.js").ExpressResponse, next: import("./error.js").ExpressNextFunction) => void;
130
+ /**
131
+ * Checks if error is 4xx client error
132
+ * @llm-rule WHEN: Categorizing errors for logging/metrics
133
+ * @llm-rule NOTE: CLIENT ERRORS: 400-499 (user's fault)
134
+ */
135
+ readonly isClientError: (err: AppError) => boolean;
136
+ /**
137
+ * Checks if error is 5xx server error
138
+ * @llm-rule WHEN: Categorizing errors for monitoring/alerting
139
+ * @llm-rule NOTE: SERVER ERRORS: 500-599 (server's fault)
140
+ */
141
+ readonly isServerError: (err: AppError) => boolean;
142
+ };
143
+ export type { ErrorConfig } from './defaults.js';
144
+ export { ErrorClass } from './error.js';
145
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/error/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,mBAAmB,KACtB,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,mBAAmB,KACtB,OAAO,CAAC,GAAG,CAAC,CAAC;AAElB,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAKD;;;;;;;GAOG;AACH,iBAAS,GAAG,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,UAAU,CAS7D;AAED;;;;;GAKG;AACH,iBAAS,KAAK,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,UAAU,CAK/D;AAED;;;;GAIG;AACH,iBAAS,UAAU,IAAI,IAAI,CAE1B;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;IASrB;;;;;OAKG;oCACoB,MAAM;IAE7B;;;;;OAKG;sCACsB,MAAM;IAE/B;;;;;OAKG;mCACmB,MAAM;IAE5B;;;;;OAKG;kCACkB,MAAM;IAE3B;;;;;OAKG;kCACkB,MAAM;IAE3B;;;;;OAKG;qCACqB,MAAM;IAE9B;;;;;OAKG;uCACuB,MAAM,WAAW,MAAM,SAAS,MAAM;IAGhE;;;;;;OAMG;sCACsB,mBAAmB;IAE5C;;;;;;OAMG;8BACc,iBAAiB;IAElC;;;;OAIG;kCACkB,QAAQ;IAE7B;;;;OAIG;kCACkB,QAAQ;CACrB,CAAC;AAGX,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Ultra-simple semantic error handling that just works
3
+ * @module @bloomneo/appkit/error
4
+ * @file src/error/index.ts
5
+ *
6
+ * @llm-rule WHEN: Building apps that need semantic HTTP error handling
7
+ * @llm-rule AVOID: Complex error setups with multiple libraries - this handles everything in one API
8
+ * @llm-rule NOTE: Provides semantic error creation (badRequest, unauthorized) and Express middleware
9
+ * @llm-rule NOTE: Common pattern - errorClass.get() → throw error.badRequest() → app.use(error.handleErrors())
10
+ * @llm-rule NOTE: COMPLETE SETUP: const error = errorClass.get(); app.use(error.handleErrors()); // Done!
11
+ */
12
+ import { ErrorClass } from './error.js';
13
+ import { getSmartDefaults } from './defaults.js';
14
+ // Global error instance for performance
15
+ let globalError = null;
16
+ /**
17
+ * Get error instance - the only function you need to learn
18
+ * Environment variables parsed once for performance
19
+ * @llm-rule WHEN: Starting any error operation - this is your main entry point
20
+ * @llm-rule AVOID: Calling new ErrorClass() directly - always use this function
21
+ * @llm-rule NOTE: USAGE FLOW: get() → create errors → setup middleware → done
22
+ * @llm-rule NOTE: TYPICAL SETUP: const error = errorClass.get(); app.use(error.handleErrors());
23
+ */
24
+ function get(overrides = {}) {
25
+ // Lazy initialization - parse environment once
26
+ if (!globalError) {
27
+ const defaults = getSmartDefaults();
28
+ const config = { ...defaults, ...overrides };
29
+ globalError = new ErrorClass(config);
30
+ }
31
+ return globalError;
32
+ }
33
+ /**
34
+ * Reset global instance (useful for testing or config changes)
35
+ * @llm-rule WHEN: Testing error logic with different configurations
36
+ * @llm-rule AVOID: Using in production - only for tests and development
37
+ * @llm-rule NOTE: TEST PATTERN: const error = errorClass.reset({showStack: false}); // Clean slate
38
+ */
39
+ function reset(newConfig = {}) {
40
+ const defaults = getSmartDefaults();
41
+ const config = { ...defaults, ...newConfig };
42
+ globalError = new ErrorClass(config);
43
+ return globalError;
44
+ }
45
+ /**
46
+ * Clear global instance cache (for testing)
47
+ * @llm-rule WHEN: Testing error configurations or between test suites
48
+ * @llm-rule AVOID: Using in production - only for tests
49
+ */
50
+ function clearCache() {
51
+ globalError = null;
52
+ }
53
+ /**
54
+ * Single error export with semantic methods and Express integration
55
+ * @llm-rule NOTE: TWO USAGE PATTERNS: errorClass.get().badRequest() OR errorClass.badRequest() (shortcuts)
56
+ * @llm-rule NOTE: MIDDLEWARE PATTERN: app.use(error.handleErrors()); // Global error handling
57
+ */
58
+ export const errorClass = {
59
+ // Core method
60
+ get,
61
+ // Utility methods
62
+ reset,
63
+ clearCache,
64
+ // Error creation shortcuts - automatically call get()
65
+ /**
66
+ * Creates 400 Bad Request error
67
+ * @llm-rule WHEN: Client input validation failures (missing/invalid data)
68
+ * @llm-rule NOTE: EXAMPLES: missing email, invalid JSON, malformed request
69
+ * @llm-rule NOTE: PATTERN: if (!email) throw error.badRequest('Email required');
70
+ */
71
+ badRequest: (message) => get().badRequest(message),
72
+ /**
73
+ * Creates 401 Unauthorized error
74
+ * @llm-rule WHEN: Authentication required but missing or invalid
75
+ * @llm-rule NOTE: EXAMPLES: missing token, expired session, invalid credentials
76
+ * @llm-rule NOTE: PATTERN: if (!token) throw error.unauthorized('Login required');
77
+ */
78
+ unauthorized: (message) => get().unauthorized(message),
79
+ /**
80
+ * Creates 403 Forbidden error
81
+ * @llm-rule WHEN: User authenticated but lacks permission for action
82
+ * @llm-rule NOTE: EXAMPLES: insufficient role, admin-only endpoint, blocked user
83
+ * @llm-rule NOTE: PATTERN: if (!user.isAdmin) throw error.forbidden('Admin only');
84
+ */
85
+ forbidden: (message) => get().forbidden(message),
86
+ /**
87
+ * Creates 404 Not Found error
88
+ * @llm-rule WHEN: Requested resource does not exist in database/system
89
+ * @llm-rule NOTE: EXAMPLES: user not found, post not found, file missing
90
+ * @llm-rule NOTE: PATTERN: if (!user) throw error.notFound('User not found');
91
+ */
92
+ notFound: (message) => get().notFound(message),
93
+ /**
94
+ * Creates 409 Conflict error
95
+ * @llm-rule WHEN: Business logic conflicts or duplicate resources
96
+ * @llm-rule NOTE: EXAMPLES: email already exists, username taken, state conflicts
97
+ * @llm-rule NOTE: PATTERN: if (existingUser) throw error.conflict('Email exists');
98
+ */
99
+ conflict: (message) => get().conflict(message),
100
+ /**
101
+ * Creates 500 Server Error
102
+ * @llm-rule WHEN: Internal failures like database/API errors
103
+ * @llm-rule NOTE: EXAMPLES: database down, external API timeout, file system errors
104
+ * @llm-rule NOTE: PATTERN: catch (dbError) { throw error.serverError('DB unavailable'); }
105
+ */
106
+ serverError: (message) => get().serverError(message),
107
+ /**
108
+ * Creates custom error with any status code
109
+ * @llm-rule WHEN: Need non-standard HTTP status codes
110
+ * @llm-rule NOTE: EXAMPLES: 429 rate limit, 503 maintenance, 418 teapot
111
+ * @llm-rule NOTE: PATTERN: error.createError(429, 'Rate limited', 'RATE_LIMIT');
112
+ */
113
+ createError: (statusCode, message, type) => get().createError(statusCode, message, type),
114
+ // Middleware and utility shortcuts
115
+ /**
116
+ * Express error handling middleware - handles all thrown errors
117
+ * @llm-rule WHEN: Setting up Express app - use as LAST middleware
118
+ * @llm-rule AVOID: Multiple error handlers - this should be the final one
119
+ * @llm-rule NOTE: EXPRESS SETUP: app.use(error.handleErrors()); // Must be last!
120
+ * @llm-rule NOTE: AUTO-FEATURES: dev vs prod responses, stack hiding, error logging
121
+ */
122
+ handleErrors: (options) => get().handleErrors(options),
123
+ /**
124
+ * Async route wrapper - automatically catches thrown errors
125
+ * @llm-rule WHEN: Creating async Express routes that might throw errors
126
+ * @llm-rule AVOID: Manual try/catch in routes - this handles it automatically
127
+ * @llm-rule NOTE: ASYNC PATTERN: app.post('/api', error.asyncRoute(async (req, res) => {...}));
128
+ * @llm-rule NOTE: ERROR FLOW: throw error → asyncRoute catches → handleErrors processes
129
+ */
130
+ asyncRoute: (fn) => get().asyncRoute(fn),
131
+ /**
132
+ * Checks if error is 4xx client error
133
+ * @llm-rule WHEN: Categorizing errors for logging/metrics
134
+ * @llm-rule NOTE: CLIENT ERRORS: 400-499 (user's fault)
135
+ */
136
+ isClientError: (err) => get().isClientError(err),
137
+ /**
138
+ * Checks if error is 5xx server error
139
+ * @llm-rule WHEN: Categorizing errors for monitoring/alerting
140
+ * @llm-rule NOTE: SERVER ERRORS: 500-599 (server's fault)
141
+ */
142
+ isServerError: (err) => get().isServerError(err),
143
+ };
144
+ export { ErrorClass } from './error.js';
145
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/error/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,eAAe,CAAC;AAsCnE,wCAAwC;AACxC,IAAI,WAAW,GAAsB,IAAI,CAAC;AAE1C;;;;;;;GAOG;AACH,SAAS,GAAG,CAAC,YAAkC,EAAE;IAC/C,+CAA+C;IAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAgB,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;QAC1D,WAAW,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,SAAS,KAAK,CAAC,YAAkC,EAAE;IACjD,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAgB,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IAC1D,WAAW,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,GAAG;IAEH,kBAAkB;IAClB,KAAK;IACL,UAAU;IAEV,sDAAsD;IACtD;;;;;OAKG;IACH,UAAU,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;IAE3D;;;;;OAKG;IACH,YAAY,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;IAE/D;;;;;OAKG;IACH,SAAS,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;IAEzD;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEvD;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEvD;;;;;OAKG;IACH,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC;IAE7D;;;;;OAKG;IACH,WAAW,EAAE,CAAC,UAAkB,EAAE,OAAe,EAAE,IAAa,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;IAEjH,mCAAmC;IACnC;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,OAA6B,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;IAE5E;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,EAAqB,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IAE3D;;;;OAIG;IACH,aAAa,EAAE,CAAC,GAAa,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC;IAE1D;;;;OAIG;IACH,aAAa,EAAE,CAAC,GAAa,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC;CAClD,CAAC;AAIX,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Smart defaults and environment validation for event system with auto-strategy detection
3
+ * @module @bloomneo/appkit/event
4
+ * @file src/event/defaults.ts
5
+ *
6
+ * @llm-rule WHEN: App startup - need to configure event system and connection strategy
7
+ * @llm-rule AVOID: Calling multiple times - expensive environment parsing, use lazy loading in get()
8
+ * @llm-rule NOTE: Called once at startup, cached globally for performance
9
+ * @llm-rule NOTE: Auto-detects Redis vs Memory based on REDIS_URL environment variable
10
+ */
11
+ export interface RedisConfig {
12
+ url: string;
13
+ password?: string;
14
+ maxRetries: number;
15
+ retryDelay: number;
16
+ connectTimeout: number;
17
+ commandTimeout: number;
18
+ keyPrefix: string;
19
+ }
20
+ export interface MemoryConfig {
21
+ maxListeners: number;
22
+ maxHistory: number;
23
+ checkInterval: number;
24
+ enableGC: boolean;
25
+ }
26
+ export interface EventConfig {
27
+ strategy: 'redis' | 'memory';
28
+ namespace: string;
29
+ redis?: RedisConfig;
30
+ memory?: MemoryConfig;
31
+ history: {
32
+ enabled: boolean;
33
+ maxSize: number;
34
+ };
35
+ environment: {
36
+ isDevelopment: boolean;
37
+ isProduction: boolean;
38
+ isTest: boolean;
39
+ nodeEnv: string;
40
+ };
41
+ }
42
+ /**
43
+ * Gets smart defaults using environment variables with auto-strategy detection
44
+ * @llm-rule WHEN: App startup to get production-ready event configuration
45
+ * @llm-rule AVOID: Calling repeatedly - expensive validation, cache the result
46
+ * @llm-rule NOTE: Auto-detects strategy: REDIS_URL → Redis, no REDIS_URL → Memory
47
+ */
48
+ export declare function getSmartDefaults(): EventConfig;
49
+ /**
50
+ * Gets event configuration summary for debugging and health checks
51
+ * @llm-rule WHEN: Debugging event configuration or building health check endpoints
52
+ * @llm-rule AVOID: Exposing sensitive connection details - this only shows safe info
53
+ */
54
+ export declare function getConfigSummary(): {
55
+ strategy: string;
56
+ namespace: string;
57
+ historyEnabled: boolean;
58
+ redisConnected: boolean;
59
+ environment: string;
60
+ };
61
+ /**
62
+ * Validates that required event configuration is present for production
63
+ * @llm-rule WHEN: App startup validation for production deployments
64
+ * @llm-rule AVOID: Skipping validation - missing event config causes runtime issues
65
+ */
66
+ export declare function validateProductionRequirements(): void;
67
+ /**
68
+ * Validates startup configuration and throws detailed errors
69
+ * @llm-rule WHEN: App startup to ensure event configuration is valid before starting
70
+ * @llm-rule AVOID: Skipping validation - catches config issues early
71
+ * @llm-rule NOTE: Comprehensive validation for production readiness
72
+ */
73
+ export declare function validateStartupConfiguration(): {
74
+ strategy: string;
75
+ warnings: string[];
76
+ errors: string[];
77
+ ready: boolean;
78
+ };
79
+ /**
80
+ * Performs comprehensive event system health check
81
+ * @llm-rule WHEN: Health check endpoints or monitoring systems
82
+ * @llm-rule AVOID: Running in critical path - this is for monitoring only
83
+ * @llm-rule NOTE: Returns detailed health status without exposing sensitive data
84
+ */
85
+ export declare function performHealthCheck(): {
86
+ status: 'healthy' | 'warning' | 'error';
87
+ strategy: string;
88
+ configured: boolean;
89
+ issues: string[];
90
+ ready: boolean;
91
+ timestamp: string;
92
+ };
93
+ /**
94
+ * Gets optimal event configuration for different environments
95
+ * @llm-rule WHEN: Setting up environment-specific event behavior
96
+ * @llm-rule AVOID: Manual environment handling - this provides optimal defaults
97
+ */
98
+ export declare function getEnvironmentOptimizedConfig(): EventConfig;
99
+ /**
100
+ * Checks if Redis is available and properly configured
101
+ * @llm-rule WHEN: Conditional logic based on event capabilities
102
+ * @llm-rule AVOID: Complex event detection - just use events normally, strategy handles it
103
+ */
104
+ export declare function hasRedis(): boolean;
105
+ /**
106
+ * Gets recommended configuration for microservices
107
+ * @llm-rule WHEN: Setting up events for microservices architecture
108
+ * @llm-rule AVOID: Default config for microservices - needs specific tuning
109
+ */
110
+ export declare function getMicroservicesConfig(): Partial<EventConfig>;
111
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/event/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,WAAW,EAAE;QACX,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAmD9C;AAuJD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB,CAUA;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAmBrD;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,CA0DA;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAsCA;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,WAAW,CA4B3D;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAGlC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,WAAW,CAAC,CAgB7D"}