unnbound-events 3.0.0-beta.2 → 3.1.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/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { createEnqueuer } from './lib/enqueue';
2
2
  export type { ServerErrorOptions } from './lib/error';
3
3
  export { ServerError } from './lib/error';
4
4
  export type { EventMetadata, EventSource, IncomingEvent, IncomingRequest } from './lib/event';
5
+ export type { As2Prepared, As2RawRequest } from './lib/routing/as2';
6
+ export { as2Endpoint } from './lib/routing/as2';
5
7
  export type { Handler } from './lib/routing/endpoint';
6
8
  export type { MiddlewareHandler } from './lib/routing/middleware';
7
9
  export type { EventVariables, MaybePromise } from './lib/routing/types';
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createServer = exports.ServerError = exports.createEnqueuer = void 0;
3
+ exports.createServer = exports.as2Endpoint = exports.ServerError = exports.createEnqueuer = void 0;
4
4
  var enqueue_1 = require("./lib/enqueue");
5
5
  Object.defineProperty(exports, "createEnqueuer", { enumerable: true, get: function () { return enqueue_1.createEnqueuer; } });
6
6
  var error_1 = require("./lib/error");
7
7
  Object.defineProperty(exports, "ServerError", { enumerable: true, get: function () { return error_1.ServerError; } });
8
+ var as2_1 = require("./lib/routing/as2");
9
+ Object.defineProperty(exports, "as2Endpoint", { enumerable: true, get: function () { return as2_1.as2Endpoint; } });
8
10
  var server_1 = require("./lib/server");
