unnbound-logger-sdk 3.2.1 → 3.2.2

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.
package/dist/axios.d.ts CHANGED
@@ -21,13 +21,17 @@ interface HttpClientOptions extends HttpOptions<GetPayload> {
21
21
  silent?: boolean;
22
22
  startSpan?: typeof startSpan;
23
23
  }
24
+ type TracedMethod = 'request' | 'get' | 'delete' | 'head' | 'options' | 'post' | 'put' | 'patch';
25
+ type TraceableAxios = Pick<AxiosInstance, 'defaults'> & Record<TracedMethod, (...args: never[]) => object>;
24
26
  /**
25
27
  * Wraps an axios instance to add tracing and span tracking.
26
28
  *
27
29
  * Repeated calls for the same instance are no-ops; the first call's options remain active.
30
+ * Axios 1.20+ types an ESM import and a CommonJS require with separate, mutually unassignable
31
+ * declarations, so the signature accepts an instance from either and returns the caller's type.
28
32
  * @param client - The axios instance to wrap
29
33
  * @param options - Configuration options for HTTP tracing
30
34
  * @returns The wrapped axios instance with span tracking
31
35
  */
32
- export declare const traceAxios: (client: AxiosInstance, { ignoreTraceRoutes, traceHeaderKey, getPayload, onRequest, redact: redactOptions, silent, startSpan: startSpanImpl, }?: HttpClientOptions) => AxiosInstance;
36
+ export declare function traceAxios<Client extends TraceableAxios>(client: Client, options?: HttpClientOptions): Client;
33
37
  export {};
package/dist/axios.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.traceAxios = void 0;
3
+ exports.traceAxios = traceAxios;
4
4
  const axios_1 = require("axios");
5
5
  const span_1 = require("./span");
6
6
  const storage_1 = require("./storage");
@@ -42,45 +42,33 @@ const buildOutgoingHttpPayload = (config, res, redact) => {
42
42
  const getNoopPayload = () => ({});
43
43
  const onNoopRequest = (config, callback) => callback(config);
44
44
  const tracedMarker = Symbol.for('unnbound-logger-sdk.traceAxios.traced');
45
- /**
46
- * Wraps an axios instance to add tracing and span tracking.
47
- *
48
- * Repeated calls for the same instance are no-ops; the first call's options remain active.
49
- * @param client - The axios instance to wrap
50
- * @param options - Configuration options for HTTP tracing
51
- * @returns The wrapped axios instance with span tracking
52
- */
53
- const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes, traceHeaderKey = types_1.defaultTraceHeaderKey, getPayload = getNoopPayload, onRequest = onNoopRequest, redact: redactOptions, silent = false, startSpan: startSpanImpl = span_1.startSpan, } = {
45
+ function traceAxios(client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes, traceHeaderKey = types_1.defaultTraceHeaderKey, getPayload = getNoopPayload, onRequest = onNoopRequest, redact: redactOptions, silent = false, startSpan: startSpanImpl = span_1.startSpan, } = {
54
46
  ignoreTraceRoutes: types_1.defaultIgnoreTraceRoutes,
55
47
  traceHeaderKey: types_1.defaultTraceHeaderKey,
56
48
  getPayload: getNoopPayload,
57
49
  onRequest: onNoopRequest,
58
- }) => {
50
+ }) {
59
51
  if (tracedMarker in client)
60
52
  return client;
61
53
  const redact = redactOptions === true || redactOptions === false
62
54
  ? { request: redactOptions, response: redactOptions }
63
55
  : redactOptions;
56
+ // Axios keeps its response defaults private; proxies preserve the original method signatures.
64
57
  const createSpanWrappedRequest = (originalMethod, method) => {
65
58
  const { headers: defaultHeaders, ...partialDefaultConfig } = client.defaults;
66
59
  const headers = { ...defaultHeaders.common, ...(method && defaultHeaders[method]) };
67
60
  const defaultConfig = { ...partialDefaultConfig, headers };
68
- return async (config) => {
69
- config = (0, axios_1.mergeConfig)(defaultConfig, config);
70
- const url = buildUrl(config.baseURL, config.url);
71
- // Check if this request should be ignored
72
- if ((0, utils_1.shouldIgnorePath)(url, ignoreTraceRoutes))
73
- return originalMethod(config);
74
- const traceId = storage_1.storage.getStore()?.traceId;
75
- config = { ...config, headers: { ...config.headers, [traceHeaderKey]: traceId } };
76
- if (silent) {
77
- // SAFETY: onRequest returns the originalMethod promise, typed as Axios R
78
- return onRequest(config, (config) => originalMethod(config));
79
- }
80
- // SAFETY: startSpan resolves to the originalMethod promise, typed as Axios R
81
- return onRequest(config, (config) => {
82
- // Execute the request within a span
83
- return startSpanImpl('Outgoing HTTP request', () => originalMethod(config), (options) => {
61
+ return new Proxy(originalMethod, {
62
+ async apply(request, _thisArg, [config]) {
63
+ config = (0, axios_1.mergeConfig)(defaultConfig, config);
64
+ const url = buildUrl(config.baseURL, config.url);
65
+ if ((0, utils_1.shouldIgnorePath)(url, ignoreTraceRoutes))
66
+ return request(config);
67
+ const traceId = storage_1.storage.getStore()?.traceId;
68
+ config = { ...config, headers: { ...config.headers, [traceHeaderKey]: traceId } };
69
+ if (silent)
70
+ return onRequest(config, (config) => request(config));
71
+ return onRequest(config, (config) => startSpanImpl('Outgoing HTTP request', () => request(config), (options) => {
84
72
  const response = options
85
73
  ? options.error
86
74
  ? (0, axios_1.isAxiosError)(options.error)
@@ -92,22 +80,29 @@ const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRout
92
80
  ...buildOutgoingHttpPayload(config, response, redact),
93
81
  ...getPayload(config, response),
94
82
  };
95
- });
96
- });
97
- };
83
+ }));
84
+ },
85
+ });
98
86
  };
