@pureq/pureq 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +932 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/scripts/benchmark.d.ts +2 -0
  8. package/dist/scripts/benchmark.d.ts.map +1 -0
  9. package/dist/scripts/benchmark.js +69 -0
  10. package/dist/scripts/benchmark.js.map +1 -0
  11. package/dist/scripts/edge-smoke-entry.d.ts +8 -0
  12. package/dist/scripts/edge-smoke-entry.d.ts.map +1 -0
  13. package/dist/scripts/edge-smoke-entry.js +23 -0
  14. package/dist/scripts/edge-smoke-entry.js.map +1 -0
  15. package/dist/src/adapters/fetchAdapter.d.ts +3 -0
  16. package/dist/src/adapters/fetchAdapter.d.ts.map +1 -0
  17. package/dist/src/adapters/fetchAdapter.js +4 -0
  18. package/dist/src/adapters/fetchAdapter.js.map +1 -0
  19. package/dist/src/adapters/instrumentedAdapter.d.ts +21 -0
  20. package/dist/src/adapters/instrumentedAdapter.d.ts.map +1 -0
  21. package/dist/src/adapters/instrumentedAdapter.js +25 -0
  22. package/dist/src/adapters/instrumentedAdapter.js.map +1 -0
  23. package/dist/src/client/createClient.d.ts +193 -0
  24. package/dist/src/client/createClient.d.ts.map +1 -0
  25. package/dist/src/client/createClient.js +310 -0
  26. package/dist/src/client/createClient.js.map +1 -0
  27. package/dist/src/executor/execute.d.ts +19 -0
  28. package/dist/src/executor/execute.d.ts.map +1 -0
  29. package/dist/src/executor/execute.js +121 -0
  30. package/dist/src/executor/execute.js.map +1 -0
  31. package/dist/src/index.d.ts +37 -0
  32. package/dist/src/index.d.ts.map +1 -0
  33. package/dist/src/index.js +36 -0
  34. package/dist/src/index.js.map +1 -0
  35. package/dist/src/middleware/circuitBreaker.d.ts +77 -0
  36. package/dist/src/middleware/circuitBreaker.d.ts.map +1 -0
  37. package/dist/src/middleware/circuitBreaker.js +246 -0
  38. package/dist/src/middleware/circuitBreaker.js.map +1 -0
  39. package/dist/src/middleware/circuitBreakerKeys.d.ts +5 -0
  40. package/dist/src/middleware/circuitBreakerKeys.d.ts.map +1 -0
  41. package/dist/src/middleware/circuitBreakerKeys.js +30 -0
  42. package/dist/src/middleware/circuitBreakerKeys.js.map +1 -0
  43. package/dist/src/middleware/compose.d.ts +9 -0
  44. package/dist/src/middleware/compose.d.ts.map +1 -0
  45. package/dist/src/middleware/compose.js +45 -0
  46. package/dist/src/middleware/compose.js.map +1 -0
  47. package/dist/src/middleware/concurrencyLimit.d.ts +11 -0
  48. package/dist/src/middleware/concurrencyLimit.d.ts.map +1 -0
  49. package/dist/src/middleware/concurrencyLimit.js +126 -0
  50. package/dist/src/middleware/concurrencyLimit.js.map +1 -0
  51. package/dist/src/middleware/deadline.d.ts +10 -0
  52. package/dist/src/middleware/deadline.d.ts.map +1 -0
  53. package/dist/src/middleware/deadline.js +99 -0
  54. package/dist/src/middleware/deadline.js.map +1 -0
  55. package/dist/src/middleware/dedupe.d.ts +13 -0
  56. package/dist/src/middleware/dedupe.d.ts.map +1 -0
  57. package/dist/src/middleware/dedupe.js +46 -0
  58. package/dist/src/middleware/dedupe.js.map +1 -0
  59. package/dist/src/middleware/defaultTimeout.d.ts +6 -0
  60. package/dist/src/middleware/defaultTimeout.d.ts.map +1 -0
  61. package/dist/src/middleware/defaultTimeout.js +23 -0
  62. package/dist/src/middleware/defaultTimeout.js.map +1 -0
  63. package/dist/src/middleware/diagnostics.d.ts +28 -0
  64. package/dist/src/middleware/diagnostics.d.ts.map +1 -0
  65. package/dist/src/middleware/diagnostics.js +131 -0
  66. package/dist/src/middleware/diagnostics.js.map +1 -0
  67. package/dist/src/middleware/diagnosticsExporters.d.ts +27 -0
  68. package/dist/src/middleware/diagnosticsExporters.d.ts.map +1 -0
  69. package/dist/src/middleware/diagnosticsExporters.js +45 -0
  70. package/dist/src/middleware/diagnosticsExporters.js.map +1 -0
  71. package/dist/src/middleware/hedge.d.ts +17 -0
  72. package/dist/src/middleware/hedge.d.ts.map +1 -0
  73. package/dist/src/middleware/hedge.js +125 -0
  74. package/dist/src/middleware/hedge.js.map +1 -0
  75. package/dist/src/middleware/httpCache.d.ts +14 -0
  76. package/dist/src/middleware/httpCache.d.ts.map +1 -0
  77. package/dist/src/middleware/httpCache.js +126 -0
  78. package/dist/src/middleware/httpCache.js.map +1 -0
  79. package/dist/src/middleware/idempotencyKey.d.ts +12 -0
  80. package/dist/src/middleware/idempotencyKey.d.ts.map +1 -0
  81. package/dist/src/middleware/idempotencyKey.js +33 -0
  82. package/dist/src/middleware/idempotencyKey.js.map +1 -0
  83. package/dist/src/middleware/offlineQueue.d.ts +78 -0
  84. package/dist/src/middleware/offlineQueue.d.ts.map +1 -0
  85. package/dist/src/middleware/offlineQueue.js +189 -0
  86. package/dist/src/middleware/offlineQueue.js.map +1 -0
  87. package/dist/src/middleware/presets.d.ts +31 -0
  88. package/dist/src/middleware/presets.d.ts.map +1 -0
  89. package/dist/src/middleware/presets.js +122 -0
  90. package/dist/src/middleware/presets.js.map +1 -0
  91. package/dist/src/middleware/retry.d.ts +27 -0
  92. package/dist/src/middleware/retry.d.ts.map +1 -0
  93. package/dist/src/middleware/retry.js +189 -0
  94. package/dist/src/middleware/retry.js.map +1 -0
  95. package/dist/src/middleware/stalePolicy.d.ts +14 -0
  96. package/dist/src/middleware/stalePolicy.d.ts.map +1 -0
  97. package/dist/src/middleware/stalePolicy.js +13 -0
  98. package/dist/src/middleware/stalePolicy.js.map +1 -0
  99. package/dist/src/observability/otelMapping.d.ts +13 -0
  100. package/dist/src/observability/otelMapping.d.ts.map +1 -0
  101. package/dist/src/observability/otelMapping.js +31 -0
  102. package/dist/src/observability/otelMapping.js.map +1 -0
  103. package/dist/src/observability/otelProfiles.d.ts +16 -0
  104. package/dist/src/observability/otelProfiles.d.ts.map +1 -0
  105. package/dist/src/observability/otelProfiles.js +66 -0
  106. package/dist/src/observability/otelProfiles.js.map +1 -0
  107. package/dist/src/observability/redaction.d.ts +39 -0
  108. package/dist/src/observability/redaction.d.ts.map +1 -0
  109. package/dist/src/observability/redaction.js +112 -0
  110. package/dist/src/observability/redaction.js.map +1 -0
  111. package/dist/src/policy/guardrails.d.ts +14 -0
  112. package/dist/src/policy/guardrails.d.ts.map +1 -0
  113. package/dist/src/policy/guardrails.js +36 -0
  114. package/dist/src/policy/guardrails.js.map +1 -0
  115. package/dist/src/response/response.d.ts +58 -0
  116. package/dist/src/response/response.d.ts.map +1 -0
  117. package/dist/src/response/response.js +91 -0
  118. package/dist/src/response/response.js.map +1 -0
  119. package/dist/src/serializers/formUrlEncodedSerializer.d.ts +6 -0
  120. package/dist/src/serializers/formUrlEncodedSerializer.d.ts.map +1 -0
  121. package/dist/src/serializers/formUrlEncodedSerializer.js +38 -0
  122. package/dist/src/serializers/formUrlEncodedSerializer.js.map +1 -0
  123. package/dist/src/serializers/jsonBodySerializer.d.ts +3 -0
  124. package/dist/src/serializers/jsonBodySerializer.d.ts.map +1 -0
  125. package/dist/src/serializers/jsonBodySerializer.js +24 -0
  126. package/dist/src/serializers/jsonBodySerializer.js.map +1 -0
  127. package/dist/src/types/events.d.ts +49 -0
  128. package/dist/src/types/events.d.ts.map +1 -0
  129. package/dist/src/types/events.js +2 -0
  130. package/dist/src/types/events.js.map +1 -0
  131. package/dist/src/types/http.d.ts +78 -0
  132. package/dist/src/types/http.d.ts.map +1 -0
  133. package/dist/src/types/http.js +2 -0
  134. package/dist/src/types/http.js.map +1 -0
  135. package/dist/src/types/internal.d.ts +20 -0
  136. package/dist/src/types/internal.d.ts.map +1 -0
  137. package/dist/src/types/internal.js +2 -0
  138. package/dist/src/types/internal.js.map +1 -0
  139. package/dist/src/types/result.d.ts +32 -0
  140. package/dist/src/types/result.d.ts.map +1 -0
  141. package/dist/src/types/result.js +66 -0
  142. package/dist/src/types/result.js.map +1 -0
  143. package/dist/src/utils/crypto.d.ts +8 -0
  144. package/dist/src/utils/crypto.d.ts.map +1 -0
  145. package/dist/src/utils/crypto.js +21 -0
  146. package/dist/src/utils/crypto.js.map +1 -0
  147. package/dist/src/utils/policyTrace.d.ts +17 -0
  148. package/dist/src/utils/policyTrace.d.ts.map +1 -0
  149. package/dist/src/utils/policyTrace.js +34 -0
  150. package/dist/src/utils/policyTrace.js.map +1 -0
  151. package/dist/src/utils/stableKey.d.ts +17 -0
  152. package/dist/src/utils/stableKey.d.ts.map +1 -0
  153. package/dist/src/utils/stableKey.js +41 -0
  154. package/dist/src/utils/stableKey.js.map +1 -0
  155. package/dist/src/utils/url.d.ts +22 -0
  156. package/dist/src/utils/url.d.ts.map +1 -0
  157. package/dist/src/utils/url.js +2 -0
  158. package/dist/src/utils/url.js.map +1 -0
  159. package/dist/tests/adapter-serializer.test.d.ts +2 -0
  160. package/dist/tests/adapter-serializer.test.d.ts.map +1 -0
  161. package/dist/tests/adapter-serializer.test.js +59 -0
  162. package/dist/tests/adapter-serializer.test.js.map +1 -0
  163. package/dist/tests/browser-runtime.smoke.test.d.ts +2 -0
  164. package/dist/tests/browser-runtime.smoke.test.d.ts.map +1 -0
  165. package/dist/tests/browser-runtime.smoke.test.js +17 -0
  166. package/dist/tests/browser-runtime.smoke.test.js.map +1 -0
  167. package/dist/tests/circuit-breaker.test.d.ts +2 -0
  168. package/dist/tests/circuit-breaker.test.d.ts.map +1 -0
  169. package/dist/tests/circuit-breaker.test.js +184 -0
  170. package/dist/tests/circuit-breaker.test.js.map +1 -0
  171. package/dist/tests/client.integration.d.ts +2 -0
  172. package/dist/tests/client.integration.d.ts.map +1 -0
  173. package/dist/tests/client.integration.js +44 -0
  174. package/dist/tests/client.integration.js.map +1 -0
  175. package/dist/tests/client.integration.test.d.ts +2 -0
  176. package/dist/tests/client.integration.test.d.ts.map +1 -0
  177. package/dist/tests/client.integration.test.js +63 -0
  178. package/dist/tests/client.integration.test.js.map +1 -0
  179. package/dist/tests/compose.test.d.ts +2 -0
  180. package/dist/tests/compose.test.d.ts.map +1 -0
  181. package/dist/tests/compose.test.js +24 -0
  182. package/dist/tests/compose.test.js.map +1 -0
  183. package/dist/tests/concurrency-limit.test.d.ts +2 -0
  184. package/dist/tests/concurrency-limit.test.d.ts.map +1 -0
  185. package/dist/tests/concurrency-limit.test.js +87 -0
  186. package/dist/tests/concurrency-limit.test.js.map +1 -0
  187. package/dist/tests/deadline-middleware.test.d.ts +2 -0
  188. package/dist/tests/deadline-middleware.test.d.ts.map +1 -0
  189. package/dist/tests/deadline-middleware.test.js +38 -0
  190. package/dist/tests/deadline-middleware.test.js.map +1 -0
  191. package/dist/tests/dedupe-middleware.test.d.ts +2 -0
  192. package/dist/tests/dedupe-middleware.test.d.ts.map +1 -0
  193. package/dist/tests/dedupe-middleware.test.js +56 -0
  194. package/dist/tests/dedupe-middleware.test.js.map +1 -0
  195. package/dist/tests/default-timeout.test.d.ts +2 -0
  196. package/dist/tests/default-timeout.test.d.ts.map +1 -0
  197. package/dist/tests/default-timeout.test.js +28 -0
  198. package/dist/tests/default-timeout.test.js.map +1 -0
  199. package/dist/tests/diagnostics-exporters.test.d.ts +2 -0
  200. package/dist/tests/diagnostics-exporters.test.d.ts.map +1 -0
  201. package/dist/tests/diagnostics-exporters.test.js +41 -0
  202. package/dist/tests/diagnostics-exporters.test.js.map +1 -0
  203. package/dist/tests/diagnostics.test.d.ts +2 -0
  204. package/dist/tests/diagnostics.test.d.ts.map +1 -0
  205. package/dist/tests/diagnostics.test.js +38 -0
  206. package/dist/tests/diagnostics.test.js.map +1 -0
  207. package/dist/tests/error-metadata.test.d.ts +2 -0
  208. package/dist/tests/error-metadata.test.d.ts.map +1 -0
  209. package/dist/tests/error-metadata.test.js +23 -0
  210. package/dist/tests/error-metadata.test.js.map +1 -0
  211. package/dist/tests/execute-timeout.test.d.ts +2 -0
  212. package/dist/tests/execute-timeout.test.d.ts.map +1 -0
  213. package/dist/tests/execute-timeout.test.js +30 -0
  214. package/dist/tests/execute-timeout.test.js.map +1 -0
  215. package/dist/tests/form-serializer.test.d.ts +2 -0
  216. package/dist/tests/form-serializer.test.d.ts.map +1 -0
  217. package/dist/tests/form-serializer.test.js +16 -0
  218. package/dist/tests/form-serializer.test.js.map +1 -0
  219. package/dist/tests/hedge.test.d.ts +2 -0
  220. package/dist/tests/hedge.test.d.ts.map +1 -0
  221. package/dist/tests/hedge.test.js +45 -0
  222. package/dist/tests/hedge.test.js.map +1 -0
  223. package/dist/tests/http-cache.test.d.ts +2 -0
  224. package/dist/tests/http-cache.test.d.ts.map +1 -0
  225. package/dist/tests/http-cache.test.js +60 -0
  226. package/dist/tests/http-cache.test.js.map +1 -0
  227. package/dist/tests/idempotency-key.test.d.ts +2 -0
  228. package/dist/tests/idempotency-key.test.d.ts.map +1 -0
  229. package/dist/tests/idempotency-key.test.js +31 -0
  230. package/dist/tests/idempotency-key.test.js.map +1 -0
  231. package/dist/tests/instrumented-adapter.test.d.ts +2 -0
  232. package/dist/tests/instrumented-adapter.test.d.ts.map +1 -0
  233. package/dist/tests/instrumented-adapter.test.js +33 -0
  234. package/dist/tests/instrumented-adapter.test.js.map +1 -0
  235. package/dist/tests/interceptor-order.test.d.ts +2 -0
  236. package/dist/tests/interceptor-order.test.d.ts.map +1 -0
  237. package/dist/tests/interceptor-order.test.js +38 -0
  238. package/dist/tests/interceptor-order.test.js.map +1 -0
  239. package/dist/tests/json-helper.test.d.ts +2 -0
  240. package/dist/tests/json-helper.test.d.ts.map +1 -0
  241. package/dist/tests/json-helper.test.js +42 -0
  242. package/dist/tests/json-helper.test.js.map +1 -0
  243. package/dist/tests/observability.test.d.ts +2 -0
  244. package/dist/tests/observability.test.d.ts.map +1 -0
  245. package/dist/tests/observability.test.js +59 -0
  246. package/dist/tests/observability.test.js.map +1 -0
  247. package/dist/tests/offline-queue.test.d.ts +2 -0
  248. package/dist/tests/offline-queue.test.d.ts.map +1 -0
  249. package/dist/tests/offline-queue.test.js +35 -0
  250. package/dist/tests/offline-queue.test.js.map +1 -0
  251. package/dist/tests/otel-mapping.test.d.ts +2 -0
  252. package/dist/tests/otel-mapping.test.d.ts.map +1 -0
  253. package/dist/tests/otel-mapping.test.js +20 -0
  254. package/dist/tests/otel-mapping.test.js.map +1 -0
  255. package/dist/tests/policy-guardrails.test.d.ts +2 -0
  256. package/dist/tests/policy-guardrails.test.d.ts.map +1 -0
  257. package/dist/tests/policy-guardrails.test.js +25 -0
  258. package/dist/tests/policy-guardrails.test.js.map +1 -0
  259. package/dist/tests/presets.test.d.ts +2 -0
  260. package/dist/tests/presets.test.d.ts.map +1 -0
  261. package/dist/tests/presets.test.js +41 -0
  262. package/dist/tests/presets.test.js.map +1 -0
  263. package/dist/tests/public-api.contract.d.ts +2 -0
  264. package/dist/tests/public-api.contract.d.ts.map +1 -0
  265. package/dist/tests/public-api.contract.js +14 -0
  266. package/dist/tests/public-api.contract.js.map +1 -0
  267. package/dist/tests/public-api.contract.test.d.ts +2 -0
  268. package/dist/tests/public-api.contract.test.d.ts.map +1 -0
  269. package/dist/tests/public-api.contract.test.js +25 -0
  270. package/dist/tests/public-api.contract.test.js.map +1 -0
  271. package/dist/tests/redaction.test.d.ts +2 -0
  272. package/dist/tests/redaction.test.d.ts.map +1 -0
  273. package/dist/tests/redaction.test.js +23 -0
  274. package/dist/tests/redaction.test.js.map +1 -0
  275. package/dist/tests/retry-after-budget.test.d.ts +2 -0
  276. package/dist/tests/retry-after-budget.test.d.ts.map +1 -0
  277. package/dist/tests/retry-after-budget.test.js +72 -0
  278. package/dist/tests/retry-after-budget.test.js.map +1 -0
  279. package/dist/tests/retry-policy-trace.test.d.ts +2 -0
  280. package/dist/tests/retry-policy-trace.test.d.ts.map +1 -0
  281. package/dist/tests/retry-policy-trace.test.js +35 -0
  282. package/dist/tests/retry-policy-trace.test.js.map +1 -0
  283. package/dist/tests/retry-policy.test.d.ts +2 -0
  284. package/dist/tests/retry-policy.test.d.ts.map +1 -0
  285. package/dist/tests/retry-policy.test.js +51 -0
  286. package/dist/tests/retry-policy.test.js.map +1 -0
  287. package/dist/tests/retry.stress.d.ts +2 -0
  288. package/dist/tests/retry.stress.d.ts.map +1 -0
  289. package/dist/tests/retry.stress.js +21 -0
  290. package/dist/tests/retry.stress.js.map +1 -0
  291. package/dist/tests/retry.stress.test.d.ts +2 -0
  292. package/dist/tests/retry.stress.test.d.ts.map +1 -0
  293. package/dist/tests/retry.stress.test.js +21 -0
  294. package/dist/tests/retry.stress.test.js.map +1 -0
  295. package/package.json +63 -0