9
11
  Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_1.createServer; } });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function assertAs2ResponseAssignableToHandlerResult(response) {
4
+ // If As2HttpResponse ever widens `status` back to `number`, or StrictEventHandlerResult's
5
+ // `status` narrows further than Hono's StatusCode, this return stops compiling.
6
+ return response;
7
+ }
8
+ // Referenced so `noUnusedLocals`-style checks never flag this fixture as dead code.
9
+ void assertAs2ResponseAssignableToHandlerResult;
@@ -0,0 +1,56 @@
1
+ import type { EventHandlerResult } from '../event';
2
+ import { type Handler } from './endpoint';
3
+ import type { EventVariables, MaybePromise } from './types';
4
+ /** Raw wire request handed to the platform verification call, byte-exact. */
5
+ export interface As2RawRequest {
6
+ headers: Record<string, string>;
7
+ body: ArrayBuffer | Uint8Array | string | undefined;
8
+ }
9
+ /**
10
+ * Result of the platform verification call. `as2.receive` results carry the exchange's
11
+ * canonical customer trace (recovered from the ledger for a loopback, server-minted for
12
+ * an external inbound); `as2.confirm` results deliberately do not — an async MDN
13
+ * callback is its own execution and stays on its own trace, linked by Message-ID.
14
+ */
15
+ export interface As2Prepared {
16
+ customerTraceId?: string | null;
17
+ }
18
+ /**
19
+ * Verify-then-bind AS2 endpoint. The public `x-unnbound-trace-id` header is never AS2
20
+ * continuation authority: the route starts on a fresh trace, runs `prepare` (the hidden
21
+ * `as2.receive`/`as2.confirm` platform call) before any customer request span exists,
22
+ * and only a verified ledger-backed trace may re-bind the request. Unverified traffic
23
+ * fails on its own sanitized trace and can assert nothing. Request/response headers are
24
+ * logged through the AS2 allowlist — Receipt-Delivery-Option and Subject never appear.
25
+ *
26
+ * ```ts
27
+ * // identity/partner are plain objects built inline from ordinary scalar workflow
28
+ * // variables — never a variable name passed to `as2.receive`/`as2.send` (see
29
+ * // @ontemper/as2's README). partner.mdn.to only matters for outbound `as2.send`.
30
+ * const identity = { as2Id: 'ACME-TEMPER', keypairs: [{ certPem: process.env.AS2_CERT_PEM!, keyPem: process.env.AS2_KEY_PEM! }] };
31
+ * const partner = { as2Id: 'ACME', url: process.env.ACME_AS2_URL!, certs: [process.env.ACME_CERT_PEM!] };
32
+ *
33
+ * server.post('/as2/inbound', as2Endpoint(
34
+ * ({ headers, body }) => as2.receive({ headers, body: Buffer.from(body as ArrayBuffer), partner, identity }),
35
+ * async (result) => {
36
+ * if (result.kind === 'received') {
37
+ * // Delivery is at-least-once, so make processing idempotent by Message-ID.
38
+ * await processDocument(result.payload);
39
+ * const receipt = await result.acknowledge();
40
+ * // Async MDN partners get no receipt unless you deliver it explicitly — the
41
+ * // response below is deliberately an empty 200 in that mode.
42
+ * if (receipt.mdnMode === 'async' && receipt.mdn && receipt.mdnDeliveryUrl) {
43
+ * await as2.deliverMdn(receipt.mdn, receipt.mdnDeliveryUrl);
44
+ * }
45
+ * return receipt.response;
46
+ * }
47
+ * // Duplicate retries need the same async redelivery, or the partner never settles.
48
+ * if (result.kind === 'duplicate' && result.mdnMode === 'async' && result.mdn && result.mdnDeliveryUrl) {
49
+ * await as2.deliverMdn(result.mdn, result.mdnDeliveryUrl);
50
+ * }
51
+ * return result.response;
52
+ * },
53
+ * ));
54
+ * ```
55
+ */
56
+ export declare const as2Endpoint: <V extends object, P extends object>(prepare: (request: As2RawRequest, event: EventVariables<V>) => Promise<P>, handler: (prepared: P, event: EventVariables<V>) => MaybePromise<EventHandlerResult>) => Handler<EventVariables<V>>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.as2Endpoint = void 0;
4
+ const unnbound_logger_sdk_1 = require("unnbound-logger-sdk");
5
+ const error_1 = require("../error");
6
+ const utils_1 = require("../utils");
7
+ const endpoint_1 = require("./endpoint");
8
+ const response_1 = require("./response");
9
+ /**
10
+ * Transient platform failures a partner should re-send against. `As2SdkError` already computed
11
+ * these from the platform response, but it arrives here as a plain unknown — this package cannot
12
+ * import `@ontemper/as2` (the dependency runs the other way), so the shape is read defensively.
13
+ */
14
+ const RETRYABLE_AS2_STATUSES = [502, 503, 504];
15
+ /**
16
+ * AS2 partners drive their re-send behaviour off the status code, so collapsing every failure to
17
+ * a flat 500 throws away the one signal telling them to try again — the same signal the
18
+ * in-flight/parked path already sends deliberately as a 503. Lift the transient statuses onto the
19
+ * wire; the message stays generic so no internal detail reaches the partner.
20
+ */
21
+ const toWireFailure = (error) => {
22
+ if (error && typeof error === 'object') {
23
+ const { name, status } = error;
24
+ const retryable = RETRYABLE_AS2_STATUSES.find((candidate) => candidate === status);
25
+ if (name === 'As2SdkError' && retryable) {
26
+ return new error_1.ServerError({
27
+ message: 'AS2 message could not be processed; retry later',
28
+ status: retryable,
29
+ cause: error,
30
+ });
31
+ }
32
+ }
33
+ return error_1.ServerError.fromError(error);
34
+ };
35
+ /**
36
+ * Verify-then-bind AS2 endpoint. The public `x-unnbound-trace-id` header is never AS2
37
+ * continuation authority: the route starts on a fresh trace, runs `prepare` (the hidden
38
+ * `as2.receive`/`as2.confirm` platform call) before any customer request span exists,
39
+ * and only a verified ledger-backed trace may re-bind the request. Unverified traffic
40
+ * fails on its own sanitized trace and can assert nothing. Request/response headers are
41
+ * logged through the AS2 allowlist — Receipt-Delivery-Option and Subject never appear.
42
+ *
43
+ * ```ts
44
+ * // identity/partner are plain objects built inline from ordinary scalar workflow
45
+ * // variables — never a variable name passed to `as2.receive`/`as2.send` (see
46
+ * // @ontemper/as2's README). partner.mdn.to only matters for outbound `as2.send`.
47
+ * const identity = { as2Id: 'ACME-TEMPER', keypairs: [{ certPem: process.env.AS2_CERT_PEM!, keyPem: process.env.AS2_KEY_PEM! }] };
48
+ * const partner = { as2Id: 'ACME', url: process.env.ACME_AS2_URL!, certs: [process.env.ACME_CERT_PEM!] };
49
+ *
50
+ * server.post('/as2/inbound', as2Endpoint(
51
+ * ({ headers, body }) => as2.receive({ headers, body: Buffer.from(body as ArrayBuffer), partner, identity }),
52
+ * async (result) => {
53
+ * if (result.kind === 'received') {
54
+ * // Delivery is at-least-once, so make processing idempotent by Message-ID.
55
+ * await processDocument(result.payload);
56
+ * const receipt = await result.acknowledge();
57
+ * // Async MDN partners get no receipt unless you deliver it explicitly — the
58
+ * // response below is deliberately an empty 200 in that mode.
59
+ * if (receipt.mdnMode === 'async' && receipt.mdn && receipt.mdnDeliveryUrl) {
60
+ * await as2.deliverMdn(receipt.mdn, receipt.mdnDeliveryUrl);
61
+ * }
62
+ * return receipt.response;
63
+ * }
64
+ * // Duplicate retries need the same async redelivery, or the partner never settles.
65
+ * if (result.kind === 'duplicate' && result.mdnMode === 'async' && result.mdn && result.mdnDeliveryUrl) {
66
+ * await as2.deliverMdn(result.mdn, result.mdnDeliveryUrl);
67
+ * }
68
+ * return result.response;
69
+ * },
70
+ * ));
71
+ * ```
72
+ */
73
+ // P is constrained to object, not As2Prepared: prepared results are unions whose
74
+ // members don't all carry customerTraceId (e.g. inFlight/parked), and TypeScript's
75
+ // weak-type check would reject those. The As2Prepared contract is read defensively.
76
+ const as2Endpoint = (prepare, handler) => {
77
+ return (0, endpoint_1.markSelfTraced)(async (event) => {
78
+ const requestTraceId = (0, unnbound_logger_sdk_1.getTraceId)();
79
+ let prepared;
80
+ try {
81
+ prepared = await (0, unnbound_logger_sdk_1.withTrace)(() => prepare({ headers: event.request.headers, body: event.request.body }, event), {
82
+ traceId: requestTraceId,
83
+ });
84
+ }
85
+ catch (error) {
86
+ return (0, unnbound_logger_sdk_1.withTrace)(async () => {
87
+ const failure = toWireFailure(error);
88
+ // Bookend the request on its own failure trace: the span records the sanitized
89
+ // AS2 payload and rethrows; the wire response carries no protocol claims.
90
+ await (0, unnbound_logger_sdk_1.startSpan)('Event request', () => Promise.reject(failure), (o) => (0, utils_1.buildAs2IncomingPayload)(event, o)).catch(() => undefined);
91
+ const result = failure.toJson();
92
+ return { ...result, headers: (0, response_1.attachTraceHeaders)(result.headers) };
93
+ }, { traceId: requestTraceId });
94
+ }
95
+ const verified = prepared.customerTraceId;
96
+ const traceId = (0, utils_1.isCanonicalTraceId)(verified) ? verified : requestTraceId;
97
+ return (0, unnbound_logger_sdk_1.withTrace)(async () => {
98
+ // Response trace headers must be attached inside this scope: respondWith runs after
99
+ // the re-bound trace exits and would otherwise advertise the pre-bind trace.
100
+ try {
101
+ const result = await (0, unnbound_logger_sdk_1.startSpan)('Event request', async () => {
102
+ const result = await handler(prepared, event);
103
+ return { status: result?.status ?? 204, headers: result?.headers, body: result?.body };
104
+ }, (o) => (0, utils_1.buildAs2IncomingPayload)(event, o));
105
+ return { ...result, headers: (0, response_1.attachTraceHeaders)(result.headers) };
106
+ }
107
+ catch (error) {
108
+ // The span above already logged the failure on the bound trace; respond with the
109
+ // sanitized shape instead of rethrowing into the header-derived middleware trace.
110
+ // `acknowledge()` runs in here too, so a transient platform failure keeps its
111
+ // retryable status rather than becoming an indistinguishable 500.
112
+ const result = toWireFailure(error).toJson();
113
+ return { ...result, headers: (0, response_1.attachTraceHeaders)(result.headers) };
114
+ }
115
+ }, { traceId });
116
+ });
117
+ };
118
+ exports.as2Endpoint = as2Endpoint;
@@ -1,8 +1,9 @@
1
1
  import type { Context } from 'hono';
