@zuplo/cli 7.11.0 → 7.11.3

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 (303) hide show
  1. package/node_modules/@hono/node-server/README.md +2 -0
  2. package/node_modules/@hono/node-server/dist/index.cjs +1 -1
  3. package/node_modules/@hono/node-server/dist/index.mjs +1 -1
  4. package/node_modules/@hono/node-server/dist/serve-static.cjs +2 -1
  5. package/node_modules/@hono/node-server/dist/serve-static.mjs +2 -1
  6. package/node_modules/@hono/node-server/package.json +1 -1
  7. package/node_modules/@posthog/core/dist/metrics/index.d.ts +9 -0
  8. package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
  9. package/node_modules/@posthog/core/dist/metrics/index.js +38 -3
  10. package/node_modules/@posthog/core/dist/metrics/index.mjs +38 -3
  11. package/node_modules/@posthog/core/dist/metrics/types.d.ts +7 -2
  12. package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
  13. package/node_modules/@posthog/core/dist/traces/ids.d.ts.map +1 -1
  14. package/node_modules/@posthog/core/dist/traces/ids.js +2 -2
  15. package/node_modules/@posthog/core/dist/traces/ids.mjs +2 -2
  16. package/node_modules/@posthog/core/package.json +2 -2
  17. package/node_modules/@posthog/core/src/metrics/index.spec.ts +75 -0
  18. package/node_modules/@posthog/core/src/metrics/index.ts +60 -0
  19. package/node_modules/@posthog/core/src/metrics/types.ts +7 -1
  20. package/node_modules/@posthog/core/src/traces/ids.ts +4 -2
  21. package/node_modules/@posthog/types/dist/capture-metric.d.ts +10 -0
  22. package/node_modules/@posthog/types/dist/capture-metric.d.ts.map +1 -1
  23. package/node_modules/@posthog/types/dist/index.d.ts +1 -1
  24. package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
  25. package/node_modules/@posthog/types/package.json +1 -1
  26. package/node_modules/@posthog/types/src/capture-metric.ts +11 -0
  27. package/node_modules/@posthog/types/src/index.ts +1 -0
  28. package/node_modules/@zuplo/core/customer.cli.minified.js +80 -80
  29. package/node_modules/@zuplo/core/index.minified.js +85 -85
  30. package/node_modules/@zuplo/core/package.json +1 -1
  31. package/node_modules/@zuplo/graphql/package.json +1 -1
  32. package/node_modules/@zuplo/openapi-tools/package.json +5 -2
  33. package/node_modules/@zuplo/otel/package.json +1 -1
  34. package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js → chunk-CDEAY3VY.js} +2 -2
  35. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js +37 -0
  36. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js.map +1 -0
  37. package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js → chunk-NUVXDVLJ.js} +2 -2
  38. package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js → chunk-TPYCFLC7.js} +109 -109
  39. package/node_modules/@zuplo/runtime/out/esm/chunk-TPYCFLC7.js.map +1 -0
  40. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  41. package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
  42. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  43. package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
  44. package/node_modules/@zuplo/runtime/out/esm/sdks/aws/index.js +1 -1
  45. package/node_modules/@zuplo/runtime/out/types/index.d.ts +43 -43
  46. package/node_modules/@zuplo/runtime/out/types/internal/index.d.ts +14 -0
  47. package/node_modules/@zuplo/runtime/package.json +1 -1
  48. package/package.json +15 -12
  49. package/dist/__tests__/archive-utils.test.d.ts +0 -2
  50. package/dist/__tests__/archive-utils.test.d.ts.map +0 -1
  51. package/dist/__tests__/archive-utils.test.js +0 -50
  52. package/dist/__tests__/archive-utils.test.js.map +0 -1
  53. package/dist/__tests__/import-openapi.test.d.ts +0 -2
  54. package/dist/__tests__/import-openapi.test.d.ts.map +0 -1
  55. package/dist/__tests__/import-openapi.test.js +0 -251
  56. package/dist/__tests__/import-openapi.test.js.map +0 -1
  57. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts +0 -2
  58. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts.map +0 -1
  59. package/dist/__tests__/integration/confirm-linked-config.integration.test.js +0 -202
  60. package/dist/__tests__/integration/confirm-linked-config.integration.test.js.map +0 -1
  61. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts +0 -2
  62. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts.map +0 -1
  63. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js +0 -184
  64. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js.map +0 -1
  65. package/dist/__tests__/integration/custom-domain.integration.test.d.ts +0 -2
  66. package/dist/__tests__/integration/custom-domain.integration.test.d.ts.map +0 -1
  67. package/dist/__tests__/integration/custom-domain.integration.test.js +0 -563
  68. package/dist/__tests__/integration/custom-domain.integration.test.js.map +0 -1
  69. package/dist/__tests__/integration/delete.integration.test.d.ts +0 -2
  70. package/dist/__tests__/integration/delete.integration.test.d.ts.map +0 -1
  71. package/dist/__tests__/integration/delete.integration.test.js +0 -262
  72. package/dist/__tests__/integration/delete.integration.test.js.map +0 -1
  73. package/dist/__tests__/integration/deploy.integration.test.d.ts +0 -2
  74. package/dist/__tests__/integration/deploy.integration.test.d.ts.map +0 -1
  75. package/dist/__tests__/integration/deploy.integration.test.js +0 -519
  76. package/dist/__tests__/integration/deploy.integration.test.js.map +0 -1
  77. package/dist/__tests__/integration/get-project-param.integration.test.d.ts +0 -2
  78. package/dist/__tests__/integration/get-project-param.integration.test.d.ts.map +0 -1
  79. package/dist/__tests__/integration/get-project-param.integration.test.js +0 -305
  80. package/dist/__tests__/integration/get-project-param.integration.test.js.map +0 -1
  81. package/dist/__tests__/integration/info.integration.test.d.ts +0 -2
  82. package/dist/__tests__/integration/info.integration.test.d.ts.map +0 -1
  83. package/dist/__tests__/integration/info.integration.test.js +0 -293
  84. package/dist/__tests__/integration/info.integration.test.js.map +0 -1
  85. package/dist/__tests__/integration/jest-mocks-setup.d.ts +0 -2
  86. package/dist/__tests__/integration/jest-mocks-setup.d.ts.map +0 -1
  87. package/dist/__tests__/integration/jest-mocks-setup.js +0 -104
  88. package/dist/__tests__/integration/jest-mocks-setup.js.map +0 -1
  89. package/dist/__tests__/integration/jest-setup.d.ts +0 -2
  90. package/dist/__tests__/integration/jest-setup.d.ts.map +0 -1
  91. package/dist/__tests__/integration/jest-setup.js +0 -12
  92. package/dist/__tests__/integration/jest-setup.js.map +0 -1
  93. package/dist/__tests__/integration/link.integration.test.d.ts +0 -2
  94. package/dist/__tests__/integration/link.integration.test.d.ts.map +0 -1
  95. package/dist/__tests__/integration/link.integration.test.js +0 -395
  96. package/dist/__tests__/integration/link.integration.test.js.map +0 -1
  97. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts +0 -2
  98. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts.map +0 -1
  99. package/dist/__tests__/integration/linked-config-cascade.integration.test.js +0 -179
  100. package/dist/__tests__/integration/linked-config-cascade.integration.test.js.map +0 -1
  101. package/dist/__tests__/integration/list.integration.test.d.ts +0 -2
  102. package/dist/__tests__/integration/list.integration.test.d.ts.map +0 -1
  103. package/dist/__tests__/integration/list.integration.test.js +0 -300
  104. package/dist/__tests__/integration/list.integration.test.js.map +0 -1
  105. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts +0 -2
  106. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts.map +0 -1
  107. package/dist/__tests__/integration/source-upgrade.integration.test.js +0 -100
  108. package/dist/__tests__/integration/source-upgrade.integration.test.js.map +0 -1
  109. package/dist/__tests__/integration/test-utils.d.ts +0 -30
  110. package/dist/__tests__/integration/test-utils.d.ts.map +0 -1
  111. package/dist/__tests__/integration/test-utils.js +0 -82
  112. package/dist/__tests__/integration/test-utils.js.map +0 -1
  113. package/dist/__tests__/integration/tunnel.integration.test.d.ts +0 -2
  114. package/dist/__tests__/integration/tunnel.integration.test.d.ts.map +0 -1
  115. package/dist/__tests__/integration/tunnel.integration.test.js +0 -486
  116. package/dist/__tests__/integration/tunnel.integration.test.js.map +0 -1
  117. package/dist/__tests__/integration/variable.integration.test.d.ts +0 -2
  118. package/dist/__tests__/integration/variable.integration.test.d.ts.map +0 -1
  119. package/dist/__tests__/integration/variable.integration.test.js +0 -258
  120. package/dist/__tests__/integration/variable.integration.test.js.map +0 -1
  121. package/dist/__tests__/integration/whoami.integration.test.d.ts +0 -2
  122. package/dist/__tests__/integration/whoami.integration.test.d.ts.map +0 -1
  123. package/dist/__tests__/integration/whoami.integration.test.js +0 -116
  124. package/dist/__tests__/integration/whoami.integration.test.js.map +0 -1
  125. package/dist/__tests__/outdated.test.d.ts +0 -2
  126. package/dist/__tests__/outdated.test.d.ts.map +0 -1
  127. package/dist/__tests__/outdated.test.js +0 -67
  128. package/dist/__tests__/outdated.test.js.map +0 -1
  129. package/dist/__tests__/populate.test.d.ts +0 -2
  130. package/dist/__tests__/populate.test.d.ts.map +0 -1
  131. package/dist/__tests__/populate.test.js +0 -445
  132. package/dist/__tests__/populate.test.js.map +0 -1
  133. package/dist/__tests__/tsconfig-upgrader.test.d.ts +0 -2
  134. package/dist/__tests__/tsconfig-upgrader.test.d.ts.map +0 -1
  135. package/dist/__tests__/tsconfig-upgrader.test.js +0 -31
  136. package/dist/__tests__/tsconfig-upgrader.test.js.map +0 -1
  137. package/dist/ca-certificate/validation.test.d.ts +0 -2
  138. package/dist/ca-certificate/validation.test.d.ts.map +0 -1
  139. package/dist/ca-certificate/validation.test.js +0 -131
  140. package/dist/ca-certificate/validation.test.js.map +0 -1
  141. package/dist/common/analytics/cli-invocation.test.d.ts +0 -2
  142. package/dist/common/analytics/cli-invocation.test.d.ts.map +0 -1
  143. package/dist/common/analytics/cli-invocation.test.js +0 -51
  144. package/dist/common/analytics/cli-invocation.test.js.map +0 -1
  145. package/dist/common/analytics/package-manager.test.d.ts +0 -2
  146. package/dist/common/analytics/package-manager.test.d.ts.map +0 -1
  147. package/dist/common/analytics/package-manager.test.js +0 -163
  148. package/dist/common/analytics/package-manager.test.js.map +0 -1
  149. package/dist/common/cli-dispatcher.test.d.ts +0 -2
  150. package/dist/common/cli-dispatcher.test.d.ts.map +0 -1
  151. package/dist/common/cli-dispatcher.test.js +0 -80
  152. package/dist/common/cli-dispatcher.test.js.map +0 -1
  153. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts +0 -2
  154. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts.map +0 -1
  155. package/dist/common/middleware/check-pnpm-lifecycle.test.js +0 -125
  156. package/dist/common/middleware/check-pnpm-lifecycle.test.js.map +0 -1
  157. package/dist/common/middleware/get-environment-param.test.d.ts +0 -2
  158. package/dist/common/middleware/get-environment-param.test.d.ts.map +0 -1
  159. package/dist/common/middleware/get-environment-param.test.js +0 -57
  160. package/dist/common/middleware/get-environment-param.test.js.map +0 -1
  161. package/dist/common/read-linked-config.test.d.ts +0 -2
  162. package/dist/common/read-linked-config.test.d.ts.map +0 -1
  163. package/dist/common/read-linked-config.test.js +0 -363
  164. package/dist/common/read-linked-config.test.js.map +0 -1
  165. package/dist/common/terminal.test.d.ts +0 -2
  166. package/dist/common/terminal.test.d.ts.map +0 -1
  167. package/dist/common/terminal.test.js +0 -101
  168. package/dist/common/terminal.test.js.map +0 -1
  169. package/dist/common/utils/build-environment-prompt-choices.test.d.ts +0 -2
  170. package/dist/common/utils/build-environment-prompt-choices.test.d.ts.map +0 -1
  171. package/dist/common/utils/build-environment-prompt-choices.test.js +0 -97
  172. package/dist/common/utils/build-environment-prompt-choices.test.js.map +0 -1
  173. package/dist/common/utils/format-environment-type.test.d.ts +0 -2
  174. package/dist/common/utils/format-environment-type.test.d.ts.map +0 -1
  175. package/dist/common/utils/format-environment-type.test.js +0 -32
  176. package/dist/common/utils/format-environment-type.test.js.map +0 -1
  177. package/dist/common/utils/pnpm-lifecycle.test.d.ts +0 -2
  178. package/dist/common/utils/pnpm-lifecycle.test.d.ts.map +0 -1
  179. package/dist/common/utils/pnpm-lifecycle.test.js +0 -196
  180. package/dist/common/utils/pnpm-lifecycle.test.js.map +0 -1
  181. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts +0 -2
  182. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts.map +0 -1
  183. package/dist/common/utils/pretty-print-environment-prompt.test.js +0 -42
  184. package/dist/common/utils/pretty-print-environment-prompt.test.js.map +0 -1
  185. package/dist/common/utils/sort-environments-for-prompt.test.d.ts +0 -2
  186. package/dist/common/utils/sort-environments-for-prompt.test.d.ts.map +0 -1
  187. package/dist/common/utils/sort-environments-for-prompt.test.js +0 -82
  188. package/dist/common/utils/sort-environments-for-prompt.test.js.map +0 -1
  189. package/dist/common/utils/stringify-config.test.d.ts +0 -2
  190. package/dist/common/utils/stringify-config.test.d.ts.map +0 -1
  191. package/dist/common/utils/stringify-config.test.js +0 -80
  192. package/dist/common/utils/stringify-config.test.js.map +0 -1
  193. package/dist/common/validators/argument-validators.spec.d.ts +0 -2
  194. package/dist/common/validators/argument-validators.spec.d.ts.map +0 -1
  195. package/dist/common/validators/argument-validators.spec.js +0 -181
  196. package/dist/common/validators/argument-validators.spec.js.map +0 -1
  197. package/dist/common/worker-output.test.d.ts +0 -2
  198. package/dist/common/worker-output.test.d.ts.map +0 -1
  199. package/dist/common/worker-output.test.js +0 -32
  200. package/dist/common/worker-output.test.js.map +0 -1
  201. package/dist/deploy/archive.local-registry.test.d.ts +0 -2
  202. package/dist/deploy/archive.local-registry.test.d.ts.map +0 -1
  203. package/dist/deploy/archive.local-registry.test.js +0 -100
  204. package/dist/deploy/archive.local-registry.test.js.map +0 -1
  205. package/dist/deploy/archive.test.d.ts +0 -2
  206. package/dist/deploy/archive.test.d.ts.map +0 -1
  207. package/dist/deploy/archive.test.js +0 -248
  208. package/dist/deploy/archive.test.js.map +0 -1
  209. package/dist/deploy/classify-build-probe.test.d.ts +0 -2
  210. package/dist/deploy/classify-build-probe.test.d.ts.map +0 -1
  211. package/dist/deploy/classify-build-probe.test.js +0 -51
  212. package/dist/deploy/classify-build-probe.test.js.map +0 -1
  213. package/dist/deploy/poll-deployment.test.d.ts +0 -2
  214. package/dist/deploy/poll-deployment.test.d.ts.map +0 -1
  215. package/dist/deploy/poll-deployment.test.js +0 -158
  216. package/dist/deploy/poll-deployment.test.js.map +0 -1
  217. package/dist/dev/zuplo-local-gitignore.test.d.ts +0 -2
  218. package/dist/dev/zuplo-local-gitignore.test.d.ts.map +0 -1
  219. package/dist/dev/zuplo-local-gitignore.test.js +0 -58
  220. package/dist/dev/zuplo-local-gitignore.test.js.map +0 -1
  221. package/dist/editor/e2e/editor.spec.d.ts +0 -2
  222. package/dist/editor/e2e/editor.spec.d.ts.map +0 -1
  223. package/dist/editor/e2e/editor.spec.js +0 -44
  224. package/dist/editor/e2e/editor.spec.js.map +0 -1
  225. package/dist/link/project-type.test.d.ts +0 -2
  226. package/dist/link/project-type.test.d.ts.map +0 -1
  227. package/dist/link/project-type.test.js +0 -225
  228. package/dist/link/project-type.test.js.map +0 -1
  229. package/dist/lint/resolve-binary.test.d.ts +0 -2
  230. package/dist/lint/resolve-binary.test.d.ts.map +0 -1
  231. package/dist/lint/resolve-binary.test.js +0 -155
  232. package/dist/lint/resolve-binary.test.js.map +0 -1
  233. package/dist/open-api/convert/handler.spec.d.ts +0 -2
  234. package/dist/open-api/convert/handler.spec.d.ts.map +0 -1
  235. package/dist/open-api/convert/handler.spec.js +0 -301
  236. package/dist/open-api/convert/handler.spec.js.map +0 -1
  237. package/dist/open-api/merge/handler.spec.d.ts +0 -2
  238. package/dist/open-api/merge/handler.spec.d.ts.map +0 -1
  239. package/dist/open-api/merge/handler.spec.js +0 -673
  240. package/dist/open-api/merge/handler.spec.js.map +0 -1
  241. package/dist/open-api/overlay/handler.spec.d.ts +0 -2
  242. package/dist/open-api/overlay/handler.spec.d.ts.map +0 -1
  243. package/dist/open-api/overlay/handler.spec.js +0 -346
  244. package/dist/open-api/overlay/handler.spec.js.map +0 -1
  245. package/dist/source/ai-gateway/files.test.d.ts +0 -2
  246. package/dist/source/ai-gateway/files.test.d.ts.map +0 -1
  247. package/dist/source/ai-gateway/files.test.js +0 -135
  248. package/dist/source/ai-gateway/files.test.js.map +0 -1
  249. package/dist/source/ai-gateway/handler.test.d.ts +0 -2
  250. package/dist/source/ai-gateway/handler.test.d.ts.map +0 -1
  251. package/dist/source/ai-gateway/handler.test.js +0 -113
  252. package/dist/source/ai-gateway/handler.test.js.map +0 -1
  253. package/dist/source/ai-gateway/package.test.d.ts +0 -2
  254. package/dist/source/ai-gateway/package.test.d.ts.map +0 -1
  255. package/dist/source/ai-gateway/package.test.js +0 -30
  256. package/dist/source/ai-gateway/package.test.js.map +0 -1
  257. package/dist/source/ai-gateway/planner.test.d.ts +0 -2
  258. package/dist/source/ai-gateway/planner.test.d.ts.map +0 -1
  259. package/dist/source/ai-gateway/planner.test.js +0 -330
  260. package/dist/source/ai-gateway/planner.test.js.map +0 -1
  261. package/dist/source/ai-gateway/release.test.d.ts +0 -2
  262. package/dist/source/ai-gateway/release.test.d.ts.map +0 -1
  263. package/dist/source/ai-gateway/release.test.js +0 -62
  264. package/dist/source/ai-gateway/release.test.js.map +0 -1
  265. package/dist/test/invoke-test.test.d.ts +0 -2
  266. package/dist/test/invoke-test.test.d.ts.map +0 -1
  267. package/dist/test/invoke-test.test.js +0 -150
  268. package/dist/test/invoke-test.test.js.map +0 -1
  269. package/dist/test/test-files.test.d.ts +0 -2
  270. package/dist/test/test-files.test.d.ts.map +0 -1
  271. package/dist/test/test-files.test.js +0 -57
  272. package/dist/test/test-files.test.js.map +0 -1
  273. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts +0 -2
  274. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts.map +0 -1
  275. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js +0 -289
  276. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js.map +0 -1
  277. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts +0 -2
  278. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts.map +0 -1
  279. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js +0 -181
  280. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js.map +0 -1
  281. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts +0 -2
  282. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts.map +0 -1
  283. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js +0 -399
  284. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js.map +0 -1
  285. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts +0 -2
  286. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts.map +0 -1
  287. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js +0 -779
  288. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js.map +0 -1
  289. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts +0 -2
  290. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts.map +0 -1
  291. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js +0 -269
  292. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js.map +0 -1
  293. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts +0 -2
  294. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts.map +0 -1
  295. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js +0 -93
  296. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js.map +0 -1
  297. package/node_modules/@zuplo/runtime/out/esm/chunk-6YPRGG62.js.map +0 -1
  298. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js +0 -37
  299. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js.map +0 -1
  300. /package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js.map → chunk-CDEAY3VY.js.map} +0 -0
  301. /package/node_modules/@zuplo/runtime/out/esm/{chunk-PBDT4FDO.js.LEGAL.txt → chunk-LVSZ3WTO.js.LEGAL.txt} +0 -0
  302. /package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js.map → chunk-NUVXDVLJ.js.map} +0 -0
  303. /package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js.LEGAL.txt → chunk-TPYCFLC7.js.LEGAL.txt} +0 -0
