apitally 0.25.7 → 1.0.0-alpha.1

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 (549) hide show
  1. package/README.md +191 -184
  2. package/dist/activation.cjs +371 -0
  3. package/dist/activation.cjs.map +1 -0
  4. package/dist/activation.d.cts +41 -0
  5. package/dist/activation.d.ts +41 -0
  6. package/dist/activation.js +357 -0
  7. package/dist/activation.js.map +1 -0
  8. package/dist/adonisjs/configure.cjs +88 -31
  9. package/dist/adonisjs/configure.cjs.map +1 -1
  10. package/dist/adonisjs/configure.d.cts +0 -4
  11. package/dist/adonisjs/configure.d.ts +0 -4
  12. package/dist/adonisjs/configure.js +85 -30
  13. package/dist/adonisjs/configure.js.map +1 -1
  14. package/dist/adonisjs/index.cjs +4 -23
  15. package/dist/adonisjs/index.cjs.map +1 -1
  16. package/dist/adonisjs/index.d.cts +3 -15
  17. package/dist/adonisjs/index.d.ts +3 -15
  18. package/dist/adonisjs/index.js +3 -20
  19. package/dist/adonisjs/index.js.map +1 -1
  20. package/dist/adonisjs/middleware.cjs +43 -109
  21. package/dist/adonisjs/middleware.cjs.map +1 -1
  22. package/dist/adonisjs/middleware.d.cts +1 -16
  23. package/dist/adonisjs/middleware.d.ts +1 -16
  24. package/dist/adonisjs/middleware.js +43 -110
  25. package/dist/adonisjs/middleware.js.map +1 -1
  26. package/dist/adonisjs/provider.cjs +19 -87
  27. package/dist/adonisjs/provider.cjs.map +1 -1
  28. package/dist/adonisjs/provider.d.cts +0 -22
  29. package/dist/adonisjs/provider.d.ts +0 -22
  30. package/dist/adonisjs/provider.js +19 -88
  31. package/dist/adonisjs/provider.js.map +1 -1
  32. package/dist/adonisjs/stubs/config/apitally.stub +11 -15
  33. package/dist/bodyCapture.cjs +128 -0
  34. package/dist/bodyCapture.cjs.map +1 -0
  35. package/dist/bodyCapture.d.cts +31 -0
  36. package/dist/bodyCapture.d.ts +31 -0
  37. package/dist/bodyCapture.js +101 -0
  38. package/dist/bodyCapture.js.map +1 -0
  39. package/dist/config.cjs +209 -0
  40. package/dist/config.cjs.map +1 -0
  41. package/dist/config.d.cts +42 -0
  42. package/dist/config.d.ts +42 -0
  43. package/dist/config.js +174 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/consumer.cjs +98 -0
  46. package/dist/consumer.cjs.map +1 -0
  47. package/dist/consumer.d.cts +13 -0
  48. package/dist/consumer.d.ts +13 -0
  49. package/dist/consumer.js +78 -0
  50. package/dist/consumer.js.map +1 -0
  51. package/dist/context.cjs +68 -0
  52. package/dist/context.cjs.map +1 -0
  53. package/dist/context.d.cts +29 -0
  54. package/dist/context.d.ts +29 -0
  55. package/dist/context.js +40 -0
  56. package/dist/context.js.map +1 -0
  57. package/dist/elysia/index.cjs +12 -13
  58. package/dist/elysia/index.cjs.map +1 -1
  59. package/dist/elysia/index.d.cts +7 -16
  60. package/dist/elysia/index.d.ts +7 -16
  61. package/dist/elysia/index.js +10 -2
  62. package/dist/elysia/index.js.map +1 -1
  63. package/dist/elysia/middleware.cjs +248 -0
  64. package/dist/elysia/middleware.cjs.map +1 -0
  65. package/dist/elysia/middleware.d.cts +13 -0
  66. package/dist/elysia/middleware.d.ts +13 -0
  67. package/dist/elysia/middleware.js +237 -0
  68. package/dist/elysia/middleware.js.map +1 -0
  69. package/dist/{loggers/index.cjs → elysia/routes.cjs} +16 -19
  70. package/dist/elysia/routes.cjs.map +1 -0
  71. package/dist/elysia/routes.d.cts +7 -0
  72. package/dist/elysia/routes.d.ts +7 -0
  73. package/dist/elysia/routes.js +14 -0
  74. package/dist/elysia/routes.js.map +1 -0
  75. package/dist/exceptions.cjs +75 -0
  76. package/dist/exceptions.cjs.map +1 -0
  77. package/dist/exceptions.d.cts +7 -0
  78. package/dist/exceptions.d.ts +7 -0
  79. package/dist/exceptions.js +49 -0
  80. package/dist/exceptions.js.map +1 -0
  81. package/dist/exportSerialization.cjs +56 -0
  82. package/dist/exportSerialization.cjs.map +1 -0
  83. package/dist/exportSerialization.d.cts +7 -0
  84. package/dist/exportSerialization.d.ts +7 -0
  85. package/dist/exportSerialization.js +32 -0
  86. package/dist/exportSerialization.js.map +1 -0
  87. package/dist/exportWorker.cjs +305 -0
  88. package/dist/exportWorker.cjs.map +1 -0
  89. package/dist/exportWorker.d.cts +46 -0
  90. package/dist/exportWorker.d.ts +46 -0
  91. package/dist/exportWorker.js +279 -0
  92. package/dist/exportWorker.js.map +1 -0
  93. package/dist/express/index.cjs +9 -4
  94. package/dist/express/index.cjs.map +1 -1
  95. package/dist/express/index.d.cts +6 -10
  96. package/dist/express/index.d.ts +6 -10
  97. package/dist/express/index.js +8 -2
  98. package/dist/express/index.js.map +1 -1
  99. package/dist/express/install.cjs +45 -0
  100. package/dist/express/install.cjs.map +1 -0
  101. package/dist/express/install.d.cts +9 -0
  102. package/dist/express/install.d.ts +9 -0
  103. package/dist/express/install.js +21 -0
  104. package/dist/express/install.js.map +1 -0
  105. package/dist/express/middleware.cjs +80 -331
  106. package/dist/express/middleware.cjs.map +1 -1
  107. package/dist/express/middleware.d.cts +3 -21
  108. package/dist/express/middleware.d.ts +3 -21
  109. package/dist/express/middleware.js +81 -328
  110. package/dist/express/middleware.js.map +1 -1
  111. package/dist/express/register.cjs +20 -0
  112. package/dist/express/register.cjs.map +1 -0
  113. package/dist/express/register.d.cts +2 -0
  114. package/dist/express/register.d.ts +2 -0
  115. package/dist/express/register.js +19 -0
  116. package/dist/express/register.js.map +1 -0
  117. package/dist/express/routes.cjs +419 -0
  118. package/dist/express/routes.cjs.map +1 -0
  119. package/dist/express/routes.d.cts +14 -0
  120. package/dist/express/routes.d.ts +14 -0
  121. package/dist/express/routes.js +391 -0
  122. package/dist/express/routes.js.map +1 -0
  123. package/dist/fastify/index.cjs +10 -15
  124. package/dist/fastify/index.cjs.map +1 -1
  125. package/dist/fastify/index.d.cts +6 -11
  126. package/dist/fastify/index.d.ts +6 -11
  127. package/dist/fastify/index.js +9 -3
  128. package/dist/fastify/index.js.map +1 -1
  129. package/dist/{common/logging.cjs → fastify/install.cjs} +15 -16
  130. package/dist/fastify/install.cjs.map +1 -0
  131. package/dist/fastify/install.d.cts +9 -0
  132. package/dist/fastify/install.d.ts +9 -0
  133. package/dist/fastify/install.js +15 -0
  134. package/dist/fastify/install.js.map +1 -0
  135. package/dist/fastify/middleware.cjs +118 -0
  136. package/dist/fastify/middleware.cjs.map +1 -0
  137. package/dist/fastify/middleware.d.cts +7 -0
  138. package/dist/fastify/middleware.d.ts +7 -0
  139. package/dist/fastify/middleware.js +97 -0
  140. package/dist/fastify/middleware.js.map +1 -0
  141. package/dist/{common/paramValidation.cjs → fastify/routes.cjs} +15 -17
  142. package/dist/fastify/routes.cjs.map +1 -0
  143. package/dist/fastify/routes.d.cts +8 -0
  144. package/dist/fastify/routes.d.ts +8 -0
  145. package/dist/fastify/routes.js +14 -0
  146. package/dist/fastify/routes.js.map +1 -0
  147. package/dist/h3/index.cjs +28 -4
  148. package/dist/h3/index.cjs.map +1 -1
  149. package/dist/h3/index.d.cts +7 -10
  150. package/dist/h3/index.d.ts +7 -10
  151. package/dist/h3/index.js +26 -2
  152. package/dist/h3/index.js.map +1 -1
  153. package/dist/h3/middleware.cjs +204 -0
  154. package/dist/h3/middleware.cjs.map +1 -0
  155. package/dist/h3/middleware.d.cts +5 -0
  156. package/dist/h3/middleware.d.ts +5 -0
  157. package/dist/h3/middleware.js +188 -0
  158. package/dist/h3/middleware.js.map +1 -0
  159. package/dist/h3/routes.cjs +66 -0
  160. package/dist/h3/routes.cjs.map +1 -0
  161. package/dist/h3/routes.d.cts +8 -0
  162. package/dist/h3/routes.d.ts +8 -0
  163. package/dist/h3/routes.js +41 -0
  164. package/dist/h3/routes.js.map +1 -0
  165. package/dist/hapi/index.cjs +15 -14
  166. package/dist/hapi/index.cjs.map +1 -1
  167. package/dist/hapi/index.d.cts +7 -10
  168. package/dist/hapi/index.d.ts +7 -10
  169. package/dist/hapi/index.js +14 -3
  170. package/dist/hapi/index.js.map +1 -1
  171. package/dist/{loggers/hapi.cjs → hapi/install.cjs} +20 -26
  172. package/dist/hapi/install.cjs.map +1 -0
  173. package/dist/hapi/install.d.cts +7 -0
  174. package/dist/hapi/install.d.ts +7 -0
  175. package/dist/hapi/install.js +22 -0
  176. package/dist/hapi/install.js.map +1 -0
  177. package/dist/hapi/middleware.cjs +158 -0
  178. package/dist/hapi/middleware.cjs.map +1 -0
  179. package/dist/hapi/middleware.d.cts +5 -0
  180. package/dist/hapi/middleware.d.ts +5 -0
  181. package/dist/hapi/middleware.js +137 -0
  182. package/dist/hapi/middleware.js.map +1 -0
  183. package/dist/hapi/routes.cjs +37 -0
  184. package/dist/hapi/routes.cjs.map +1 -0
  185. package/dist/hapi/routes.d.cts +8 -0
  186. package/dist/hapi/routes.d.ts +8 -0
  187. package/dist/hapi/routes.js +12 -0
  188. package/dist/hapi/routes.js.map +1 -0
  189. package/dist/hono/index.cjs +13 -3
  190. package/dist/hono/index.cjs.map +1 -1
  191. package/dist/hono/index.d.cts +6 -10
  192. package/dist/hono/index.d.ts +6 -10
  193. package/dist/hono/index.js +13 -2
  194. package/dist/hono/index.js.map +1 -1
  195. package/dist/hono/middleware.cjs +211 -127
  196. package/dist/hono/middleware.cjs.map +1 -1
  197. package/dist/hono/middleware.d.cts +3 -18
  198. package/dist/hono/middleware.d.ts +3 -18
  199. package/dist/hono/middleware.js +216 -125
  200. package/dist/hono/middleware.js.map +1 -1
  201. package/dist/hono/routes.cjs +74 -0
  202. package/dist/hono/routes.cjs.map +1 -0
  203. package/dist/hono/routes.d.cts +8 -0
  204. package/dist/hono/routes.d.ts +8 -0
  205. package/dist/hono/routes.js +49 -0
  206. package/dist/hono/routes.js.map +1 -0
  207. package/dist/index.cjs +108 -0
  208. package/dist/index.cjs.map +1 -1
  209. package/dist/index.d.cts +28 -1
  210. package/dist/index.d.ts +28 -1
  211. package/dist/index.js +77 -0
  212. package/dist/index.js.map +1 -1
  213. package/dist/koa/index.cjs +13 -3
  214. package/dist/koa/index.cjs.map +1 -1
  215. package/dist/koa/index.d.cts +6 -10
  216. package/dist/koa/index.d.ts +6 -10
  217. package/dist/koa/index.js +13 -2
  218. package/dist/koa/index.js.map +1 -1
  219. package/dist/koa/middleware.cjs +75 -184
  220. package/dist/koa/middleware.cjs.map +1 -1
  221. package/dist/koa/middleware.d.cts +3 -13
  222. package/dist/koa/middleware.d.ts +3 -13
  223. package/dist/koa/middleware.js +78 -183
  224. package/dist/koa/middleware.js.map +1 -1
  225. package/dist/koa/routes.cjs +71 -0
  226. package/dist/koa/routes.cjs.map +1 -0
  227. package/dist/koa/routes.d.cts +8 -0
  228. package/dist/koa/routes.d.ts +8 -0
  229. package/dist/koa/routes.js +46 -0
  230. package/dist/koa/routes.js.map +1 -0
  231. package/dist/logCapture.cjs +410 -0
  232. package/dist/logCapture.cjs.map +1 -0
  233. package/dist/logCapture.d.cts +16 -0
  234. package/dist/logCapture.d.ts +16 -0
  235. package/dist/logCapture.js +383 -0
  236. package/dist/logCapture.js.map +1 -0
  237. package/dist/logRecordExporter.cjs +83 -0
  238. package/dist/logRecordExporter.cjs.map +1 -0
  239. package/dist/logRecordExporter.d.cts +14 -0
  240. package/dist/logRecordExporter.d.ts +14 -0
  241. package/dist/logRecordExporter.js +59 -0
  242. package/dist/logRecordExporter.js.map +1 -0
  243. package/dist/logRecordProcessor.cjs +120 -0
  244. package/dist/logRecordProcessor.cjs.map +1 -0
  245. package/dist/logRecordProcessor.d.cts +23 -0
  246. package/dist/logRecordProcessor.d.ts +23 -0
  247. package/dist/logRecordProcessor.js +96 -0
  248. package/dist/logRecordProcessor.js.map +1 -0
  249. package/dist/{otel/index.cjs → logRecordTruncation.cjs} +10 -7
  250. package/dist/logRecordTruncation.cjs.map +1 -0
  251. package/dist/logRecordTruncation.d.cts +6 -0
  252. package/dist/logRecordTruncation.d.ts +6 -0
  253. package/dist/logRecordTruncation.js +8 -0
  254. package/dist/logRecordTruncation.js.map +1 -0
  255. package/dist/logger.cjs +62 -0
  256. package/dist/logger.cjs.map +1 -0
  257. package/dist/logger.d.cts +7 -0
  258. package/dist/logger.d.ts +7 -0
  259. package/dist/logger.js +34 -0
  260. package/dist/logger.js.map +1 -0
  261. package/dist/metrics.cjs +171 -0
  262. package/dist/metrics.cjs.map +1 -0
  263. package/dist/metrics.d.cts +24 -0
  264. package/dist/metrics.d.ts +24 -0
  265. package/dist/metrics.js +153 -0
  266. package/dist/metrics.js.map +1 -0
  267. package/dist/nestjs/index.cjs +61 -71
  268. package/dist/nestjs/index.cjs.map +1 -1
  269. package/dist/nestjs/index.d.cts +3 -11
  270. package/dist/nestjs/index.d.ts +3 -11
  271. package/dist/nestjs/index.js +61 -61
  272. package/dist/nestjs/index.js.map +1 -1
  273. package/dist/packageVersion.cjs +67 -0
  274. package/dist/packageVersion.cjs.map +1 -0
  275. package/dist/packageVersion.d.cts +5 -0
  276. package/dist/packageVersion.d.ts +5 -0
  277. package/dist/packageVersion.js +39 -0
  278. package/dist/packageVersion.js.map +1 -0
  279. package/dist/providers.cjs +149 -0
  280. package/dist/providers.cjs.map +1 -0
  281. package/dist/providers.d.cts +15 -0
  282. package/dist/providers.d.ts +15 -0
  283. package/dist/providers.js +136 -0
  284. package/dist/providers.js.map +1 -0
  285. package/dist/redaction.cjs +116 -0
  286. package/dist/redaction.cjs.map +1 -0
  287. package/dist/redaction.d.cts +17 -0
  288. package/dist/redaction.d.ts +17 -0
  289. package/dist/redaction.js +98 -0
  290. package/dist/redaction.js.map +1 -0
  291. package/dist/{common/packageVersions.cjs → requestAttributes.cjs} +21 -19
  292. package/dist/requestAttributes.cjs.map +1 -0
  293. package/dist/requestAttributes.d.cts +8 -0
  294. package/dist/requestAttributes.d.ts +8 -0
  295. package/dist/requestAttributes.js +22 -0
  296. package/dist/requestAttributes.js.map +1 -0
  297. package/dist/requestObservation.cjs +228 -0
  298. package/dist/requestObservation.cjs.map +1 -0
  299. package/dist/requestObservation.d.cts +60 -0
  300. package/dist/requestObservation.d.ts +60 -0
  301. package/dist/requestObservation.js +208 -0
  302. package/dist/requestObservation.js.map +1 -0
  303. package/dist/requestObservationNode.cjs +193 -0
  304. package/dist/requestObservationNode.cjs.map +1 -0
  305. package/dist/requestObservationNode.d.cts +29 -0
  306. package/dist/requestObservationNode.d.ts +29 -0
  307. package/dist/requestObservationNode.js +170 -0
  308. package/dist/requestObservationNode.js.map +1 -0
  309. package/dist/requestObservationWeb.cjs +202 -0
  310. package/dist/requestObservationWeb.cjs.map +1 -0
  311. package/dist/requestObservationWeb.d.cts +32 -0
  312. package/dist/requestObservationWeb.d.ts +32 -0
  313. package/dist/requestObservationWeb.js +182 -0
  314. package/dist/requestObservationWeb.js.map +1 -0
  315. package/dist/sentry.cjs +103 -0
  316. package/dist/sentry.cjs.map +1 -0
  317. package/dist/sentry.d.cts +3 -0
  318. package/dist/sentry.d.ts +3 -0
  319. package/dist/sentry.js +79 -0
  320. package/dist/sentry.js.map +1 -0
  321. package/dist/spanExporter.cjs +218 -0
  322. package/dist/spanExporter.cjs.map +1 -0
  323. package/dist/spanExporter.d.cts +33 -0
  324. package/dist/spanExporter.d.ts +33 -0
  325. package/dist/spanExporter.js +194 -0
  326. package/dist/spanExporter.js.map +1 -0
  327. package/dist/spanProcessor.cjs +523 -0
  328. package/dist/spanProcessor.cjs.map +1 -0
  329. package/dist/spanProcessor.d.cts +67 -0
  330. package/dist/spanProcessor.d.ts +67 -0
  331. package/dist/spanProcessor.js +501 -0
  332. package/dist/spanProcessor.js.map +1 -0
  333. package/dist/spool.cjs +314 -0
  334. package/dist/spool.cjs.map +1 -0
  335. package/dist/spool.d.cts +49 -0
  336. package/dist/spool.d.ts +49 -0
  337. package/dist/spool.js +297 -0
  338. package/dist/spool.js.map +1 -0
  339. package/dist/startup.cjs +93 -0
  340. package/dist/startup.cjs.map +1 -0
  341. package/dist/startup.d.cts +15 -0
  342. package/dist/startup.d.ts +15 -0
  343. package/dist/startup.js +68 -0
  344. package/dist/startup.js.map +1 -0
  345. package/dist/tracing.cjs +116 -0
  346. package/dist/tracing.cjs.map +1 -0
  347. package/dist/tracing.d.cts +5 -0
  348. package/dist/tracing.d.ts +5 -0
  349. package/dist/tracing.js +96 -0
  350. package/dist/tracing.js.map +1 -0
  351. package/package.json +113 -155
  352. package/dist/common/client.cjs +0 -335
  353. package/dist/common/client.cjs.map +0 -1
  354. package/dist/common/client.d.cts +0 -50
  355. package/dist/common/client.d.ts +0 -50
  356. package/dist/common/client.js +0 -302
  357. package/dist/common/client.js.map +0 -1
  358. package/dist/common/consumerRegistry.cjs +0 -84
  359. package/dist/common/consumerRegistry.cjs.map +0 -1
  360. package/dist/common/consumerRegistry.d.cts +0 -20
  361. package/dist/common/consumerRegistry.d.ts +0 -20
  362. package/dist/common/consumerRegistry.js +0 -61
  363. package/dist/common/consumerRegistry.js.map +0 -1
  364. package/dist/common/headers.cjs +0 -55
  365. package/dist/common/headers.cjs.map +0 -1
  366. package/dist/common/headers.d.cts +0 -6
  367. package/dist/common/headers.d.ts +0 -6
  368. package/dist/common/headers.js +0 -31
  369. package/dist/common/headers.js.map +0 -1
  370. package/dist/common/instance.cjs +0 -158
  371. package/dist/common/instance.cjs.map +0 -1
  372. package/dist/common/instance.d.cts +0 -4
  373. package/dist/common/instance.d.ts +0 -4
  374. package/dist/common/instance.js +0 -134
  375. package/dist/common/instance.js.map +0 -1
  376. package/dist/common/logging.cjs.map +0 -1
  377. package/dist/common/logging.d.cts +0 -11
  378. package/dist/common/logging.d.ts +0 -11
  379. package/dist/common/logging.js +0 -17
  380. package/dist/common/logging.js.map +0 -1
  381. package/dist/common/packageVersions.cjs.map +0 -1
  382. package/dist/common/packageVersions.d.cts +0 -3
  383. package/dist/common/packageVersions.d.ts +0 -3
  384. package/dist/common/packageVersions.js +0 -21
  385. package/dist/common/packageVersions.js.map +0 -1
  386. package/dist/common/paramValidation.cjs.map +0 -1
  387. package/dist/common/paramValidation.d.cts +0 -4
  388. package/dist/common/paramValidation.d.ts +0 -4
  389. package/dist/common/paramValidation.js +0 -17
  390. package/dist/common/paramValidation.js.map +0 -1
  391. package/dist/common/requestCounter.cjs +0 -109
  392. package/dist/common/requestCounter.cjs.map +0 -1
  393. package/dist/common/requestCounter.d.cts +0 -24
  394. package/dist/common/requestCounter.d.ts +0 -24
  395. package/dist/common/requestCounter.js +0 -90
  396. package/dist/common/requestCounter.js.map +0 -1
  397. package/dist/common/requestLogger.cjs +0 -541
  398. package/dist/common/requestLogger.cjs.map +0 -1
  399. package/dist/common/requestLogger.d.cts +0 -85
  400. package/dist/common/requestLogger.d.ts +0 -85
  401. package/dist/common/requestLogger.js +0 -507
  402. package/dist/common/requestLogger.js.map +0 -1
  403. package/dist/common/resources.cjs +0 -49
  404. package/dist/common/resources.cjs.map +0 -1
  405. package/dist/common/resources.d.cts +0 -6
  406. package/dist/common/resources.d.ts +0 -6
  407. package/dist/common/resources.js +0 -26
  408. package/dist/common/resources.js.map +0 -1
  409. package/dist/common/response.cjs +0 -104
  410. package/dist/common/response.cjs.map +0 -1
  411. package/dist/common/response.d.cts +0 -15
  412. package/dist/common/response.d.ts +0 -15
  413. package/dist/common/response.js +0 -80
  414. package/dist/common/response.js.map +0 -1
  415. package/dist/common/sentry.cjs +0 -56
  416. package/dist/common/sentry.cjs.map +0 -1
  417. package/dist/common/sentry.d.cts +0 -6
  418. package/dist/common/sentry.d.ts +0 -6
  419. package/dist/common/sentry.js +0 -23
  420. package/dist/common/sentry.js.map +0 -1
  421. package/dist/common/serverErrorCounter.cjs +0 -121
  422. package/dist/common/serverErrorCounter.cjs.map +0 -1
  423. package/dist/common/serverErrorCounter.d.cts +0 -23
  424. package/dist/common/serverErrorCounter.d.ts +0 -23
  425. package/dist/common/serverErrorCounter.js +0 -97
  426. package/dist/common/serverErrorCounter.js.map +0 -1
  427. package/dist/common/spanCollector.cjs +0 -199
  428. package/dist/common/spanCollector.cjs.map +0 -1
  429. package/dist/common/spanCollector.d.cts +0 -45
  430. package/dist/common/spanCollector.d.ts +0 -45
  431. package/dist/common/spanCollector.js +0 -176
  432. package/dist/common/spanCollector.js.map +0 -1
  433. package/dist/common/tempGzipFile.cjs +0 -125
  434. package/dist/common/tempGzipFile.cjs.map +0 -1
  435. package/dist/common/tempGzipFile.d.cts +0 -19
  436. package/dist/common/tempGzipFile.d.ts +0 -19
  437. package/dist/common/tempGzipFile.js +0 -102
  438. package/dist/common/tempGzipFile.js.map +0 -1
  439. package/dist/common/types.cjs +0 -17
  440. package/dist/common/types.cjs.map +0 -1
  441. package/dist/common/types.d.cts +0 -95
  442. package/dist/common/types.d.ts +0 -95
  443. package/dist/common/types.js +0 -1
  444. package/dist/common/types.js.map +0 -1
  445. package/dist/common/validationErrorCounter.cjs +0 -74
  446. package/dist/common/validationErrorCounter.cjs.map +0 -1
  447. package/dist/common/validationErrorCounter.d.cts +0 -20
  448. package/dist/common/validationErrorCounter.d.ts +0 -20
  449. package/dist/common/validationErrorCounter.js +0 -55
  450. package/dist/common/validationErrorCounter.js.map +0 -1
  451. package/dist/elysia/plugin.cjs +0 -237
  452. package/dist/elysia/plugin.cjs.map +0 -1
  453. package/dist/elysia/plugin.d.cts +0 -70
  454. package/dist/elysia/plugin.d.ts +0 -70
  455. package/dist/elysia/plugin.js +0 -218
  456. package/dist/elysia/plugin.js.map +0 -1
  457. package/dist/elysia/utils.cjs +0 -77
  458. package/dist/elysia/utils.cjs.map +0 -1
  459. package/dist/elysia/utils.d.cts +0 -14
  460. package/dist/elysia/utils.d.ts +0 -14
  461. package/dist/elysia/utils.js +0 -54
  462. package/dist/elysia/utils.js.map +0 -1
  463. package/dist/express/utils.cjs +0 -217
  464. package/dist/express/utils.cjs.map +0 -1
  465. package/dist/express/utils.d.cts +0 -37
  466. package/dist/express/utils.d.ts +0 -37
  467. package/dist/express/utils.js +0 -189
  468. package/dist/express/utils.js.map +0 -1
  469. package/dist/fastify/plugin.cjs +0 -316
  470. package/dist/fastify/plugin.cjs.map +0 -1
  471. package/dist/fastify/plugin.d.cts +0 -34
  472. package/dist/fastify/plugin.d.ts +0 -34
  473. package/dist/fastify/plugin.js +0 -282
  474. package/dist/fastify/plugin.js.map +0 -1
  475. package/dist/h3/plugin.cjs +0 -183
  476. package/dist/h3/plugin.cjs.map +0 -1
  477. package/dist/h3/plugin.d.cts +0 -27
  478. package/dist/h3/plugin.d.ts +0 -27
  479. package/dist/h3/plugin.js +0 -159
  480. package/dist/h3/plugin.js.map +0 -1
  481. package/dist/h3/utils.cjs +0 -77
  482. package/dist/h3/utils.cjs.map +0 -1
  483. package/dist/h3/utils.d.cts +0 -14
  484. package/dist/h3/utils.d.ts +0 -14
  485. package/dist/h3/utils.js +0 -54
  486. package/dist/h3/utils.js.map +0 -1
  487. package/dist/hapi/plugin.cjs +0 -210
  488. package/dist/hapi/plugin.cjs.map +0 -1
  489. package/dist/hapi/plugin.d.cts +0 -40
  490. package/dist/hapi/plugin.d.ts +0 -40
  491. package/dist/hapi/plugin.js +0 -187
  492. package/dist/hapi/plugin.js.map +0 -1
  493. package/dist/hapi/utils.cjs +0 -77
  494. package/dist/hapi/utils.cjs.map +0 -1
  495. package/dist/hapi/utils.d.cts +0 -16
  496. package/dist/hapi/utils.d.ts +0 -16
  497. package/dist/hapi/utils.js +0 -53
  498. package/dist/hapi/utils.js.map +0 -1
  499. package/dist/hono/utils.cjs +0 -113
  500. package/dist/hono/utils.cjs.map +0 -1
  501. package/dist/hono/utils.d.cts +0 -16
  502. package/dist/hono/utils.d.ts +0 -16
  503. package/dist/hono/utils.js +0 -88
  504. package/dist/hono/utils.js.map +0 -1
  505. package/dist/loggers/console.cjs +0 -67
  506. package/dist/loggers/console.cjs.map +0 -1
  507. package/dist/loggers/console.d.cts +0 -11
  508. package/dist/loggers/console.d.ts +0 -11
  509. package/dist/loggers/console.js +0 -44
  510. package/dist/loggers/console.js.map +0 -1
  511. package/dist/loggers/hapi.cjs.map +0 -1
  512. package/dist/loggers/hapi.d.cts +0 -12
  513. package/dist/loggers/hapi.d.ts +0 -12
  514. package/dist/loggers/hapi.js +0 -29
  515. package/dist/loggers/hapi.js.map +0 -1
  516. package/dist/loggers/index.cjs.map +0 -1
  517. package/dist/loggers/index.d.cts +0 -13
  518. package/dist/loggers/index.d.ts +0 -13
  519. package/dist/loggers/index.js +0 -13
  520. package/dist/loggers/index.js.map +0 -1
  521. package/dist/loggers/nestjs.cjs +0 -104
  522. package/dist/loggers/nestjs.cjs.map +0 -1
  523. package/dist/loggers/nestjs.d.cts +0 -11
  524. package/dist/loggers/nestjs.d.ts +0 -11
  525. package/dist/loggers/nestjs.js +0 -71
  526. package/dist/loggers/nestjs.js.map +0 -1
  527. package/dist/loggers/pino.cjs +0 -152
  528. package/dist/loggers/pino.cjs.map +0 -1
  529. package/dist/loggers/pino.d.cts +0 -11
  530. package/dist/loggers/pino.d.ts +0 -11
  531. package/dist/loggers/pino.js +0 -119
  532. package/dist/loggers/pino.js.map +0 -1
  533. package/dist/loggers/utils.cjs +0 -64
  534. package/dist/loggers/utils.cjs.map +0 -1
  535. package/dist/loggers/utils.d.cts +0 -6
  536. package/dist/loggers/utils.d.ts +0 -6
  537. package/dist/loggers/utils.js +0 -40
  538. package/dist/loggers/utils.js.map +0 -1
  539. package/dist/loggers/winston.cjs +0 -101
  540. package/dist/loggers/winston.cjs.map +0 -1
  541. package/dist/loggers/winston.d.cts +0 -11
  542. package/dist/loggers/winston.d.ts +0 -11
  543. package/dist/loggers/winston.js +0 -68
  544. package/dist/loggers/winston.js.map +0 -1
  545. package/dist/otel/index.cjs.map +0 -1
  546. package/dist/otel/index.d.cts +0 -2
  547. package/dist/otel/index.d.ts +0 -2
  548. package/dist/otel/index.js +0 -5
  549. package/dist/otel/index.js.map +0 -1