2
- import type { EventHandlerResult } from '../event';
2
+ import type { EventHandlerResult, StrictEventHandlerResult } from '../event';
3
3
  import { type MiddlewareHandler } from './middleware';
4
4
  import type { EventEnvironment, EventVariables, MaybePromise } from './types';
5
5
  export type Handler<I, R = EventHandlerResult> = (input: I) => MaybePromise<R>;
6
+ export declare const markSelfTraced: <I>(handler: (input: I) => Promise<StrictEventHandlerResult>) => Handler<I>;
6
7
  export interface Endpoint<I> {
7
8
  (path: string, handler: Handler<I>): MaybePromise<void>;
8
9
  (path: string, middleware: MiddlewareHandler<I>, handler: Handler<I>): MaybePromise<void>;
@@ -1,10 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchEndpoint = exports.parseEndpointArguments = exports.buildEndpointArguments = void 0;
3
+ exports.patchEndpoint = exports.parseEndpointArguments = exports.buildEndpointArguments = exports.markSelfTraced = void 0;
4
4
  const unnbound_logger_sdk_1 = require("unnbound-logger-sdk");
5
5
  const utils_1 = require("../utils");
6
6
  const middleware_1 = require("./middleware");
7
7
  const response_1 = require("./response");
8
+ /**
9
+ * Marks a handler that owns its customer trace and request span. The generic endpoint
10
+ * wrapper binds the header-derived trace before running a handler; AS2 endpoints must
11
+ * instead verify the protocol exchange first and only then choose the trace, so their
12
+ * wrapper (see routing/as2.ts) emits the request span itself and returns a strict result.
13
+ */
14
+ const selfTraced = Symbol.for('unnbound-events.selfTraced');
15
+ const markSelfTraced = (handler) => {
16
+ return Object.assign(handler, { [selfTraced]: true });
17
+ };
18
+ exports.markSelfTraced = markSelfTraced;
19
+ const isSelfTraced = (handler) => selfTraced in handler;
8
20
  const buildEndpointArguments = (...args) => {
9
21
  const { path, middlewares, handler } = (0, exports.parseEndpointArguments)(...args);
10
22
  const patchedHandler = (0, exports.patchEndpoint)(handler);
@@ -22,10 +34,12 @@ const patchEndpoint = (handler) => {
22
34
  const state = context.get('state');
23
35
  // We have to recalculate the params because the handler path might contain url params
24
36
  state.request.params = { ...state.request.params, ...context.req.param() };
25
- const result = await (0, unnbound_logger_sdk_1.startSpan)('Event request', async () => {
26
- const result = await handler(state);
27
- return { status: (0, response_1.resolveStatus)(result), headers: result?.headers, body: result?.body };
28
- }, (o) => (0, utils_1.buildIncomingPayload)(state, o));
37
+ const result = isSelfTraced(handler)
38
+ ? await handler(state)
39
+ : await (0, unnbound_logger_sdk_1.startSpan)('Event request', async () => {
40
+ const result = await handler(state);
41
+ return { status: (0, response_1.resolveStatus)(result), headers: result?.headers, body: result?.body };
42
+ }, (o) => (0, utils_1.buildIncomingPayload)(state, o));
29
43
  return (0, response_1.respondWith)(context, result);
30
44
  };
31
45
  };
@@ -3,6 +3,7 @@ import { type Maybe } from 'unnbound-logger-sdk/dist/types';
3
3
  import type { EventHandlerResult, EventMetadata, EventSource, IncomingEvent, IncomingRequest, MatchedIncomingRequest } from './event';
4
4
  export declare const normalizeHeaders: (headers: Record<string, string | string[]>) => Record<string, string>;
5
5
  export declare const getIncomingEvent: (event: HonoRequest) => Promise<IncomingEvent<MatchedIncomingRequest>>;
6
+ export declare const isCanonicalTraceId: (value: string | undefined | null) => value is string;
6
7
  export declare const getMetadataFromRequest: (request: Pick<IncomingRequest, 'headers'>, source: EventSource) => EventMetadata;
7
8
  interface ForwardedMetadata {
8
9
  source: EventSource;
@@ -34,5 +35,27 @@ export declare const buildIncomingPayload: (event: IncomingEvent<MatchedIncoming
34
35
  } | undefined;
35
36
  };
36
37
  };