@@ -224,6 +224,8 @@ app.use('/static/*', serveStatic({ root: './static' }))
224
224
 
225
225
  Notice that `root` here is not relative to `src/index.ts`, rather to `my-hono-project`.
226
226
 
227
+ Only `GET` and `HEAD` requests are served. Requests with other methods are passed to the next middleware.
228
+
227
229
  ### Options
228
230
 
229
231
  #### `allowPercentInPath`
@@ -846,7 +846,7 @@ const makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
846
846
  if (incoming.errored) {
847
847
  recordBodyBufferedBeforeDisconnect(incoming);
848
848
  req[abortRequest](incoming.errored.toString());
849
- } else if (!outgoing.writableFinished) {
849
+ } else if (!outgoing.writableFinished || incoming instanceof node_http2.Http2ServerRequest && incoming.aborted) {
850
850
  recordBodyBufferedBeforeDisconnect(incoming);
851
851
  req[abortRequest]("Client connection prematurely closed.");
852
852
  }
@@ -845,7 +845,7 @@ const makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
845
845
  if (incoming.errored) {
846
846
  recordBodyBufferedBeforeDisconnect(incoming);
847
847
  req[abortRequest](incoming.errored.toString());
848
- } else if (!outgoing.writableFinished) {
848
+ } else if (!outgoing.writableFinished || incoming instanceof Http2ServerRequest && incoming.aborted) {
849
849
  recordBodyBufferedBeforeDisconnect(incoming);
850
850
  req[abortRequest]("Client connection prematurely closed.");
851
851
  }
