@apifuse/provider-sdk 2.2.0-beta.61 → 2.2.0-beta.63

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 (258) hide show
  1. package/AUTHORING.md +268 -9
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +1 -0
  4. package/bin/apifuse-check.ts +84 -2
  5. package/bin/apifuse-dev.ts +11 -31
  6. package/bin/apifuse-migrate-deployment.ts +200 -0
  7. package/bin/apifuse-pack-check.ts +11 -4
  8. package/bin/apifuse-pack-types.ts +191 -4
  9. package/bin/apifuse-record.ts +44 -32
  10. package/bin/apifuse-test.ts +3 -1
  11. package/dist/cli/commands.d.ts +1 -1
  12. package/dist/cli/commands.js +11 -0
  13. package/dist/cli/deployment-intent.d.ts +178 -0
  14. package/dist/cli/deployment-intent.js +277 -0
  15. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  16. package/dist/cli/migrate-deployment-intent.js +1552 -0
  17. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  18. package/dist/cli/migrate-provider-shape.js +4 -2
  19. package/dist/cli/resolver-runtime.d.ts +21 -0
  20. package/dist/cli/resolver-runtime.js +31 -0
  21. package/dist/define.d.ts +3 -0
  22. package/dist/define.js +5 -0
  23. package/dist/dev.d.ts +3 -1
  24. package/dist/dev.js +6 -1
  25. package/dist/engine.d.ts +35 -1
  26. package/dist/engine.js +21 -2
  27. package/dist/error-resolution.d.ts +1 -0
  28. package/dist/error-resolution.js +54 -0
  29. package/dist/errors.d.ts +39 -1
  30. package/dist/errors.js +50 -0
  31. package/dist/handle-meta.d.ts +18 -2
  32. package/dist/handle-meta.js +30 -2
  33. package/dist/handle.d.ts +33 -12
  34. package/dist/handle.js +69 -24
  35. package/dist/i18n/error-messages.d.ts +86 -0
  36. package/dist/i18n/error-messages.js +192 -0
  37. package/dist/i18n/index.d.ts +1 -0
  38. package/dist/i18n/index.js +1 -0
  39. package/dist/i18n/keys.d.ts +12 -0
  40. package/dist/i18n/keys.js +76 -5
  41. package/dist/index.d.ts +10 -2
  42. package/dist/index.js +9 -1
  43. package/dist/lint.d.ts +10 -0
  44. package/dist/lint.js +440 -57
  45. package/dist/provider.d.ts +7 -5
  46. package/dist/provider.js +4 -2
  47. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  48. package/dist/runtime/browser-telemetry-binding.js +83 -0
  49. package/dist/runtime/browser-telemetry.d.ts +76 -0
  50. package/dist/runtime/browser-telemetry.js +165 -0
  51. package/dist/runtime/browser.d.ts +3 -0
  52. package/dist/runtime/browser.js +208 -47
  53. package/dist/runtime/cache-telemetry.d.ts +71 -0
  54. package/dist/runtime/cache-telemetry.js +177 -0
  55. package/dist/runtime/cache.js +67 -7
  56. package/dist/runtime/capability-response.d.ts +3 -0
  57. package/dist/runtime/capability-response.js +56 -0
  58. package/dist/runtime/capability-telemetry.d.ts +46 -0
  59. package/dist/runtime/capability-telemetry.js +68 -0
  60. package/dist/runtime/diagnostic-env.d.ts +3 -0
  61. package/dist/runtime/diagnostic-env.js +10 -1
  62. package/dist/runtime/engine-mode.d.ts +74 -0
  63. package/dist/runtime/engine-mode.js +152 -0
  64. package/dist/runtime/handle.js +15 -10
  65. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  66. package/dist/runtime/http-telemetry-binding.js +152 -0
  67. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  68. package/dist/runtime/http-telemetry-guard.js +202 -0
  69. package/dist/runtime/http-telemetry.d.ts +104 -0
  70. package/dist/runtime/http-telemetry.js +190 -0
  71. package/dist/runtime/http.d.ts +31 -0
  72. package/dist/runtime/http.js +356 -174
  73. package/dist/runtime/instrumentation.js +92 -13
  74. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  75. package/dist/runtime/ocr-telemetry.js +192 -0
  76. package/dist/runtime/ocr.js +30 -8
  77. package/dist/runtime/request-telemetry.d.ts +2 -0
  78. package/dist/runtime/request-telemetry.js +2 -1
  79. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  80. package/dist/runtime/resolver-runtime-options.js +33 -0
  81. package/dist/runtime/resolver-shared.d.ts +3 -2
  82. package/dist/runtime/resolver-shared.js +4 -4
  83. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  84. package/dist/runtime/resolver-telemetry.js +1 -1
  85. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  86. package/dist/runtime/resolver-vendors/browser.js +46 -0
  87. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  88. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  89. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  90. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  91. package/dist/runtime/resolver.d.ts +4 -1
  92. package/dist/runtime/resolver.js +46 -13
  93. package/dist/runtime/state-telemetry.d.ts +79 -0
  94. package/dist/runtime/state-telemetry.js +194 -0
  95. package/dist/runtime/state.d.ts +3 -0
  96. package/dist/runtime/state.js +26 -7
  97. package/dist/runtime/stealth-cookies.d.ts +5 -1
  98. package/dist/runtime/stealth-cookies.js +21 -1
  99. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  100. package/dist/runtime/stealth-owned-headers.js +37 -0
  101. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  102. package/dist/runtime/stealth-telemetry.js +179 -0
  103. package/dist/runtime/stealth.d.ts +4 -1
  104. package/dist/runtime/stealth.js +228 -85
  105. package/dist/runtime/stt-telemetry.d.ts +77 -0
  106. package/dist/runtime/stt-telemetry.js +176 -0
  107. package/dist/runtime/stt.js +15 -6
  108. package/dist/server/error-stack-frames.d.ts +35 -0
  109. package/dist/server/error-stack-frames.js +219 -0
  110. package/dist/server/index.d.ts +9 -0
  111. package/dist/server/index.js +5 -0
  112. package/dist/server/sdk-version.d.ts +3 -0
  113. package/dist/server/sdk-version.js +19 -0
  114. package/dist/server/self-test.js +1 -18
  115. package/dist/server/sensitive-values.d.ts +1 -1
  116. package/dist/server/sensitive-values.js +9 -0
  117. package/dist/server/serve-implementation.d.ts +53 -2
  118. package/dist/server/serve-implementation.js +369 -123
  119. package/dist/server/types.d.ts +1 -0
  120. package/dist/server/types.js +7 -0
  121. package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
  122. package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
  123. package/dist/stateful/stateful-provider-runtime-context.js +1 -0
  124. package/dist/types.d.ts +94 -1
  125. package/package.json +6 -1
  126. package/src/cli/commands.ts +14 -0
  127. package/src/cli/deployment-intent.ts +364 -0
  128. package/src/cli/migrate-deployment-intent.ts +1908 -0
  129. package/src/cli/migrate-provider-shape.ts +10 -4
  130. package/src/cli/resolver-runtime.ts +72 -0
  131. package/src/define.ts +13 -0
  132. package/src/dev.ts +9 -2
  133. package/src/engine.ts +38 -2
  134. package/src/error-resolution.ts +58 -0
  135. package/src/errors.ts +77 -1
  136. package/src/handle-meta.ts +39 -4
  137. package/src/handle.ts +121 -38
  138. package/src/i18n/error-messages.ts +255 -0
  139. package/src/i18n/index.ts +1 -0
  140. package/src/i18n/keys.ts +80 -6
  141. package/src/index.ts +91 -0
  142. package/src/lint.ts +552 -57
  143. package/src/provider.ts +20 -0
  144. package/src/runtime/browser-telemetry-binding.ts +92 -0
  145. package/src/runtime/browser-telemetry.ts +289 -0
  146. package/src/runtime/browser.ts +249 -65
  147. package/src/runtime/cache-telemetry.ts +247 -0
  148. package/src/runtime/cache.ts +68 -17
  149. package/src/runtime/capability-response.ts +53 -0
  150. package/src/runtime/capability-telemetry.ts +101 -0
  151. package/src/runtime/diagnostic-env.ts +11 -1
  152. package/src/runtime/engine-mode.ts +233 -0
  153. package/src/runtime/handle.ts +20 -10
  154. package/src/runtime/http-telemetry-binding.ts +162 -0
  155. package/src/runtime/http-telemetry-guard.ts +208 -0
  156. package/src/runtime/http-telemetry.ts +292 -0
  157. package/src/runtime/http.ts +457 -204
  158. package/src/runtime/instrumentation.ts +105 -16
  159. package/src/runtime/ocr-telemetry.ts +308 -0
  160. package/src/runtime/ocr.ts +109 -74
  161. package/src/runtime/request-telemetry.ts +2 -1
  162. package/src/runtime/resolver-runtime-options.ts +50 -0
  163. package/src/runtime/resolver-shared.ts +9 -4
  164. package/src/runtime/resolver-telemetry.ts +1 -1
  165. package/src/runtime/resolver-vendors/browser.ts +65 -7
  166. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  167. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  168. package/src/runtime/resolver-vendors/types.ts +5 -4
  169. package/src/runtime/resolver.ts +64 -21
  170. package/src/runtime/state-telemetry.ts +298 -0
  171. package/src/runtime/state.ts +46 -45
  172. package/src/runtime/stealth-cookies.ts +24 -1
  173. package/src/runtime/stealth-owned-headers.ts +41 -0
  174. package/src/runtime/stealth-telemetry.ts +304 -0
  175. package/src/runtime/stealth.ts +355 -150
  176. package/src/runtime/stt-telemetry.ts +282 -0
  177. package/src/runtime/stt.ts +93 -71
  178. package/src/server/error-stack-frames.ts +214 -0
  179. package/src/server/index.ts +66 -0
  180. package/src/server/sdk-version.ts +22 -0
  181. package/src/server/self-test.ts +1 -21
  182. package/src/server/sensitive-values.ts +14 -0
  183. package/src/server/serve-implementation.ts +601 -157
  184. package/src/server/types.ts +7 -0
  185. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  186. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  187. package/src/types.ts +99 -1
  188. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  189. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  190. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  249. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  250. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  251. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  252. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  253. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  254. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  255. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  256. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  257. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  258. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