38
+ export declare const buildAs2IncomingPayload: (event: IncomingEvent<MatchedIncomingRequest>, result?: Maybe<EventHandlerResult>) => {
39
+ type: string;
40
+ source: EventSource;
41
+ delay: number | undefined;
42
+ http: {
43
+ url: string;
44
+ method: string;
45
+ query: Record<string, any>;
46
+ params: Record<string, string> | undefined;
47
+ ip: string | undefined;
48
+ incoming: boolean;
49
+ request: {
50
+ headers: Record<string, string>;
51
+ body: unknown;
52
+ };
53
+ response?: {
54
+ status: import("hono/utils/http-status").StatusCode;
55
+ headers: Record<string, string>;
56
+ body: unknown;
57
+ } | undefined;
58
+ };
59
+ };
37
60
  export declare const batchArray: <T>(array: T[], size: number) => T[][];
38
61
  export {};
package/dist/lib/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.batchArray = exports.buildIncomingPayload = exports.serializeMetadata = exports.getMetadataFromRequest = exports.getIncomingEvent = exports.normalizeHeaders = void 0;
3
+ exports.batchArray = exports.buildAs2IncomingPayload = exports.buildIncomingPayload = exports.serializeMetadata = exports.getMetadataFromRequest = exports.isCanonicalTraceId = exports.getIncomingEvent = exports.normalizeHeaders = void 0;
4
4
  const unnbound_logger_sdk_1 = require("unnbound-logger-sdk");
