prismcast 1.8.0 → 1.10.0

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 (392) hide show
  1. package/README.md +6 -6
  2. package/dist/app.d.ts +1 -1
  3. package/dist/app.js +41 -13
  4. package/dist/app.js.map +1 -1
  5. package/dist/browser/cdp.d.ts +4 -6
  6. package/dist/browser/cdp.js +18 -22
  7. package/dist/browser/cdp.js.map +1 -1
  8. package/dist/browser/channelSelection.d.ts +41 -11
  9. package/dist/browser/channelSelection.js +75 -24
  10. package/dist/browser/channelSelection.js.map +1 -1
  11. package/dist/browser/display.d.ts +1 -1
  12. package/dist/browser/index.d.ts +8 -8
  13. package/dist/browser/index.js +44 -45
  14. package/dist/browser/index.js.map +1 -1
  15. package/dist/browser/login.d.ts +2 -2
  16. package/dist/browser/login.js +1 -1
  17. package/dist/browser/manifestInterceptor.d.ts +77 -0
  18. package/dist/browser/manifestInterceptor.js +323 -0
  19. package/dist/browser/manifestInterceptor.js.map +1 -0
  20. package/dist/browser/precaching.d.ts +1 -1
  21. package/dist/browser/precaching.js +23 -23
  22. package/dist/browser/precaching.js.map +1 -1
  23. package/dist/browser/tuning/comcastPolymer.d.ts +1 -1
  24. package/dist/browser/tuning/cox.d.ts +1 -1
  25. package/dist/browser/tuning/directv.d.ts +1 -1
  26. package/dist/browser/tuning/directv.js +65 -69
  27. package/dist/browser/tuning/directv.js.map +1 -1
  28. package/dist/browser/tuning/fox.d.ts +1 -1
  29. package/dist/browser/tuning/fox.js +172 -15
  30. package/dist/browser/tuning/fox.js.map +1 -1
  31. package/dist/browser/tuning/hbo.d.ts +1 -1
  32. package/dist/browser/tuning/hbo.js +7 -7
  33. package/dist/browser/tuning/hbo.js.map +1 -1
  34. package/dist/browser/tuning/hulu.d.ts +1 -1
  35. package/dist/browser/tuning/hulu.js +120 -113
  36. package/dist/browser/tuning/hulu.js.map +1 -1
  37. package/dist/browser/tuning/shared.d.ts +3 -3
  38. package/dist/browser/tuning/shared.js +5 -5
  39. package/dist/browser/tuning/sling.d.ts +1 -1
  40. package/dist/browser/tuning/sling.js +30 -30
  41. package/dist/browser/tuning/sling.js.map +1 -1
  42. package/dist/browser/tuning/spectrum.d.ts +1 -1
  43. package/dist/browser/tuning/spectrum.js +21 -22
  44. package/dist/browser/tuning/spectrum.js.map +1 -1
  45. package/dist/browser/tuning/thumbnailRow.d.ts +1 -1
  46. package/dist/browser/tuning/thumbnailRow.js +1 -1
  47. package/dist/browser/tuning/tileClick.d.ts +1 -1
  48. package/dist/browser/tuning/tileClick.js +5 -5
  49. package/dist/browser/tuning/xfinity.d.ts +1 -1
  50. package/dist/browser/tuning/youtubeTv.d.ts +1 -1
  51. package/dist/browser/tuning/youtubeTv.js +17 -18
  52. package/dist/browser/tuning/youtubeTv.js.map +1 -1
  53. package/dist/browser/video.d.ts +20 -6
  54. package/dist/browser/video.js +30 -38
  55. package/dist/browser/video.js.map +1 -1
  56. package/dist/channels/index.d.ts +1 -2
  57. package/dist/channels/index.js +475 -442
  58. package/dist/channels/index.js.map +1 -1
  59. package/dist/config/channelForm.d.ts +58 -0
  60. package/dist/config/channelForm.js +129 -0
  61. package/dist/config/channelForm.js.map +1 -0
  62. package/dist/config/consistencyProbe.d.ts +7 -0
  63. package/dist/config/consistencyProbe.js +143 -0
  64. package/dist/config/consistencyProbe.js.map +1 -0
  65. package/dist/config/health.d.ts +7 -6
  66. package/dist/config/health.js +78 -65
  67. package/dist/config/health.js.map +1 -1
  68. package/dist/config/index.d.ts +1 -1
  69. package/dist/config/index.js +21 -14
  70. package/dist/config/index.js.map +1 -1
  71. package/dist/config/paths.d.ts +9 -3
  72. package/dist/config/paths.js +12 -4
  73. package/dist/config/paths.js.map +1 -1
  74. package/dist/config/persistence.context.d.ts +8 -0
  75. package/dist/config/persistence.context.js +30 -0
  76. package/dist/config/persistence.context.js.map +1 -0
  77. package/dist/config/persistence.d.ts +157 -0
  78. package/dist/config/persistence.js +446 -0
  79. package/dist/config/persistence.js.map +1 -0
  80. package/dist/config/presets.d.ts +14 -4
  81. package/dist/config/presets.js +84 -75
  82. package/dist/config/presets.js.map +1 -1
  83. package/dist/config/profiles.d.ts +2 -2
  84. package/dist/config/profiles.js +7 -9
  85. package/dist/config/profiles.js.map +1 -1
  86. package/dist/config/servicePacks.d.ts +46 -0
  87. package/dist/config/{providerPacks.js → servicePacks.js} +50 -53
  88. package/dist/config/servicePacks.js.map +1 -0
  89. package/dist/config/services.d.ts +228 -0
  90. package/dist/config/services.js +772 -0
  91. package/dist/config/services.js.map +1 -0
  92. package/dist/config/sites.d.ts +3 -3
  93. package/dist/config/sites.js +75 -75
  94. package/dist/config/sites.js.map +1 -1
  95. package/dist/config/userChannels.d.ts +522 -54
  96. package/dist/config/userChannels.js +1343 -366
  97. package/dist/config/userChannels.js.map +1 -1
  98. package/dist/config/userConfig.d.ts +108 -13
  99. package/dist/config/userConfig.js +296 -143
  100. package/dist/config/userConfig.js.map +1 -1
  101. package/dist/config/userProfiles.d.ts +34 -16
  102. package/dist/config/userProfiles.js +189 -100
  103. package/dist/config/userProfiles.js.map +1 -1
  104. package/dist/hdhr/channelMap.d.ts +1 -1
  105. package/dist/hdhr/channelMap.js +10 -16
  106. package/dist/hdhr/channelMap.js.map +1 -1
  107. package/dist/hdhr/deviceId.js +10 -9
  108. package/dist/hdhr/deviceId.js.map +1 -1
  109. package/dist/hdhr/discover.js +4 -5
  110. package/dist/hdhr/discover.js.map +1 -1
  111. package/dist/hdhr/index.js +12 -19
  112. package/dist/hdhr/index.js.map +1 -1
  113. package/dist/index.js +12 -12
  114. package/dist/index.js.map +1 -1
  115. package/dist/native/codecInference.d.ts +44 -0
  116. package/dist/native/codecInference.js +327 -0
  117. package/dist/native/codecInference.js.map +1 -0
  118. package/dist/native/decrypt.d.ts +1 -1
  119. package/dist/native/index.d.ts +5 -5
  120. package/dist/native/index.js +45 -67
  121. package/dist/native/index.js.map +1 -1
  122. package/dist/native/probe.d.ts +27 -9
  123. package/dist/native/probe.js +159 -68
  124. package/dist/native/probe.js.map +1 -1
  125. package/dist/native/proxy.d.ts +4 -2
  126. package/dist/native/proxy.js +56 -53
  127. package/dist/native/proxy.js.map +1 -1
  128. package/dist/native/tokenExpiry.d.ts +22 -0
  129. package/dist/native/tokenExpiry.js +153 -0
  130. package/dist/native/tokenExpiry.js.map +1 -0
  131. package/dist/routes/assets.js +3 -3
  132. package/dist/routes/assets.js.map +1 -1
  133. package/dist/routes/auth.js +9 -13
  134. package/dist/routes/auth.js.map +1 -1
  135. package/dist/routes/components.js +2 -2
  136. package/dist/routes/components.js.map +1 -1
  137. package/dist/routes/config/channels/endpoints/browse.d.ts +6 -0
  138. package/dist/routes/config/channels/endpoints/browse.js +195 -0
  139. package/dist/routes/config/channels/endpoints/browse.js.map +1 -0
  140. package/dist/routes/config/channels/endpoints/bulk.d.ts +6 -0
  141. package/dist/routes/config/channels/endpoints/bulk.js +128 -0
  142. package/dist/routes/config/channels/endpoints/bulk.js.map +1 -0
  143. package/dist/routes/config/channels/endpoints/crud.d.ts +6 -0
  144. package/dist/routes/config/channels/endpoints/crud.js +504 -0
  145. package/dist/routes/config/channels/endpoints/crud.js.map +1 -0
  146. package/dist/routes/config/channels/endpoints/importExport.d.ts +6 -0
  147. package/dist/routes/config/channels/endpoints/importExport.js +131 -0
  148. package/dist/routes/config/channels/endpoints/importExport.js.map +1 -0
  149. package/dist/routes/config/channels/endpoints/predefined.d.ts +6 -0
  150. package/dist/routes/config/channels/endpoints/predefined.js +78 -0
  151. package/dist/routes/config/channels/endpoints/predefined.js.map +1 -0
  152. package/dist/routes/config/channels/endpoints/prefs.d.ts +6 -0
  153. package/dist/routes/config/channels/endpoints/prefs.js +58 -0
  154. package/dist/routes/config/channels/endpoints/prefs.js.map +1 -0
  155. package/dist/routes/config/channels/endpoints/service.d.ts +6 -0
  156. package/dist/routes/config/channels/endpoints/service.js +149 -0
  157. package/dist/routes/config/channels/endpoints/service.js.map +1 -0
  158. package/dist/routes/config/channels/endpoints/tags.d.ts +6 -0
  159. package/dist/routes/config/channels/endpoints/tags.js +185 -0
  160. package/dist/routes/config/channels/endpoints/tags.js.map +1 -0
  161. package/dist/routes/config/channels/http/handler.d.ts +10 -0
  162. package/dist/routes/config/channels/http/handler.js +20 -0
  163. package/dist/routes/config/channels/http/handler.js.map +1 -0
  164. package/dist/routes/config/channels/http/playlistHint.d.ts +25 -0
  165. package/dist/routes/config/channels/http/playlistHint.js +40 -0
  166. package/dist/routes/config/channels/http/playlistHint.js.map +1 -0
  167. package/dist/routes/config/channels/http/serviceWarning.d.ts +10 -0
  168. package/dist/routes/config/channels/http/serviceWarning.js +28 -0
  169. package/dist/routes/config/channels/http/serviceWarning.js.map +1 -0
  170. package/dist/routes/config/channels/index.d.ts +3 -3
  171. package/dist/routes/config/channels/index.js +2 -2
  172. package/dist/routes/config/channels/index.js.map +1 -1
  173. package/dist/routes/config/channels/{routes.d.ts → setup.d.ts} +1 -1
  174. package/dist/routes/config/channels/setup.js +23 -0
  175. package/dist/routes/config/channels/setup.js.map +1 -0
  176. package/dist/routes/config/channels/table.d.ts +13 -13
  177. package/dist/routes/config/channels/table.js +291 -184
  178. package/dist/routes/config/channels/table.js.map +1 -1
  179. package/dist/routes/config/http/envelope.d.ts +111 -0
  180. package/dist/routes/config/http/envelope.js +103 -0
  181. package/dist/routes/config/http/envelope.js.map +1 -0
  182. package/dist/routes/config/index.d.ts +9 -9
  183. package/dist/routes/config/index.js +5 -5
  184. package/dist/routes/config/index.js.map +1 -1
  185. package/dist/routes/config/{providers.js → services.js} +105 -99
  186. package/dist/routes/config/services.js.map +1 -0
  187. package/dist/routes/config/settings.d.ts +1 -1
  188. package/dist/routes/config/settings.js +85 -60
  189. package/dist/routes/config/settings.js.map +1 -1
  190. package/dist/routes/debug.js +17 -18
  191. package/dist/routes/debug.js.map +1 -1
  192. package/dist/routes/health.js +1 -1
  193. package/dist/routes/health.js.map +1 -1
  194. package/dist/routes/icons.js +2 -2
  195. package/dist/routes/icons.js.map +1 -1
  196. package/dist/routes/index.js +2 -2
  197. package/dist/routes/index.js.map +1 -1
  198. package/dist/routes/logs.js +23 -34
  199. package/dist/routes/logs.js.map +1 -1
  200. package/dist/routes/mpegts.js +1 -1
  201. package/dist/routes/playlist.d.ts +5 -5
  202. package/dist/routes/playlist.js +84 -61
  203. package/dist/routes/playlist.js.map +1 -1
  204. package/dist/routes/root/content.js +82 -61
  205. package/dist/routes/root/content.js.map +1 -1
  206. package/dist/routes/root/index.js +2 -5
  207. package/dist/routes/root/index.js.map +1 -1
  208. package/dist/routes/root/scripts/channels.js +538 -581
  209. package/dist/routes/root/scripts/channels.js.map +1 -1
  210. package/dist/routes/root/scripts/config.js +868 -1022
  211. package/dist/routes/root/scripts/config.js.map +1 -1
  212. package/dist/routes/root/scripts/index.d.ts +4 -4
  213. package/dist/routes/root/scripts/shared.js +445 -197
  214. package/dist/routes/root/scripts/shared.js.map +1 -1
  215. package/dist/routes/root/scripts/status.d.ts +4 -0
  216. package/dist/routes/root/scripts/status.handlers.d.ts +182 -0
  217. package/dist/routes/root/scripts/status.handlers.js +713 -0
  218. package/dist/routes/root/scripts/status.handlers.js.map +1 -0
  219. package/dist/routes/root/scripts/status.js +85 -436
  220. package/dist/routes/root/scripts/status.js.map +1 -1
  221. package/dist/routes/root/styles.js +16 -8
  222. package/dist/routes/root/styles.js.map +1 -1
  223. package/dist/routes/services.d.ts +6 -0
  224. package/dist/routes/{providers.js → services.js} +58 -55
  225. package/dist/routes/services.js.map +1 -0
  226. package/dist/routes/sse.d.ts +16 -0
  227. package/dist/routes/sse.js +29 -0
  228. package/dist/routes/sse.js.map +1 -0
  229. package/dist/routes/streams.js +10 -23
  230. package/dist/routes/streams.js.map +1 -1
  231. package/dist/routes/ui.d.ts +2 -2
  232. package/dist/routes/ui.js +2 -0
  233. package/dist/routes/ui.js.map +1 -1
  234. package/dist/routes/upgrade.js +6 -7
  235. package/dist/routes/upgrade.js.map +1 -1
  236. package/dist/service/commands.context.d.ts +6 -0
  237. package/dist/service/commands.context.js +47 -0
  238. package/dist/service/commands.context.js.map +1 -0
  239. package/dist/service/commands.d.ts +53 -8
  240. package/dist/service/commands.js +172 -192
  241. package/dist/service/commands.js.map +1 -1
  242. package/dist/service/generators.context.d.ts +6 -0
  243. package/dist/service/generators.context.js +45 -0
  244. package/dist/service/generators.context.js.map +1 -0
  245. package/dist/service/generators.d.ts +56 -16
  246. package/dist/service/generators.js +509 -291
  247. package/dist/service/generators.js.map +1 -1
  248. package/dist/service/index.d.ts +2 -2
  249. package/dist/streaming/clients.d.ts +2 -2
  250. package/dist/streaming/clients.js +2 -2
  251. package/dist/streaming/codec.d.ts +2 -2
  252. package/dist/streaming/codec.js +0 -1
  253. package/dist/streaming/codec.js.map +1 -1
  254. package/dist/streaming/fmp4Segmenter.d.ts +2 -2
  255. package/dist/streaming/fmp4Segmenter.js +12 -12
  256. package/dist/streaming/hls.d.ts +7 -7
  257. package/dist/streaming/hls.js +104 -92
  258. package/dist/streaming/hls.js.map +1 -1
  259. package/dist/streaming/hlsResume.d.ts +3 -3
  260. package/dist/streaming/hlsResume.js +6 -6
  261. package/dist/streaming/hlsResume.js.map +1 -1
  262. package/dist/streaming/hlsSegments.d.ts +5 -2
  263. package/dist/streaming/hlsSegments.js +14 -9
  264. package/dist/streaming/hlsSegments.js.map +1 -1
  265. package/dist/streaming/monitor.d.ts +12 -12
  266. package/dist/streaming/monitor.js +98 -66
  267. package/dist/streaming/monitor.js.map +1 -1
  268. package/dist/streaming/mp4Parser.d.ts +34 -4
  269. package/dist/streaming/mp4Parser.js +111 -29
  270. package/dist/streaming/mp4Parser.js.map +1 -1
  271. package/dist/streaming/mpegts.d.ts +1 -1
  272. package/dist/streaming/mpegts.js +13 -10
  273. package/dist/streaming/mpegts.js.map +1 -1
  274. package/dist/streaming/playlistBuilder.d.ts +1 -1
  275. package/dist/streaming/playlistBuilder.js +2 -2
  276. package/dist/streaming/preroll.d.ts +9 -9
  277. package/dist/streaming/preroll.js +40 -42
  278. package/dist/streaming/preroll.js.map +1 -1
  279. package/dist/streaming/pretune.js +4 -4
  280. package/dist/streaming/pretune.js.map +1 -1
  281. package/dist/streaming/recovery.d.ts +3 -3
  282. package/dist/streaming/recovery.js +4 -4
  283. package/dist/streaming/registry.d.ts +6 -6
  284. package/dist/streaming/registry.js +4 -8
  285. package/dist/streaming/registry.js.map +1 -1
  286. package/dist/streaming/setup.d.ts +11 -10
  287. package/dist/streaming/setup.js +120 -71
  288. package/dist/streaming/setup.js.map +1 -1
  289. package/dist/streaming/showInfo.d.ts +9 -3
  290. package/dist/streaming/showInfo.js +33 -27
  291. package/dist/streaming/showInfo.js.map +1 -1
  292. package/dist/streaming/statusEmitter.d.ts +8 -7
  293. package/dist/streaming/statusEmitter.js +5 -5
  294. package/dist/streaming/statusEmitter.js.map +1 -1
  295. package/dist/types/channels.d.ts +139 -36
  296. package/dist/types/channels.js +39 -1
  297. package/dist/types/channels.js.map +1 -1
  298. package/dist/types/config.d.ts +22 -3
  299. package/dist/types/index.d.ts +9 -8
  300. package/dist/types/index.js +1 -0
  301. package/dist/types/index.js.map +1 -1
  302. package/dist/types/profiles.d.ts +14 -13
  303. package/dist/types/selection.d.ts +49 -5
  304. package/dist/types/shared.d.ts +1 -1
  305. package/dist/types/streaming.d.ts +2 -2
  306. package/dist/upgrade/commands.context.d.ts +6 -0
  307. package/dist/upgrade/commands.context.js +29 -0
  308. package/dist/upgrade/commands.context.js.map +1 -0
  309. package/dist/upgrade/commands.d.ts +29 -2
  310. package/dist/upgrade/commands.js +87 -134
  311. package/dist/upgrade/commands.js.map +1 -1
  312. package/dist/upgrade/detection.context.d.ts +6 -0
  313. package/dist/upgrade/detection.context.js +24 -0
  314. package/dist/upgrade/detection.context.js.map +1 -0
  315. package/dist/upgrade/detection.d.ts +140 -10
  316. package/dist/upgrade/detection.js +153 -66
  317. package/dist/upgrade/detection.js.map +1 -1
  318. package/dist/upgrade/index.d.ts +2 -2
  319. package/dist/utils/chromeFetch.d.ts +1 -1
  320. package/dist/utils/chromeFetch.js +2 -2
  321. package/dist/utils/clock.d.ts +14 -0
  322. package/dist/utils/clock.js +28 -0
  323. package/dist/utils/clock.js.map +1 -0
  324. package/dist/utils/debugFilter.d.ts +1 -1
  325. package/dist/utils/debugFilter.js +8 -6
  326. package/dist/utils/debugFilter.js.map +1 -1
  327. package/dist/utils/delay.d.ts +2 -3
  328. package/dist/utils/delay.js +10 -16
  329. package/dist/utils/delay.js.map +1 -1
  330. package/dist/utils/evaluate.js +12 -14
  331. package/dist/utils/evaluate.js.map +1 -1
  332. package/dist/utils/ffmpeg.context.d.ts +6 -0
  333. package/dist/utils/ffmpeg.context.js +31 -0
  334. package/dist/utils/ffmpeg.context.js.map +1 -0
  335. package/dist/utils/ffmpeg.d.ts +85 -29
  336. package/dist/utils/ffmpeg.js +126 -129
  337. package/dist/utils/ffmpeg.js.map +1 -1
  338. package/dist/utils/fileLogger.d.ts +18 -2
  339. package/dist/utils/fileLogger.js +60 -31
  340. package/dist/utils/fileLogger.js.map +1 -1
  341. package/dist/utils/format.d.ts +7 -1
  342. package/dist/utils/format.js +22 -2
  343. package/dist/utils/format.js.map +1 -1
  344. package/dist/utils/html.js +1 -3
  345. package/dist/utils/html.js.map +1 -1
  346. package/dist/utils/index.d.ts +21 -20
  347. package/dist/utils/index.js +1 -0
  348. package/dist/utils/index.js.map +1 -1
  349. package/dist/utils/logger.js +31 -45
  350. package/dist/utils/logger.js.map +1 -1
  351. package/dist/utils/m3u.d.ts +18 -3
  352. package/dist/utils/m3u.js +28 -14
  353. package/dist/utils/m3u.js.map +1 -1
  354. package/dist/utils/memo.d.ts +19 -0
  355. package/dist/utils/memo.js +53 -0
  356. package/dist/utils/memo.js.map +1 -0
  357. package/dist/utils/morganStream.js +4 -4
  358. package/dist/utils/morganStream.js.map +1 -1
  359. package/dist/utils/pid.d.ts +2 -2
  360. package/dist/utils/pid.js +2 -2
  361. package/dist/utils/platform.d.ts +1 -1
  362. package/dist/utils/platform.js +3 -2
  363. package/dist/utils/platform.js.map +1 -1
  364. package/dist/utils/retry.d.ts +2 -0
  365. package/dist/utils/retry.js +9 -7
  366. package/dist/utils/retry.js.map +1 -1
  367. package/dist/utils/sanitize.d.ts +2 -2
  368. package/dist/utils/sanitize.js +4 -4
  369. package/dist/utils/streamContext.d.ts +7 -0
  370. package/dist/utils/streamContext.js +10 -1
  371. package/dist/utils/streamContext.js.map +1 -1
  372. package/dist/utils/timing.d.ts +6 -3
  373. package/dist/utils/timing.js +10 -6
  374. package/dist/utils/timing.js.map +1 -1
  375. package/dist/utils/version.d.ts +3 -2
  376. package/dist/utils/version.js +15 -28
  377. package/dist/utils/version.js.map +1 -1
  378. package/package.json +14 -10
  379. package/dist/config/providerPacks.d.ts +0 -46
  380. package/dist/config/providerPacks.js.map +0 -1
  381. package/dist/config/providers.d.ts +0 -175
  382. package/dist/config/providers.js +0 -691
  383. package/dist/config/providers.js.map +0 -1
  384. package/dist/native/intercept.d.ts +0 -35
  385. package/dist/native/intercept.js +0 -184
  386. package/dist/native/intercept.js.map +0 -1
  387. package/dist/routes/config/channels/routes.js +0 -1477
  388. package/dist/routes/config/channels/routes.js.map +0 -1
  389. package/dist/routes/config/providers.js.map +0 -1
  390. package/dist/routes/providers.d.ts +0 -6
  391. package/dist/routes/providers.js.map +0 -1
  392. /package/dist/routes/config/{providers.d.ts → services.d.ts} +0 -0