@@ -0,0 +1,189 @@
1
+ import { markPolicyMiddleware } from "../policy/guardrails";
2
+ import { appendPolicyTrace } from "../utils/policyTrace";
3
+ function isRetryableStatus(status, allowList) {
4
+ if (allowList && allowList.length > 0) {
5
+ return allowList.includes(status);
6
+ }
7
+ return status >= 500;
8
+ }
9
+ // appendPolicyTrace is imported from ../utils/policyTrace
10
+ function parseRetryAfter(value, nowMs) {
11
+ if (!value) {
12
+ return undefined;
13
+ }
14
+ const deltaSeconds = Number(value);
15
+ if (Number.isFinite(deltaSeconds)) {
16
+ return Math.max(0, Math.round(deltaSeconds * 1000));
17
+ }
18
+ const parsedDate = Date.parse(value);
19
+ if (!Number.isNaN(parsedDate)) {
20
+ return Math.max(0, parsedDate - nowMs);
21
+ }
22
+ return undefined;
23
+ }
24
+ async function sleep(ms, signal) {
25
+ if (ms <= 0) {
26
+ return;
27
+ }
28
+ await new Promise((resolve, reject) => {
29
+ const timeoutId = setTimeout(() => {
30
+ if (signal) {
31
+ signal.removeEventListener("abort", onAbort);
32
+ }
33
+ resolve();
34
+ }, ms);
35
+ const onAbort = () => {
36
+ clearTimeout(timeoutId);
37
+ if (signal) {
38
+ signal.removeEventListener("abort", onAbort);
39
+ }
40
+ reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
41
+ };
42
+ if (signal) {
43
+ if (signal.aborted) {
44
+ onAbort();
45
+ return;
46
+ }
47
+ signal.addEventListener("abort", onAbort, { once: true });
48
+ }
49
+ });
50
+ }
51
+ /**
52
+ * pureq Retry Middleware
53
+ * Implements exponential backoff strategy for network failures or configured status codes.
54
+ */
55
+ export function retry(options) {
56
+ if (!Number.isInteger(options.maxRetries) || options.maxRetries < 0) {
57
+ throw new Error("pureq: retry requires maxRetries to be a non-negative integer");
58
+ }
59
+ const { maxRetries, delay = 300, backoff = true, maxDelay = 5000, retryBudgetMs, retryOnStatus, retryOnNetworkError = true, respectRetryAfter = true, retryAfterHeaderName = "retry-after", onRetry, } = options;
60
+ const middleware = async (req, next) => {
61
+ let attempts = 0;
62
+ let totalWaitMs = 0;
63
+ const hasBudget = retryBudgetMs !== undefined && Number.isFinite(retryBudgetMs) && retryBudgetMs > 0;
64
+ const withRetryMeta = () => {
65
+ const hasMeta = typeof req === "object" && req !== null && "_meta" in req;
66
+ const currentMeta = hasMeta
67
+ ? (req._meta ?? {})
68
+ : {};
69
+ currentMeta.retryCount = attempts;
70
+ if (hasMeta) {
71
+ return req;
72
+ }
73
+ return {
74
+ ...req,
75
+ _meta: currentMeta,
76
+ };
77
+ };
78
+ const executeWithRetry = async () => {
79
+ try {
80
+ const res = await next(withRetryMeta());
81
+ if (isRetryableStatus(res.status, retryOnStatus) && attempts < maxRetries) {
82
+ attempts++;
83
+ const baseWait = backoff ? Math.min(delay * 2 ** (attempts - 1), maxDelay) : delay;
84
+ const retryAfterMs = respectRetryAfter
85
+ ? parseRetryAfter(res.headers.get(retryAfterHeaderName), Date.now())
86
+ : undefined;
87
+ const waitTime = Math.max(baseWait, retryAfterMs ?? 0);
88
+ const budgetRemainingMs = hasBudget ? Math.max(0, retryBudgetMs - totalWaitMs) : undefined;
89
+ if (budgetRemainingMs !== undefined && waitTime > budgetRemainingMs) {
90
+ appendPolicyTrace(req, {
91
+ policy: "retry",
92
+ decision: "skip",
93
+ at: Date.now(),
94
+ attempt: attempts,
95
+ reason: "retry budget exhausted",
96
+ waitTimeMs: waitTime,
97
+ status: res.status,
98
+ ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
99
+ budgetRemainingMs,
100
+ source: "status",
101
+ });
102
+ return res;
103
+ }
104
+ appendPolicyTrace(req, {
105
+ policy: "retry",
106
+ decision: "retry",
107
+ at: Date.now(),
108
+ attempt: attempts,
109
+ reason: `retryable status ${res.status}`,
110
+ waitTimeMs: waitTime,
111
+ status: res.status,
112
+ ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
113
+ ...(budgetRemainingMs !== undefined ? { budgetRemainingMs } : {}),
114
+ source: "status",
115
+ });
116
+ onRetry?.({
117
+ attempt: attempts,
118
+ waitTime,
119
+ status: res.status,
120
+ ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
121
+ ...(budgetRemainingMs !== undefined ? { budgetRemainingMs } : {}),
122
+ source: "status",
123
+ });
124
+ totalWaitMs += waitTime;
125
+ await sleep(waitTime, req.signal);
126
+ return executeWithRetry();
127
+ }
128
+ return res;
129
+ }
130
+ catch (error) {
131
+ if (!retryOnNetworkError) {
132
+ throw error;
133
+ }
134
+ if (attempts < maxRetries) {
135
+ attempts++;
136
+ const waitTime = backoff ? Math.min(delay * 2 ** (attempts - 1), maxDelay) : delay;
137
+ const budgetRemainingMs = hasBudget ? Math.max(0, retryBudgetMs - totalWaitMs) : undefined;
138
+ if (budgetRemainingMs !== undefined && waitTime > budgetRemainingMs) {
139
+ appendPolicyTrace(req, {
140
+ policy: "retry",
141
+ decision: "give-up",
142
+ at: Date.now(),
143
+ attempt: attempts,
144
+ reason: "retry budget exhausted",
145
+ waitTimeMs: waitTime,
146
+ budgetRemainingMs,
147
+ source: "network",
148
+ });
149
+ if (typeof error === "object" && error !== null) {
150
+ error.__pureqRetryCount = attempts - 1;
151
+ }
152
+ throw error;
153
+ }
154
+ appendPolicyTrace(req, {
155
+ policy: "retry",
156
+ decision: "retry",
157
+ at: Date.now(),
158
+ attempt: attempts,
159
+ reason: "network failure",
160
+ waitTimeMs: waitTime,
161
+ ...(budgetRemainingMs !== undefined ? { budgetRemainingMs } : {}),
162
+ source: "network",
163
+ });
164
+ onRetry?.({
165
+ attempt: attempts,
166
+ waitTime,
167
+ error,
168
+ ...(budgetRemainingMs !== undefined ? { budgetRemainingMs } : {}),
169
+ source: "network",
170
+ });
171
+ totalWaitMs += waitTime;
172
+ await sleep(waitTime, req.signal);
173
+ return executeWithRetry();
174
+ }
175
+ if (typeof error === "object" && error !== null) {
176
+ error.__pureqRetryCount = attempts;
177
+ }
178
+ throw error;
179
+ }
180
+ };
181
+ return executeWithRetry();
182
+ };
183
+ return markPolicyMiddleware(middleware, {
184
+ name: "retry",
185
+ kind: "retry",
186
+ maxRetries,
187
+ });
188
+ }
189
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/middleware/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface StalePolicyDecision {
2
+ readonly ageMs: number;
3
+ readonly isFresh: boolean;
4
+ readonly canServeStaleOnError: boolean;
5
+ readonly ttlMs: number;
6
+ readonly staleIfErrorMs: number;
7
+ }
8
+ export declare function resolveStalePolicy(options: {
9
+ readonly storedAt: number;
10
+ readonly now: number;
11
+ readonly ttlMs: number;
12
+ readonly staleIfErrorMs: number;
13
+ }): StalePolicyDecision;
14
+ //# sourceMappingURL=stalePolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stalePolicy.d.ts","sourceRoot":"","sources":["../../../src/middleware/stalePolicy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,GAAG,mBAAmB,CAYtB"}
@@ -0,0 +1,13 @@
1
+ export function resolveStalePolicy(options) {
2
+ const ageMs = Math.max(0, options.now - options.storedAt);
3
+ const isFresh = ageMs <= options.ttlMs;
4
+ const canServeStaleOnError = ageMs <= options.ttlMs + options.staleIfErrorMs;
5
+ return {
6
+ ageMs,
7
+ isFresh,
8
+ canServeStaleOnError,
9
+ ttlMs: options.ttlMs,
10
+ staleIfErrorMs: options.staleIfErrorMs,
11
+ };
12
+ }
13
+ //# sourceMappingURL=stalePolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stalePolicy.js","sourceRoot":"","sources":["../../../src/middleware/stalePolicy.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,kBAAkB,CAAC,OAKlC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;IACvC,MAAM,oBAAoB,GAAG,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC;IAE7E,OAAO;QACL,KAAK;QACL,OAAO;QACP,oBAAoB;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { TransportEvent } from "../types/events";
2
+ export interface OpenTelemetryLikeAttributes {
3
+ readonly [key: string]: string | number | boolean;
4
+ }
5
+ /**
6
+ * Maps a transport event to OpenTelemetry-like attributes.
7
+ *
8
+ * SECURITY NOTE: The `url.full` attribute contains the raw URL which may include
9
+ * sensitive query parameters (tokens, API keys). Use `redactUrlQueryParams()`
10
+ * from the redaction module to sanitize URLs before exporting to telemetry backends.
11
+ */
12
+ export declare function mapTransportEventToOtelAttributes(event: TransportEvent): OpenTelemetryLikeAttributes;
13
+ //# sourceMappingURL=otelMapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otelMapping.d.ts","sourceRoot":"","sources":["../../../src/observability/otelMapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACnD;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,cAAc,GACpB,2BAA2B,CA4B7B"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Maps a transport event to OpenTelemetry-like attributes.
3
+ *
4
+ * SECURITY NOTE: The `url.full` attribute contains the raw URL which may include
5
+ * sensitive query parameters (tokens, API keys). Use `redactUrlQueryParams()`
6
+ * from the redaction module to sanitize URLs before exporting to telemetry backends.
7
+ */
8
+ export function mapTransportEventToOtelAttributes(event) {
9
+ const attributes = {
10
+ "http.request.method": event.method,
11
+ "url.full": event.url,
12
+ "pureq.phase": event.phase,
13
+ };
14
+ if (event.status !== undefined) {
15
+ attributes["http.response.status_code"] = event.status;
16
+ }
17
+ if (event.durationMs !== undefined) {
18
+ attributes["pureq.duration_ms"] = event.durationMs;
19
+ }
20
+ if (event.retryCount !== undefined) {
21
+ attributes["pureq.retry_count"] = event.retryCount;
22
+ }
23
+ if (event.errorKind !== undefined) {
24
+ attributes["pureq.error_kind"] = event.errorKind;
25
+ }
26
+ if (event.policyTrace !== undefined) {
27
+ attributes["pureq.policy_trace_count"] = event.policyTrace.length;
28
+ }
29
+ return attributes;
30
+ }
31
+ //# sourceMappingURL=otelMapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otelMapping.js","sourceRoot":"","sources":["../../../src/observability/otelMapping.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAAqB;IAErB,MAAM,UAAU,GAA8C;QAC5D,qBAAqB,EAAE,KAAK,CAAC,MAAM;QACnC,UAAU,EAAE,KAAK,CAAC,GAAG;QACrB,aAAa,EAAE,KAAK,CAAC,KAAK;KAC3B,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,UAAU,CAAC,2BAA2B,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,UAAU,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,UAAU,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,UAAU,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IACnD,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACpC,UAAU,CAAC,0BAA0B,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;IACpE,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { TransportEvent } from "../types/events";
2
+ import type { OpenTelemetryLikeAttributes } from "./otelMapping";
3
+ /**
4
+ * Maps a transport event to standard HTTP OpenTelemetry semantic conventions.
5
+ * @see https://opentelemetry.io/docs/specs/semconv/http/http-spans/
6
+ */
7
+ export declare function mapToStandardHttpAttributes(event: TransportEvent): OpenTelemetryLikeAttributes;
8
+ /**
9
+ * Maps a transport event to AWS X-Ray compatible semantic conventions.
10
+ */
11
+ export declare function mapToAwsSemanticConventions(event: TransportEvent): OpenTelemetryLikeAttributes;
12
+ /**
13
+ * Maps a transport event to GCP Cloud Trace compatible semantic conventions.
14
+ */
15
+ export declare function mapToGcpSemanticConventions(event: TransportEvent): OpenTelemetryLikeAttributes;
16
+ //# sourceMappingURL=otelProfiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otelProfiles.d.ts","sourceRoot":"","sources":["../../../src/observability/otelProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAGjE;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,GACpB,2BAA2B,CAwB7B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,GACpB,2BAA2B,CAgB7B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,GACpB,2BAA2B,CAgB7B"}
@@ -0,0 +1,66 @@
1
+ import { mapTransportEventToOtelAttributes } from "./otelMapping";
2
+ /**
3
+ * Maps a transport event to standard HTTP OpenTelemetry semantic conventions.
4
+ * @see https://opentelemetry.io/docs/specs/semconv/http/http-spans/
5
+ */
6
+ export function mapToStandardHttpAttributes(event) {
7
+ const base = mapTransportEventToOtelAttributes(event);
8
+ const attributes = {
9
+ ...base,
10
+ "http.method": event.method,
11
+ "http.url": event.url,
12
+ };
13
+ if (event.status !== undefined) {
14
+ attributes["http.status_code"] = event.status;
15
+ }
16
+ // Optionally extract host/scheme if URL is valid
17
+ try {
18
+ const urlObj = new URL(event.url);
19
+ attributes["http.scheme"] = urlObj.protocol.replace(":", "");
20
+ attributes["http.host"] = urlObj.host;
21
+ attributes["net.peer.name"] = urlObj.hostname;
22
+ attributes["net.peer.port"] = urlObj.port ? parseInt(urlObj.port, 10) : (urlObj.protocol === "https:" ? 443 : 80);
23
+ }
24
+ catch {
25
+ // Ignore invalid URLs
26
+ }
27
+ return attributes;
28
+ }
29
+ /**
30
+ * Maps a transport event to AWS X-Ray compatible semantic conventions.
31
+ */
32
+ export function mapToAwsSemanticConventions(event) {
33
+ const standard = mapToStandardHttpAttributes(event);
34
+ const awsAttributes = {
35
+ ...standard,
36
+ "aws.service": "pureq-client",
37
+ };
38
+ if (event.status !== undefined) {
39
+ if (event.status >= 500)
40
+ awsAttributes["aws.is_fault"] = true;
41
+ else if (event.status >= 400)
42
+ awsAttributes["aws.is_error"] = true;
43
+ }
44
+ else if (event.errorKind !== undefined) {
45
+ awsAttributes["aws.is_fault"] = true;
46
+ }
47
+ return awsAttributes;
48
+ }
49
+ /**
50
+ * Maps a transport event to GCP Cloud Trace compatible semantic conventions.
51
+ */
52
+ export function mapToGcpSemanticConventions(event) {
53
+ const standard = mapToStandardHttpAttributes(event);
54
+ const gcpAttributes = {
55
+ ...standard,
56
+ };
57
+ // GCP Cloud Trace often looks for specific agent identifiers and status mappings
58
+ if (event.status !== undefined) {
59
+ gcpAttributes["/http/status_code"] = event.status;
60
+ }
61
+ gcpAttributes["/http/url"] = event.url;
62
+ gcpAttributes["/http/method"] = event.method;
63
+ gcpAttributes["/agent"] = "pureq";
64
+ return gcpAttributes;
65
+ }
66
+ //# sourceMappingURL=otelProfiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otelProfiles.js","sourceRoot":"","sources":["../../../src/observability/otelProfiles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAqB;IAErB,MAAM,IAAI,GAAG,iCAAiC,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,UAAU,GAA8C;QAC5D,GAAG,IAAI;QACP,aAAa,EAAE,KAAK,CAAC,MAAM;QAC3B,UAAU,EAAE,KAAK,CAAC,GAAG;KACtB,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,UAAU,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAChD,CAAC;IAED,iDAAiD;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC7D,UAAU,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QACtC,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9C,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpH,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAqB;IAErB,MAAM,QAAQ,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,aAAa,GAA8C;QAC/D,GAAG,QAAQ;QACX,aAAa,EAAE,cAAc;KAC9B,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;YAAE,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;aACzD,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;YAAE,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACrE,CAAC;SAAM,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACzC,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACvC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAqB;IAErB,MAAM,QAAQ,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,aAAa,GAA8C;QAC/D,GAAG,QAAQ;KACZ,CAAC;IAEF,iFAAiF;IACjF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,aAAa,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IACpD,CAAC;IACD,aAAa,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;IACvC,aAAa,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAC7C,aAAa,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAElC,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,39 @@
1
+ export interface RedactionOptions {
2
+ readonly redactedValue?: string;
3
+ readonly sensitiveHeaderNames?: readonly string[];
4
+ readonly sensitiveFieldPatterns?: readonly RegExp[];
5
+ }
6
+ /**
7
+ * Redacts sensitive header values while preserving keys.
8
+ */
9
+ export declare function redactHeaders(headers: Readonly<Record<string, string>>, options?: RedactionOptions): Readonly<Record<string, string>>;
10
+ /**
11
+ * Redacts sensitive object fields by key pattern.
12
+ */
13
+ export declare function redactObjectFields<T extends Readonly<Record<string, unknown>>>(value: T, options?: RedactionOptions): T;
14
+ /**
15
+ * Standard PII (Personally Identifiable Information) Redaction Profile.
16
+ * Redacts common PII field names like email, phone, ssn, address.
17
+ */
18
+ export declare const piiRedactionOptions: RedactionOptions;
19
+ /**
20
+ * Standard Auth Redaction Profile.
21
+ * Extends the default auth redaction with stricter keys and patterns.
22
+ */
23
+ export declare const authRedactionOptions: RedactionOptions;
24
+ export interface UrlRedactionOptions {
25
+ readonly redactedValue?: string;
26
+ readonly sensitiveParams?: readonly string[];
27
+ }
28
+ /**
29
+ * Redacts sensitive query parameters from a URL string.
30
+ * Useful for preventing secret leakage via telemetry/logging.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * redactUrlQueryParams("https://api.example.com/v1?token=secret123&page=1")
35
+ * // => "https://api.example.com/v1?token=[REDACTED]&page=1"
36
+ * ```
37
+ */
38
+ export declare function redactUrlQueryParams(url: string, options?: UrlRedactionOptions): string;
39
+ //# sourceMappingURL=redaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../../src/observability/redaction.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrD;AAYD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACzC,OAAO,GAAE,gBAAqB,GAC7B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAYlC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC5E,KAAK,EAAE,CAAC,EACR,OAAO,GAAE,gBAAqB,GAC7B,CAAC,CAWH;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAWjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAalC,CAAC;AAkBF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAsBR"}
@@ -0,0 +1,112 @@
1
+ const defaultSensitiveHeaders = [
2
+ "authorization",
3
+ "proxy-authorization",
4
+ "cookie",
5
+ "set-cookie",
6
+ "x-api-key",
7
+ ];
8
+ const defaultSensitiveFieldPatterns = [/token/i, /secret/i, /password/i, /api[-_]?key/i];
9
+ /**
10
+ * Redacts sensitive header values while preserving keys.
11
+ */
12
+ export function redactHeaders(headers, options = {}) {
13
+ const redactedValue = options.redactedValue ?? "[REDACTED]";
14
+ const sensitive = new Set((options.sensitiveHeaderNames ?? defaultSensitiveHeaders).map((key) => key.toLowerCase()));
15
+ const result = {};
16
+ for (const [key, value] of Object.entries(headers)) {
17
+ result[key] = sensitive.has(key.toLowerCase()) ? redactedValue : value;
18
+ }
19
+ return result;
20
+ }
21
+ /**
22
+ * Redacts sensitive object fields by key pattern.
23
+ */
24
+ export function redactObjectFields(value, options = {}) {
25
+ const redactedValue = options.redactedValue ?? "[REDACTED]";
26
+ const patterns = options.sensitiveFieldPatterns ?? defaultSensitiveFieldPatterns;
27
+ const result = {};
28
+ for (const [key, fieldValue] of Object.entries(value)) {
29
+ const sensitive = patterns.some((pattern) => pattern.test(key));
30
+ result[key] = sensitive ? redactedValue : fieldValue;
31
+ }
32
+ return result;
33
+ }
34
+ /**
35
+ * Standard PII (Personally Identifiable Information) Redaction Profile.
36
+ * Redacts common PII field names like email, phone, ssn, address.
37
+ */
38
+ export const piiRedactionOptions = {
39
+ sensitiveFieldPatterns: [
40
+ /email/i,
41
+ /phone/i,
42
+ /ssn/i,
43
+ /social.?security/i,
44
+ /address/i,
45
+ /credit.?card/i,
46
+ /dob/i,
47
+ /date.?of.?birth/i,
48
+ ],
49
+ };
50
+ /**
51
+ * Standard Auth Redaction Profile.
52
+ * Extends the default auth redaction with stricter keys and patterns.
53
+ */
54
+ export const authRedactionOptions = {
55
+ sensitiveHeaderNames: [
56
+ ...defaultSensitiveHeaders,
57
+ "x-amz-security-token",
58
+ "x-goog-api-key",
59
+ ],
60
+ sensitiveFieldPatterns: [
61
+ ...defaultSensitiveFieldPatterns,
62
+ /client.?secret/i,
63
+ /access.?token/i,
64
+ /refresh.?token/i,
65
+ /auth/i,
66
+ ],
67
+ };
68
+ /**
69
+ * Default query parameter names considered sensitive in URLs.
70
+ */
71
+ const defaultSensitiveQueryParams = [
72
+ "token",
73
+ "key",
74
+ "api_key",
75
+ "apiKey",
76
+ "apikey",
77
+ "secret",
78
+ "password",
79
+ "access_token",
80
+ "refresh_token",
81
+ "client_secret",
82
+ ];
83
+ /**
84
+ * Redacts sensitive query parameters from a URL string.
85
+ * Useful for preventing secret leakage via telemetry/logging.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * redactUrlQueryParams("https://api.example.com/v1?token=secret123&page=1")
90
+ * // => "https://api.example.com/v1?token=[REDACTED]&page=1"
91
+ * ```
92
+ */
93
+ export function redactUrlQueryParams(url, options = {}) {
94
+ const redactedValue = options.redactedValue ?? "[REDACTED]";
95
+ const sensitiveParams = new Set((options.sensitiveParams ?? defaultSensitiveQueryParams).map((p) => p.toLowerCase()));
96
+ try {
97
+ const parsed = new URL(url);
98
+ let redacted = false;
99
+ for (const key of [...parsed.searchParams.keys()]) {
100
+ if (sensitiveParams.has(key.toLowerCase())) {
101
+ parsed.searchParams.set(key, redactedValue);
102
+ redacted = true;
103
+ }
104
+ }
105
+ return redacted ? parsed.toString() : url;
106
+ }
107
+ catch {
108
+ // If the URL is not parseable (e.g. relative path), return as-is
109
+ return url;
110
+ }
111
+ }
112
+ //# sourceMappingURL=redaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../../src/observability/redaction.ts"],"names":[],"mappings":"AAMA,MAAM,uBAAuB,GAAG;IAC9B,eAAe;IACf,qBAAqB;IACrB,QAAQ;IACR,YAAY;IACZ,WAAW;CACZ,CAAC;AAEF,MAAM,6BAA6B,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;AAEzF;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAyC,EACzC,UAA4B,EAAE;IAE9B,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,YAAY,CAAC;IAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,CAAC,OAAO,CAAC,oBAAoB,IAAI,uBAAuB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAC1F,CAAC;IAEF,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;IACzE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAQ,EACR,UAA4B,EAAE;IAE9B,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,YAAY,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,sBAAsB,IAAI,6BAA6B,CAAC;IAEjF,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;IACvD,CAAC;IAED,OAAO,MAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,sBAAsB,EAAE;QACtB,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,mBAAmB;QACnB,UAAU;QACV,eAAe;QACf,MAAM;QACN,kBAAkB;KACnB;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAqB;IACpD,oBAAoB,EAAE;QACpB,GAAG,uBAAuB;QAC1B,sBAAsB;QACtB,gBAAgB;KACjB;IACD,sBAAsB,EAAE;QACtB,GAAG,6BAA6B;QAChC,iBAAiB;QACjB,gBAAgB;QAChB,iBAAiB;QACjB,OAAO;KACR;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,2BAA2B,GAAG;IAClC,OAAO;IACP,KAAK;IACL,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,cAAc;IACd,eAAe;IACf,eAAe;CAChB,CAAC;AAOF;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAW,EACX,UAA+B,EAAE;IAEjC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,YAAY,CAAC;IAC5D,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,CAAC,OAAO,CAAC,eAAe,IAAI,2BAA2B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CACrF,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAClD,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAC3C,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;gBAC5C,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;QACjE,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Middleware } from "../types/http";
2
+ export interface PolicyMetadata {
3
+ readonly name: string;
4
+ readonly kind: "timeout" | "retry" | "hedge" | "cache" | "concurrency";
5
+ readonly maxRetries?: number;
6
+ readonly maxConcurrent?: number;
7
+ }
8
+ export type PolicyAwareMiddleware = Middleware & {
9
+ readonly __pureqPolicy?: PolicyMetadata;
10
+ };
11
+ export declare function markPolicyMiddleware<T extends Middleware>(middleware: T, metadata: PolicyMetadata): T;
12
+ export declare function getPolicyMetadata(middleware: Middleware): PolicyMetadata | undefined;
13
+ export declare function validatePolicyGuardrails(middlewares: readonly Middleware[]): void;
14
+ //# sourceMappingURL=guardrails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../../src/policy/guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC;CACzC,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,GAAG,CAAC,CASrG;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc,GAAG,SAAS,CAEpF;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CA0BjF"}
@@ -0,0 +1,36 @@
1
+ export function markPolicyMiddleware(middleware, metadata) {
2
+ Object.defineProperty(middleware, "__pureqPolicy", {
3
+ value: metadata,
4
+ enumerable: false,
5
+ configurable: false,
6
+ writable: false,
7
+ });
8
+ return middleware;
9
+ }
10
+ export function getPolicyMetadata(middleware) {
11
+ return middleware.__pureqPolicy;
12
+ }
13
+ export function validatePolicyGuardrails(middlewares) {
14
+ const policies = middlewares
15
+ .map((middleware) => getPolicyMetadata(middleware))
16
+ .filter((policy) => policy !== undefined);
17
+ const retryPolicies = policies.filter((policy) => policy.kind === "retry");
18
+ if (retryPolicies.length > 1) {
19
+ throw new Error("pureq: multiple retry policies are not allowed in one client");
20
+ }
21
+ const timeoutPolicies = policies.filter((policy) => policy.kind === "timeout");
22
+ const hasDeadline = timeoutPolicies.some((policy) => policy.name === "deadline");
23
+ const hasDefaultTimeout = timeoutPolicies.some((policy) => policy.name === "defaultTimeout");
24
+ if (hasDeadline && hasDefaultTimeout) {
25
+ throw new Error("pureq: use deadline or defaultTimeout, not both");
26
+ }
27
+ if (timeoutPolicies.length > 1) {
28
+ throw new Error("pureq: do not combine multiple timeout policies in one client");
29
+ }
30
+ for (const policy of retryPolicies) {
31
+ if (policy.maxRetries !== undefined && policy.maxRetries > 10) {
32
+ throw new Error("pureq: retry maxRetries must be 10 or less");
33
+ }
34
+ }
35
+ }
36
+ //# sourceMappingURL=guardrails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../../src/policy/guardrails.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,oBAAoB,CAAuB,UAAa,EAAE,QAAwB;IAChG,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,eAAe,EAAE;QACjD,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAsB;IACtD,OAAQ,UAAoC,CAAC,aAAa,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,WAAkC;IACzE,MAAM,QAAQ,GAAG,WAAW;SACzB,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;SAClD,MAAM,CAAC,CAAC,MAAM,EAA4B,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAEtE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IAC3E,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC/E,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACjF,MAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;IAC7F,IAAI,WAAW,IAAI,iBAAiB,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,GAAG,EAAE,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;AACH,CAAC"}