@@ -74,6 +74,7 @@ const serveStatic = (options = { root: "" }) => {
74
74
  if (root !== "" && !(0, node_fs.existsSync)(root)) console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
75
75
  return async (c, next) => {
76
76
  if (c.finalized) return next();
77
+ if (c.req.method !== "GET" && c.req.method !== "HEAD") return next();
77
78
  let filename;
78
79
  if (optionPath) filename = optionPath;
79
80
  else try {
@@ -115,7 +116,7 @@ const serveStatic = (options = { root: "" }) => {
115
116
  const size = stats.size;
116
117
  const range = c.req.header("range") || "";
117
118
  c.header("Last-Modified", stats.mtime.toUTCString());
118
- if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
119
+ if (c.req.method === "HEAD") {
119
120
  c.header("Content-Length", size.toString());
120
121
  c.status(200);
121
122
  result = c.body(null);
@@ -73,6 +73,7 @@ const serveStatic = (options = { root: "" }) => {
73
73
  if (root !== "" && !existsSync(root)) console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
74
74
  return async (c, next) => {
75
75
  if (c.finalized) return next();
76
+ if (c.req.method !== "GET" && c.req.method !== "HEAD") return next();
76
77
  let filename;
77
78
  if (optionPath) filename = optionPath;
78
79
  else try {
@@ -114,7 +115,7 @@ const serveStatic = (options = { root: "" }) => {
114
115
  const size = stats.size;
115
116
  const range = c.req.header("range") || "";
116
117
  c.header("Last-Modified", stats.mtime.toUTCString());
117
- if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
118
+ if (c.req.method === "HEAD") {
118
119
  c.header("Content-Length", size.toString());
119
120
  c.status(200);
120
121
  result = c.body(null);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono/node-server",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "Node.js Adapter for Hono",
5
5
  "main": "dist/index.mjs",
6
6
  "type": "module",
@@ -14,6 +14,10 @@ import type { MetricsHost, ResolvedPostHogMetricsConfig } from './types';
14
14
  * Deliberately unlike logs, no per-user context (distinct ID, session ID) is
15
15
  * attached: every attribute value creates a new series, and per-user series
16
16
  * are the canonical metrics-cardinality explosion.
17
+ *
18
+ * A sample recorded inside a sampled span stamps its series with an exemplar
19
+ * (trace ID, span ID, value). One per series per window, last sample wins, so a
20
+ * metric point links to one representative trace at no cardinality cost.
17
21
  */
18
22
  export declare class PostHogMetrics {
19
23
  private readonly _instance;
@@ -46,6 +50,11 @@ export declare class PostHogMetrics {
46
50
  /** Clears the flush timer, drops the current window, and invalidates in-flight flushes. */
47
51
  reset(): void;
48
52
  private _capture;
53
+ /**
54
+ * The sampled span a sample is recorded in. An unsampled span is never
55
+ * exported, so an exemplar pointing at it would link to a missing trace.
56
+ */
57
+ private _activeTraceContext;
49
58
  /**
50
59
  * Cardinality gate for adding a series to the live window — warns once per
51
60
  * window when the cap is hit. Applied on capture and on merge-back alike.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAMpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AActC,OAAO,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AA2BxE;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;IA0BvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IA3B1B,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAI3B;IAGD,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,gBAAgB,CAAQ;IAIhC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,yBAAyB,CAAI;IACrC,OAAO,CAAC,YAAY,CAAY;IAIhC,OAAO,CAAC,WAAW,CAAI;IAEvB,YACmB,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE,MAAM,EAC9B;IAEJ,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAE3E;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAEvE;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAE3E;IAED,iFAAiF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAerB;IAED;;;;;;OAMG;IACH,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAUvC;IAED,2FAA2F;IAC3F,KAAK,IAAI,IAAI,CAWZ;IAED,OAAO,CAAC,QAAQ;IAsEhB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,KAAK;IA6Bb,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,eAAe;YAYT,QAAQ;IAyDtB,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAwDrB,oFAAoF;IACpF,OAAO,CAAC,gBAAgB;CAqCzB;AAED,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AACnH,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAOpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAetC,OAAO,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AAoCxE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAc;IA0BvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IA3B1B,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAI3B;IAGD,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,gBAAgB,CAAQ;IAIhC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,yBAAyB,CAAI;IACrC,OAAO,CAAC,YAAY,CAAY;IAIhC,OAAO,CAAC,WAAW,CAAI;IAEvB,YACmB,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE,MAAM,EAC9B;IAEJ,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAE3E;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAEvE;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAE3E;IAED,iFAAiF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAerB;IAED;;;;;;OAMG;IACH,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAUvC;IAED,2FAA2F;IAC3F,KAAK,IAAI,IAAI,CAWZ;IAED,OAAO,CAAC,QAAQ;IA0EhB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,KAAK;IA6Bb,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,eAAe;YAYT,QAAQ;IAyDtB,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IA4DrB,oFAAoF;IACpF,OAAO,CAAC,gBAAgB;CAuCzB;AAqBD,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AACnH,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA"}
@@ -39,6 +39,7 @@ const flush_timer_js_namespaceObject = require("../utils/flush-timer.js");
39
39
  const retry_after_js_namespaceObject = require("../utils/retry-after.js");
40
40
  const backoff_js_namespaceObject = require("../utils/backoff.js");
41
41
  const otlp_any_value_js_namespaceObject = require("../utils/otlp-any-value.js");
42
+ const traceparent_js_namespaceObject = require("../traces/traceparent.js");
42
43
  const external_metrics_utils_js_namespaceObject = require("./metrics-utils.js");
43
44
  const external_config_js_namespaceObject = require("./config.js");
44
45
  const OTLP_TEMPORALITY_DELTA = 1;
@@ -157,8 +158,23 @@ class PostHogMetrics {
157
158
  this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
158
159
  }
159
160
  this._fold(state, filtered.value);
161
+ const traceContext = this._activeTraceContext();
162
+ if (traceContext) state.exemplar = {
163
+ ...traceContext,
164
+ value: filtered.value,
165
+ timeMs: Date.now()
166
+ };
160
167
  this._armFlushTimer();
161
168
  }
169
+ _activeTraceContext() {
170
+ try {
171
+ const parsed = (0, traceparent_js_namespaceObject.parseTraceparent)(this._instance.getActiveSpan?.()?.traceparent());
172
+ if (parsed && parsed.flags === traceparent_js_namespaceObject.TRACE_FLAGS_SAMPLED) return {
173
+ traceId: parsed.traceId,
174
+ spanId: parsed.spanId
175
+ };
176
+ } catch {}
177
+ }
162
178
  _admitNewSeries() {
163
179
  if (this._series.size < this._config.maxSeriesPerFlush) return true;
164
180
  if (!this._seriesCapWarned) {
@@ -288,19 +304,22 @@ class PostHogMetrics {
288
304
  }
289
305
  const attributes = (0, otlp_any_value_js_namespaceObject.toOtlpKeyValueList)(state.attributes ?? {}, this._logger);
290
306
  const startNano = (0, external_metrics_utils_js_namespaceObject.msToUnixNano)(state.windowStartMs);
307
+ const exemplars = toOtlpExemplars(state.exemplar);
291
308
  if ('count' === state.type) {
292
309
  const dp = {
293
310
  attributes,
294
311
  startTimeUnixNano: startNano,
295
312
  timeUnixNano: nowNano,
296
- asDouble: state.total ?? 0
313
+ asDouble: state.total ?? 0,
314
+ ...exemplars
297
315
  };
298
316
  metric.sum.dataPoints.push(dp);
299
317
  } else if ('gauge' === state.type) {
300
318
  const dp = {
301
319
  attributes,
302
320
  timeUnixNano: nowNano,
303
- asDouble: state.last ?? 0
321
+ asDouble: state.last ?? 0,
322
+ ...exemplars
304
323
  };
305
324
  metric.gauge.dataPoints.push(dp);
306
325
  } else if (state.hist) {
@@ -313,7 +332,8 @@ class PostHogMetrics {
313
332
  min: state.hist.min,
314
333
  max: state.hist.max,
315
334
  bucketCounts: state.hist.bucketCounts,
316
- explicitBounds: external_metrics_utils_js_namespaceObject.DEFAULT_HISTOGRAM_BOUNDS
335
+ explicitBounds: external_metrics_utils_js_namespaceObject.DEFAULT_HISTOGRAM_BOUNDS,
336
+ ...exemplars
317
337
  };
318
338
  metric.histogram.dataPoints.push(dp);
319
339
  }
@@ -328,6 +348,7 @@ class PostHogMetrics {
328
348
  continue;
329
349
  }
330
350
  current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
351
+ current.exemplar = current.exemplar ?? old.exemplar;
331
352
  switch(current.type){
332
353
  case 'count':
333
354
  current.total = (current.total ?? 0) + (old.total ?? 0);
@@ -347,6 +368,20 @@ class PostHogMetrics {
347
368
  }
348
369
  }
349
370
  }
371
+ function toOtlpExemplars(exemplar) {
372
+ if (!exemplar) return {};
373
+ return {
374
+ exemplars: [
375
+ {
376
+ filteredAttributes: [],
377
+ timeUnixNano: (0, external_metrics_utils_js_namespaceObject.msToUnixNano)(exemplar.timeMs),
378
+ asDouble: exemplar.value,
379
+ traceId: exemplar.traceId,
380
+ spanId: exemplar.spanId
381
+ }
382
+ ]
383
+ };
384
+ }
350
385
  exports.DEFAULT_HISTOGRAM_BOUNDS = __webpack_exports__.DEFAULT_HISTOGRAM_BOUNDS;
351
386
  exports.PostHogMetrics = __webpack_exports__.PostHogMetrics;
352
387
  exports.buildMetricsResourceAttributes = __webpack_exports__.buildMetricsResourceAttributes;
@@ -3,6 +3,7 @@ import { FlushTimer } from "../utils/flush-timer.mjs";
3
3
  import { RetryAfterWindow } from "../utils/retry-after.mjs";
4
4
  import { MAX_FLUSH_BACKOFF_MS, NO_JITTER, backoffDelayMs, drawJitter } from "../utils/backoff.mjs";
5
5
  import { toOtlpKeyValueList } from "../utils/otlp-any-value.mjs";
6
+ import { TRACE_FLAGS_SAMPLED, parseTraceparent } from "../traces/traceparent.mjs";
6
7
  import { DEFAULT_HISTOGRAM_BOUNDS, bucketIndexFor, buildMetricsResourceAttributes, buildOtlpMetricsPayload, msToUnixNano, seriesKey } from "./metrics-utils.mjs";
7
8
  const OTLP_TEMPORALITY_DELTA = 1;
8
9
  class PostHogMetrics {
@@ -120,8 +121,23 @@ class PostHogMetrics {
120
121
  this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
121
122
  }
122
123
  this._fold(state, filtered.value);
124
+ const traceContext = this._activeTraceContext();
125
+ if (traceContext) state.exemplar = {
126
+ ...traceContext,
127
+ value: filtered.value,
128
+ timeMs: Date.now()
129
+ };
123
130
  this._armFlushTimer();
124
131
  }
132
+ _activeTraceContext() {
133
+ try {
134
+ const parsed = parseTraceparent(this._instance.getActiveSpan?.()?.traceparent());
135
+ if (parsed && parsed.flags === TRACE_FLAGS_SAMPLED) return {
136
+ traceId: parsed.traceId,
137
+ spanId: parsed.spanId
138
+ };
139
+ } catch {}
140
+ }
125
141
  _admitNewSeries() {
126
142
  if (this._series.size < this._config.maxSeriesPerFlush) return true;
127
143
  if (!this._seriesCapWarned) {
@@ -251,19 +267,22 @@ class PostHogMetrics {
251
267
  }
252
268
  const attributes = toOtlpKeyValueList(state.attributes ?? {}, this._logger);
253
269
  const startNano = msToUnixNano(state.windowStartMs);
270
+ const exemplars = toOtlpExemplars(state.exemplar);
254
271
  if ('count' === state.type) {
255
272
  const dp = {
256
273
  attributes,
257
274
  startTimeUnixNano: startNano,
258
275
  timeUnixNano: nowNano,
259
- asDouble: state.total ?? 0
276
+ asDouble: state.total ?? 0,
277
+ ...exemplars
260
278
  };
261
279
  metric.sum.dataPoints.push(dp);
262
280
  } else if ('gauge' === state.type) {
263
281
  const dp = {
264
282
  attributes,
265
283
  timeUnixNano: nowNano,
266
- asDouble: state.last ?? 0
284
+ asDouble: state.last ?? 0,
285
+ ...exemplars
267
286
  };
268
287
  metric.gauge.dataPoints.push(dp);
269
288
  } else if (state.hist) {
@@ -276,7 +295,8 @@ class PostHogMetrics {
276
295
  min: state.hist.min,
277
296
  max: state.hist.max,
278
297
  bucketCounts: state.hist.bucketCounts,
279
- explicitBounds: DEFAULT_HISTOGRAM_BOUNDS
298
+ explicitBounds: DEFAULT_HISTOGRAM_BOUNDS,
299
+ ...exemplars
280
300
  };
281
301
  metric.histogram.dataPoints.push(dp);
282
302
  }
@@ -291,6 +311,7 @@ class PostHogMetrics {
291
311
  continue;
292
312
  }
293
313
  current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
314
+ current.exemplar = current.exemplar ?? old.exemplar;
294
315
  switch(current.type){
295
316
  case 'count':
296
317
  current.total = (current.total ?? 0) + (old.total ?? 0);
@@ -310,5 +331,19 @@ class PostHogMetrics {
310
331
  }
311
332
  }
312
333
  }
334
+ function toOtlpExemplars(exemplar) {
335
+ if (!exemplar) return {};
336
+ return {
337
+ exemplars: [
338
+ {
339
+ filteredAttributes: [],
340
+ timeUnixNano: msToUnixNano(exemplar.timeMs),
341
+ asDouble: exemplar.value,
342
+ traceId: exemplar.traceId,
343
+ spanId: exemplar.spanId
344
+ }
345
+ ]
346
+ };
347
+ }
313
348
  export { resolveMetricsConfig } from "./config.mjs";
314
349
  export { DEFAULT_HISTOGRAM_BOUNDS, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpMetricsPayload };
@@ -1,5 +1,5 @@
1
- export type { MetricAttributeValue, MetricAttributes, MetricType, MetricsConfig, CaptureMetricOptions, MetricSample, BeforeSendMetricFn, Metrics, OtlpNumberDataPoint, OtlpHistogramDataPoint, OtlpMetric, OtlpMetricsPayload, } from '@posthog/types';
2
- import type { BeforeSendMetricFn, MetricAttributeValue, OtlpMetricsPayload } from '@posthog/types';
1
+ export type { MetricAttributeValue, MetricAttributes, MetricType, MetricsConfig, CaptureMetricOptions, MetricSample, BeforeSendMetricFn, Metrics, OtlpNumberDataPoint, OtlpHistogramDataPoint, OtlpMetric, OtlpMetricsPayload, OtlpExemplar, } from '@posthog/types';
2
+ import type { BeforeSendMetricFn, MetricAttributeValue, OtlpMetricsPayload, Span } from '@posthog/types';
3
3
  /** Same tagged outcome shape as `SendLogsBatchOutcome` — one policy for both signals. */
4
4
  export type SendMetricsBatchOutcome = {
5
5
  kind: 'ok';
@@ -30,6 +30,11 @@ export interface MetricsHost {
30
30
  _sendMetricsBatch(payload: OtlpMetricsPayload): Promise<SendMetricsBatchOutcome>;
31
31
  getLibraryId(): string;
32
32
  getLibraryVersion(): string;
33
+ /**
34
+ * The span active where a sample is recorded. A sampled one stamps the
35
+ * sample's series with an exemplar. Hosts without tracing leave it out.
36
+ */
37
+ getActiveSpan?(): Span | null;
33
38
  }
34
39
  /**
35
40
  * Configuration for the metrics feature on `new PostHog(key, { metrics: ... })`.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAElG,yFAAyF;AACzF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IACE,IAAI,EAAE,WAAW,CAAA;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAErC;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAChF,YAAY,IAAI,MAAM,CAAA;IACtB,iBAAiB,IAAI,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAEzD;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAA;CACvD;AAID,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAExG,yFAAyF;AACzF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IACE,IAAI,EAAE,WAAW,CAAA;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAErC;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAChF,YAAY,IAAI,MAAM,CAAA;IACtB,iBAAiB,IAAI,MAAM,CAAA;IAC3B;;;OAGG;IACH,aAAa,CAAC,IAAI,IAAI,GAAG,IAAI,CAAA;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAEzD;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAA;CACvD;AAID,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;CAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/traces/ids.ts"],"names":[],"mappings":"AAkBA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAe7D;AAiBD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D"}
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/traces/ids.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAe7D;AAiBD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D"}
@@ -31,8 +31,8 @@ const TRACE_ID_BYTES = 16;
31
31
  const SPAN_ID_BYTES = 8;
32
32
  const TRACE_ID_HEX = 2 * TRACE_ID_BYTES;
33
33
  const SPAN_ID_HEX = 2 * SPAN_ID_BYTES;
34
- const INVALID_TRACE_ID = '0'.repeat(TRACE_ID_HEX);
35
- const INVALID_SPAN_ID = '0'.repeat(SPAN_ID_HEX);
34
+ const INVALID_SPAN_ID = '0000000000000000';
35
+ const INVALID_TRACE_ID = INVALID_SPAN_ID + INVALID_SPAN_ID;
36
36
  const HEX_RE = /^[0-9a-f]+$/;
37
37
  function getRandomBytes(byteLength) {
38
38
  const bytes = new Uint8Array(byteLength);
@@ -2,8 +2,8 @@ const TRACE_ID_BYTES = 16;
2
2
  const SPAN_ID_BYTES = 8;
3
3
  const TRACE_ID_HEX = 2 * TRACE_ID_BYTES;
4
4
  const SPAN_ID_HEX = 2 * SPAN_ID_BYTES;
5
- const INVALID_TRACE_ID = '0'.repeat(TRACE_ID_HEX);
6
- const INVALID_SPAN_ID = '0'.repeat(SPAN_ID_HEX);
5
+ const INVALID_SPAN_ID = '0000000000000000';
6
+ const INVALID_TRACE_ID = INVALID_SPAN_ID + INVALID_SPAN_ID;
7
7
  const HEX_RE = /^[0-9a-f]+$/;
8
8
  function getRandomBytes(byteLength) {
9
9
  const bytes = new Uint8Array(byteLength);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/core",
3
- "version": "1.58.1",
3
+ "version": "1.59.0",
4
4
  "bugs": {
5
5
  "url": "https://github.com/PostHog/posthog-js/issues"
6
6
  },
@@ -72,7 +72,7 @@
72
72
  }
73
73
  },
74
74
  "dependencies": {
75
- "@posthog/types": "^1.415.3"
75
+ "@posthog/types": "^1.416.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@rslib/core": "0.23.2",
@@ -203,6 +203,81 @@ describe('PostHogMetrics', () => {
203
203
  })
204
204
  })
205
205
 
206
+ describe('exemplars', () => {
207
+ const TRACE_ID = '4bf92f3577b34da6a3ce929d0e0e4736'
208
+ const SPAN_ID = '00f067aa0ba902b7'
209
+ const withActiveSpan = (traceparent: string | null): any =>
210
+ createMockInstance({ getActiveSpan: () => ({ traceparent: () => traceparent }) })
211
+
212
+ const dataPoints = (instance: any): any[] =>
213
+ sentMetrics(instance).map((m) => (m.sum ?? m.gauge ?? m.histogram)!.dataPoints[0])
214
+
215
+ it('stamps every metric type with the last sample recorded inside a sampled span', async () => {
216
+ const instance = withActiveSpan(`00-${TRACE_ID}-${SPAN_ID}-01`)
217
+ const metrics = createMetrics(undefined, instance)
218
+ metrics.count('c', 1)
219
+ metrics.count('c', 4)
220
+ metrics.gauge('g', 7)
221
+ metrics.histogram('h', 12)
222
+ await metrics.flush()
223
+
224
+ const points = dataPoints(instance)
225
+ expect(points.map((p) => p.exemplars)).toEqual(
226
+ [4, 7, 12].map((value) => [
227
+ {
228
+ filteredAttributes: [],
229
+ timeUnixNano: expect.stringMatching(/^\d+$/),
230
+ asDouble: value,
231
+ traceId: TRACE_ID,
232
+ spanId: SPAN_ID,
233
+ },
234
+ ])
235
+ )
236
+ })
237
+
238
+ it.each([
239
+ ['no getActiveSpan on the host', createMockInstance],
240
+ ['no active span', () => createMockInstance({ getActiveSpan: () => null })],
241
+ ['an unsampled span', () => withActiveSpan(`00-${TRACE_ID}-${SPAN_ID}-00`)],
242
+ ['a span with no traceparent', () => withActiveSpan(null)],
243
+ [
244
+ 'a throwing host',
245
+ () =>
246
+ createMockInstance({
247
+ getActiveSpan: () => {
248
+ throw new Error('boom')
249
+ },
250
+ }),
251
+ ],
252
+ ])('records the sample without an exemplar for %s', async (_, makeInstance) => {
253
+ const instance = makeInstance()
254
+ const metrics = createMetrics(undefined, instance)
255
+ metrics.count('c', 2)
256
+ await metrics.flush()
257
+
258
+ const [point] = dataPoints(instance)
259
+ expect(point.asDouble).toBe(2)
260
+ expect(point).not.toHaveProperty('exemplars')
261
+ })
262
+
263
+ it('keeps the exemplar of a window merged back after a failed flush', async () => {
264
+ const instance = withActiveSpan(`00-${TRACE_ID}-${SPAN_ID}-01`)
265
+ instance._sendMetricsBatch
266
+ .mockResolvedValueOnce({ kind: 'retry-later', error: new Error('503') })
267
+ .mockResolvedValue({ kind: 'ok' })
268
+ const metrics = createMetrics(undefined, instance)
269
+ metrics.count('c', 1)
270
+ await metrics.flush()
271
+ instance.getActiveSpan = () => null
272
+ metrics.count('c', 2)
273
+ await metrics.flush()
274
+
275
+ const point = dataPoints(instance)[1]
276
+ expect(point.asDouble).toBe(3)
277
+ expect(point.exemplars[0]).toMatchObject({ traceId: TRACE_ID, spanId: SPAN_ID, asDouble: 1 })
278
+ })
279
+ })
280
+
206
281
  describe('resource attributes', () => {
207
282
  it('attaches service.name, sdk identity, and user resource attributes', async () => {
208
283
  const metrics = createMetrics({
@@ -3,6 +3,7 @@ import type {
3
3
  MetricAttributes,
4
4
  MetricSample,
5
5
  MetricType,
6
+ OtlpExemplar,
6
7
  OtlpHistogramDataPoint,
7
8
  OtlpMetric,
8
9
  OtlpMetricsPayload,
@@ -14,6 +15,7 @@ import { FlushTimer } from '../utils/flush-timer'
14
15
  import { RetryAfterWindow } from '../utils/retry-after'
15
16
  import { MAX_FLUSH_BACKOFF_MS, NO_JITTER, backoffDelayMs, drawJitter } from '../utils/backoff'
16
17
  import { toOtlpKeyValueList } from '../utils/otlp-any-value'
18
+ import { TRACE_FLAGS_SAMPLED, parseTraceparent } from '../traces/traceparent'
17
19
  import {
18
20
  DEFAULT_HISTOGRAM_BOUNDS,
19
21
  bucketIndexFor,
@@ -26,6 +28,13 @@ import type { MetricsHost, ResolvedPostHogMetricsConfig } from './types'
26
28
 
27
29
  const OTLP_TEMPORALITY_DELTA = 1
28
30
 
31
+ interface ExemplarState {
32
+ traceId: string
33
+ spanId: string
34
+ value: number
35
+ timeMs: number
36
+ }
37
+
29
38
  interface HistogramState {
30
39
  count: number
31
40
  sum: number
@@ -47,6 +56,8 @@ interface SeriesState {
47
56
  total?: number
48
57
  last?: number
49
58
  hist?: HistogramState
59
+ /** The last sample recorded inside a sampled span this window. */
60
+ exemplar?: ExemplarState
50
61
  }
51
62
 
52
63
  /**
@@ -62,6 +73,10 @@ interface SeriesState {
62
73
  * Deliberately unlike logs, no per-user context (distinct ID, session ID) is
63
74
  * attached: every attribute value creates a new series, and per-user series
64
75
  * are the canonical metrics-cardinality explosion.
76
+ *
77
+ * A sample recorded inside a sampled span stamps its series with an exemplar
78
+ * (trace ID, span ID, value). One per series per window, last sample wins, so a
79
+ * metric point links to one representative trace at no cardinality cost.
65
80
  */
66
81
  export class PostHogMetrics {
67
82
  private _series = new Map<string, SeriesState>()
@@ -224,9 +239,29 @@ export class PostHogMetrics {
224
239
  }
225
240
 
226
241
  this._fold(state, filtered.value)
242
+ const traceContext = this._activeTraceContext()
243
+ if (traceContext) {
244
+ state.exemplar = { ...traceContext, value: filtered.value, timeMs: Date.now() }
245
+ }
227
246
  this._armFlushTimer()
228
247
  }
229
248
 
249
+ /**
250
+ * The sampled span a sample is recorded in. An unsampled span is never
251
+ * exported, so an exemplar pointing at it would link to a missing trace.
252
+ */
253
+ private _activeTraceContext(): { traceId: string; spanId: string } | undefined {
254
+ try {
255
+ const parsed = parseTraceparent(this._instance.getActiveSpan?.()?.traceparent())
256
+ if (parsed && parsed.flags === TRACE_FLAGS_SAMPLED) {
257
+ return { traceId: parsed.traceId, spanId: parsed.spanId }
258
+ }
259
+ } catch {
260
+ // A throwing host never costs the sample itself.
261
+ }
262
+ return undefined
263
+ }
264
+
230
265
  /**
231
266
  * Cardinality gate for adding a series to the live window — warns once per
232
267
  * window when the cap is hit. Applied on capture and on merge-back alike.
@@ -413,6 +448,7 @@ export class PostHogMetrics {
413
448
 
414
449
  const attributes = toOtlpKeyValueList(state.attributes ?? {}, this._logger)
415
450
  const startNano = msToUnixNano(state.windowStartMs)
451
+ const exemplars = toOtlpExemplars(state.exemplar)
416
452
 
417
453
  if (state.type === 'count') {
418
454
  const dp: OtlpNumberDataPoint = {
@@ -420,6 +456,7 @@ export class PostHogMetrics {
420
456
  startTimeUnixNano: startNano,
421
457
  timeUnixNano: nowNano,
422
458
  asDouble: state.total ?? 0,
459
+ ...exemplars,
423
460
  }
424
461
  metric.sum!.dataPoints.push(dp)
425
462
  } else if (state.type === 'gauge') {
@@ -427,6 +464,7 @@ export class PostHogMetrics {
427
464
  attributes,
428
465
  timeUnixNano: nowNano,
429
466
  asDouble: state.last ?? 0,
467
+ ...exemplars,
430
468
  }
431
469
  metric.gauge!.dataPoints.push(dp)
432
470
  } else if (state.hist) {
@@ -440,6 +478,7 @@ export class PostHogMetrics {
440
478
  max: state.hist.max,
441
479
  bucketCounts: state.hist.bucketCounts,
442
480
  explicitBounds: DEFAULT_HISTOGRAM_BOUNDS,
481
+ ...exemplars,
443
482
  }
444
483
  metric.histogram!.dataPoints.push(dp)
445
484
  }
@@ -461,6 +500,8 @@ export class PostHogMetrics {
461
500
  continue
462
501
  }
463
502
  current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs)
503
+ // The live window's exemplar is newer; the old one only fills a gap.
504
+ current.exemplar = current.exemplar ?? old.exemplar
464
505
  switch (current.type) {
465
506
  case 'count':
466
507
  current.total = (current.total ?? 0) + (old.total ?? 0)
@@ -488,6 +529,25 @@ export class PostHogMetrics {
488
529
  }
489
530
  }
490
531
 
532
+ // Spread into the data point, so a point without an exemplar keeps its exact
533
+ // pre-exemplar wire shape.
534
+ function toOtlpExemplars(exemplar: ExemplarState | undefined): { exemplars?: OtlpExemplar[] } {
535
+ if (!exemplar) {
536
+ return {}
537
+ }
538
+ return {
539
+ exemplars: [
540
+ {
541
+ filteredAttributes: [],
542
+ timeUnixNano: msToUnixNano(exemplar.timeMs),
543
+ asDouble: exemplar.value,
544
+ traceId: exemplar.traceId,
545
+ spanId: exemplar.spanId,
546
+ },
547
+ ],
548
+ }
549
+ }
550
+
491
551
  export { buildOtlpMetricsPayload, buildMetricsResourceAttributes, DEFAULT_HISTOGRAM_BOUNDS } from './metrics-utils'
492
552
  export { resolveMetricsConfig } from './config'
493
553
  export type { MetricsHost, PostHogMetricsConfig, ResolvedPostHogMetricsConfig, SendMetricsBatchOutcome } from './types'
@@ -13,9 +13,10 @@ export type {
13
13
  OtlpHistogramDataPoint,
14
14
  OtlpMetric,
15
15
  OtlpMetricsPayload,
16
+ OtlpExemplar,
16
17
  } from '@posthog/types'
17
18
 
18
- import type { BeforeSendMetricFn, MetricAttributeValue, OtlpMetricsPayload } from '@posthog/types'
19
+ import type { BeforeSendMetricFn, MetricAttributeValue, OtlpMetricsPayload, Span } from '@posthog/types'
19
20
 
20
21
  /** Same tagged outcome shape as `SendLogsBatchOutcome` — one policy for both signals. */
21
22
  export type SendMetricsBatchOutcome =
@@ -43,6 +44,11 @@ export interface MetricsHost {
43
44
  _sendMetricsBatch(payload: OtlpMetricsPayload): Promise<SendMetricsBatchOutcome>
44
45
  getLibraryId(): string
45
46
  getLibraryVersion(): string
47
+ /**
48
+ * The span active where a sample is recorded. A sampled one stamps the
49
+ * sample's series with an exemplar. Hosts without tracing leave it out.
50
+ */
51
+ getActiveSpan?(): Span | null
46
52
  }
47
53
 
48
54
  /**
@@ -9,8 +9,10 @@ const SPAN_ID_BYTES = 8
9
9
  const TRACE_ID_HEX = TRACE_ID_BYTES * 2
10
10
  const SPAN_ID_HEX = SPAN_ID_BYTES * 2
11
11
 
12
- const INVALID_TRACE_ID = '0'.repeat(TRACE_ID_HEX)
13
- const INVALID_SPAN_ID = '0'.repeat(SPAN_ID_HEX)
12
+ // Spelled out rather than `'0'.repeat(...)`: this runs at module load and the
13
+ // browser bundle, which reaches it through metrics, still loads in IE11.
14
+ const INVALID_SPAN_ID = '0000000000000000'
15
+ const INVALID_TRACE_ID = INVALID_SPAN_ID + INVALID_SPAN_ID
14
16
 
15
17
  const HEX_RE = /^[0-9a-f]+$/
16
18