@@ -1,7 +1,8 @@
1
- import df from "dateformat";
1
+ import { formatTimestamp } from "./format.js";
2
2
  import fs from "node:fs";
3
3
  import { isAnyDebugEnabled } from "./debugFilter.js";
4
4
  import path from "node:path";
5
+ import { styleText } from "node:util";
5
6
  const { promises: fsPromises } = fs;
6
7
  /* The file logger provides persistent logging to a configurable log file with automatic size-based trimming. When the log file exceeds the configured maximum
7
8
  * size, it is trimmed to half the maximum size, keeping only complete lines (the most recent logs are preserved). This approach prevents unbounded log growth while
@@ -12,7 +13,11 @@ const { promises: fsPromises } = fs;
12
13
  * 1. Asynchronous buffered writes - Logs are collected in a buffer and flushed periodically to avoid blocking the event loop during high-frequency logging.
13
14
  * 2. Periodic size checking - File size is checked every N writes rather than on each write to minimize syscall overhead.
14
15
  * 3. Atomic trim operations - Trimming writes to a temp file then renames, preventing data loss if the process crashes during trim.
15
- * 4. Timestamps - Uses the same format as console-stamp for consistency: yyyy/mm/dd HH:MM:ss.l
16
+ * 4. Timestamps - Delegates to formatTimestamp() in utils/format.ts, which emits yyyy/mm/dd hh:mm:ss.mmm AM/PM. The same helper feeds the console method
17
+ * wrappers in app.ts and the Morgan HTTP request logger, so file, console, and request logs share identical timestamps.
18
+ * 5. Terminal coloring - SGR escape codes are baked into the file output via styleText so that viewing the log with terminal commands (tail -f, less -R, cat)
19
+ * shows the same color scheme as console output. styleText emits both the opening color code and the trailing reset in one call, with validateStream disabled
20
+ * because the log file is not a TTY but we still want the codes preserved for downstream terminal viewers.
16
21
  */