5
5
  const trace_1 = require("unnbound-logger-sdk/dist/trace");
6
6
  const types_1 = require("unnbound-logger-sdk/dist/types");
@@ -54,11 +54,22 @@ const readBody = async (request) => {
54
54
  throw new error_1.ServerError({ status: 400, message: 'Failed to read request body.', cause: error });
55
55
  }
56
56
  };
57
- const getMetadataFromRequest = (request, source) => ({
58
- traceId: request.headers[types_1.defaultTraceHeaderKey] ?? (0, unnbound_logger_sdk_1.getTraceId)(),
59
- messageId: request.headers[types_1.defaultMessageHeaderKey] ?? (0, trace_1.getMessageId)(),
60
- source,
61
- });
57
+ /**
58
+ * The customer trace ID the product groups logs by — a logger-SDK UUID. Public callers
59
+ * can set the trace header, so anything non-canonical (oversized values, W3C
60
+ * traceparents, arbitrary strings) is ignored and a fresh trace is minted instead.
61
+ */
62
+ const CANONICAL_TRACE_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
63
+ const isCanonicalTraceId = (value) => typeof value === 'string' && CANONICAL_TRACE_ID.test(value);
64
+ exports.isCanonicalTraceId = isCanonicalTraceId;
65
+ const getMetadataFromRequest = (request, source) => {
66
+ const headerTraceId = request.headers[types_1.defaultTraceHeaderKey];
67
+ return {
68
+ traceId: (0, exports.isCanonicalTraceId)(headerTraceId) ? headerTraceId : (0, unnbound_logger_sdk_1.getTraceId)(),
69
+ messageId: request.headers[types_1.defaultMessageHeaderKey] ?? (0, trace_1.getMessageId)(),
70
+ source,
71
+ };
72
+ };
62
73
  exports.getMetadataFromRequest = getMetadataFromRequest;
63
74
  const sourceKey = 'x-unnbound-source';
64
75
  const timestampKey = 'x-unnbound-timestamp';
@@ -112,13 +123,36 @@ const headersForTrace = (headers) => Object.fromEntries(Object.entries(headers).
112
123
  name,
113
124
  REDACTED_TRACE_HEADERS.has(name.toLowerCase()) ? '[redacted]' : value,
114
125
  ]));
