@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,146 @@
1
+ /**
2
+ * File transport with automatic rotation, retention and scope optimization
3
+ * @module @bloomneo/appkit/logger
4
+ * @file src/logger/transports/file.ts
5
+ *
6
+ * @llm-rule WHEN: Need persistent log storage with automatic file management
7
+ * @llm-rule AVOID: Manual file handling - this manages rotation and cleanup automatically
8
+ * @llm-rule NOTE: Auto-rotates daily and by size, cleans old files, optimizes for minimal/full scope
9
+ */
10
+ import type { LogEntry, Transport } from '../logger.js';
11
+ import type { LoggingConfig } from '../defaults.js';
12
+ /**
13
+ * File transport with built-in rotation, retention and scope optimization
14
+ */
15
+ export declare class FileTransport implements Transport {
16
+ private dir;
17
+ private filename;
18
+ private maxSize;
19
+ private retentionDays;
20
+ private minimal;
21
+ private currentSize;
22
+ private currentDate;
23
+ private stream;
24
+ private cleanupInterval;
25
+ /**
26
+ * Creates file transport with direct environment access (like auth pattern)
27
+ * @llm-rule WHEN: Logger initialization - gets config from environment defaults
28
+ * @llm-rule AVOID: Manual file configuration - environment detection handles this
29
+ */
30
+ constructor(config: LoggingConfig);
31
+ /**
32
+ * Initialize file transport with directory and stream setup
33
+ * @llm-rule WHEN: Transport creation - sets up directory and initial file
34
+ * @llm-rule AVOID: Calling manually - constructor handles initialization
35
+ */
36
+ private initialize;
37
+ /**
38
+ * Write log entry to file with automatic rotation
39
+ * @llm-rule WHEN: Storing logs to persistent file storage
40
+ * @llm-rule AVOID: Calling directly - logger routes entries automatically
41
+ */
42
+ write(entry: LogEntry): Promise<void>;
43
+ /**
44
+ * Optimize log entry based on scope settings
45
+ * @llm-rule WHEN: Reducing file size and focusing on essential data
46
+ * @llm-rule AVOID: Always using full entries - minimal scope saves significant space
47
+ */
48
+ private optimizeEntry;
49
+ /**
50
+ * Optimize error object for file storage
51
+ * @llm-rule WHEN: Storing error information efficiently in minimal mode
52
+ * @llm-rule AVOID: Including full stack traces in production - security and size concerns
53
+ */
54
+ private optimizeError;
55
+ /**
56
+ * Filter metadata to keep only essential fields
57
+ * @llm-rule WHEN: Minimizing file size while preserving correlation data
58
+ * @llm-rule AVOID: Storing all metadata - focus on correlation and debugging fields
59
+ */
60
+ private filterEssentialMeta;
61
+ /**
62
+ * Write line to stream with timeout protection
63
+ * @llm-rule WHEN: Writing to file stream safely
64
+ * @llm-rule AVOID: Blocking writes - uses timeout to prevent hanging
65
+ */
66
+ private writeToStream;
67
+ /**
68
+ * Check if rotation is needed and perform it
69
+ * @llm-rule WHEN: Before each write to manage file size and date rotation
70
+ * @llm-rule AVOID: Manual rotation - automatic rotation prevents large files
71
+ */
72
+ private checkRotation;
73
+ /**
74
+ * Perform date-based rotation
75
+ * @llm-rule WHEN: Date changes - creates new file for new day
76
+ * @llm-rule AVOID: Manual date rotation - automatic daily rotation is better
77
+ */
78
+ private rotateDateBased;
79
+ /**
80
+ * Perform size-based rotation
81
+ * @llm-rule WHEN: File exceeds max size - prevents huge log files
82
+ * @llm-rule AVOID: Letting files grow infinitely - rotation maintains manageable sizes
83
+ */
84
+ private rotateSizeBased;
85
+ /**
86
+ * Create write stream for current log file
87
+ * @llm-rule WHEN: Starting new file or after rotation
88
+ * @llm-rule AVOID: Creating multiple streams - one stream per file
89
+ */
90
+ private createStream;
91
+ /**
92
+ * Close current stream safely
93
+ * @llm-rule WHEN: Rotation, shutdown, or error recovery
94
+ * @llm-rule AVOID: Abrupt stream closure - graceful close prevents data loss
95
+ */
96
+ private closeStream;
97
+ /**
98
+ * Get current date string for file naming
99
+ * @llm-rule WHEN: Creating date-based file names
100
+ * @llm-rule AVOID: Custom date formats - YYYY-MM-DD is standard and sortable
101
+ */
102
+ private getCurrentDate;
103
+ /**
104
+ * Get current log file path with date suffix
105
+ * @llm-rule WHEN: Determining where to write current logs
106
+ * @llm-rule AVOID: Hardcoded paths - use configurable directory and filename
107
+ */
108
+ private getCurrentFilepath;
109
+ /**
110
+ * Ensure log directory exists
111
+ * @llm-rule WHEN: Transport initialization - creates directory if needed
112
+ * @llm-rule AVOID: Assuming directory exists - auto-creation prevents errors
113
+ */
114
+ private ensureDirectoryExists;
115
+ /**
116
+ * Setup automatic cleanup of old log files
117
+ * @llm-rule WHEN: Transport initialization - prevents disk space issues
118
+ * @llm-rule AVOID: Manual cleanup - automatic retention prevents disk overflow
119
+ */
120
+ private setupRetentionCleanup;
121
+ /**
122
+ * Clean old log files based on retention policy
123
+ * @llm-rule WHEN: Daily cleanup or transport initialization
124
+ * @llm-rule AVOID: Keeping logs forever - retention policy prevents disk issues
125
+ */
126
+ private cleanOldLogs;
127
+ /**
128
+ * Check if this transport should log the given level
129
+ * @llm-rule WHEN: Logger asks if transport handles this level
130
+ * @llm-rule AVOID: Complex level logic - simple comparison is sufficient
131
+ */
132
+ shouldLog(level: string, configLevel: string): boolean;
133
+ /**
134
+ * Flush pending logs to disk
135
+ * @llm-rule WHEN: App shutdown or ensuring logs are persisted
136
+ * @llm-rule AVOID: Frequent flushing - impacts performance
137
+ */
138
+ flush(): Promise<void>;
139
+ /**
140
+ * Close file transport and cleanup resources
141
+ * @llm-rule WHEN: App shutdown or logger cleanup
142
+ * @llm-rule AVOID: Abrupt shutdown - graceful close prevents data loss
143
+ */
144
+ close(): Promise<void>;
145
+ }
146
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/logger/transports/file.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,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,eAAe,CAA+B;IAEtD;;;;OAIG;gBACS,MAAM,EAAE,aAAa;IAcjC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAUlB;;;;OAIG;IACG,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB3C;;;;OAIG;IACH,OAAO,CAAC,aAAa;IA4DrB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAiCrB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAuBrB;;;;OAIG;YACW,aAAa;IAe3B;;;;OAIG;YACW,eAAe;IAO7B;;;;OAIG;YACW,eAAe;IA4B7B;;;;OAIG;IACH,OAAO,CAAC,YAAY;IA8BpB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IA4BnB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAKtB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;;OAIG;YACW,YAAY;IAgC1B;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAOtD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
@@ -0,0 +1,464 @@
1
+ /**
2
+ * File transport with automatic rotation, retention and scope optimization
3
+ * @module @bloomneo/appkit/logger
4
+ * @file src/logger/transports/file.ts
5
+ *
6
+ * @llm-rule WHEN: Need persistent log storage with automatic file management
7
+ * @llm-rule AVOID: Manual file handling - this manages rotation and cleanup automatically
8
+ * @llm-rule NOTE: Auto-rotates daily and by size, cleans old files, optimizes for minimal/full scope
9
+ */
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ /**
13
+ * File transport with built-in rotation, retention and scope optimization
14
+ */
15
+ export class FileTransport {
16
+ dir;
17
+ filename;
18
+ maxSize;
19
+ retentionDays;
20
+ minimal;
21
+ // File state
22
+ currentSize = 0;
23
+ currentDate;
24
+ stream = null;
25
+ cleanupInterval = null;
26
+ /**
27
+ * Creates file transport with direct environment access (like auth pattern)
28
+ * @llm-rule WHEN: Logger initialization - gets config from environment defaults
29
+ * @llm-rule AVOID: Manual file configuration - environment detection handles this
30
+ */
31
+ constructor(config) {
32
+ // Direct access to config (like auth module pattern)
33
+ this.dir = config.file.dir;
34
+ this.filename = config.file.filename;
35
+ this.maxSize = config.file.maxSize;
36
+ this.retentionDays = config.file.retentionDays;
37
+ this.minimal = config.minimal;
38
+ this.currentDate = this.getCurrentDate();
39
+ // Initialize file logging
40
+ this.initialize();
41
+ }
42
+ /**
43
+ * Initialize file transport with directory and stream setup
44
+ * @llm-rule WHEN: Transport creation - sets up directory and initial file
45
+ * @llm-rule AVOID: Calling manually - constructor handles initialization
46
+ */
47
+ initialize() {
48
+ try {
49
+ this.ensureDirectoryExists();
50
+ this.createStream();
51
+ this.setupRetentionCleanup();
52
+ }
53
+ catch (error) {
54
+ console.error('File transport initialization failed:', error.message);
55
+ }
56
+ }
57
+ /**
58
+ * Write log entry to file with automatic rotation
59
+ * @llm-rule WHEN: Storing logs to persistent file storage
60
+ * @llm-rule AVOID: Calling directly - logger routes entries automatically
61
+ */
62
+ async write(entry) {
63
+ try {
64
+ await this.checkRotation();
65
+ if (!this.stream || !this.stream.writable) {
66
+ this.createStream();
67
+ }
68
+ // Optimize entry based on scope (minimal vs full)
69
+ const optimizedEntry = this.optimizeEntry(entry);
70
+ // Always write structured JSON to files
71
+ const line = JSON.stringify(optimizedEntry) + '\n';
72
+ const size = Buffer.byteLength(line);
73
+ await this.writeToStream(line);
74
+ this.currentSize += size;
75
+ }
76
+ catch (error) {
77
+ console.error('File transport write error:', error.message);
78
+ }
79
+ }
80
+ /**
81
+ * Optimize log entry based on scope settings
82
+ * @llm-rule WHEN: Reducing file size and focusing on essential data
83
+ * @llm-rule AVOID: Always using full entries - minimal scope saves significant space
84
+ */
85
+ optimizeEntry(entry) {
86
+ if (!this.minimal) {
87
+ return entry; // Full scope - keep everything
88
+ }
89
+ // Minimal scope optimization for smaller files
90
+ const { timestamp, level, message, component, requestId, userId, method, url, statusCode, durationMs, error, service, version, environment, ...rest } = entry;
91
+ const minimal = {
92
+ ts: timestamp,
93
+ lvl: level,
94
+ msg: message,
95
+ };
96
+ // Add essential context with short field names
97
+ if (component)
98
+ minimal.comp = component;
99
+ if (requestId)
100
+ minimal.req = requestId;
101
+ if (userId)
102
+ minimal.uid = userId;
103
+ // Add HTTP context if present
104
+ if (method)
105
+ minimal.method = method;
106
+ if (url)
107
+ minimal.url = url;
108
+ if (statusCode)
109
+ minimal.status = statusCode;
110
+ if (durationMs)
111
+ minimal.dur = durationMs;
112
+ // Add service context
113
+ if (service)
114
+ minimal.svc = service;
115
+ if (version)
116
+ minimal.ver = version;
117
+ if (environment)
118
+ minimal.env = environment;
119
+ // Optimize error information
120
+ if (error) {
121
+ minimal.err = this.optimizeError(error);
122
+ }
123
+ // Add only essential metadata
124
+ const essentialMeta = this.filterEssentialMeta(rest);
125
+ if (Object.keys(essentialMeta).length > 0) {
126
+ minimal.meta = essentialMeta;
127
+ }
128
+ return minimal;
129
+ }
130
+ /**
131
+ * Optimize error object for file storage
132
+ * @llm-rule WHEN: Storing error information efficiently in minimal mode
133
+ * @llm-rule AVOID: Including full stack traces in production - security and size concerns
134
+ */
135
+ optimizeError(error) {
136
+ if (typeof error === 'string') {
137
+ return error;
138
+ }
139
+ if (typeof error === 'object' && error !== null) {
140
+ const optimized = {
141
+ message: error.message,
142
+ };
143
+ // Add important error fields
144
+ if (error.name && error.name !== 'Error') {
145
+ optimized.name = error.name;
146
+ }
147
+ if (error.code) {
148
+ optimized.code = error.code;
149
+ }
150
+ if (error.statusCode) {
151
+ optimized.statusCode = error.statusCode;
152
+ }
153
+ // Include stack trace only in development
154
+ const isDevelopment = process.env.NODE_ENV === 'development';
155
+ if (isDevelopment && error.stack) {
156
+ optimized.stack = error.stack;
157
+ }
158
+ return optimized;
159
+ }
160
+ return error;
161
+ }
162
+ /**
163
+ * Filter metadata to keep only essential fields
164
+ * @llm-rule WHEN: Minimizing file size while preserving correlation data
165
+ * @llm-rule AVOID: Storing all metadata - focus on correlation and debugging fields
166
+ */
167
+ filterEssentialMeta(meta) {
168
+ const essential = {};
169
+ // Essential correlation fields
170
+ const essentialKeys = [
171
+ 'traceId', 'spanId', 'sessionId', 'tenantId', 'ip'
172
+ ];
173
+ for (const key of essentialKeys) {
174
+ if (meta[key] !== undefined) {
175
+ essential[key] = meta[key];
176
+ }
177
+ }
178
+ // Include any field ending with 'Id' (correlation IDs)
179
+ for (const [key, value] of Object.entries(meta)) {
180
+ if (key.endsWith('Id') && !essential[key]) {
181
+ essential[key] = value;
182
+ }
183
+ }
184
+ return essential;
185
+ }
186
+ /**
187
+ * Write line to stream with timeout protection
188
+ * @llm-rule WHEN: Writing to file stream safely
189
+ * @llm-rule AVOID: Blocking writes - uses timeout to prevent hanging
190
+ */
191
+ writeToStream(line) {
192
+ return new Promise((resolve) => {
193
+ if (!this.stream || !this.stream.writable) {
194
+ resolve();
195
+ return;
196
+ }
197
+ const timeout = setTimeout(() => {
198
+ console.warn('File write timed out after 5000ms');
199
+ resolve();
200
+ }, 5000);
201
+ this.stream.write(line, (error) => {
202
+ clearTimeout(timeout);
203
+ if (error) {
204
+ console.error('Error writing to log file:', error.message);
205
+ this.stream = null;
206
+ }
207
+ resolve();
208
+ });
209
+ });
210
+ }
211
+ /**
212
+ * Check if rotation is needed and perform it
213
+ * @llm-rule WHEN: Before each write to manage file size and date rotation
214
+ * @llm-rule AVOID: Manual rotation - automatic rotation prevents large files
215
+ */
216
+ async checkRotation() {
217
+ const currentDate = this.getCurrentDate();
218
+ // Daily rotation
219
+ if (currentDate !== this.currentDate) {
220
+ await this.rotateDateBased();
221
+ return;
222
+ }
223
+ // Size-based rotation
224
+ if (this.currentSize >= this.maxSize) {
225
+ await this.rotateSizeBased();
226
+ }
227
+ }
228
+ /**
229
+ * Perform date-based rotation
230
+ * @llm-rule WHEN: Date changes - creates new file for new day
231
+ * @llm-rule AVOID: Manual date rotation - automatic daily rotation is better
232
+ */
233
+ async rotateDateBased() {
234
+ await this.closeStream();
235
+ this.currentDate = this.getCurrentDate();
236
+ this.currentSize = 0;
237
+ this.createStream();
238
+ }
239
+ /**
240
+ * Perform size-based rotation
241
+ * @llm-rule WHEN: File exceeds max size - prevents huge log files
242
+ * @llm-rule AVOID: Letting files grow infinitely - rotation maintains manageable sizes
243
+ */
244
+ async rotateSizeBased() {
245
+ await this.closeStream();
246
+ const currentFilepath = this.getCurrentFilepath();
247
+ try {
248
+ if (!fs.existsSync(currentFilepath)) {
249
+ this.currentSize = 0;
250
+ this.createStream();
251
+ return;
252
+ }
253
+ // Find next rotation number
254
+ let rotation = 1;
255
+ while (fs.existsSync(`${currentFilepath}.${rotation}`)) {
256
+ rotation++;
257
+ }
258
+ // Rename current file
259
+ await fs.promises.rename(currentFilepath, `${currentFilepath}.${rotation}`);
260
+ }
261
+ catch (error) {
262
+ console.error('Error during file rotation:', error.message);
263
+ }
264
+ this.currentSize = 0;
265
+ this.createStream();
266
+ }
267
+ /**
268
+ * Create write stream for current log file
269
+ * @llm-rule WHEN: Starting new file or after rotation
270
+ * @llm-rule AVOID: Creating multiple streams - one stream per file
271
+ */
272
+ createStream() {
273
+ const filepath = this.getCurrentFilepath();
274
+ try {
275
+ // Get current file size if it exists
276
+ if (fs.existsSync(filepath)) {
277
+ const stats = fs.statSync(filepath);
278
+ this.currentSize = stats.size;
279
+ }
280
+ else {
281
+ this.currentSize = 0;
282
+ }
283
+ // Close existing stream
284
+ if (this.stream) {
285
+ this.stream.end();
286
+ }
287
+ // Create new write stream
288
+ this.stream = fs.createWriteStream(filepath, { flags: 'a' });
289
+ this.stream.on('error', (error) => {
290
+ console.error('Log file write error:', error.message);
291
+ this.stream = null;
292
+ });
293
+ }
294
+ catch (error) {
295
+ console.error('Error creating write stream:', error.message);
296
+ this.stream = null;
297
+ }
298
+ }
299
+ /**
300
+ * Close current stream safely
301
+ * @llm-rule WHEN: Rotation, shutdown, or error recovery
302
+ * @llm-rule AVOID: Abrupt stream closure - graceful close prevents data loss
303
+ */
304
+ closeStream() {
305
+ return new Promise((resolve) => {
306
+ if (!this.stream) {
307
+ resolve();
308
+ return;
309
+ }
310
+ const timeout = setTimeout(() => {
311
+ console.warn('Stream close timed out after 5000ms');
312
+ this.stream = null;
313
+ resolve();
314
+ }, 5000);
315
+ this.stream.on('error', (error) => {
316
+ console.error('Stream error during close:', error.message);
317
+ clearTimeout(timeout);
318
+ this.stream = null;
319
+ resolve();
320
+ });
321
+ this.stream.end(() => {
322
+ clearTimeout(timeout);
323
+ this.stream = null;
324
+ resolve();
325
+ });
326
+ });
327
+ }
328
+ /**
329
+ * Get current date string for file naming
330
+ * @llm-rule WHEN: Creating date-based file names
331
+ * @llm-rule AVOID: Custom date formats - YYYY-MM-DD is standard and sortable
332
+ */
333
+ getCurrentDate() {
334
+ const now = new Date();
335
+ return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
336
+ }
337
+ /**
338
+ * Get current log file path with date suffix
339
+ * @llm-rule WHEN: Determining where to write current logs
340
+ * @llm-rule AVOID: Hardcoded paths - use configurable directory and filename
341
+ */
342
+ getCurrentFilepath() {
343
+ const base = path.basename(this.filename, path.extname(this.filename));
344
+ const ext = path.extname(this.filename);
345
+ const filename = `${base}-${this.currentDate}${ext}`;
346
+ return path.join(this.dir, filename);
347
+ }
348
+ /**
349
+ * Ensure log directory exists
350
+ * @llm-rule WHEN: Transport initialization - creates directory if needed
351
+ * @llm-rule AVOID: Assuming directory exists - auto-creation prevents errors
352
+ */
353
+ ensureDirectoryExists() {
354
+ try {
355
+ if (!fs.existsSync(this.dir)) {
356
+ fs.mkdirSync(this.dir, { recursive: true });
357
+ }
358
+ }
359
+ catch (error) {
360
+ console.error('Error creating log directory:', error.message);
361
+ }
362
+ }
363
+ /**
364
+ * Setup automatic cleanup of old log files
365
+ * @llm-rule WHEN: Transport initialization - prevents disk space issues
366
+ * @llm-rule AVOID: Manual cleanup - automatic retention prevents disk overflow
367
+ */
368
+ setupRetentionCleanup() {
369
+ // Clean old logs immediately
370
+ this.cleanOldLogs();
371
+ // Setup daily cleanup interval
372
+ this.cleanupInterval = setInterval(() => {
373
+ this.cleanOldLogs();
374
+ }, 24 * 60 * 60 * 1000); // Daily
375
+ }
376
+ /**
377
+ * Clean old log files based on retention policy
378
+ * @llm-rule WHEN: Daily cleanup or transport initialization
379
+ * @llm-rule AVOID: Keeping logs forever - retention policy prevents disk issues
380
+ */
381
+ async cleanOldLogs() {
382
+ if (this.retentionDays <= 0)
383
+ return;
384
+ try {
385
+ const files = await fs.promises.readdir(this.dir);
386
+ const now = Date.now();
387
+ const maxAge = this.retentionDays * 24 * 60 * 60 * 1000;
388
+ const base = path.basename(this.filename, path.extname(this.filename));
389
+ for (const file of files) {
390
+ // Only clean files that match our log file pattern
391
+ if (!file.startsWith(base)) {
392
+ continue;
393
+ }
394
+ const filepath = path.join(this.dir, file);
395
+ try {
396
+ const stats = await fs.promises.stat(filepath);
397
+ if (now - stats.mtimeMs > maxAge) {
398
+ await fs.promises.unlink(filepath);
399
+ console.log(`Deleted old log file: ${file}`);
400
+ }
401
+ }
402
+ catch (error) {
403
+ console.error(`Error processing log file ${file}:`, error.message);
404
+ }
405
+ }
406
+ }
407
+ catch (error) {
408
+ console.error('Error cleaning old logs:', error.message);
409
+ }
410
+ }
411
+ /**
412
+ * Check if this transport should log the given level
413
+ * @llm-rule WHEN: Logger asks if transport handles this level
414
+ * @llm-rule AVOID: Complex level logic - simple comparison is sufficient
415
+ */
416
+ shouldLog(level, configLevel) {
417
+ const levels = {
418
+ error: 0, warn: 1, info: 2, debug: 3
419
+ };
420
+ return levels[level] <= levels[configLevel];
421
+ }
422
+ /**
423
+ * Flush pending logs to disk
424
+ * @llm-rule WHEN: App shutdown or ensuring logs are persisted
425
+ * @llm-rule AVOID: Frequent flushing - impacts performance
426
+ */
427
+ async flush() {
428
+ return new Promise((resolve) => {
429
+ if (!this.stream || !this.stream.writable) {
430
+ resolve();
431
+ return;
432
+ }
433
+ if (this.stream.writableLength === 0) {
434
+ resolve();
435
+ return;
436
+ }
437
+ const timeout = setTimeout(() => {
438
+ console.warn('File flush timed out after 5000ms');
439
+ resolve();
440
+ }, 5000);
441
+ this.stream.once('drain', () => {
442
+ clearTimeout(timeout);
443
+ resolve();
444
+ });
445
+ // Trigger drain event
446
+ this.stream.write('');
447
+ });
448
+ }
449
+ /**
450
+ * Close file transport and cleanup resources
451
+ * @llm-rule WHEN: App shutdown or logger cleanup
452
+ * @llm-rule AVOID: Abrupt shutdown - graceful close prevents data loss
453
+ */
454
+ async close() {
455
+ // Clear cleanup interval
456
+ if (this.cleanupInterval) {
457
+ clearInterval(this.cleanupInterval);
458
+ this.cleanupInterval = null;
459
+ }
460
+ // Close stream gracefully
461
+ await this.closeStream();
462
+ }
463
+ }
464
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/logger/transports/file.ts"],"names":[],"mappings":"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"}