17
22
  /* The file logger maintains state for the log file path, write buffer, and size tracking. State is initialized when initializeFileLogger() is called during server
18
23
  * startup.
@@ -42,10 +47,6 @@ const FLUSH_INTERVAL_MS = 1000;
42
47
  const SIZE_CHECK_FREQUENCY = 100;
43
48
  // Duration in milliseconds to disable logging after a write error before retrying.
44
49
  const ERROR_RETRY_DELAY_MS = 60000;
45
- /* Terminal color codes for log file output. These match the colors used in console mode so that viewing the log file with terminal commands (tail -f, less -R, cat)
46
- * shows the same color scheme as console output.
47
- */
48
- const ANSI_RESET = "\x1b[0m";
49
50
  // Initialization.
50
51
  /**
51
52
  * Initializes the file logger. Creates the log file if it does not exist. Must be called after the data directory is ensured to exist.
@@ -90,7 +91,7 @@ export async function initializeFileLogger(logPath, maxSize) {
90
91
  * Writes a log entry to the buffer. Entries are flushed to disk periodically.
91
92
  * @param level - Log level ("info", "warn", "error", "debug").
92
93
  * @param message - The formatted log message.
93
- * @param color - Optional ANSI color code to apply to the level prefix and message.
94
+ * @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
94
95
  * @param categoryTag - Optional debug category tag (e.g., "recovery:tab"). Appended to the level prefix as [DEBUG:category].
95
96
  */