115
- const buildResponsePayload = (result) => {
126
+ // AS2 routes carry partner-controlled protocol headers, so logging flips from a
127
+ // redaction denylist to an allowlist: protocol identity/framing and Temper correlation
128
+ // headers pass; everything else is redacted. Receipt-Delivery-Option (its URL may embed
129
+ // query credentials) and Subject (business metadata) are deliberately NOT listed.
130
+ const AS2_TRACE_HEADER_ALLOWLIST = new Set([
131
+ 'as2-from',
132
+ 'as2-to',
133
+ 'as2-version',
134
+ 'content-length',
135
+ 'content-transfer-encoding',
136
+ 'content-type',
137
+ 'date',
138
+ 'disposition-notification-options',
139
+ 'disposition-notification-to',
140
+ 'message-id',
141
+ 'mime-version',
142
+ 'x-message-id',
143
+ 'x-unnbound-trace-id',
144
+ ]);
145
+ const as2HeadersForTrace = (headers) => Object.fromEntries(Object.entries(headers).map(([name, value]) => [
146
+ name,
147
+ AS2_TRACE_HEADER_ALLOWLIST.has(name.toLowerCase()) ? value : '[redacted]',
148
+ ]));
149
+ const buildResponsePayloadWith = (headersPolicy, result) => {
116
150
  const declaredHeaders = result?.headers
117
151
  ? Object.fromEntries(Object.entries((0, exports.normalizeHeaders)(result.headers)).map(([name, value]) => [name.toLowerCase(), value]))
118
152
  : undefined;
119
153
  // Binary responses keep declared headers; JSON gets the SDK default.
120
154
  // The declared content type also controls trace decoding.
121
- const traceHeaders = headersForTrace(declaredHeaders ?? {});
155
+ const traceHeaders = headersPolicy(declaredHeaders ?? {});
122
156
  const status = (0, response_1.resolveStatus)(result);
123
157
  // Mirror the wire: respondWith drops the body on contentless statuses, so the
124
158
  // trace must not claim one — nor a content type for a body never sent.
@@ -130,7 +164,7 @@ const buildResponsePayload = (result) => {
130
164
  body: body ? describeBody(body, declaredHeaders?.['content-type']) : undefined,
131
165
  };
132
166
  };
133
- const buildIncomingPayload = (event, result) => {
167
+ const buildIncomingPayloadWith = (headersPolicy) => (event, result) => {
134
168
  return {
135
169
  type: 'http',
136
170
  source: event.metadata.source,
@@ -145,18 +179,19 @@ const buildIncomingPayload = (event, result) => {
145
179
  event.request.headers['x-real-ip']),
146
180
  incoming: true,
147
181
  request: {
148
- headers: headersForTrace(event.request.headers),
182
+ headers: headersPolicy(event.request.headers),
149
183
  body: describeBody(event.request.body, event.request.headers['content-type']),
150
184
  },
151
185
  ...(result && {
152
186
  response: result.error
153
- ? buildResponsePayload(error_1.ServerError.fromError(result.error).toJson())
154
- : buildResponsePayload(result.result),
187
+ ? buildResponsePayloadWith(headersPolicy, error_1.ServerError.fromError(result.error).toJson())
188
+ : buildResponsePayloadWith(headersPolicy, result.result),
155
189
  }),
156
190
  },
157
191
  };
158
192
  };
159
- exports.buildIncomingPayload = buildIncomingPayload;
193
+ exports.buildIncomingPayload = buildIncomingPayloadWith(headersForTrace);
194
+ exports.buildAs2IncomingPayload = buildIncomingPayloadWith(as2HeadersForTrace);
160
195
  const batchArray = (array, size) => {
161
196
  return [...Array(Math.ceil(array.length / size))].map((_, i) => array.slice(i * size, i * size + size));
162
197
  };
package/package.json CHANGED
@@ -1,19 +1,9 @@
1
1
  {
2
2
  "name": "unnbound-events",
3
3
  "description": "Unified events SDK to handle HTTP routes and queued messages with a single routing API.",
4
- "version": "3.0.0-beta.2",
4
+ "version": "3.1.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc",
9
- "test": "vitest run",
10
- "typecheck": "tsc --noEmit",
11
- "format": "biome format --write .",
12
- "format:check": "biome format .",
13
- "prepublishOnly": "pnpm run build",
14
- "start:example": "tsx watch examples/node-server.ts",
15
- "version:bump": "npm version patch"
16
- },
17
7
  "author": "Unnbound Team",
18
8
  "license": "MIT",
19
9
  "repository": {
@@ -30,7 +20,7 @@
30
20
  "@hono/node-server": "^1.19.11",
31
21
  "axios": "1.16.0",
32
22
  "hono": "^4.12.21",
33
- "unnbound-logger-sdk": "^3.0.34"
23
+ "unnbound-logger-sdk": "3.1.0"
34
24
  },
35
25
  "devDependencies": {
36
26
  "@types/jest": "^29.5.12",
@@ -45,5 +35,14 @@
45
35
  "engines": {
46
36
  "node": ">=22"
47
37
  },
48
- "sideEffects": false
49
- }
38
+ "sideEffects": false,
39
+ "scripts": {
40
+ "build": "tsc",
41
+ "test": "vitest run",
42
+ "typecheck": "tsc --noEmit",
43
+ "format": "biome format --write .",
44
+ "format:check": "biome format .",
45
+ "start:example": "tsx watch examples/node-server.ts",
46
+ "version:bump": "npm version patch"
47
+ }
48
+ }