package/dist/spool.js ADDED
@@ -0,0 +1,297 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import {
3
+ createWriteStream,
4
+ openSync,
5
+ readdirSync,
6
+ statSync,
7
+ unlinkSync,
8
+ utimesSync,
9
+ writeFileSync
10
+ } from "node:fs";
11
+ import { readFile, unlink } from "node:fs/promises";
12
+ import { tmpdir } from "node:os";
13
+ import { join } from "node:path";
14
+ import { createGzip } from "node:zlib";
15
+ import { logWarning, resetWarning } from "./logger.js";
16
+ const WRITE_FAILURE_WARNING = "Error writing to disk, dropping buffered telemetry";
17
+ const SIGNALS = ["traces", "logs", "metrics"];
18
+ const MAX_UNCOMPRESSED_FILE_SIZE = 4e6;
19
+ const MAX_RETRY_TIME_AFTER_FIRST_ATTEMPT_MILLIS = 59 * 60 * 1e3;
20
+ const MAX_SPOOL_SIZE_DISK = 5e7;
21
+ const MAX_SPOOL_SIZE_MEMORY = 1e7;
22
+ const MAX_UNTOUCHED_FILE_AGE_MILLIS = 2 * 60 * 60 * 1e3;
23
+ const SPOOL_FILE_NAME_PATTERN = /^apitally-.*\.gz$/;
24
+ class Spool {
25
+ inMemory;
26
+ maxSize;
27
+ current = /* @__PURE__ */ new Map();
28
+ closed = [];
29
+ tempDir;
30
+ queues = {
31
+ traces: Promise.resolve(),
32
+ logs: Promise.resolve(),
33
+ metrics: Promise.resolve()
34
+ };
35
+ constructor(tempDir = tmpdir()) {
36
+ this.tempDir = tempDir;
37
+ this.inMemory = !isTempDirWritable(tempDir);
38
+ if (this.inMemory) {
39
+ logWarning(
40
+ `Unable to create temporary files, buffering telemetry in memory (max ${MAX_SPOOL_SIZE_MEMORY / 1e6} MB)`
41
+ );
42
+ } else {
43
+ cleanupOrphanedFiles(tempDir);
44
+ }
45
+ this.maxSize = this.inMemory ? MAX_SPOOL_SIZE_MEMORY : MAX_SPOOL_SIZE_DISK;
46
+ }
47
+ append(signal, payload) {
48
+ return this.enqueue(signal, async () => {
49
+ let file = this.current.get(signal);
50
+ if (file && file.uncompressedSize + payload.length > MAX_UNCOMPRESSED_FILE_SIZE) {
51
+ await this.closeCurrentFile(signal);
52
+ file = void 0;
53
+ }
54
+ try {
55
+ if (!file) {
56
+ file = new SpoolFile(signal, this.inMemory ? void 0 : this.tempDir);
57
+ this.current.set(signal, file);
58
+ }
59
+ await file.write(payload);
60
+ resetWarning(WRITE_FAILURE_WARNING);
61
+ } catch {
62
+ logWarning(WRITE_FAILURE_WARNING);
63
+ await this.discardCurrentFile(signal);
64
+ }
65
+ await this.evict();
66
+ });
67
+ }
68
+ // Current files close only when no backlog exists, avoiding one file per cycle.
69
+ // Sequential rotation preserves send order.
70
+ async rotateForExport() {
71
+ for (const signal of SIGNALS) {
72
+ await this.enqueue(signal, async () => {
73
+ if (this.current.has(signal) && !this.closed.some((file) => file.signal === signal)) {
74
+ await this.closeCurrentFile(signal);
75
+ }
76
+ });
77
+ }
78
+ await this.evict();
79
+ }
80
+ async closeCurrentFiles() {
81
+ for (const signal of SIGNALS) {
82
+ await this.enqueue(signal, () => this.closeCurrentFile(signal));
83
+ }
84
+ }
85
+ pendingFiles() {
86
+ return [...this.closed];
87
+ }
88
+ async deleteFile(file) {
89
+ const index = this.closed.indexOf(file);
90
+ if (index >= 0) {
91
+ this.closed.splice(index, 1);
92
+ }
93
+ await file.delete();
94
+ }
95
+ // Apitally ingest deduplicates for one hour; a later retry could ingest the file twice.
96
+ deleteIfExpired(file) {
97
+ if (!file.isExpired()) {
98
+ return void 0;
99
+ }
100
+ logWarning(`Buffered ${file.signal} could not be delivered within an hour and were dropped`);
101
+ return this.deleteFile(file);
102
+ }
103
+ // Refresh mtimes so orphan cleanup in another process preserves live files.
104
+ touchFiles() {
105
+ for (const file of [...this.current.values(), ...this.closed]) {
106
+ file.touch();
107
+ }
108
+ }
109
+ async clear() {
110
+ await Promise.all(
111
+ SIGNALS.map((signal) => this.enqueue(signal, () => this.discardCurrentFile(signal)))
112
+ );
113
+ const files = this.closed.splice(0);
114
+ await Promise.all(files.map((file) => file.delete()));
115
+ }
116
+ enqueue(signal, operation) {
117
+ const result = this.queues[signal].then(operation);
118
+ this.queues[signal] = result.catch(() => void 0);
119
+ return result;
120
+ }
121
+ async closeCurrentFile(signal) {
122
+ const file = this.current.get(signal);
123
+ if (!file) {
124
+ return;
125
+ }
126
+ this.current.delete(signal);
127
+ try {
128
+ await file.close();
129
+ this.closed.push(file);
130
+ } catch {
131
+ logWarning(WRITE_FAILURE_WARNING);
132
+ await file.delete();
133
+ }
134
+ }
135
+ async discardCurrentFile(signal) {
136
+ const file = this.current.get(signal);
137
+ if (file) {
138
+ this.current.delete(signal);
139
+ await file.delete();
140
+ }
141
+ }
142
+ async evict() {
143
+ const deletions = [...this.closed].map((file) => this.deleteIfExpired(file));
144
+ while (this.totalSize() > this.maxSize) {
145
+ const oldest = this.closed.find((file) => file.signal !== "metrics") ?? this.closed[0];
146
+ if (!oldest) {
147
+ break;
148
+ }
149
+ logWarning(`Buffer size limit reached, dropping oldest buffered ${oldest.signal}`);
150
+ deletions.push(this.deleteFile(oldest));
151
+ }
152
+ await Promise.all(deletions);
153
+ }
154
+ totalSize() {
155
+ let total = 0;
156
+ for (const file of [...this.closed, ...this.current.values()]) {
157
+ total += file.storedSize;
158
+ }
159
+ return total;
160
+ }
161
+ }
162
+ class SpoolFile {
163
+ signal;
164
+ path;
165
+ firstAttemptAtMillis;
166
+ uncompressedSize = 0;
167
+ gzip;
168
+ fileStream;
169
+ memoryChunks;
170
+ memorySize = 0;
171
+ streamError;
172
+ closedPromise;
173
+ constructor(signal, tempDir) {
174
+ this.signal = signal;
175
+ this.gzip = createGzip();
176
+ let closeTarget;
177
+ let closeEvent;
178
+ if (tempDir === void 0) {
179
+ const chunks = [];
180
+ this.memoryChunks = chunks;
181
+ this.gzip.on("data", (chunk) => {
182
+ chunks.push(chunk);
183
+ this.memorySize += chunk.length;
184
+ });
185
+ closeTarget = this.gzip;
186
+ closeEvent = "end";
187
+ } else {
188
+ this.path = join(tempDir, `apitally-${randomUUID()}.gz`);
189
+ const fd = openSync(this.path, "wx", 384);
190
+ this.fileStream = createWriteStream(this.path, { fd });
191
+ this.gzip.pipe(this.fileStream);
192
+ closeTarget = this.fileStream;
193
+ closeEvent = "close";
194
+ }
195
+ const streams = this.fileStream ? [this.gzip, this.fileStream] : [this.gzip];
196
+ this.closedPromise = new Promise((resolve, reject) => {
197
+ closeTarget.once(closeEvent, resolve);
198
+ for (const stream of streams) {
199
+ stream.once("error", reject);
200
+ }
201
+ });
202
+ this.closedPromise.catch(() => void 0);
203
+ for (const stream of streams) {
204
+ stream.on("error", (error) => {
205
+ this.streamError ??= error;
206
+ });
207
+ }
208
+ }
209
+ write(payload) {
210
+ return new Promise((resolve, reject) => {
211
+ if (this.streamError) {
212
+ reject(this.streamError);
213
+ return;
214
+ }
215
+ this.gzip.write(payload, (error) => {
216
+ const failure = error ?? this.streamError;
217
+ if (failure) {
218
+ reject(failure);
219
+ } else {
220
+ this.uncompressedSize += payload.length;
221
+ resolve();
222
+ }
223
+ });
224
+ });
225
+ }
226
+ async close() {
227
+ if (this.streamError) {
228
+ throw this.streamError;
229
+ }
230
+ this.gzip.end();
231
+ await this.closedPromise;
232
+ }
233
+ get storedSize() {
234
+ return this.fileStream ? this.fileStream.bytesWritten : this.memorySize;
235
+ }
236
+ markAttempt() {
237
+ this.firstAttemptAtMillis ??= performance.now();
238
+ }
239
+ isExpired() {
240
+ return this.firstAttemptAtMillis !== void 0 && performance.now() - this.firstAttemptAtMillis > MAX_RETRY_TIME_AFTER_FIRST_ATTEMPT_MILLIS;
241
+ }
242
+ touch() {
243
+ if (this.path) {
244
+ try {
245
+ const now = /* @__PURE__ */ new Date();
246
+ utimesSync(this.path, now, now);
247
+ } catch {
248
+ }
249
+ }
250
+ }
251
+ readStoredBytes() {
252
+ if (this.path) {
253
+ return readFile(this.path);
254
+ }
255
+ return Promise.resolve(Buffer.concat(this.memoryChunks ?? []));
256
+ }
257
+ async delete() {
258
+ this.gzip.destroy();
259
+ this.fileStream?.destroy();
260
+ if (this.path) {
261
+ await unlink(this.path).catch(() => void 0);
262
+ }
263
+ }
264
+ }
265
+ function isTempDirWritable(tempDir) {
266
+ const probePath = join(tempDir, `apitally-${randomUUID()}.gz`);
267
+ try {
268
+ writeFileSync(probePath, "", { flag: "wx", mode: 384 });
269
+ unlinkSync(probePath);
270
+ return true;
271
+ } catch {
272
+ return false;
273
+ }
274
+ }
275
+ function cleanupOrphanedFiles(tempDir) {
276
+ const cutoff = Date.now() - MAX_UNTOUCHED_FILE_AGE_MILLIS;
277
+ try {
278
+ for (const name of readdirSync(tempDir)) {
279
+ if (!SPOOL_FILE_NAME_PATTERN.test(name)) {
280
+ continue;
281
+ }
282
+ try {
283
+ const filePath = join(tempDir, name);
284
+ if (statSync(filePath).mtimeMs < cutoff) {
285
+ unlinkSync(filePath);
286
+ }
287
+ } catch {
288
+ }
289
+ }
290
+ } catch {
291
+ }
292
+ }
293
+ export {
294
+ Spool,
295
+ SpoolFile
296
+ };
297
+ //# sourceMappingURL=spool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/spool.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport {\n createWriteStream,\n openSync,\n readdirSync,\n statSync,\n unlinkSync,\n utimesSync,\n type WriteStream,\n writeFileSync,\n} from \"node:fs\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createGzip, type Gzip } from \"node:zlib\";\nimport { logWarning, resetWarning } from \"./logger.js\";\n\nconst WRITE_FAILURE_WARNING = \"Error writing to disk, dropping buffered telemetry\";\n\nconst SIGNALS = [\"traces\", \"logs\", \"metrics\"] as const;\nexport type Signal = (typeof SIGNALS)[number];\n\nconst MAX_UNCOMPRESSED_FILE_SIZE = 4_000_000;\nconst MAX_RETRY_TIME_AFTER_FIRST_ATTEMPT_MILLIS = 59 * 60 * 1000;\nconst MAX_SPOOL_SIZE_DISK = 50_000_000;\nconst MAX_SPOOL_SIZE_MEMORY = 10_000_000;\nconst MAX_UNTOUCHED_FILE_AGE_MILLIS = 2 * 60 * 60 * 1000;\nconst SPOOL_FILE_NAME_PATTERN = /^apitally-.*\\.gz$/;\n\n// Operations for each signal are serialized because gzip and file streams\n// complete asynchronously.\nexport class Spool {\n readonly inMemory: boolean;\n maxSize: number;\n readonly current = new Map<Signal, SpoolFile>();\n private readonly closed: SpoolFile[] = [];\n private readonly tempDir: string;\n private readonly queues: Record<Signal, Promise<void>> = {\n traces: Promise.resolve(),\n logs: Promise.resolve(),\n metrics: Promise.resolve(),\n };\n\n constructor(tempDir: string = tmpdir()) {\n this.tempDir = tempDir;\n this.inMemory = !isTempDirWritable(tempDir);\n if (this.inMemory) {\n logWarning(\n `Unable to create temporary files, buffering telemetry in memory (max ${MAX_SPOOL_SIZE_MEMORY / 1_000_000} MB)`,\n );\n } else {\n cleanupOrphanedFiles(tempDir);\n }\n this.maxSize = this.inMemory ? MAX_SPOOL_SIZE_MEMORY : MAX_SPOOL_SIZE_DISK;\n }\n\n append(signal: Signal, payload: Uint8Array): Promise<void> {\n return this.enqueue(signal, async () => {\n let file = this.current.get(signal);\n if (file && file.uncompressedSize + payload.length > MAX_UNCOMPRESSED_FILE_SIZE) {\n await this.closeCurrentFile(signal);\n file = undefined;\n }\n try {\n if (!file) {\n file = new SpoolFile(signal, this.inMemory ? undefined : this.tempDir);\n this.current.set(signal, file);\n }\n await file.write(payload);\n // Writes recovered; the write-failure warning may fire again later.\n resetWarning(WRITE_FAILURE_WARNING);\n } catch {\n logWarning(WRITE_FAILURE_WARNING);\n await this.discardCurrentFile(signal);\n }\n await this.evict();\n });\n }\n\n // Current files close only when no backlog exists, avoiding one file per cycle.\n // Sequential rotation preserves send order.\n async rotateForExport(): Promise<void> {\n for (const signal of SIGNALS) {\n await this.enqueue(signal, async () => {\n if (this.current.has(signal) && !this.closed.some((file) => file.signal === signal)) {\n await this.closeCurrentFile(signal);\n }\n });\n }\n await this.evict();\n }\n\n async closeCurrentFiles(): Promise<void> {\n for (const signal of SIGNALS) {\n await this.enqueue(signal, () => this.closeCurrentFile(signal));\n }\n }\n\n pendingFiles(): SpoolFile[] {\n return [...this.closed];\n }\n\n async deleteFile(file: SpoolFile): Promise<void> {\n const index = this.closed.indexOf(file);\n if (index >= 0) {\n this.closed.splice(index, 1);\n }\n await file.delete();\n }\n\n // Apitally ingest deduplicates for one hour; a later retry could ingest the file twice.\n deleteIfExpired(file: SpoolFile): Promise<void> | undefined {\n if (!file.isExpired()) {\n return undefined;\n }\n logWarning(`Buffered ${file.signal} could not be delivered within an hour and were dropped`);\n return this.deleteFile(file);\n }\n\n // Refresh mtimes so orphan cleanup in another process preserves live files.\n touchFiles(): void {\n for (const file of [...this.current.values(), ...this.closed]) {\n file.touch();\n }\n }\n\n async clear(): Promise<void> {\n await Promise.all(\n SIGNALS.map((signal) => this.enqueue(signal, () => this.discardCurrentFile(signal))),\n );\n const files = this.closed.splice(0);\n await Promise.all(files.map((file) => file.delete()));\n }\n\n private enqueue(signal: Signal, operation: () => Promise<void>): Promise<void> {\n const result = this.queues[signal].then(operation);\n this.queues[signal] = result.catch(() => undefined);\n return result;\n }\n\n private async closeCurrentFile(signal: Signal): Promise<void> {\n const file = this.current.get(signal);\n if (!file) {\n return;\n }\n this.current.delete(signal);\n try {\n await file.close();\n this.closed.push(file);\n } catch {\n logWarning(WRITE_FAILURE_WARNING);\n await file.delete();\n }\n }\n\n private async discardCurrentFile(signal: Signal): Promise<void> {\n const file = this.current.get(signal);\n if (file) {\n this.current.delete(signal);\n await file.delete();\n }\n }\n\n private async evict(): Promise<void> {\n const deletions = [...this.closed].map((file) => this.deleteIfExpired(file));\n while (this.totalSize() > this.maxSize) {\n // Prefer retaining metrics, but enforce the size limit when only metrics remain.\n const oldest = this.closed.find((file) => file.signal !== \"metrics\") ?? this.closed[0];\n if (!oldest) {\n break;\n }\n logWarning(`Buffer size limit reached, dropping oldest buffered ${oldest.signal}`);\n deletions.push(this.deleteFile(oldest));\n }\n await Promise.all(deletions);\n }\n\n private totalSize(): number {\n let total = 0;\n for (const file of [...this.closed, ...this.current.values()]) {\n total += file.storedSize;\n }\n return total;\n }\n}\n\n// One gzip stream of concatenated OTLP request payloads for a single signal,\n// written through to a temp file or, as fallback, an in-memory buffer.\nexport class SpoolFile {\n readonly signal: Signal;\n readonly path?: string;\n firstAttemptAtMillis?: number;\n uncompressedSize = 0;\n readonly gzip: Gzip;\n private readonly fileStream?: WriteStream;\n private readonly memoryChunks?: Buffer[];\n private memorySize = 0;\n private streamError?: Error;\n private readonly closedPromise: Promise<void>;\n\n constructor(signal: Signal, tempDir?: string) {\n this.signal = signal;\n this.gzip = createGzip();\n let closeTarget: Gzip | WriteStream;\n let closeEvent: string;\n if (tempDir === undefined) {\n const chunks: Buffer[] = [];\n this.memoryChunks = chunks;\n this.gzip.on(\"data\", (chunk: Buffer) => {\n chunks.push(chunk);\n this.memorySize += chunk.length;\n });\n closeTarget = this.gzip;\n closeEvent = \"end\";\n } else {\n this.path = join(tempDir, `apitally-${randomUUID()}.gz`);\n // A synchronous exclusive open reports creation errors to the triggering append.\n const fd = openSync(this.path, \"wx\", 0o600);\n this.fileStream = createWriteStream(this.path, { fd });\n this.gzip.pipe(this.fileStream);\n closeTarget = this.fileStream;\n closeEvent = \"close\";\n }\n const streams: (Gzip | WriteStream)[] = this.fileStream\n ? [this.gzip, this.fileStream]\n : [this.gzip];\n this.closedPromise = new Promise((resolve, reject) => {\n closeTarget.once(closeEvent, resolve);\n for (const stream of streams) {\n stream.once(\"error\", reject);\n }\n });\n // Stream errors can occur outside an awaited operation; rejection handling\n // prevents an unhandled rejection.\n this.closedPromise.catch(() => undefined);\n for (const stream of streams) {\n stream.on(\"error\", (error: Error) => {\n this.streamError ??= error;\n });\n }\n }\n\n write(payload: Uint8Array): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.streamError) {\n reject(this.streamError);\n return;\n }\n this.gzip.write(payload, (error) => {\n const failure = error ?? this.streamError;\n if (failure) {\n reject(failure);\n } else {\n this.uncompressedSize += payload.length;\n resolve();\n }\n });\n });\n }\n\n async close(): Promise<void> {\n if (this.streamError) {\n throw this.streamError;\n }\n this.gzip.end();\n await this.closedPromise;\n }\n\n get storedSize(): number {\n return this.fileStream ? this.fileStream.bytesWritten : this.memorySize;\n }\n\n markAttempt(): void {\n this.firstAttemptAtMillis ??= performance.now();\n }\n\n isExpired(): boolean {\n return (\n this.firstAttemptAtMillis !== undefined &&\n performance.now() - this.firstAttemptAtMillis > MAX_RETRY_TIME_AFTER_FIRST_ATTEMPT_MILLIS\n );\n }\n\n touch(): void {\n if (this.path) {\n try {\n const now = new Date();\n utimesSync(this.path, now, now);\n } catch {\n // The file may already be gone; orphan cleanup only targets stale files.\n }\n }\n }\n\n readStoredBytes(): Promise<Buffer> {\n if (this.path) {\n return readFile(this.path);\n }\n return Promise.resolve(Buffer.concat(this.memoryChunks ?? []));\n }\n\n async delete(): Promise<void> {\n this.gzip.destroy();\n this.fileStream?.destroy();\n if (this.path) {\n await unlink(this.path).catch(() => undefined);\n }\n }\n}\n\nfunction isTempDirWritable(tempDir: string): boolean {\n const probePath = join(tempDir, `apitally-${randomUUID()}.gz`);\n try {\n writeFileSync(probePath, \"\", { flag: \"wx\", mode: 0o600 });\n unlinkSync(probePath);\n return true;\n } catch {\n return false;\n }\n}\n\n// Live processes refresh mtimes each cycle, so only stale spool files from dead\n// processes are removed.\nfunction cleanupOrphanedFiles(tempDir: string): void {\n const cutoff = Date.now() - MAX_UNTOUCHED_FILE_AGE_MILLIS;\n try {\n for (const name of readdirSync(tempDir)) {\n if (!SPOOL_FILE_NAME_PATTERN.test(name)) {\n continue;\n }\n try {\n const filePath = join(tempDir, name);\n if (statSync(filePath).mtimeMs < cutoff) {\n unlinkSync(filePath);\n }\n } catch {\n // Another process may have removed the file first.\n }\n }\n } catch {\n // Reading the temporary directory is best-effort.\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var startup_exports = {};
20
+ __export(startup_exports, {
21
+ emitStartupEvent: () => emitStartupEvent,
22
+ resetStartupEventEmitted: () => resetStartupEventEmitted
23
+ });
24
+ module.exports = __toCommonJS(startup_exports);
25
+ var import_api = require("@opentelemetry/api");
26
+ var import_config = require('./config.cjs');
27
+ var import_logger = require('./logger.cjs');
28
+ let startupEventEmitted = false;
29
+ function emitStartupEvent(loggerProvider, info) {
30
+ if (startupEventEmitted) {
31
+ return;
32
+ }
33
+ startupEventEmitted = true;
34
+ const versions = { node: process.versions.node };
35
+ if (info.frameworkVersion) {
36
+ versions[info.framework] = info.frameworkVersion;
37
+ }
38
+ const appVersion = (0, import_config.getConfig)().appVersion;
39
+ if (appVersion) {
40
+ versions.app = appVersion;
41
+ }
42
+ let paths;
43
+ try {
44
+ paths = normalizeStartupPaths(info.resolvePaths());
45
+ } catch (error) {
46
+ (0, import_logger.logDebug)(`Error resolving the app's routes for the startup event: ${String(error)}`);
47
+ }
48
+ const body = serializePayload({ framework: info.framework, versions, paths }) ?? (paths !== void 0 ? serializePayload({ framework: info.framework, versions }) : void 0);
49
+ if (body === void 0) {
50
+ return;
51
+ }
52
+ loggerProvider.getLogger("apitally").emit({
53
+ timestamp: Date.now(),
54
+ // The explicit root context keeps the record separate from the request
55
+ // whose handling triggered the emit.
56
+ context: import_api.ROOT_CONTEXT,
57
+ eventName: "apitally.app.startup",
58
+ body
59
+ });
60
+ }
61
+ function resetStartupEventEmitted() {
62
+ startupEventEmitted = false;
63
+ }
64
+ function normalizeStartupPaths(candidates) {
65
+ const paths = [];
66
+ const seenPaths = /* @__PURE__ */ new Set();
67
+ for (const candidate of candidates) {
68
+ const method = candidate.method.toUpperCase();
69
+ if (method === "ALL" || method === "HEAD" || method === "OPTIONS") {
70
+ continue;
71
+ }
72
+ const key = `${method}\0${candidate.path}`;
73
+ if (!seenPaths.has(key)) {
74
+ seenPaths.add(key);
75
+ paths.push({ ...candidate, method });
76
+ }
77
+ }
78
+ return paths;
79
+ }
80
+ function serializePayload(payload) {
81
+ try {
82
+ return JSON.stringify(payload);
83
+ } catch (error) {
84
+ (0, import_logger.logDebug)(`Error serializing the startup event payload: ${String(error)}`);
85
+ return void 0;
86
+ }
87
+ }
88
+ // Annotate the CommonJS export names for ESM import in node:
89
+ 0 && (module.exports = {
90
+ emitStartupEvent,
91
+ resetStartupEventEmitted
92
+ });
93
+ //# sourceMappingURL=startup.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/startup.ts"],"sourcesContent":["import { ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport type { LoggerProvider } from \"@opentelemetry/api-logs\";\nimport { getConfig } from \"./config.js\";\nimport { logDebug } from \"./logger.js\";\n\nexport interface RoutePath {\n method: string;\n path: string;\n}\n\nexport interface StartupEventInfo {\n framework: string;\n frameworkVersion?: string;\n // Resolved at emission because routes often finalize after setup.\n resolvePaths: () => RoutePath[];\n}\n\nlet startupEventEmitted = false;\n\n// The startup event emits at most once. Route resolution or serialization\n// failures emit the remaining valid data and never reach the application.\nexport function emitStartupEvent(loggerProvider: LoggerProvider, info: StartupEventInfo): void {\n if (startupEventEmitted) {\n return;\n }\n startupEventEmitted = true;\n const versions: Record<string, string> = { node: process.versions.node };\n if (info.frameworkVersion) {\n versions[info.framework] = info.frameworkVersion;\n }\n const appVersion = getConfig().appVersion;\n if (appVersion) {\n versions.app = appVersion;\n }\n let paths: RoutePath[] | undefined;\n try {\n paths = normalizeStartupPaths(info.resolvePaths());\n } catch (error) {\n logDebug(`Error resolving the app's routes for the startup event: ${String(error)}`);\n }\n const body =\n serializePayload({ framework: info.framework, versions, paths }) ??\n (paths !== undefined ? serializePayload({ framework: info.framework, versions }) : undefined);\n if (body === undefined) {\n return;\n }\n loggerProvider.getLogger(\"apitally\").emit({\n timestamp: Date.now(),\n // The explicit root context keeps the record separate from the request\n // whose handling triggered the emit.\n context: ROOT_CONTEXT,\n eventName: \"apitally.app.startup\",\n body,\n });\n}\n\nexport function resetStartupEventEmitted(): void {\n startupEventEmitted = false;\n}\n\nfunction normalizeStartupPaths(candidates: RoutePath[]): RoutePath[] {\n const paths: RoutePath[] = [];\n const seenPaths = new Set<string>();\n for (const candidate of candidates) {\n const method = candidate.method.toUpperCase();\n if (method === \"ALL\" || method === \"HEAD\" || method === \"OPTIONS\") {\n continue;\n }\n const key = `${method}\\0${candidate.path}`;\n if (!seenPaths.has(key)) {\n seenPaths.add(key);\n paths.push({ ...candidate, method });\n }\n }\n return paths;\n}\n\nfunction serializePayload(payload: {\n framework: string;\n versions: Record<string, string>;\n paths?: RoutePath[];\n}): string | undefined {\n try {\n return JSON.stringify(payload);\n } catch (error) {\n logDebug(`Error serializing the startup event payload: ${String(error)}`);\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAE7B,oBAA0B;AAC1B,oBAAyB;AAczB,IAAI,sBAAsB;AAInB,SAAS,iBAAiB,gBAAgC,MAA8B;AAC7F,MAAI,qBAAqB;AACvB;AAAA,EACF;AACA,wBAAsB;AACtB,QAAM,WAAmC,EAAE,MAAM,QAAQ,SAAS,KAAK;AACvE,MAAI,KAAK,kBAAkB;AACzB,aAAS,KAAK,SAAS,IAAI,KAAK;AAAA,EAClC;AACA,QAAM,iBAAa,yBAAU,EAAE;AAC/B,MAAI,YAAY;AACd,aAAS,MAAM;AAAA,EACjB;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,sBAAsB,KAAK,aAAa,CAAC;AAAA,EACnD,SAAS,OAAO;AACd,gCAAS,2DAA2D,OAAO,KAAK,CAAC,EAAE;AAAA,EACrF;AACA,QAAM,OACJ,iBAAiB,EAAE,WAAW,KAAK,WAAW,UAAU,MAAM,CAAC,MAC9D,UAAU,SAAY,iBAAiB,EAAE,WAAW,KAAK,WAAW,SAAS,CAAC,IAAI;AACrF,MAAI,SAAS,QAAW;AACtB;AAAA,EACF;AACA,iBAAe,UAAU,UAAU,EAAE,KAAK;AAAA,IACxC,WAAW,KAAK,IAAI;AAAA;AAAA;AAAA,IAGpB,SAAS;AAAA,IACT,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAEO,SAAS,2BAAiC;AAC/C,wBAAsB;AACxB;AAEA,SAAS,sBAAsB,YAAsC;AACnE,QAAM,QAAqB,CAAC;AAC5B,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,aAAa,YAAY;AAClC,UAAM,SAAS,UAAU,OAAO,YAAY;AAC5C,QAAI,WAAW,SAAS,WAAW,UAAU,WAAW,WAAW;AACjE;AAAA,IACF;AACA,UAAM,MAAM,GAAG,MAAM,KAAK,UAAU,IAAI;AACxC,QAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,gBAAU,IAAI,GAAG;AACjB,YAAM,KAAK,EAAE,GAAG,WAAW,OAAO,CAAC;AAAA,IACrC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAIH;AACrB,MAAI;AACF,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B,SAAS,OAAO;AACd,gCAAS,gDAAgD,OAAO,KAAK,CAAC,EAAE;AACxE,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,15 @@
1
+ import { LoggerProvider } from '@opentelemetry/api-logs';
2
+
3
+ interface RoutePath {
4
+ method: string;
5
+ path: string;
6
+ }
7
+ interface StartupEventInfo {
8
+ framework: string;
9
+ frameworkVersion?: string;
10
+ resolvePaths: () => RoutePath[];
11
+ }
12
+ declare function emitStartupEvent(loggerProvider: LoggerProvider, info: StartupEventInfo): void;
13
+ declare function resetStartupEventEmitted(): void;
14
+
15
+ export { type RoutePath, type StartupEventInfo, emitStartupEvent, resetStartupEventEmitted };
@@ -0,0 +1,15 @@
1
+ import { LoggerProvider } from '@opentelemetry/api-logs';
2
+
3
+ interface RoutePath {
4
+ method: string;
5
+ path: string;
6
+ }
7
+ interface StartupEventInfo {
8
+ framework: string;
9
+ frameworkVersion?: string;
10
+ resolvePaths: () => RoutePath[];
11
+ }
12
+ declare function emitStartupEvent(loggerProvider: LoggerProvider, info: StartupEventInfo): void;
13
+ declare function resetStartupEventEmitted(): void;
14
+
15
+ export { type RoutePath, type StartupEventInfo, emitStartupEvent, resetStartupEventEmitted };
@@ -0,0 +1,68 @@
1
+ import { ROOT_CONTEXT } from "@opentelemetry/api";
2
+ import { getConfig } from "./config.js";
3
+ import { logDebug } from "./logger.js";
4
+ let startupEventEmitted = false;
5
+ function emitStartupEvent(loggerProvider, info) {
6
+ if (startupEventEmitted) {
7
+ return;
8
+ }
9
+ startupEventEmitted = true;
10
+ const versions = { node: process.versions.node };
11
+ if (info.frameworkVersion) {
12
+ versions[info.framework] = info.frameworkVersion;
13
+ }
14
+ const appVersion = getConfig().appVersion;
15
+ if (appVersion) {
16
+ versions.app = appVersion;
17
+ }
18
+ let paths;
19
+ try {
20
+ paths = normalizeStartupPaths(info.resolvePaths());
21
+ } catch (error) {
22
+ logDebug(`Error resolving the app's routes for the startup event: ${String(error)}`);
23
+ }
24
+ const body = serializePayload({ framework: info.framework, versions, paths }) ?? (paths !== void 0 ? serializePayload({ framework: info.framework, versions }) : void 0);
25
+ if (body === void 0) {
26
+ return;
27
+ }
28
+ loggerProvider.getLogger("apitally").emit({
29
+ timestamp: Date.now(),
30
+ // The explicit root context keeps the record separate from the request
31
+ // whose handling triggered the emit.
32
+ context: ROOT_CONTEXT,
33
+ eventName: "apitally.app.startup",
34
+ body
35
+ });
36
+ }
37
+ function resetStartupEventEmitted() {
38
+ startupEventEmitted = false;
39
+ }
40
+ function normalizeStartupPaths(candidates) {
41
+ const paths = [];
42
+ const seenPaths = /* @__PURE__ */ new Set();
43
+ for (const candidate of candidates) {
44
+ const method = candidate.method.toUpperCase();
45
+ if (method === "ALL" || method === "HEAD" || method === "OPTIONS") {
46
+ continue;
47
+ }
48
+ const key = `${method}\0${candidate.path}`;
49
+ if (!seenPaths.has(key)) {
50
+ seenPaths.add(key);
51
+ paths.push({ ...candidate, method });
52
+ }
53
+ }
54
+ return paths;
55
+ }
56
+ function serializePayload(payload) {
57
+ try {
58
+ return JSON.stringify(payload);
59
+ } catch (error) {
60
+ logDebug(`Error serializing the startup event payload: ${String(error)}`);
61
+ return void 0;
62
+ }
63
+ }
64
+ export {
65
+ emitStartupEvent,
66
+ resetStartupEventEmitted
67
+ };
68
+ //# sourceMappingURL=startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/startup.ts"],"sourcesContent":["import { ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport type { LoggerProvider } from \"@opentelemetry/api-logs\";\nimport { getConfig } from \"./config.js\";\nimport { logDebug } from \"./logger.js\";\n\nexport interface RoutePath {\n method: string;\n path: string;\n}\n\nexport interface StartupEventInfo {\n framework: string;\n frameworkVersion?: string;\n // Resolved at emission because routes often finalize after setup.\n resolvePaths: () => RoutePath[];\n}\n\nlet startupEventEmitted = false;\n\n// The startup event emits at most once. Route resolution or serialization\n// failures emit the remaining valid data and never reach the application.\nexport function emitStartupEvent(loggerProvider: LoggerProvider, info: StartupEventInfo): void {\n if (startupEventEmitted) {\n return;\n }\n startupEventEmitted = true;\n const versions: Record<string, string> = { node: process.versions.node };\n if (info.frameworkVersion) {\n versions[info.framework] = info.frameworkVersion;\n }\n const appVersion = getConfig().appVersion;\n if (appVersion) {\n versions.app = appVersion;\n }\n let paths: RoutePath[] | undefined;\n try {\n paths = normalizeStartupPaths(info.resolvePaths());\n } catch (error) {\n logDebug(`Error resolving the app's routes for the startup event: ${String(error)}`);\n }\n const body =\n serializePayload({ framework: info.framework, versions, paths }) ??\n (paths !== undefined ? serializePayload({ framework: info.framework, versions }) : undefined);\n if (body === undefined) {\n return;\n }\n loggerProvider.getLogger(\"apitally\").emit({\n timestamp: Date.now(),\n // The explicit root context keeps the record separate from the request\n // whose handling triggered the emit.\n context: ROOT_CONTEXT,\n eventName: \"apitally.app.startup\",\n body,\n });\n}\n\nexport function resetStartupEventEmitted(): void {\n startupEventEmitted = false;\n}\n\nfunction normalizeStartupPaths(candidates: RoutePath[]): RoutePath[] {\n const paths: RoutePath[] = [];\n const seenPaths = new Set<string>();\n for (const candidate of candidates) {\n const method = candidate.method.toUpperCase();\n if (method === \"ALL\" || method === \"HEAD\" || method === \"OPTIONS\") {\n continue;\n }\n const key = `${method}\\0${candidate.path}`;\n if (!seenPaths.has(key)) {\n seenPaths.add(key);\n paths.push({ ...candidate, method });\n }\n }\n return paths;\n}\n\nfunction serializePayload(payload: {\n framework: string;\n versions: Record<string, string>;\n paths?: RoutePath[];\n}): string | undefined {\n try {\n return JSON.stringify(payload);\n } catch (error) {\n logDebug(`Error serializing the startup event payload: ${String(error)}`);\n return undefined;\n }\n}\n"],"mappings":"AAAA,SAAS,oBAAoB;AAE7B,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AAczB,IAAI,sBAAsB;AAInB,SAAS,iBAAiB,gBAAgC,MAA8B;AAC7F,MAAI,qBAAqB;AACvB;AAAA,EACF;AACA,wBAAsB;AACtB,QAAM,WAAmC,EAAE,MAAM,QAAQ,SAAS,KAAK;AACvE,MAAI,KAAK,kBAAkB;AACzB,aAAS,KAAK,SAAS,IAAI,KAAK;AAAA,EAClC;AACA,QAAM,aAAa,UAAU,EAAE;AAC/B,MAAI,YAAY;AACd,aAAS,MAAM;AAAA,EACjB;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,sBAAsB,KAAK,aAAa,CAAC;AAAA,EACnD,SAAS,OAAO;AACd,aAAS,2DAA2D,OAAO,KAAK,CAAC,EAAE;AAAA,EACrF;AACA,QAAM,OACJ,iBAAiB,EAAE,WAAW,KAAK,WAAW,UAAU,MAAM,CAAC,MAC9D,UAAU,SAAY,iBAAiB,EAAE,WAAW,KAAK,WAAW,SAAS,CAAC,IAAI;AACrF,MAAI,SAAS,QAAW;AACtB;AAAA,EACF;AACA,iBAAe,UAAU,UAAU,EAAE,KAAK;AAAA,IACxC,WAAW,KAAK,IAAI;AAAA;AAAA;AAAA,IAGpB,SAAS;AAAA,IACT,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAEO,SAAS,2BAAiC;AAC/C,wBAAsB;AACxB;AAEA,SAAS,sBAAsB,YAAsC;AACnE,QAAM,QAAqB,CAAC;AAC5B,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,aAAa,YAAY;AAClC,UAAM,SAAS,UAAU,OAAO,YAAY;AAC5C,QAAI,WAAW,SAAS,WAAW,UAAU,WAAW,WAAW;AACjE;AAAA,IACF;AACA,UAAM,MAAM,GAAG,MAAM,KAAK,UAAU,IAAI;AACxC,QAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,gBAAU,IAAI,GAAG;AACjB,YAAM,KAAK,EAAE,GAAG,WAAW,OAAO,CAAC;AAAA,IACrC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAIH;AACrB,MAAI;AACF,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B,SAAS,OAAO;AACd,aAAS,gDAAgD,OAAO,KAAK,CAAC,EAAE;AACxE,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var tracing_exports = {};
20
+ __export(tracing_exports, {
21
+ instrument: () => instrument,
22
+ span: () => span
23
+ });
24
+ module.exports = __toCommonJS(tracing_exports);
25
+ var import_node_url = require("node:url");
26
+ var import_api = require("@opentelemetry/api");
27
+ var import_exceptions = require('./exceptions.cjs');
28
+ var import_logger = require('./logger.cjs');
29
+ const STACK_FRAME_PATTERN = /at (?:.*\()?(.*?):(\d+):\d+\)?$/;
30
+ function instrument(nameOrFn, fnWhenNamed) {
31
+ const fn = typeof nameOrFn === "function" ? nameOrFn : fnWhenNamed;
32
+ const spanName = typeof nameOrFn === "string" ? nameOrFn : fn.name || "anonymous";
33
+ const attributes = {};
34
+ if (fn.name) {
35
+ attributes["code.function.name"] = fn.name;
36
+ }
37
+ const wrapSite = resolveWrapSite();
38
+ if (wrapSite) {
39
+ attributes["code.file.path"] = wrapSite.filePath;
40
+ attributes["code.line.number"] = wrapSite.lineNumber;
41
+ }
42
+ return function(...args) {
43
+ return runInsideSpan(spanName, attributes, () => fn.apply(this, args));
44
+ };
45
+ }
46
+ function span(name, fn) {
47
+ return runInsideSpan(name, void 0, fn);
48
+ }
49
+ function runInsideSpan(name, attributes, fn) {
50
+ let internalSpan;
51
+ try {
52
+ internalSpan = import_api.trace.getTracer("apitally.otel").startSpan(name, { kind: import_api.SpanKind.INTERNAL, attributes });
53
+ } catch (error) {
54
+ (0, import_logger.logDebug)(`Error starting a manual span: ${String(error)}`);
55
+ return fn();
56
+ }
57
+ let result;
58
+ try {
59
+ result = import_api.context.with(import_api.trace.setSpan(import_api.context.active(), internalSpan), fn);
60
+ } catch (error) {
61
+ endSpanWithError(internalSpan, error);
62
+ throw error;
63
+ }
64
+ if (isPromiseLike(result)) {
65
+ result.then(
66
+ () => endSpan(internalSpan),
67
+ (error) => endSpanWithError(internalSpan, error)
68
+ );
69
+ return result;
70
+ }
71
+ endSpan(internalSpan);
72
+ return result;
73
+ }
74
+ function resolveWrapSite() {
75
+ const holder = {};
76
+ Error.captureStackTrace(holder, instrument);
77
+ for (const frame of (holder.stack ?? "").split("\n")) {
78
+ const match = STACK_FRAME_PATTERN.exec(frame);
79
+ if (match) {
80
+ return {
81
+ filePath: match[1].startsWith("file://") ? (0, import_node_url.fileURLToPath)(match[1]) : match[1],
82
+ lineNumber: Number(match[2])
83
+ };
84
+ }
85
+ }
86
+ return void 0;
87
+ }
88
+ function isPromiseLike(value) {
89
+ return typeof value === "object" && value !== null && typeof value.then === "function";
90
+ }
91
+ function endSpan(internalSpan) {
92
+ try {
93
+ internalSpan.end();
94
+ } catch (error) {
95
+ (0, import_logger.logDebug)(`Error ending a manual span: ${String(error)}`);
96
+ }
97
+ }
98
+ function endSpanWithError(internalSpan, error) {
99
+ try {
100
+ const exception = (0, import_exceptions.coerceToException)(error);
101
+ internalSpan.recordException(exception);
102
+ internalSpan.setStatus({
103
+ code: import_api.SpanStatusCode.ERROR,
104
+ message: typeof exception === "string" ? exception : exception.message
105
+ });
106
+ internalSpan.end();
107
+ } catch (endError) {
108
+ (0, import_logger.logDebug)(`Error ending a manual span: ${String(endError)}`);
109
+ }
110
+ }
111
+ // Annotate the CommonJS export names for ESM import in node:
112
+ 0 && (module.exports = {
113
+ instrument,
114
+ span
115
+ });
116
+ //# sourceMappingURL=tracing.cjs.map