unnbound-logger-sdk 3.0.36 → 3.1.0-beta.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.
package/dist/axios.d.ts CHANGED
@@ -8,6 +8,13 @@ export type OnRequest = (config: AxiosRequestConfig, callback: (config: AxiosReq
8
8
  interface HttpClientOptions extends HttpOptions<GetPayload> {
9
9
  onRequest?: OnRequest;
10
10
  redact?: RedactOptions | boolean;
11
+ /**
12
+ * Propagate correlation headers but emit no request/response logs, in every
13
+ * environment. For internal platform transports whose payloads must never become
14
+ * customer-visible (e.g. AS2 envelopes and MDNs) — unlike the `internal()` payload
15
+ * marker, suppression does not depend on runtime env vars.
16
+ */
17
+ silent?: boolean;
11
18
  }
12
19
  /**
13
20
  * Wraps an axios instance to add tracing and span tracking
@@ -15,5 +22,5 @@ interface HttpClientOptions extends HttpOptions<GetPayload> {
15
22
  * @param options - Configuration options for HTTP tracing
16
23
  * @returns The wrapped axios instance with span tracking
17
24
  */
18
- export declare const traceAxios: (client: AxiosInstance, { ignoreTraceRoutes, traceHeaderKey, getPayload, onRequest, redact: redactOptions, }?: HttpClientOptions) => AxiosInstance;
25
+ export declare const traceAxios: (client: AxiosInstance, { ignoreTraceRoutes, traceHeaderKey, getPayload, onRequest, redact: redactOptions, silent, }?: HttpClientOptions) => AxiosInstance;
19
26
  export {};
package/dist/axios.js CHANGED
@@ -43,7 +43,7 @@ const onNoopRequest = (config, callback) => callback(config);
43
43
  * @param options - Configuration options for HTTP tracing
44
44
  * @returns The wrapped axios instance with span tracking
45
45
  */
46
- const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes, traceHeaderKey = types_1.defaultTraceHeaderKey, getPayload = getNoopPayload, onRequest = onNoopRequest, redact: redactOptions, } = {
46
+ const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes, traceHeaderKey = types_1.defaultTraceHeaderKey, getPayload = getNoopPayload, onRequest = onNoopRequest, redact: redactOptions, silent = false, } = {
47
47
  ignoreTraceRoutes: types_1.defaultIgnoreTraceRoutes,
48
48
  traceHeaderKey: types_1.defaultTraceHeaderKey,
49
49
  getPayload: getNoopPayload,
@@ -62,6 +62,8 @@ const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRout
62
62
  return originalMethod(config);
63
63
  const traceId = storage_1.storage.getStore()?.traceId;
64
64
  config = { ...config, headers: { ...config.headers, [traceHeaderKey]: traceId } };
65
+ if (silent)
66
+ return onRequest(config, (config) => originalMethod(config));
65
67
  return onRequest(config, (config) => {
66
68
  // Execute the request within a span
67
69
  return (0, span_1.startSpan)('Outgoing HTTP request', () => originalMethod(config), (options) => {
package/dist/index.d.ts CHANGED
@@ -4,16 +4,16 @@
4
4
  * A structured logging library built on Pino with TypeScript support.
5
5
  * Provides consistent, well-typed logging across different operational contexts.
6
6
  */
7
- export type { LogLevel, LogType, HttpMethod, Maybe, EventSource, Log, HttpPayload, SftpPayload, EdiPayload, EdiOperation, EdiFormat, EdiX12Payload, EdiX12Operation, } from './types';
8
- export { defaultTraceHeaderKey, defaultMessageHeaderKey } from './types';
7
+ export { type OnRequest, traceAxios } from './axios';
8
+ export type { EmitMetricOptions, MetricDefinition, MetricUnit } from './emf';
9
+ export { emitMetric, emitMetrics } from './emf';
10
+ export { decode, encode } from './encode';
9
11
  export type { ILogger, UnnboundLogger } from './logger';
10
12
  export { logger } from './logger';
11
- export { encode, decode } from './encode';
12
- export { withTrace, getTraceId } from './trace';
13
- export { startSpan } from './span';
14
- export { traceAxios, type OnRequest } from './axios';
15
13
  export { traceMiddleware } from './middleware';
16
- export { storage, withStorage } from './storage';
14
+ export { startSpan } from './span';
17
15
  export type { UnnboundContext } from './storage';
18
- export type { MetricUnit, MetricDefinition, EmitMetricOptions } from './emf';
19
- export { emitMetric, emitMetrics } from './emf';
16
+ export { storage, withStorage } from './storage';
17
+ export { getTraceId, withTrace } from './trace';
18
+ export type { As2Operation, As2Outcome, As2Payload, EdiFormat, EdiOperation, EdiPayload, EdiX12Operation, EdiX12Payload, EventSource, HttpMethod, HttpPayload, Log, LogLevel, LogType, Maybe, SftpPayload, } from './types';
19
+ export { defaultMessageHeaderKey, defaultTraceHeaderKey } from './types';
package/dist/index.js CHANGED
@@ -1,26 +1,32 @@
1
1
  "use strict";
2
+ /**
3
+ * unnbound-logger
4
+ *
5
+ * A structured logging library built on Pino with TypeScript support.
6
+ * Provides consistent, well-typed logging across different operational contexts.
7
+ */
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.emitMetrics = exports.emitMetric = exports.withStorage = exports.storage = exports.traceMiddleware = exports.traceAxios = exports.startSpan = exports.getTraceId = exports.withTrace = exports.decode = exports.encode = exports.logger = exports.defaultMessageHeaderKey = exports.defaultTraceHeaderKey = void 0;
4
- var types_1 = require("./types");
5
- Object.defineProperty(exports, "defaultTraceHeaderKey", { enumerable: true, get: function () { return types_1.defaultTraceHeaderKey; } });
6
- Object.defineProperty(exports, "defaultMessageHeaderKey", { enumerable: true, get: function () { return types_1.defaultMessageHeaderKey; } });
7
- var logger_1 = require("./logger");
8
- Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
9
- var encode_1 = require("./encode");
10
- Object.defineProperty(exports, "encode", { enumerable: true, get: function () { return encode_1.encode; } });
11
- Object.defineProperty(exports, "decode", { enumerable: true, get: function () { return encode_1.decode; } });
12
- var trace_1 = require("./trace");
13
- Object.defineProperty(exports, "withTrace", { enumerable: true, get: function () { return trace_1.withTrace; } });
14
- Object.defineProperty(exports, "getTraceId", { enumerable: true, get: function () { return trace_1.getTraceId; } });
15
- var span_1 = require("./span");
16
- Object.defineProperty(exports, "startSpan", { enumerable: true, get: function () { return span_1.startSpan; } });
9
+ exports.defaultTraceHeaderKey = exports.defaultMessageHeaderKey = exports.withTrace = exports.getTraceId = exports.withStorage = exports.storage = exports.startSpan = exports.traceMiddleware = exports.logger = exports.encode = exports.decode = exports.emitMetrics = exports.emitMetric = exports.traceAxios = void 0;
17
10
  var axios_1 = require("./axios");
18
11
  Object.defineProperty(exports, "traceAxios", { enumerable: true, get: function () { return axios_1.traceAxios; } });
12
+ var emf_1 = require("./emf");
13
+ Object.defineProperty(exports, "emitMetric", { enumerable: true, get: function () { return emf_1.emitMetric; } });
14
+ Object.defineProperty(exports, "emitMetrics", { enumerable: true, get: function () { return emf_1.emitMetrics; } });
15
+ var encode_1 = require("./encode");
16
+ Object.defineProperty(exports, "decode", { enumerable: true, get: function () { return encode_1.decode; } });
17
+ Object.defineProperty(exports, "encode", { enumerable: true, get: function () { return encode_1.encode; } });
18
+ var logger_1 = require("./logger");
19
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
19
20
  var middleware_1 = require("./middleware");
20
21
  Object.defineProperty(exports, "traceMiddleware", { enumerable: true, get: function () { return middleware_1.traceMiddleware; } });
22
+ var span_1 = require("./span");
23
+ Object.defineProperty(exports, "startSpan", { enumerable: true, get: function () { return span_1.startSpan; } });
21
24
  var storage_1 = require("./storage");
22
25
  Object.defineProperty(exports, "storage", { enumerable: true, get: function () { return storage_1.storage; } });
23
26
  Object.defineProperty(exports, "withStorage", { enumerable: true, get: function () { return storage_1.withStorage; } });
24
- var emf_1 = require("./emf");
25
- Object.defineProperty(exports, "emitMetric", { enumerable: true, get: function () { return emf_1.emitMetric; } });
26
- Object.defineProperty(exports, "emitMetrics", { enumerable: true, get: function () { return emf_1.emitMetrics; } });
27
+ var trace_1 = require("./trace");
28
+ Object.defineProperty(exports, "getTraceId", { enumerable: true, get: function () { return trace_1.getTraceId; } });
29
+ Object.defineProperty(exports, "withTrace", { enumerable: true, get: function () { return trace_1.withTrace; } });
30
+ var types_1 = require("./types");
31
+ Object.defineProperty(exports, "defaultMessageHeaderKey", { enumerable: true, get: function () { return types_1.defaultMessageHeaderKey; } });
32
+ Object.defineProperty(exports, "defaultTraceHeaderKey", { enumerable: true, get: function () { return types_1.defaultTraceHeaderKey; } });
package/dist/internal.js CHANGED
@@ -2,8 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.internal = exports.hidden = void 0;
4
4
  const o = { _internal: true };
5
- // Internal logs should be hidden in sandbox
6
- // TODO: Find a better way to detect sandbox
5
+ // Sandbox-internal logs are hidden from customer-visible streams.
7
6
  if (process.env.UNNBOUND_IDLE_TIMEOUT)
8
7
  o._hide = true;
9
8
  const hidden = (data) => '_hide' in data && data._hide;
package/dist/logger.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import pino from 'pino';
2
+ import type { DestinationStream } from 'pino';
2
3
  export interface ILogger {
3
- trace(object: {}, message: string): void;
4
+ trace(object: object, message: string): void;
4
5
  trace(message: string): void;
5
- debug(object: {}, message: string): void;
6
+ debug(object: object, message: string): void;
6
7
  debug(message: string): void;
7
- info(object: {}, message: string): void;
8
+ info(object: object, message: string): void;
8
9
  info(message: string): void;
9
- warn(object: {}, message: string): void;
10
+ warn(object: object, message: string): void;
10
11
  warn(message: string): void;
11
12
  error<O extends {
12
13
  err: unknown;
@@ -14,4 +15,5 @@ export interface ILogger {
14
15
  }
15
16
  export interface UnnboundLogger extends ILogger, Omit<pino.Logger, keyof ILogger> {
16
17
  }
18
+ export declare const createLogger: (destination?: DestinationStream) => UnnboundLogger;
17
19
  export declare const logger: UnnboundLogger;
package/dist/logger.js CHANGED
@@ -3,18 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logger = void 0;
6
+ exports.logger = exports.createLogger = void 0;
7
7
  const pino_1 = __importDefault(require("pino"));
8
8
  const uuid_1 = require("uuid");
9
9
  const encode_1 = require("./encode");
10
10
  const internal_1 = require("./internal");
11
11
  const storage_1 = require("./storage");
12
12
  const levels = new Set(['debug', 'info', 'warn', 'error']);
13
+ const workflowEnvironment = process.env.WORKFLOW_ENV ?? process.env.UNNBOUND_ENVIRONMENT ?? process.env.ENVIRONMENT;
14
+ const stackEnvironment = process.env.ENVIRONMENT ?? process.env.APP_ENV;
13
15
  const formatLevel = (level) => ({ level });
14
- // TODO: Check if there is a better way to encode the log object.
15
16
  const formatLog = (log, visited = new WeakSet()) => {
16
- if (!log || typeof log !== 'object')
17
- return log;
18
17
  // Prevent infinite loops from circular references
19
18
  if (visited.has(log))
20
19
  return log;
@@ -24,6 +23,12 @@ const formatLog = (log, visited = new WeakSet()) => {
24
23
  return log;
25
24
  // We don't use Object.entries() for performance reasons
26
25
  for (const key in log) {
26
+ if (!Object.hasOwn(log, key))
27
+ continue;
28
+ // JSON.parse produces own '__proto__'/'constructor' keys; assigning to them
29
+ // routes through Object.prototype setters and pollutes the prototype chain.
30
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype')
31
+ continue;
27
32
  const value = log[key];
28
33
  // We don't want to encode undefined values.
29
34
  if (value === undefined)
@@ -47,10 +52,11 @@ const formatLog = (log, visited = new WeakSet()) => {
47
52
  }
48
53
  return log;
49
54
  };
50
- exports.logger = (0, pino_1.default)({
55
+ const loggerOptions = {
51
56
  level: process.env.LOG_LEVEL ?? 'debug',
52
57
  base: {
53
- environment: process.env.ENVIRONMENT,
58
+ environment: workflowEnvironment,
59
+ stack: stackEnvironment,
54
60
  workflowId: process.env.UNNBOUND_WORKFLOW_ID,
55
61
  serviceId: process.env.UNNBOUND_SERVICE_ID,
56
62
  deploymentId: process.env.UNNBOUND_DEPLOYMENT_ID,
@@ -71,17 +77,18 @@ exports.logger = (0, pino_1.default)({
71
77
  hooks: {
72
78
  logMethod(args, method) {
73
79
  const firstArg = args[0];
80
+ let activeMethod = method;
74
81
  if (!!firstArg && typeof firstArg === 'object') {
75
82
  // If the log entry is considered hidden, don't log it
76
83
  if ((0, internal_1.hidden)(firstArg))
77
84
  return;
78
85
  // Dynamic log level by allowing overwriting the log level
79
86
  if ('level' in firstArg && typeof firstArg.level === 'string' && levels.has(firstArg.level)) {
80
- method = this[firstArg.level];
87
+ activeMethod = this[firstArg.level];
81
88
  firstArg.level = undefined;
82
89
  }
83
90
  }
84
- method.apply(this, args);
91
+ activeMethod.apply(this, args);
85
92
  },
86
93
  },
87
94
  redact: {
@@ -94,7 +101,10 @@ exports.logger = (0, pino_1.default)({
94
101
  ],
95
102
  remove: true,
96
103
  },
97
- });
104
+ };
105
+ const createLogger = (destination) => destination ? (0, pino_1.default)(loggerOptions, destination) : (0, pino_1.default)(loggerOptions);
106
+ exports.createLogger = createLogger;
107
+ exports.logger = (0, exports.createLogger)();
98
108
  process.on('uncaughtException', (err, origin) => {
99
109
  try {
100
110
  exports.logger.error({ err, origin }, 'Uncaught exception.');
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.traceMiddleware = void 0;
4
4
  const span_1 = require("./span");
5
- const types_1 = require("./types");
6
5
  const trace_1 = require("./trace");
6
+ const types_1 = require("./types");
7
7
  const utils_1 = require("./utils");
8
8
  const extractQueryParams = (url) => {
9
9
  const object = new URL(url);
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type LogLevel = 'info' | 'debug' | 'error' | 'warn';
2
- export type LogType = 'general' | 'http' | 'sftp' | 'edi';
2
+ export type LogType = 'general' | 'http' | 'sftp' | 'edi' | 'as2';
3
3
  export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
4
4
  export type EventSource = 'http' | 'queue';
5
5
  export type Maybe<T> = {
@@ -22,6 +22,7 @@ export interface Log<T extends LogType = 'general'> {
22
22
  http: T extends 'http' ? HttpPayload : never;
23
23
  sftp: T extends 'sftp' ? SftpPayload : never;
24
24
  edi: T extends 'edi' ? EdiPayload : never;
25
+ as2: T extends 'as2' ? As2Payload : never;
25
26
  duration?: number;
26
27
  err?: unknown;
27
28
  }
@@ -63,6 +64,39 @@ export interface EdiPayload {
63
64
  type: EdiFormat;
64
65
  x12?: EdiX12Payload;
65
66
  }
67
+ export type As2Operation = 'send' | 'deliver' | 'receive' | 'acknowledge' | 'mdn-generate' | 'mdn-deliver' | 'mdn-verify';
68
+ export type As2Outcome = 'confirmed' | 'failed' | 'pending' | 'received' | 'duplicate' | 'inFlight' | 'parked' | 'delivered' | 'generated' | 'verified';
69
+ /**
70
+ * Customer-visible AS2 protocol milestone. Metadata only, by contract: AS2 transport
71
+ * bodies are plaintext business documents, sealed envelopes, and signed MDNs, so this
72
+ * payload must never carry bodies, full URLs, tokens, or certificate material.
73
+ */
74
+ export interface As2Payload {
75
+ operation: As2Operation;
76
+ /** AS2 protocol Message-ID. The log root's messageId stays the Temper event identifier. */
77
+ messageId?: string;
78
+ /** Original-Message-ID of the message an MDN settles. */
79
+ originalMessageId?: string;
80
+ /** Customer trace that originated the transaction, linked from async callback traces. */
81
+ originatingTraceId?: string;
82
+ /** Partner config reference (a variable name), never a URL or certificate. */
83
+ partner?: string;
84
+ /** Destination host only — never full URLs or query strings. */
85
+ host?: string;
86
+ byteLength?: number;
87
+ contentType?: string;
88
+ mdnMode?: 'sync' | 'async';
89
+ replayed?: boolean;
90
+ attempt?: number;
91
+ /** HTTP status of a delivery POST. */
92
+ status?: number;
93
+ outcome?: As2Outcome;
94
+ /** Normalized MDN disposition, e.g. "automatic-action/MDN-sent-automatically; processed". */
95
+ disposition?: string;
96
+ micMatched?: boolean;
97
+ /** Normalized safe error code (As2SdkError.code), never a stack trace. */
98
+ errorCode?: string;
99
+ }
66
100
  export interface HttpOptions<G extends Function> {
67
101
  ignoreTraceRoutes?: string[];
68
102
  traceHeaderKey?: string;
package/package.json CHANGED
@@ -1,24 +1,11 @@
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.0.36",
4
+ "version": "3.1.0-beta.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "bun x tsc",
9
- "test": "echo 'No tests'",
10
- "typecheck": "tsc -noEmit",
11
- "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
12
- "lint:fix": "bun run lint --fix",
13
- "format": "biome format --write .",
14
- "format:check": "biome format .",
15
- "prepublishOnly": "bun run build",
16
- "start:example": "bun --watch examples/node-express.ts",
17
- "version:bump": "npm version patch"
18
- },
19
7
  "keywords": [
20
8
  "logging",
21
- "typescript",
22
9
  "structured-logging",
23
10
  "pino",
24
11
  "tracing",
@@ -38,19 +25,19 @@
38
25
  "url": "https://github.com/unnbounddev/unnbound-sdks/issues"
39
26
  },
40
27
  "dependencies": {
41
- "axios": "^1.12.2",
28
+ "axios": "1.16.0",
42
29
  "express": "^4.0.0 || ^5.0.0",
43
- "pino": "^8.17.2",
44
- "uuid": "^11.1.0"
30
+ "pino": "^10.3.1",
31
+ "uuid": "^11.1.1"
45
32
  },
46
33
  "devDependencies": {
47
34
  "@types/express": "^4.17.21",
48
- "@types/node": "^22",
35
+ "@types/node": "^24.12.2",
49
36
  "@types/uuid": "^9.0.8",
50
- "typescript": "^5.9.3"
37
+ "vitest": "^4.0.15"
51
38
  },
52
39
  "peerDependencies": {
53
- "axios": "^1.12.2",
40
+ "axios": "^1.15.1",
54
41
  "express": "^4.0.0 || ^5.0.0"
55
42
  },
56
43
  "peerDependenciesMeta": {
@@ -69,5 +56,14 @@
69
56
  "engines": {
70
57
  "node": ">=22"
71
58
  },
72
- "sideEffects": false
73
- }
59
+ "sideEffects": false,
60
+ "scripts": {
61
+ "build": "tsc",
62
+ "test": "vitest run src",
63
+ "typecheck": "tsc --noEmit",
64
+ "format": "biome format --write .",
65
+ "format:check": "biome format .",
66
+ "start:example": "tsx watch examples/node-express.ts",
67
+ "version:bump": "npm version patch"
68
+ }
69
+ }