96
97
  export function writeLogEntry(level, message, color, categoryTag) {
@@ -105,13 +106,13 @@ export function writeLogEntry(level, message, color, categoryTag) {
105
106
  // Re-enable logging and try again.
106
107
  isDisabled = false;
107
108
  }
108
- // Format the log entry with timestamp and level. Apply ANSI color if provided.
109
- const timestamp = df(new Date(), "yyyy/mm/dd HH:MM:ss.l");
109
+ // Format the log entry with timestamp and level. See the file's design block for the rationale behind baking SGR codes into the file output.
110
+ const timestamp = formatTimestamp();
110
111
  const levelTag = categoryTag ? [level.toUpperCase(), ":", categoryTag].join("") : level.toUpperCase();
111
112
  const levelPrefix = (level === "info") ? "" : ["[", levelTag, "] "].join("");
112
- const colorStart = color ?? "";
113
- const colorEnd = color ? ANSI_RESET : "";
114
- const entry = ["[", timestamp, "] ", colorStart, levelPrefix, message, colorEnd, "\n"].join("");
113
+ const body = levelPrefix + message;
114
+ const coloredBody = color ? styleText(color, body, { validateStream: false }) : body;
115
+ const entry = ["[", timestamp, "] ", coloredBody, "\n"].join("");
115
116
  // Add to buffer.
116
117
  writeBuffer.push(entry);
117
118
  approximateSize += entry.length;
@@ -174,7 +175,7 @@ async function checkAndTrimFile() {
174
175
  try {
175
176
  const stats = await fsPromises.stat(logFilePath);
176
177
  approximateSize = stats.size;
177
- // Skip trimming when debug logging is active. Debug sessions generate high-volume output that is valuable for diagnosis — trimming mid-session would discard
178
+ // Skip trimming when debug logging is active. Debug sessions generate high-volume output that is valuable for diagnosis - trimming mid-session would discard
178
179
  // the very data we are trying to capture.
179
180
  if ((approximateSize > maxLogSize) && !isAnyDebugEnabled()) {
180
181
  await trimLogFile();
@@ -191,7 +192,42 @@ async function checkAndTrimFile() {
191
192
  }
192
193
  }
193
194
  /**
194
- * Trims the log file to half the maximum size, keeping only complete lines. The most recent logs are preserved.
195
+ * Pure trim logic: given the current log file content and the configured maximum size, returns the trimmed content (keeping complete lines from the file's tail)
196
+ * or null when no trim is needed (file is already at or below half maxSize). Extracted from trimLogFile so the cut-at-newline algorithm is testable in isolation
197
+ * without orchestrating real filesystem I/O - the surrounding read/write/rename chain is small enough to be exercised at the integration level.
198
+ *
199
+ * Algorithm: target half of maxSize as the post-trim file size, cut from (content.length - targetSize), then advance to the next newline so the trimmed file
200
+ * begins on a complete line. If no newline exists past the cut, the cut position is taken as-is (the trim still drops earlier content even if the kept tail is
201
+ * a single fragment line).
202
+ *
203
+ * @param content - The current log file content as a UTF-8 string.
204
+ * @param maxSize - The configured maximum log file size in bytes.
205
+ * @returns The trimmed content, or null when no trim is needed.
206
+ */
207
+ export function computeTrimmedLogContent(content, maxSize) {
208
+ // Calculate target size (half of max).
209
+ const targetSize = Math.floor(maxSize / 2);
210
+ // We want to keep the END of the file (most recent logs). Find where to cut.
211
+ const cutPosition = content.length - targetSize;
212
+ if (cutPosition <= 0) {
213
+ // File is smaller than target, no trimming needed.
214
+ return null;
215
+ }
216
+ // Find the next newline after the cut position to keep complete lines.
217
+ let lineStart = content.indexOf("\n", cutPosition);
218
+ if (lineStart === -1) {
219
+ // No newline found after cut position, keep from cut position.
220
+ lineStart = cutPosition;
221
+ }
222
+ else {
223
+ // Start after the newline.
224
+ lineStart += 1;
225
+ }
226
+ return content.substring(lineStart);
227
+ }
228
+ /**
229
+ * Trims the log file to half the maximum size, keeping only complete lines. The most recent logs are preserved. Pure cut logic lives in
230
+ * computeTrimmedLogContent; this function is the I/O orchestration shell around it.
195
231
  */
196
232
  async function trimLogFile() {
197
233
  if (!logFilePath) {
@@ -199,25 +235,10 @@ async function trimLogFile() {
199
235
  }
200
236
  try {
201
237
  const content = await fsPromises.readFile(logFilePath, "utf-8");
202
- // Calculate target size (half of max).
203
- const targetSize = Math.floor(maxLogSize / 2);
204
- // We want to keep the END of the file (most recent logs). Find where to cut.
205
- const cutPosition = content.length - targetSize;
206
- if (cutPosition <= 0) {
207
- // File is smaller than target, no trimming needed.
238
+ const trimmedContent = computeTrimmedLogContent(content, maxLogSize);
239
+ if (trimmedContent === null) {
208
240
  return;
209
241
  }
210
- // Find the next newline after the cut position to keep complete lines.
211
- let lineStart = content.indexOf("\n", cutPosition);
212
- if (lineStart === -1) {
213
- // No newline found after cut position, keep from cut position.
214
- lineStart = cutPosition;
215
- }
216
- else {
217
- // Start after the newline.
218
- lineStart += 1;
219
- }
220
- const trimmedContent = content.substring(lineStart);
221
242
  // Write to temp file, then rename (atomic replace).
222
243
  const tempPath = logFilePath + ".tmp";
223
244
  await fsPromises.writeFile(tempPath, trimmedContent, "utf-8");
@@ -245,6 +266,14 @@ export function shutdownFileLogger() {
245
266
  }
246
267
  // Flush remaining buffer synchronously.
247
268
  flushLogBufferSync();
269
+ // Reset all module state so a subsequent initializeFileLogger() starts from a clean slate. The disabled-on-write-error flag in particular must not survive
270
+ // shutdown - if a prior run hit a write failure and entered the 60-second retry window, that window should not silently drop writes from the next run.
248
271
  isInitialized = false;
272
+ isDisabled = false;
273
+ disabledAt = 0;
274
+ writeBuffer = [];
275
+ approximateSize = 0;
276
+ writeCount = 0;
277
+ logFilePath = null;
249
278
  }
250
279
  //# sourceMappingURL=fileLogger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileLogger.js","sourceRoot":"","sources":["../../src/utils/fileLogger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fileLogger.js","sourceRoot":"","sources":["../../src/utils/fileLogger.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Formats the current date and time as a log timestamp string: `yyyy/mm/dd hh:mm:ss.mmm AM/PM`. Uses 12-hour time with decimalized seconds and AM/PM.
3
+ * Single source of truth for all log timestamp formatting - used by the console wrapper in app.ts, the file logger, and the Morgan HTTP request logger.
4
+ * @returns Formatted timestamp string.
5
+ */
6
+ export declare function formatTimestamp(): string;
1
7
  /**
2
8
  * Formats a duration as a human-readable string. The format varies based on duration length:
3
9
  * - Less than 60 seconds: "17s"
@@ -19,7 +25,7 @@ export declare function formatDuration(value: number, unit?: "ms" | "s"): string
19
25
  export declare function formatTimeAgo(timestamp: number): string;
20
26
  /**
21
27
  * Extracts a concise domain from a URL by keeping only the last two portions of the hostname (e.g., "watch.foodnetwork.com" becomes "foodnetwork.com",
22
- * "www.hulu.com" becomes "hulu.com"). Used as a standard domain key for DOMAIN_CONFIG lookups and as a display fallback when no provider name is configured.
28
+ * "www.hulu.com" becomes "hulu.com"). Used as a standard domain key for DOMAIN_CONFIG lookups and as a display fallback when no service name is configured.
23
29
  * @param url - The URL to extract the domain from.
24
30
  * @returns The concise domain, or the original URL if parsing fails.
25
31
  */
@@ -2,6 +2,26 @@
2
2
  *
3
3
  * format.ts: Formatting utilities for PrismCast.
4
4
  */
5
+ /**
6
+ * Formats the current date and time as a log timestamp string: `yyyy/mm/dd hh:mm:ss.mmm AM/PM`. Uses 12-hour time with decimalized seconds and AM/PM.
7
+ * Single source of truth for all log timestamp formatting - used by the console wrapper in app.ts, the file logger, and the Morgan HTTP request logger.
8
+ * @returns Formatted timestamp string.
9
+ */
10
+ export function formatTimestamp() {
11
+ const now = new Date();
12
+ const yyyy = String(now.getFullYear());
13
+ const mm = String(now.getMonth() + 1).padStart(2, "0");
14
+ const dd = String(now.getDate()).padStart(2, "0");
15
+ let hours = now.getHours();
16
+ const ampm = (hours >= 12) ? "PM" : "AM";
17
+ hours = hours % 12;
18
+ hours ||= 12;
19
+ const hh = String(hours).padStart(2, "0");
20
+ const min = String(now.getMinutes()).padStart(2, "0");
21
+ const ss = String(now.getSeconds()).padStart(2, "0");
22
+ const ms = String(now.getMilliseconds()).padStart(3, "0");
23
+ return yyyy + "/" + mm + "/" + dd + " " + hh + ":" + min + ":" + ss + "." + ms + " " + ampm;
24
+ }
5
25
  /**
6
26
  * Formats a duration as a human-readable string. The format varies based on duration length:
7
27
  * - Less than 60 seconds: "17s"
@@ -50,7 +70,7 @@ export function formatTimeAgo(timestamp) {
50
70
  }
51
71
  /**
52
72
  * Extracts a concise domain from a URL by keeping only the last two portions of the hostname (e.g., "watch.foodnetwork.com" becomes "foodnetwork.com",
53
- * "www.hulu.com" becomes "hulu.com"). Used as a standard domain key for DOMAIN_CONFIG lookups and as a display fallback when no provider name is configured.
73
+ * "www.hulu.com" becomes "hulu.com"). Used as a standard domain key for DOMAIN_CONFIG lookups and as a display fallback when no service name is configured.
54
74
  * @param url - The URL to extract the domain from.
55
75
  * @returns The concise domain, or the original URL if parsing fails.
56
76
  */
@@ -86,7 +106,7 @@ export function capitalize(str) {
86
106
  export function stringifySorted(data, indent = 2) {
87
107
  return JSON.stringify(data, (_key, value) => {
88
108
  if (value && (typeof value === "object") && !Array.isArray(value)) {
89
- return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
109
+ return Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)));
90
110
  }
91
111
  return value;
92
112
  }, indent);
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"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"}
@@ -17,8 +17,6 @@ export function escapeHtml(text) {
17
17
  "<": "&lt;",
18
18
  ">": "&gt;"
19
19
  };
20
- return text.replace(/[&<>"']/g, (char) => {
21
- return replacements[char];
22
- });
20
+ return text.replace(/[&<>"']/g, (char) => replacements[char] ?? char);
23
21
  }
24
22
  //# sourceMappingURL=html.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;GACG;AAEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IAErC,MAAM,YAAY,GAA2B;QAE3C,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,MAAM;KACZ,CAAC;IAEF,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;QAEvC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;GACG;AAEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IAErC,MAAM,YAAY,GAA2B;QAE3C,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,MAAM;KACZ,CAAC;IAEF,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AACxE,CAAC"}
@@ -1,20 +1,21 @@
1
- export * from "./chromeFetch.js";
2
- export * from "./cliOutput.js";
3
- export * from "./debugFilter.js";
4
- export * from "./delay.js";
5
- export * from "./errors.js";
6
- export * from "./evaluate.js";
7
- export * from "./ffmpeg.js";
8
- export * from "./format.js";
9
- export * from "./html.js";
10
- export * from "./logEmitter.js";
11
- export * from "./logger.js";
12
- export * from "./m3u.js";
13
- export * from "./morganStream.js";
14
- export * from "./pid.js";
15
- export * from "./platform.js";
16
- export * from "./retry.js";
17
- export * from "./sanitize.js";
18
- export * from "./streamContext.js";
19
- export * from "./timing.js";
20
- export * from "./version.js";
1
+ export * from "./chromeFetch.ts";
2
+ export * from "./cliOutput.ts";
3
+ export * from "./clock.ts";
4
+ export * from "./debugFilter.ts";
5
+ export * from "./delay.ts";
6
+ export * from "./errors.ts";
7
+ export * from "./evaluate.ts";
8
+ export * from "./ffmpeg.ts";
9
+ export * from "./format.ts";
10
+ export * from "./html.ts";
11
+ export * from "./logEmitter.ts";
12
+ export * from "./logger.ts";
13
+ export * from "./m3u.ts";
14
+ export * from "./morganStream.ts";
15
+ export * from "./pid.ts";
16
+ export * from "./platform.ts";
17
+ export * from "./retry.ts";
18
+ export * from "./sanitize.ts";
19
+ export * from "./streamContext.ts";
20
+ export * from "./timing.ts";
21
+ export * from "./version.ts";
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export * from "./chromeFetch.js";
6
6
  export * from "./cliOutput.js";
7
+ export * from "./clock.js";
7
8
  export * from "./debugFilter.js";
8
9
  export * from "./delay.js";
9
10
  export * from "./errors.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
@@ -2,20 +2,15 @@
2
2
  *
3
3
  * logger.ts: Logging utilities with color-coded output for PrismCast.
4
4
  */
5
+ import { format, styleText } from "node:util";
6
+ import { getStreamId, resolveContextShowName } from "./streamContext.js";
5
7
  import { initDebugFilter, isAnyDebugEnabled, isCategoryEnabled } from "./debugFilter.js";
6
8
  import { emitLogEntry } from "./logEmitter.js";
7
- import { format } from "util";
8
- import { getStreamId } from "./streamContext.js";
9
+ import { formatTimestamp } from "./format.js";
9
10
  import { writeLogEntry } from "./fileLogger.js";
10
- /* Terminal color codes for log output formatting. Warnings appear in yellow and errors in red, making it easy to spot issues when scanning log output. The reset
11
- * code restores the default color after each colored message to prevent color bleeding into subsequent output.
11
+ /* Terminal color choices for log output. Warnings appear in yellow and errors in red, making it easy to spot issues when scanning log output. Coloring is delegated
12
+ * to node:util.styleText so the SGR sequences are managed by the platform rather than hand-written escape codes.
12
13
  */
13
- const ANSI_COLORS = {
14
- cyan: "\x1b[36m",
15
- red: "\x1b[31m",
16
- reset: "\x1b[0m",
17
- yellow: "\x1b[33m"
18
- };
19
14
  /* The logger can operate in two modes: console mode (output to stdout/stderr with colors) or file mode (output to the configured log file). By default, file mode
20
15
  * is used. Console mode is enabled via the --console CLI flag for Docker deployments or interactive debugging.
21
16
  */
@@ -60,21 +55,6 @@ export function isDebugLogging() {
60
55
  *
61
56
  * For logging outside a stream context (e.g., iterating over streams in a disconnect handler), use LOG.withStreamId() to create a bound logger.
62
57
  */
63
- /**
64
- * Formats the current time as a timestamp string matching the log file format.
65
- * @returns A timestamp string in the format "YYYY/MM/DD HH:MM:ss.lll".
66
- */
67
- function formatTimestamp() {
68
- const now = new Date();
69
- const year = now.getFullYear();
70
- const month = String(now.getMonth() + 1).padStart(2, "0");
71
- const day = String(now.getDate()).padStart(2, "0");
72
- const hours = String(now.getHours()).padStart(2, "0");
73
- const minutes = String(now.getMinutes()).padStart(2, "0");
74
- const seconds = String(now.getSeconds()).padStart(2, "0");
75
- const ms = String(now.getMilliseconds()).padStart(3, "0");
76
- return [year, "/", month, "/", day, " ", hours, ":", minutes, ":", seconds, ".", ms].join("");
77
- }
78
58
  /**
79
59
  * Emits a log entry to SSE subscribers for real-time streaming.
80
60
  * @param level - The log level.
@@ -95,7 +75,7 @@ function emitToSubscribers(level, message, categoryTag) {
95
75
  /**
96
76
  * Core logging implementation shared by all log levels. Handles stream ID prefixing, SSE emission, and output routing.
97
77
  * @param level - The log level (error, warn, info, debug).
98
- * @param color - ANSI color code for console output (empty string for no color).
78
+ * @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
99
79
  * @param message - The format string.
100
80
  * @param args - Format arguments.
101
81
  * @param explicitStreamId - Optional explicit stream ID (used by withStreamId helper).
@@ -104,7 +84,17 @@ function emitToSubscribers(level, message, categoryTag) {
104
84
  function logWithLevel(level, color, message, args, explicitStreamId, categoryTag) {
105
85
  const streamId = explicitStreamId ?? getStreamId();
106
86
  const formatted = args.length > 0 ? format(message, ...args) : message;
107
- const logMessage = streamId ? ["[", streamId, "] ", formatted].join("") : formatted;
87
+ // Build the log prefix. Stream ID is always included when available. The show name (resolved lazily from the stream context) is appended when present,
88
+ // giving log readers immediate context for correlating issues with DVR recordings without cross-referencing timestamps against the guide.
89
+ let logMessage;
90
+ if (streamId) {
91
+ const showName = explicitStreamId ? "" : resolveContextShowName();
92
+ const showPrefix = showName ? " [" + showName + "]" : "";
93
+ logMessage = "[" + streamId + "]" + showPrefix + " " + formatted;
94
+ }
95
+ else {
96
+ logMessage = formatted;
97
+ }
108
98
  // Emit to SSE subscribers for real-time streaming.
109
99
  emitToSubscribers(level, logMessage, categoryTag);
110
100
  if (useConsoleLogging) {
@@ -125,21 +115,17 @@ function logWithLevel(level, color, message, args, explicitStreamId, categoryTag
125
115
  }
126
116
  }
127
117
  /* eslint-enable no-console */
128
- if (streamId && color) {
129
- consoleMethod("%s[%s] %s%s", color, streamId, formatted, ANSI_COLORS.reset);
130
- }
131
- else if (streamId) {
132
- consoleMethod("[%s] %s", streamId, formatted);
133
- }
134
- else if (color) {
135
- consoleMethod("%s%s%s", color, formatted, ANSI_COLORS.reset);
118
+ if (color) {
119
+ // styleText emits both the SGR opening code and the trailing reset, so callers do not need to manage the reset themselves. We disable validateStream because
120
+ // we want colors regardless of TTY detection - downstream consumers (Docker log drivers, file viewers with -R) handle the codes correctly.
121
+ consoleMethod(styleText(color, logMessage, { validateStream: false }));
136
122
  }
137
123
  else {
138
- consoleMethod(formatted);
124
+ consoleMethod(logMessage);
139
125
  }
140
126
  }
141
127
  else {
142
- writeLogEntry(level, logMessage, color || undefined, categoryTag);
128
+ writeLogEntry(level, logMessage, color, categoryTag);
143
129
  }
144
130
  }
145
131
  export const LOG = {
@@ -156,7 +142,7 @@ export const LOG = {
156
142
  if (!isAnyDebugEnabled() || !isCategoryEnabled(category)) {
157
143
  return;
158
144
  }
159
- logWithLevel("debug", ANSI_COLORS.cyan, message, args, undefined, category);
145
+ logWithLevel("debug", "cyan", message, args, undefined, category);
160
146
  },
161
147
  /**
162
148
  * Logs an error message in red. Use this for critical failures that prevent normal operation, such as browser crashes, navigation failures after all retries, or
@@ -167,7 +153,7 @@ export const LOG = {
167
153
  * @param args - Values to interpolate into the format string.
168
154
  */
169
155
  error: function (message, ...args) {
170
- logWithLevel("error", ANSI_COLORS.red, message, args);
156
+ logWithLevel("error", "red", message, args);
171
157
  },
172
158
  /**
173
159
  * Logs an informational message in the default terminal color. Use this for normal operational messages like startup notifications, successful operations, and
@@ -178,7 +164,7 @@ export const LOG = {
178
164
  * @param args - Values to interpolate into the format string.
179
165
  */
180
166
  info: function (message, ...args) {
181
- logWithLevel("info", "", message, args);
167
+ logWithLevel("info", null, message, args);
182
168
  },
183
169
  /**
184
170
  * Logs a warning message in yellow. Use this for non-critical issues that do not prevent operation but indicate potential problems, such as timeouts that were
@@ -189,7 +175,7 @@ export const LOG = {
189
175
  * @param args - Values to interpolate into the format string.
190
176
  */
191
177
  warn: function (message, ...args) {
192
- logWithLevel("warn", ANSI_COLORS.yellow, message, args);
178
+ logWithLevel("warn", "yellow", message, args);
193
179
  },
194
180
  /**
195
181
  * Creates a bound logger with a fixed stream ID. Use this when logging about a stream from outside its async context, such as when iterating over multiple streams
@@ -207,12 +193,12 @@ export const LOG = {
207
193
  return {
208
194
  debug: (category, message, ...args) => {
209
195
  if (isAnyDebugEnabled() && isCategoryEnabled(category)) {
210
- logWithLevel("debug", ANSI_COLORS.cyan, message, args, streamId, category);
196
+ logWithLevel("debug", "cyan", message, args, streamId, category);
211
197
  }
212
198
  },
213
- error: (message, ...args) => { logWithLevel("error", ANSI_COLORS.red, message, args, streamId); },
214
- info: (message, ...args) => { logWithLevel("info", "", message, args, streamId); },
215
- warn: (message, ...args) => { logWithLevel("warn", ANSI_COLORS.yellow, message, args, streamId); }
199
+ error: (message, ...args) => { logWithLevel("error", "red", message, args, streamId); },
200
+ info: (message, ...args) => { logWithLevel("info", null, message, args, streamId); },
201
+ warn: (message, ...args) => { logWithLevel("warn", "yellow", message, args, streamId); }
216
202
  };
217
203
  }
218
204
  };
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Escapes a string for safe inclusion as an M3U quoted attribute value (the `value` portion of `attribute="value"`). RFC 8216 section 4.2 forbids the
3
+ * double-quote character (the attribute terminator) and bare line feed / carriage return inside a quoted-string and defines no escape sequence; the de-facto
4
+ * extended-M3U convention used by VLC, IPTV-Org tooling, and downstream consumers is backslash-escaping. We backslash-escape the structural characters and
5
+ * replace literal CR/LF with a single space - there is no portable escape sequence for line breaks inside a quoted-string, and dropping the line break entirely
6
+ * would silently glue adjacent words together while leaving the attribute syntactically valid. Apply this helper at every M3U attribute write site that flows
7
+ * user-controlled content; structurally server-controlled values (validated channel keys, numeric fields, fixed literals) do not need it but pass through
8
+ * unchanged when wrapped, so prefer wrapping for uniformity.
9
+ *
10
+ * Order matters: the backslash replacement runs first so the backslashes we introduce when escaping double-quote do not get re-escaped by a second pass.
11
+ *
12
+ * @param value - The raw string to escape.
13
+ * @returns A string safe to embed between the surrounding double-quotes of an M3U attribute value.
14
+ */
15
+ export declare function escapeM3uAttribute(value: string): string;
1
16
  /**
2
17
  * Represents a channel parsed from an M3U playlist.
3
18
  */
@@ -19,9 +34,9 @@ export interface M3UParseResult {
19
34
  * @returns A lowercase, hyphen-separated key suitable for URLs.
20
35
  *
21
36
  * Examples:
22
- * - "CNN Live!" → "cnn-live"
23
- * - "BBC News 24/7" → "bbc-news-247"
24
- * - " Spaces Everywhere " → "spaces-everywhere"
37
+ * - "CNN Live!" -> "cnn-live"
38
+ * - "BBC News 24/7" -> "bbc-news-247"
39
+ * - " Spaces Everywhere " -> "spaces-everywhere"
25
40
  */
26
41
  export declare function generateChannelKey(name: string): string;
27
42
  /**