99
87
  const request = client.request.bind(client);
100
88
  const tracedRequest = createSpanWrappedRequest(request);
101
89
  client.request = tracedRequest;
102
90
  ['post', 'put', 'patch'].forEach((method) => {
103
91
  const func = createSpanWrappedRequest(request, method);
104
- client[method] = (url, data, config) => func({ ...config, method, url, data });
92
+ client[method] = new Proxy(client[method], {
93
+ apply(_target, _thisArg, [url, data, config]) {
94
+ return func({ ...config, method, url, data });
95
+ },
96
+ });
105
97
  });
106
98
  ['delete', 'get', 'head', 'options'].forEach((method) => {
107
99
  const func = createSpanWrappedRequest(request, method);
108
- client[method] = (url, config) => func({ ...config, method, url });
100
+ client[method] = new Proxy(client[method], {
101
+ apply(_target, _thisArg, [url, config]) {
102
+ return func({ ...config, method, url });
103
+ },
104
+ });
109
105
  });
110
106
  Object.defineProperty(client, tracedMarker, { value: true });
111
107
  return client;
112
- };
113
- exports.traceAxios = traceAxios;
108
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unnbound-logger-sdk",
3
3
  "description": "A structured logging library with TypeScript support using Pino. Provides consistent, well-typed logging with automatic logId, workflowId, traceId, and deploymentId tracking across operational contexts.",
4
- "version": "3.2.1",
4
+ "version": "3.2.2",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "keywords": [
@@ -25,7 +25,7 @@
25
25
  "url": "https://github.com/unnbounddev/unnbound-sdks/issues"
26
26
  },
27
27
  "dependencies": {
28
- "axios": "1.18.0",
28
+ "axios": "1.20.0",
29
29
  "express": "^4.0.0 || ^5.0.0",
30
30
  "pino": "^10.3.1",
31
31
  "uuid": "^11.1.1"
@@ -37,7 +37,7 @@
37
37
  "vitest": "^4.0.15"
38
38
  },
39
39
  "peerDependencies": {
40
- "axios": "^1.18.0",
40
+ "axios": "^1.20.0",
41
41
  "express": "^4.0.0 || ^5.0.0"
42
42
  },
43
43
  "peerDependenciesMeta": {
@@ -60,7 +60,7 @@
60
60
  "scripts": {
61
61
  "build": "tsc",
62
62
  "test": "vitest run src",
63
- "typecheck": "tsc --noEmit",
63
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json",
64
64
  "format": "oxfmt --write .",
65
65
  "format:check": "oxfmt --check .",
66
66
  "start:example": "tsx watch examples/node-express.ts",