@@ -0,0 +1,292 @@
1
+ import { Buffer } from "node:buffer";
2
+ import type { HttpRetrySummary } from "../types.js";
3
+ import {
4
+ closedEnum,
5
+ type ClosedEnum,
6
+ type TelemetryContributor,
7
+ type TenantNeutral,
8
+ } from "./request-telemetry.js";
9
+
10
+ /** The same closed vocabulary used by tenant-visible meta.retry. */
11
+ export type HttpTelemetryErrorCode =
12
+ | "transport_network_error"
13
+ | "transport_timeout"
14
+ | "transport_cancelled"
15
+ | "upstream_http_error"
16
+ | "other";
17
+
18
+ export function httpTelemetryErrorCode(code: string | undefined): HttpTelemetryErrorCode {
19
+ switch (code) {
20
+ case "transport_network_error":
21
+ case "transport_timeout":
22
+ case "transport_cancelled":
23
+ case "upstream_http_error":
24
+ return code;
25
+ default:
26
+ return "other";
27
+ }
28
+ }
29
+
30
+ export type HttpTelemetryRetryPayload = {
31
+ attempts: number;
32
+ retries: number;
33
+ preset?: ClosedEnum<NonNullable<HttpRetrySummary["preset"]>>;
34
+ transport: ClosedEnum<HttpRetrySummary["transport"]>;
35
+ lastErrorCode?: ClosedEnum<HttpTelemetryErrorCode>;
36
+ /** Last failed attempt's status, preserving the existing meta.retry contract. */
37
+ lastStatus?: number;
38
+ };
39
+
40
+ export type HttpAttemptTelemetryEvent = {
41
+ ms: number;
42
+ proxyUsed: boolean;
43
+ status?: number;
44
+ e?: HttpTelemetryErrorCode;
45
+ /** A returned status-retry outcome, rather than a thrown transport error. */
46
+ statusRetry?: boolean;
47
+ /** Operator-only error text. Never projected into the header or tenant metadata. */
48
+ diagnostics?: { name: string; message: string; cause?: { name: string; message: string } };
49
+ };
50
+
51
+ export interface HttpTelemetryRequestSink {
52
+ recordAttempt(event: HttpAttemptTelemetryEvent): void;
53
+ /** Called once when the logical HTTP call settles; includes backoff time. */
54
+ finish(ms: number): void;
55
+ toTenantRetryPayload(): TenantNeutral<HttpTelemetryRetryPayload> | undefined;
56
+ }
57
+
58
+ export interface HttpTelemetrySink {
59
+ /** Optional, best-effort failure marker; called at most once per logical request. */
60
+ markTelemetryFailed?(): void;
61
+ /** Each call gets independent retry state, including concurrent calls. */
62
+ startRequest(options: { retryPreset?: HttpRetrySummary["preset"] }): HttpTelemetryRequestSink;
63
+ }
64
+
65
+ export type HttpAttemptSample = {
66
+ n: number;
67
+ ms: number;
68
+ status?: number;
69
+ e?: HttpTelemetryErrorCode;
70
+ diagnostics?: HttpAttemptTelemetryEvent["diagnostics"];
71
+ };
72
+
73
+ export type HttpTelemetryLogPayload = {
74
+ /** Observer failure; operator-only and never projected into the header. */
75
+ telemetryFailed?: true;
76
+ attempts: number;
77
+ retries: number;
78
+ timeouts: number;
79
+ proxyUsed: boolean;
80
+ /** Most recently completed attempt's status, including successful statuses. */
81
+ lastStatus?: number;
82
+ retryPreset?: HttpRetrySummary["preset"];
83
+ transport: HttpRetrySummary["transport"];
84
+ lastErrorCode?: HttpTelemetryErrorCode;
85
+ attemptSamples: HttpAttemptSample[];
86
+ dropped: number;
87
+ /** Sum of logical call durations, including retry delays. */
88
+ ms: number;
89
+ /** Most recent successful retried call; also the source of tenant meta.retry. */
90
+ retry?: HttpTelemetryRetryPayload;
91
+ };
92
+
93
+ export type HttpTelemetryHeaderPayload = {
94
+ attempts: number;
95
+ retries: number;
96
+ timeouts: number;
97
+ proxyUsed: boolean;
98
+ lastStatus?: number;
99
+ retryPreset?: ClosedEnum<NonNullable<HttpRetrySummary["preset"]>>;
100
+ transport: ClosedEnum<HttpRetrySummary["transport"]>;
101
+ lastErrorCode?: ClosedEnum<HttpTelemetryErrorCode>;
102
+ attemptSamples: {
103
+ n: number;
104
+ ms: number;
105
+ status?: number;
106
+ e?: ClosedEnum<HttpTelemetryErrorCode>;
107
+ }[];
108
+ dropped: number;
109
+ ms: number;
110
+ retry?: HttpTelemetryRetryPayload;
111
+ };
112
+
113
+ const MAX_ATTEMPT_SAMPLES = 24;
114
+ const MAX_DIAGNOSTIC_TEXT = 300;
115
+
116
+ function integer(value: number): number {
117
+ return Math.max(0, Math.floor(Number.isFinite(value) ? value : 0));
118
+ }
119
+
120
+ function saturatingAdd(a: number, b: number): number {
121
+ if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.MAX_SAFE_INTEGER;
122
+ return Math.min(Number.MAX_SAFE_INTEGER, integer(a) + integer(b));
123
+ }
124
+
125
+ function boundedText(value: string, redact?: (text: string) => string): string {
126
+ let result: string;
127
+ try {
128
+ result = redact?.(value) ?? value;
129
+ } catch {
130
+ return "[REDACTION_FAILED]";
131
+ }
132
+ // Detach caller text through independent UTF-16 storage, preserving lone surrogates.
133
+ const length = Math.min(result.length, MAX_DIAGNOSTIC_TEXT);
134
+ const units = Buffer.alloc(length * 2);
135
+ for (let index = 0; index < length; index++)
136
+ units.writeUInt16LE(result.charCodeAt(index), index * 2);
137
+ return units.toString("utf16le");
138
+ }
139
+
140
+ export class HttpTelemetryCollector
141
+ implements
142
+ HttpTelemetrySink,
143
+ TelemetryContributor<HttpTelemetryLogPayload, HttpTelemetryHeaderPayload>
144
+ {
145
+ readonly key = "http" as const;
146
+ readonly #redact: ((text: string) => string) | undefined;
147
+ #telemetryFailed = false;
148
+ #attempts = 0;
149
+ #retries = 0;
150
+ #timeouts = 0;
151
+ #proxyUsed = false;
152
+ #lastStatus: number | undefined;
153
+ #retryPreset: HttpRetrySummary["preset"];
154
+ #lastErrorCode: HttpTelemetryErrorCode | undefined;
155
+ #samples: HttpAttemptSample[] = [];
156
+ #dropped = 0;
157
+ #ms = 0;
158
+ #retry: HttpTelemetryRetryPayload | undefined;
159
+
160
+ constructor(options: { redact?: (text: string) => string } = {}) {
161
+ this.#redact = options.redact;
162
+ }
163
+
164
+ markTelemetryFailed(): void {
165
+ this.#telemetryFailed = true;
166
+ }
167
+
168
+ startRequest(options: { retryPreset?: HttpRetrySummary["preset"] }): HttpTelemetryRequestSink {
169
+ const preset = options.retryPreset;
170
+ let attempts = 0;
171
+ let retries = 0;
172
+ let lastErrorCode: HttpTelemetryErrorCode | undefined;
173
+ let lastStatus: number | undefined;
174
+ let retry: HttpTelemetryRetryPayload | undefined;
175
+ let finished = false;
176
+ return {
177
+ recordAttempt: (event) => {
178
+ if (attempts > 0) {
179
+ retries = saturatingAdd(retries, 1);
180
+ this.#retries = saturatingAdd(this.#retries, 1);
181
+ }
182
+ attempts = saturatingAdd(attempts, 1);
183
+ this.#attempts = saturatingAdd(this.#attempts, 1);
184
+ if (event.e === "transport_timeout") this.#timeouts = saturatingAdd(this.#timeouts, 1);
185
+ this.#proxyUsed ||= event.proxyUsed;
186
+ this.#retryPreset = preset;
187
+ if (event.status !== undefined) this.#lastStatus = integer(event.status);
188
+ if (event.e) this.#lastErrorCode = event.e;
189
+ if (this.#samples.length < MAX_ATTEMPT_SAMPLES) {
190
+ const text = (value: string) => boundedText(value, this.#redact);
191
+ this.#samples.push({
192
+ n: attempts,
193
+ ms: saturatingAdd(0, event.ms),
194
+ ...(event.status === undefined ? {} : { status: integer(event.status) }),
195
+ ...(event.e ? { e: event.e } : {}),
196
+ ...(event.diagnostics
197
+ ? {
198
+ diagnostics: {
199
+ name: text(event.diagnostics.name),
200
+ message: text(event.diagnostics.message),
201
+ ...(event.diagnostics.cause
202
+ ? {
203
+ cause: {
204
+ name: text(event.diagnostics.cause.name),
205
+ message: text(event.diagnostics.cause.message),
206
+ },
207
+ }
208
+ : {}),
209
+ },
210
+ }
211
+ : {}),
212
+ });
213
+ } else this.#dropped = saturatingAdd(this.#dropped, 1);
214
+ if (event.e) {
215
+ lastStatus = event.status;
216
+ // Historically status-retry outcomes set lastStatus only. Preserve those pins.
217
+ if (!event.statusRetry) lastErrorCode = event.e;
218
+ } else if (attempts > 1) {
219
+ retry = {
220
+ attempts,
221
+ retries,
222
+ ...(preset ? { preset: closedEnum(preset) } : {}),
223
+ transport: closedEnum("native"),
224
+ ...(lastErrorCode ? { lastErrorCode: closedEnum(lastErrorCode) } : {}),
225
+ ...(lastStatus ? { lastStatus: integer(lastStatus) } : {}),
226
+ };
227
+ this.#retry = retry;
228
+ }
229
+ },
230
+ finish: (ms) => {
231
+ if (!finished && attempts > 0) this.#ms = saturatingAdd(this.#ms, ms);
232
+ finished = true;
233
+ },
234
+ toTenantRetryPayload: () => (!this.#telemetryFailed && retry ? { ...retry } : undefined),
235
+ };
236
+ }
237
+
238
+ toTenantRetryPayload(): TenantNeutral<HttpTelemetryRetryPayload> | undefined {
239
+ return !this.#telemetryFailed && this.#retry ? { ...this.#retry } : undefined;
240
+ }
241
+
242
+ toLogPayload(): HttpTelemetryLogPayload | undefined {
243
+ if (this.#attempts === 0 && !this.#telemetryFailed) return undefined;
244
+ return {
245
+ ...(this.#telemetryFailed ? { telemetryFailed: true as const } : {}),
246
+ attempts: this.#attempts,
247
+ retries: this.#retries,
248
+ timeouts: this.#timeouts,
249
+ proxyUsed: this.#proxyUsed,
250
+ ...(this.#lastStatus === undefined ? {} : { lastStatus: this.#lastStatus }),
251
+ ...(this.#retryPreset ? { retryPreset: this.#retryPreset } : {}),
252
+ transport: "native",
253
+ ...(this.#lastErrorCode ? { lastErrorCode: this.#lastErrorCode } : {}),
254
+ attemptSamples: this.#samples.map((sample) => ({
255
+ ...sample,
256
+ ...(sample.diagnostics
257
+ ? {
258
+ diagnostics: {
259
+ ...sample.diagnostics,
260
+ ...(sample.diagnostics.cause ? { cause: { ...sample.diagnostics.cause } } : {}),
261
+ },
262
+ }
263
+ : {}),
264
+ })),
265
+ dropped: this.#dropped,
266
+ ms: this.#ms,
267
+ ...(this.#retry ? { retry: { ...this.#retry } } : {}),
268
+ };
269
+ }
270
+
271
+ toHeaderPayload(log: HttpTelemetryLogPayload): HttpTelemetryHeaderPayload {
272
+ return {
273
+ attempts: log.attempts,
274
+ retries: log.retries,
275
+ timeouts: log.timeouts,
276
+ proxyUsed: log.proxyUsed,
277
+ ...(log.lastStatus === undefined ? {} : { lastStatus: log.lastStatus }),
278
+ ...(log.retryPreset ? { retryPreset: closedEnum(log.retryPreset) } : {}),
279
+ transport: closedEnum(log.transport),
280
+ ...(log.lastErrorCode ? { lastErrorCode: closedEnum(log.lastErrorCode) } : {}),
281
+ attemptSamples: log.attemptSamples.map(({ n, ms, status, e }) => ({
282
+ n,
283
+ ms,
284
+ ...(status === undefined ? {} : { status }),
285
+ ...(e ? { e: closedEnum(e) } : {}),
286
+ })),
287
+ dropped: log.dropped,
288
+ ms: log.ms,
289
+ ...(log.retry ? { retry: { ...log.retry } } : {}),
290
+ };
291
+ }
292
+ }