@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,152 @@
1
+ /**
2
+ * Webhook transport for real-time alerts with Slack and generic webhook support
3
+ * @module @bloomneo/appkit/logger
4
+ * @file src/logger/transports/webhook.ts
5
+ *
6
+ * @llm-rule WHEN: Need real-time error alerts or notifications to Slack/Discord/Teams
7
+ * @llm-rule AVOID: High-frequency logging - webhooks are for alerts, not all logs
8
+ * @llm-rule NOTE: Only sends errors by default, auto-detects Slack format, includes rate limiting
9
+ */
10
+ import type { LogEntry, Transport } from '../logger.js';
11
+ import type { LoggingConfig } from '../defaults.js';
12
+ /**
13
+ * Webhook transport for real-time alerts with automatic service detection
14
+ */
15
+ export declare class WebhookTransport implements Transport {
16
+ private url;
17
+ private level;
18
+ private rateLimit;
19
+ private minimal;
20
+ private parsedUrl;
21
+ private serviceType;
22
+ private rateLimitQueue;
23
+ private rateLimitWindow;
24
+ /**
25
+ * Creates webhook transport with direct environment access (like auth pattern)
26
+ * @llm-rule WHEN: Logger initialization with VOILA_LOGGING_WEBHOOK_URL environment variable
27
+ * @llm-rule AVOID: Manual webhook configuration - environment detection handles this
28
+ * @llm-rule NOTE: Auto-detects Slack URLs and formats messages appropriately
29
+ */
30
+ constructor(config: LoggingConfig);
31
+ /**
32
+ * Detect webhook service type from URL
33
+ * @llm-rule WHEN: Determining message format based on webhook provider
34
+ * @llm-rule AVOID: Manual service configuration - URL detection is automatic
35
+ */
36
+ private detectServiceType;
37
+ /**
38
+ * Write log entry to webhook (immediate, level-filtered)
39
+ * @llm-rule WHEN: Sending critical alerts and errors to notification services
40
+ * @llm-rule AVOID: Calling directly - logger routes entries automatically
41
+ */
42
+ write(entry: LogEntry): Promise<void>;
43
+ /**
44
+ * Check if log level should be sent to webhook
45
+ * @llm-rule WHEN: Filtering logs to only send important alerts
46
+ * @llm-rule AVOID: Sending all logs - webhooks are for errors and critical events
47
+ */
48
+ private shouldSendLevel;
49
+ /**
50
+ * Check rate limiting to prevent webhook spam
51
+ * @llm-rule WHEN: Preventing too many webhook calls in short time
52
+ * @llm-rule AVOID: Unlimited webhook sending - can get you banned from services
53
+ */
54
+ private checkRateLimit;
55
+ /**
56
+ * Optimize log entry for webhook alerts
57
+ * @llm-rule WHEN: Creating focused alert messages with essential information
58
+ * @llm-rule AVOID: Sending full log entries - webhooks need concise, actionable alerts
59
+ */
60
+ private optimizeEntry;
61
+ /**
62
+ * Optimize error object for webhook alerts
63
+ * @llm-rule WHEN: Including error details in alerts without sensitive information
64
+ * @llm-rule AVOID: Including stack traces - security risk and too verbose for alerts
65
+ */
66
+ private optimizeError;
67
+ /**
68
+ * Filter metadata for critical alert information only
69
+ * @llm-rule WHEN: Including only the most important context in alerts
70
+ * @llm-rule AVOID: Including all metadata - alerts should be concise and actionable
71
+ */
72
+ private filterCriticalMeta;
73
+ /**
74
+ * Send log entry via webhook with service-specific formatting
75
+ * @llm-rule WHEN: Transmitting alert to webhook service
76
+ * @llm-rule AVOID: Generic format for known services - optimized formats are better
77
+ */
78
+ private sendWebhook;
79
+ /**
80
+ * Format log entry for specific webhook services
81
+ * @llm-rule WHEN: Converting alerts to service-specific format for better presentation
82
+ * @llm-rule AVOID: Always using generic format - Slack format shows much better
83
+ */
84
+ private formatWebhookPayload;
85
+ /**
86
+ * Format alert for Slack with rich formatting
87
+ * @llm-rule WHEN: Sending alerts to Slack channels for team notifications
88
+ * @llm-rule AVOID: Plain text format - Slack's rich format is much more readable
89
+ */
90
+ private formatSlackPayload;
91
+ /**
92
+ * Get Slack color for different log levels
93
+ * @llm-rule WHEN: Styling Slack messages for visual priority
94
+ * @llm-rule AVOID: Same color for all levels - visual distinction helps prioritization
95
+ */
96
+ private getSlackColor;
97
+ /**
98
+ * Get emoji for different log levels
99
+ * @llm-rule WHEN: Adding visual indicators to alerts for quick recognition
100
+ * @llm-rule AVOID: No visual indicators - emojis help with quick alert scanning
101
+ */
102
+ private getLevelEmoji;
103
+ /**
104
+ * Map log level to alert severity
105
+ * @llm-rule WHEN: Converting log levels to standard alert severity levels
106
+ * @llm-rule AVOID: Using log levels directly - severity is more standardized
107
+ */
108
+ private mapLevelToSeverity;
109
+ /**
110
+ * Make HTTP request with retry logic
111
+ * @llm-rule WHEN: Sending webhook with reliability for important alerts
112
+ * @llm-rule AVOID: Single attempt - webhooks can fail due to network issues
113
+ */
114
+ private makeHttpRequest;
115
+ /**
116
+ * Execute single HTTP request with timeout
117
+ * @llm-rule WHEN: Making actual webhook call
118
+ * @llm-rule AVOID: Long timeouts - webhooks should respond quickly
119
+ */
120
+ private executeHttpRequest;
121
+ /**
122
+ * Setup rate limit cleanup
123
+ * @llm-rule WHEN: Preventing memory leaks from rate limit tracking
124
+ * @llm-rule AVOID: Infinite memory growth - periodic cleanup is essential
125
+ */
126
+ private setupRateLimitCleanup;
127
+ /**
128
+ * Sleep for specified milliseconds
129
+ * @llm-rule WHEN: Implementing retry delays
130
+ * @llm-rule AVOID: Busy waiting - proper sleep prevents CPU waste
131
+ */
132
+ private sleep;
133
+ /**
134
+ * Check if this transport should log the given level
135
+ * @llm-rule WHEN: Logger asks if transport handles this level
136
+ * @llm-rule AVOID: Complex level logic - webhook uses own level filtering
137
+ */
138
+ shouldLog(level: string, configLevel: string): boolean;
139
+ /**
140
+ * Flush pending logs (no-op for webhook - immediate sending)
141
+ * @llm-rule WHEN: Logger cleanup - webhooks send immediately
142
+ * @llm-rule AVOID: Expecting batching behavior - webhooks are immediate
143
+ */
144
+ flush(): Promise<void>;
145
+ /**
146
+ * Close webhook transport
147
+ * @llm-rule WHEN: Logger shutdown or cleanup
148
+ * @llm-rule AVOID: Expecting cleanup behavior - webhooks have no persistent resources
149
+ */
150
+ close(): Promise<void>;
151
+ }
152
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/logger/transports/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;GAEG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAS;IAEhC;;;;;OAKG;gBACS,MAAM,EAAE,aAAa;IAmBjC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;OAIG;IACG,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B3C;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAUvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAStB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAqDrB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IA4BrB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;OAIG;YACW,WAAW;IAKzB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAoG1B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;;;OAIG;YACW,eAAe;IAyB7B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAiD1B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAKtD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
@@ -0,0 +1,485 @@
1
+ /**
2
+ * Webhook transport for real-time alerts with Slack and generic webhook support
3
+ * @module @bloomneo/appkit/logger
4
+ * @file src/logger/transports/webhook.ts
5
+ *
6
+ * @llm-rule WHEN: Need real-time error alerts or notifications to Slack/Discord/Teams
7
+ * @llm-rule AVOID: High-frequency logging - webhooks are for alerts, not all logs
8
+ * @llm-rule NOTE: Only sends errors by default, auto-detects Slack format, includes rate limiting
9
+ */
10
+ import https from 'https';
11
+ import http from 'http';
12
+ /**
13
+ * Webhook transport for real-time alerts with automatic service detection
14
+ */
15
+ export class WebhookTransport {
16
+ url;
17
+ level;
18
+ rateLimit;
19
+ minimal;
20
+ // Webhook state
21
+ parsedUrl;
22
+ serviceType;
23
+ rateLimitQueue = [];
24
+ rateLimitWindow = 60000; // 1 minute
25
+ /**
26
+ * Creates webhook transport with direct environment access (like auth pattern)
27
+ * @llm-rule WHEN: Logger initialization with VOILA_LOGGING_WEBHOOK_URL environment variable
28
+ * @llm-rule AVOID: Manual webhook configuration - environment detection handles this
29
+ * @llm-rule NOTE: Auto-detects Slack URLs and formats messages appropriately
30
+ */
31
+ constructor(config) {
32
+ // Direct access to config (like auth module pattern)
33
+ this.url = config.webhook.url;
34
+ this.level = config.webhook.level;
35
+ this.rateLimit = config.webhook.rateLimit;
36
+ this.minimal = config.minimal;
37
+ this.parsedUrl = new URL(this.url);
38
+ this.serviceType = this.detectServiceType();
39
+ // Adjust rate limiting for minimal mode (fewer alerts)
40
+ if (this.minimal) {
41
+ this.rateLimit = Math.min(this.rateLimit, 5);
42
+ }
43
+ // Initialize cleanup for rate limiting
44
+ this.setupRateLimitCleanup();
45
+ }
46
+ /**
47
+ * Detect webhook service type from URL
48
+ * @llm-rule WHEN: Determining message format based on webhook provider
49
+ * @llm-rule AVOID: Manual service configuration - URL detection is automatic
50
+ */
51
+ detectServiceType() {
52
+ const hostname = this.parsedUrl.hostname.toLowerCase();
53
+ if (hostname.includes('slack.com'))
54
+ return 'slack';
55
+ return 'generic';
56
+ }
57
+ /**
58
+ * Write log entry to webhook (immediate, level-filtered)
59
+ * @llm-rule WHEN: Sending critical alerts and errors to notification services
60
+ * @llm-rule AVOID: Calling directly - logger routes entries automatically
61
+ */
62
+ async write(entry) {
63
+ try {
64
+ // Check if this level should be sent
65
+ if (!this.shouldSendLevel(entry.level)) {
66
+ return;
67
+ }
68
+ // Check rate limiting to prevent spam
69
+ if (!this.checkRateLimit()) {
70
+ console.warn('Webhook rate limit exceeded, dropping alert');
71
+ return;
72
+ }
73
+ // Optimize entry for webhook transmission
74
+ const optimizedEntry = this.optimizeEntry(entry);
75
+ // Send immediately (webhooks are for real-time alerts)
76
+ await this.sendWebhook(optimizedEntry);
77
+ // Track for rate limiting
78
+ this.rateLimitQueue.push(Date.now());
79
+ }
80
+ catch (error) {
81
+ console.error('Webhook transport write error:', error.message);
82
+ }
83
+ }
84
+ /**
85
+ * Check if log level should be sent to webhook
86
+ * @llm-rule WHEN: Filtering logs to only send important alerts
87
+ * @llm-rule AVOID: Sending all logs - webhooks are for errors and critical events
88
+ */
89
+ shouldSendLevel(level) {
90
+ const levels = {
91
+ error: 0, warn: 1, info: 2, debug: 3
92
+ };
93
+ const configLevel = levels[this.level];
94
+ const entryLevel = levels[level];
95
+ return entryLevel <= configLevel;
96
+ }
97
+ /**
98
+ * Check rate limiting to prevent webhook spam
99
+ * @llm-rule WHEN: Preventing too many webhook calls in short time
100
+ * @llm-rule AVOID: Unlimited webhook sending - can get you banned from services
101
+ */
102
+ checkRateLimit() {
103
+ const now = Date.now();
104
+ const recentWebhooks = this.rateLimitQueue.filter(timestamp => now - timestamp < this.rateLimitWindow);
105
+ return recentWebhooks.length < this.rateLimit;
106
+ }
107
+ /**
108
+ * Optimize log entry for webhook alerts
109
+ * @llm-rule WHEN: Creating focused alert messages with essential information
110
+ * @llm-rule AVOID: Sending full log entries - webhooks need concise, actionable alerts
111
+ */
112
+ optimizeEntry(entry) {
113
+ const { timestamp, level, message, component, requestId, userId, method, url, statusCode, error, service, environment, ...rest } = entry;
114
+ const optimized = {
115
+ timestamp,
116
+ level,
117
+ message,
118
+ };
119
+ // Add essential context for alerts
120
+ if (component)
121
+ optimized.component = component;
122
+ if (requestId)
123
+ optimized.requestId = requestId;
124
+ if (userId)
125
+ optimized.userId = userId;
126
+ if (service)
127
+ optimized.service = service;
128
+ if (environment)
129
+ optimized.environment = environment;
130
+ // Add HTTP context for API errors
131
+ if (level === 'error') {
132
+ if (method)
133
+ optimized.method = method;
134
+ if (url)
135
+ optimized.url = url;
136
+ if (statusCode)
137
+ optimized.statusCode = statusCode;
138
+ }
139
+ // Optimize error information for alerts
140
+ if (error) {
141
+ optimized.error = this.optimizeError(error);
142
+ }
143
+ // Add only critical metadata for alerts
144
+ if (!this.minimal) {
145
+ const criticalMeta = this.filterCriticalMeta(rest);
146
+ if (Object.keys(criticalMeta).length > 0) {
147
+ optimized.meta = criticalMeta;
148
+ }
149
+ }
150
+ return optimized;
151
+ }
152
+ /**
153
+ * Optimize error object for webhook alerts
154
+ * @llm-rule WHEN: Including error details in alerts without sensitive information
155
+ * @llm-rule AVOID: Including stack traces - security risk and too verbose for alerts
156
+ */
157
+ optimizeError(error) {
158
+ if (typeof error === 'string') {
159
+ return error;
160
+ }
161
+ if (typeof error === 'object' && error !== null) {
162
+ const optimized = {
163
+ message: error.message,
164
+ };
165
+ // Add important error fields for debugging
166
+ if (error.name && error.name !== 'Error') {
167
+ optimized.name = error.name;
168
+ }
169
+ if (error.code) {
170
+ optimized.code = error.code;
171
+ }
172
+ if (error.statusCode) {
173
+ optimized.statusCode = error.statusCode;
174
+ }
175
+ // Never include stack traces in webhooks (security + brevity)
176
+ return optimized;
177
+ }
178
+ return error;
179
+ }
180
+ /**
181
+ * Filter metadata for critical alert information only
182
+ * @llm-rule WHEN: Including only the most important context in alerts
183
+ * @llm-rule AVOID: Including all metadata - alerts should be concise and actionable
184
+ */
185
+ filterCriticalMeta(meta) {
186
+ const critical = {};
187
+ // Only the most critical fields for alerts
188
+ const criticalKeys = [
189
+ 'tenantId', 'appName', 'version'
190
+ ];
191
+ for (const key of criticalKeys) {
192
+ if (meta[key] !== undefined) {
193
+ critical[key] = meta[key];
194
+ }
195
+ }
196
+ return critical;
197
+ }
198
+ /**
199
+ * Send log entry via webhook with service-specific formatting
200
+ * @llm-rule WHEN: Transmitting alert to webhook service
201
+ * @llm-rule AVOID: Generic format for known services - optimized formats are better
202
+ */
203
+ async sendWebhook(entry) {
204
+ const payload = this.formatWebhookPayload(entry);
205
+ await this.makeHttpRequest(payload);
206
+ }
207
+ /**
208
+ * Format log entry for specific webhook services
209
+ * @llm-rule WHEN: Converting alerts to service-specific format for better presentation
210
+ * @llm-rule AVOID: Always using generic format - Slack format shows much better
211
+ */
212
+ formatWebhookPayload(entry) {
213
+ switch (this.serviceType) {
214
+ case 'slack':
215
+ return JSON.stringify(this.formatSlackPayload(entry));
216
+ case 'generic':
217
+ default:
218
+ return JSON.stringify({
219
+ timestamp: entry.timestamp,
220
+ level: entry.level,
221
+ message: entry.message,
222
+ scope: this.minimal ? 'minimal' : 'full',
223
+ data: entry,
224
+ alert: {
225
+ severity: this.mapLevelToSeverity(entry.level),
226
+ service: entry.service || 'unknown',
227
+ component: entry.component || 'unknown',
228
+ },
229
+ });
230
+ }
231
+ }
232
+ /**
233
+ * Format alert for Slack with rich formatting
234
+ * @llm-rule WHEN: Sending alerts to Slack channels for team notifications
235
+ * @llm-rule AVOID: Plain text format - Slack's rich format is much more readable
236
+ */
237
+ formatSlackPayload(entry) {
238
+ const color = this.getSlackColor(entry.level);
239
+ const emoji = this.getLevelEmoji(entry.level);
240
+ const scopeIndicator = this.minimal ? '🔹' : '🔸';
241
+ const fields = [
242
+ {
243
+ title: 'Message',
244
+ value: entry.message,
245
+ short: false,
246
+ },
247
+ ];
248
+ // Add context fields
249
+ if (entry.component) {
250
+ fields.push({
251
+ title: 'Component',
252
+ value: entry.component,
253
+ short: true,
254
+ });
255
+ }
256
+ if (entry.service) {
257
+ fields.push({
258
+ title: 'Service',
259
+ value: entry.service,
260
+ short: true,
261
+ });
262
+ }
263
+ if (entry.environment) {
264
+ fields.push({
265
+ title: 'Environment',
266
+ value: entry.environment,
267
+ short: true,
268
+ });
269
+ }
270
+ // Add error details if present
271
+ if (entry.error) {
272
+ const errorText = typeof entry.error === 'object'
273
+ ? entry.error.message
274
+ : entry.error;
275
+ fields.push({
276
+ title: 'Error Details',
277
+ value: errorText,
278
+ short: false,
279
+ });
280
+ }
281
+ // Add HTTP context for API errors
282
+ if (entry.level === 'error' && (entry.method || entry.url || entry.statusCode)) {
283
+ let httpInfo = '';
284
+ if (entry.method && entry.url) {
285
+ httpInfo += `${entry.method} ${entry.url}`;
286
+ }
287
+ if (entry.statusCode) {
288
+ httpInfo += ` (${entry.statusCode})`;
289
+ }
290
+ if (httpInfo) {
291
+ fields.push({
292
+ title: 'HTTP Context',
293
+ value: httpInfo,
294
+ short: true,
295
+ });
296
+ }
297
+ }
298
+ // Add user context if available
299
+ if (entry.userId) {
300
+ fields.push({
301
+ title: 'User ID',
302
+ value: entry.userId,
303
+ short: true,
304
+ });
305
+ }
306
+ if (entry.requestId) {
307
+ fields.push({
308
+ title: 'Request ID',
309
+ value: entry.requestId,
310
+ short: true,
311
+ });
312
+ }
313
+ return {
314
+ text: `${scopeIndicator} ${emoji} *${entry.level.toUpperCase()}* Alert`,
315
+ attachments: [
316
+ {
317
+ color: color,
318
+ fields: fields,
319
+ footer: 'VoilaJSX AppKit Logging',
320
+ ts: Math.floor(new Date(entry.timestamp).getTime() / 1000),
321
+ },
322
+ ],
323
+ };
324
+ }
325
+ /**
326
+ * Get Slack color for different log levels
327
+ * @llm-rule WHEN: Styling Slack messages for visual priority
328
+ * @llm-rule AVOID: Same color for all levels - visual distinction helps prioritization
329
+ */
330
+ getSlackColor(level) {
331
+ const colors = {
332
+ error: 'danger', // Red
333
+ warn: 'warning', // Yellow
334
+ info: 'good', // Green
335
+ debug: '#36a64f', // Light green
336
+ };
337
+ return colors[level] || 'good';
338
+ }
339
+ /**
340
+ * Get emoji for different log levels
341
+ * @llm-rule WHEN: Adding visual indicators to alerts for quick recognition
342
+ * @llm-rule AVOID: No visual indicators - emojis help with quick alert scanning
343
+ */
344
+ getLevelEmoji(level) {
345
+ const emojis = {
346
+ error: '🚨', // Siren
347
+ warn: '⚠️', // Warning
348
+ info: 'ℹ️', // Information
349
+ debug: '🐛', // Bug
350
+ };
351
+ return emojis[level] || 'ℹ️';
352
+ }
353
+ /**
354
+ * Map log level to alert severity
355
+ * @llm-rule WHEN: Converting log levels to standard alert severity levels
356
+ * @llm-rule AVOID: Using log levels directly - severity is more standardized
357
+ */
358
+ mapLevelToSeverity(level) {
359
+ const severityMap = {
360
+ error: 'critical',
361
+ warn: 'warning',
362
+ info: 'info',
363
+ debug: 'low',
364
+ };
365
+ return severityMap[level] || 'info';
366
+ }
367
+ /**
368
+ * Make HTTP request with retry logic
369
+ * @llm-rule WHEN: Sending webhook with reliability for important alerts
370
+ * @llm-rule AVOID: Single attempt - webhooks can fail due to network issues
371
+ */
372
+ async makeHttpRequest(payload) {
373
+ const maxRetries = 2; // Limited retries for webhooks
374
+ let lastError;
375
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
376
+ try {
377
+ await this.executeHttpRequest(payload);
378
+ return; // Success
379
+ }
380
+ catch (error) {
381
+ lastError = error;
382
+ if (attempt < maxRetries) {
383
+ const delay = 1000 * attempt; // Linear backoff for webhooks
384
+ console.warn(`Webhook attempt ${attempt} failed, retrying in ${delay}ms:`, error.message);
385
+ await this.sleep(delay);
386
+ }
387
+ }
388
+ }
389
+ throw lastError;
390
+ }
391
+ /**
392
+ * Execute single HTTP request with timeout
393
+ * @llm-rule WHEN: Making actual webhook call
394
+ * @llm-rule AVOID: Long timeouts - webhooks should respond quickly
395
+ */
396
+ executeHttpRequest(payload) {
397
+ return new Promise((resolve, reject) => {
398
+ const isHttps = this.parsedUrl.protocol === 'https:';
399
+ const httpModule = isHttps ? https : http;
400
+ const options = {
401
+ hostname: this.parsedUrl.hostname,
402
+ port: this.parsedUrl.port || (isHttps ? 443 : 80),
403
+ path: this.parsedUrl.pathname + this.parsedUrl.search,
404
+ method: 'POST',
405
+ headers: {
406
+ 'Content-Type': 'application/json',
407
+ 'Content-Length': Buffer.byteLength(payload),
408
+ 'User-Agent': 'VoilaJSX-AppKit-Logging/1.0.0',
409
+ },
410
+ timeout: 10000, // 10 second timeout for webhooks
411
+ };
412
+ const req = httpModule.request(options, (res) => {
413
+ let responseData = '';
414
+ res.on('data', (chunk) => {
415
+ responseData += chunk;
416
+ });
417
+ res.on('end', () => {
418
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
419
+ resolve();
420
+ }
421
+ else {
422
+ reject(new Error(`Webhook HTTP ${res.statusCode}: ${responseData}`));
423
+ }
424
+ });
425
+ });
426
+ req.on('timeout', () => {
427
+ req.destroy();
428
+ reject(new Error('Webhook timeout after 10000ms'));
429
+ });
430
+ req.on('error', (error) => {
431
+ reject(new Error(`Webhook request failed: ${error.message}`));
432
+ });
433
+ // Write payload and end request
434
+ req.write(payload);
435
+ req.end();
436
+ });
437
+ }
438
+ /**
439
+ * Setup rate limit cleanup
440
+ * @llm-rule WHEN: Preventing memory leaks from rate limit tracking
441
+ * @llm-rule AVOID: Infinite memory growth - periodic cleanup is essential
442
+ */
443
+ setupRateLimitCleanup() {
444
+ setInterval(() => {
445
+ const now = Date.now();
446
+ this.rateLimitQueue = this.rateLimitQueue.filter(timestamp => now - timestamp < this.rateLimitWindow);
447
+ }, this.rateLimitWindow);
448
+ }
449
+ /**
450
+ * Sleep for specified milliseconds
451
+ * @llm-rule WHEN: Implementing retry delays
452
+ * @llm-rule AVOID: Busy waiting - proper sleep prevents CPU waste
453
+ */
454
+ sleep(ms) {
455
+ return new Promise(resolve => setTimeout(resolve, ms));
456
+ }
457
+ /**
458
+ * Check if this transport should log the given level
459
+ * @llm-rule WHEN: Logger asks if transport handles this level
460
+ * @llm-rule AVOID: Complex level logic - webhook uses own level filtering
461
+ */
462
+ shouldLog(level, configLevel) {
463
+ // Webhook uses its own level filtering via shouldSendLevel
464
+ return this.shouldSendLevel(level);
465
+ }
466
+ /**
467
+ * Flush pending logs (no-op for webhook - immediate sending)
468
+ * @llm-rule WHEN: Logger cleanup - webhooks send immediately
469
+ * @llm-rule AVOID: Expecting batching behavior - webhooks are immediate
470
+ */
471
+ async flush() {
472
+ // Webhooks send immediately, no batching needed
473
+ return Promise.resolve();
474
+ }
475
+ /**
476
+ * Close webhook transport
477
+ * @llm-rule WHEN: Logger shutdown or cleanup
478
+ * @llm-rule AVOID: Expecting cleanup behavior - webhooks have no persistent resources
479
+ */
480
+ async close() {
481
+ // Webhook transport has no persistent resources to clean up
482
+ return Promise.resolve();
483
+ }
484
+ }
485
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../../src/logger/transports/webhook.ts"],"names":[],"mappings":"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"}