@gomessaging/messaging 0.0.1

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 (47) hide show
  1. package/README.md +185 -0
  2. package/dist/cloudevents.d.ts +73 -0
  3. package/dist/cloudevents.d.ts.map +1 -0
  4. package/dist/cloudevents.js +148 -0
  5. package/dist/cloudevents.js.map +1 -0
  6. package/dist/index.d.ts +11 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +15 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/metrics.d.ts +40 -0
  11. package/dist/metrics.d.ts.map +1 -0
  12. package/dist/metrics.js +11 -0
  13. package/dist/metrics.js.map +1 -0
  14. package/dist/naming.d.ts +54 -0
  15. package/dist/naming.d.ts.map +1 -0
  16. package/dist/naming.js +78 -0
  17. package/dist/naming.js.map +1 -0
  18. package/dist/routing.d.ts +10 -0
  19. package/dist/routing.d.ts.map +1 -0
  20. package/dist/routing.js +41 -0
  21. package/dist/routing.js.map +1 -0
  22. package/dist/topology.d.ts +2 -0
  23. package/dist/topology.d.ts.map +1 -0
  24. package/dist/topology.js +4 -0
  25. package/dist/topology.js.map +1 -0
  26. package/dist/types.d.ts +73 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +5 -0
  29. package/dist/types.js.map +1 -0
  30. package/dist/validate.d.ts +12 -0
  31. package/dist/validate.d.ts.map +1 -0
  32. package/dist/validate.js +138 -0
  33. package/dist/validate.js.map +1 -0
  34. package/dist/visualize.d.ts +10 -0
  35. package/dist/visualize.d.ts.map +1 -0
  36. package/dist/visualize.js +134 -0
  37. package/dist/visualize.js.map +1 -0
  38. package/package.json +34 -0
  39. package/src/cloudevents.ts +166 -0
  40. package/src/index.ts +86 -0
  41. package/src/metrics.ts +58 -0
  42. package/src/naming.ts +94 -0
  43. package/src/routing.ts +39 -0
  44. package/src/topology.ts +13 -0
  45. package/src/types.ts +101 -0
  46. package/src/validate.ts +183 -0
  47. package/src/visualize.ts +167 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # @gomessaging/messaging
2
+
3
+ TypeScript implementation of the [messaging specification](https://codeberg.org/messaging/messaging). This package mirrors the Go messaging library, providing identical naming functions, validation, CloudEvents handling, routing, and visualization for Node.js/TypeScript transport implementations.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ npm install @gomessaging/messaging
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import {
15
+ // Naming
16
+ topicExchangeName,
17
+ serviceEventQueueName,
18
+ natsStreamName,
19
+ natsSubject,
20
+
21
+ // CloudEvents
22
+ validateCEHeaders,
23
+ metadataFromHeaders,
24
+ normalizeCEHeaders,
25
+ hasCEHeaders,
26
+ enrichLegacyMetadata,
27
+
28
+ // Validation
29
+ validate,
30
+ validateTopologies,
31
+
32
+ // Visualization
33
+ mermaid,
34
+
35
+ // Routing
36
+ matchRoutingKey,
37
+ routingKeyOverlaps,
38
+
39
+ // Types
40
+ type Topology,
41
+ type Endpoint,
42
+ type ConsumableEvent,
43
+ type Metadata,
44
+ type EventHandler,
45
+ } from "@gomessaging/messaging";
46
+ ```
47
+
48
+ ### Naming
49
+
50
+ Deterministic resource names for AMQP and NATS:
51
+
52
+ ```typescript
53
+ topicExchangeName("events");
54
+ // "events.topic.exchange"
55
+
56
+ serviceEventQueueName("events.topic.exchange", "notifications");
57
+ // "events.topic.exchange.queue.notifications"
58
+
59
+ natsStreamName("audit.topic.exchange");
60
+ // "audit"
61
+
62
+ natsSubject("events", "Order.Created");
63
+ // "events.Order.Created"
64
+ ```
65
+
66
+ ### Validation
67
+
68
+ Validate service topologies statically:
69
+
70
+ ```typescript
71
+ const errors = validate(topology);
72
+
73
+ // Cross-validate multiple services
74
+ const errors = validateTopologies([orderTopology, notificationTopology]);
75
+ ```
76
+
77
+ ### CloudEvents
78
+
79
+ Parse and validate CloudEvents headers:
80
+
81
+ ```typescript
82
+ const warnings = validateCEHeaders(headers);
83
+ const metadata = metadataFromHeaders(headers);
84
+
85
+ // Normalize AMQP prefixes (cloudEvents:type → ce-type)
86
+ const normalized = normalizeCEHeaders(headers);
87
+
88
+ // Enrich legacy messages without CE headers
89
+ const enriched = enrichLegacyMetadata(metadata, deliveryInfo, () => crypto.randomUUID());
90
+ ```
91
+
92
+ ### Visualization
93
+
94
+ Generate Mermaid diagrams:
95
+
96
+ ```typescript
97
+ const diagram = mermaid([orderTopology, notificationTopology]);
98
+ // Returns a Mermaid flowchart string
99
+ ```
100
+
101
+ ### Routing
102
+
103
+ Match routing keys with AMQP-style wildcards:
104
+
105
+ ```typescript
106
+ matchRoutingKey("Order.*", "Order.Created"); // true
107
+ matchRoutingKey("Order.*", "Order.Item.Added"); // false
108
+ routingKeyOverlaps("Order.*", "Order.Created"); // true
109
+ ```
110
+
111
+ ## API Reference
112
+
113
+ ### Naming Functions
114
+
115
+ | Function | Signature | Description |
116
+ |----------|-----------|-------------|
117
+ | `topicExchangeName` | `(name: string) => string` | Topic exchange name |
118
+ | `serviceEventQueueName` | `(exchange: string, service: string) => string` | Event consumer queue |
119
+ | `serviceRequestExchangeName` | `(service: string) => string` | Request exchange |
120
+ | `serviceResponseExchangeName` | `(service: string) => string` | Response exchange |
121
+ | `serviceRequestQueueName` | `(service: string) => string` | Request queue |
122
+ | `serviceResponseQueueName` | `(target: string, service: string) => string` | Response queue |
123
+ | `natsStreamName` | `(name: string) => string` | NATS stream name |
124
+ | `natsSubject` | `(stream: string, routingKey: string) => string` | NATS subject |
125
+ | `translateWildcard` | `(routingKey: string) => string` | AMQP `#` to NATS `>` |
126
+
127
+ ### Validation Functions
128
+
129
+ | Function | Signature | Description |
130
+ |----------|-----------|-------------|
131
+ | `validate` | `(topology: Topology) => string \| null` | Single-service validation |
132
+ | `validateTopologies` | `(topologies: Topology[]) => string \| null` | Cross-service validation |
133
+
134
+ ### CloudEvents Functions
135
+
136
+ | Function | Signature | Description |
137
+ |----------|-----------|-------------|
138
+ | `validateCEHeaders` | `(headers: Headers) => string[]` | Validate CE headers, returns warnings |
139
+ | `metadataFromHeaders` | `(headers: Headers) => Metadata` | Parse headers into Metadata |
140
+ | `normalizeCEHeaders` | `(headers: Headers) => Headers` | Normalize prefix to `ce-` |
141
+ | `hasCEHeaders` | `(headers: Headers) => boolean` | Check if any CE headers present |
142
+ | `enrichLegacyMetadata` | `(m: Metadata, d: DeliveryInfo, idGen: () => string) => Metadata` | Enrich missing fields |
143
+
144
+ ### Core Types
145
+
146
+ ```typescript
147
+ type Transport = "amqp" | "nats";
148
+ type EndpointDirection = "publish" | "consume";
149
+ type ExchangeKind = "topic" | "direct" | "headers";
150
+ type Pattern = "event-stream" | "custom-stream" | "service-request" | "service-response" | "queue-publish";
151
+
152
+ interface Endpoint {
153
+ direction: EndpointDirection;
154
+ pattern: Pattern;
155
+ exchangeName: string;
156
+ exchangeKind: ExchangeKind;
157
+ queueName?: string;
158
+ routingKey?: string;
159
+ messageType?: string;
160
+ ephemeral?: boolean;
161
+ }
162
+
163
+ interface Topology {
164
+ transport: Transport;
165
+ serviceName: string;
166
+ endpoints: Endpoint[];
167
+ }
168
+
169
+ interface ConsumableEvent<T> extends Metadata {
170
+ deliveryInfo: DeliveryInfo;
171
+ payload: T;
172
+ }
173
+ ```
174
+
175
+ ## Conformance
176
+
177
+ This package is tested against the shared JSON fixtures in [`testdata/`](../testdata/). The same fixtures are used by the Go messaging library, ensuring both implementations produce identical outputs.
178
+
179
+ ```sh
180
+ npm test
181
+ ```
182
+
183
+ ## License
184
+
185
+ MIT
@@ -0,0 +1,73 @@
1
+ import type { DeliveryInfo, Headers, Metadata } from "./types.js";
2
+ /** CloudEvents attribute header keys for binary content mode (canonical "ce-" prefix). */
3
+ export declare const CESpecVersion = "ce-specversion";
4
+ export declare const CEType = "ce-type";
5
+ export declare const CESource = "ce-source";
6
+ export declare const CEID = "ce-id";
7
+ export declare const CETime = "ce-time";
8
+ export declare const CESpecVersionValue = "1.0";
9
+ /** Optional CE attributes */
10
+ export declare const CEDataContentType = "ce-datacontenttype";
11
+ export declare const CESubject = "ce-subject";
12
+ export declare const CEDataSchema = "ce-dataschema";
13
+ /** Extension attribute for correlation */
14
+ export declare const CECorrelationID = "ce-correlationid";
15
+ /** Bare CE attribute names (without prefix). */
16
+ export declare const CEAttrSpecVersion = "specversion";
17
+ export declare const CEAttrType = "type";
18
+ export declare const CEAttrSource = "source";
19
+ export declare const CEAttrID = "id";
20
+ export declare const CEAttrTime = "time";
21
+ export declare const CEAttrDataContentType = "datacontenttype";
22
+ export declare const CEAttrSubject = "subject";
23
+ export declare const CEAttrCorrelationID = "correlationid";
24
+ /** CERequiredAttributes lists header keys required by CE 1.0. */
25
+ export declare const CERequiredAttributes: string[];
26
+ /**
27
+ * AMQPCEHeaderKey returns the AMQP application-properties key for a bare
28
+ * CloudEvents attribute name, using the "cloudEvents:" prefix per the
29
+ * CloudEvents AMQP Protocol Binding specification.
30
+ * Example: AMQPCEHeaderKey("specversion") -> "cloudEvents:specversion"
31
+ */
32
+ export declare function AMQPCEHeaderKey(attr: string): string;
33
+ /**
34
+ * NormalizeCEHeaders rewrites incoming transport headers so that all
35
+ * CloudEvents attributes use the canonical "ce-" prefix. This allows
36
+ * consumers to accept messages with any known prefix variant:
37
+ * - "cloudEvents:specversion" -> "ce-specversion"
38
+ * - "cloudEvents_specversion" -> "ce-specversion" (JMS compat)
39
+ * - "ce-specversion" -> unchanged
40
+ *
41
+ * Non-CE headers are preserved unchanged. A new object is returned.
42
+ */
43
+ export declare function normalizeCEHeaders(h: Headers): Headers;
44
+ /**
45
+ * HasCEHeaders reports whether h contains at least one CE required attribute,
46
+ * checking for "ce-", "cloudEvents:", and "cloudEvents_" prefixes.
47
+ * Use this to distinguish legacy (pre-CloudEvents) messages from malformed CE messages.
48
+ */
49
+ export declare function hasCEHeaders(h: Headers): boolean;
50
+ /**
51
+ * EnrichLegacyMetadata populates empty Metadata fields with synthetic
52
+ * CloudEvents attributes derived from transport delivery information.
53
+ *
54
+ * Fields set when empty: id (randomUUID), timestamp (now), type (from key),
55
+ * source (from source), dataContentType ("application/json"), specVersion ("1.0").
56
+ *
57
+ * Fields NOT set: correlationId, subject (cannot be inferred).
58
+ * Any non-empty fields in m are preserved (not overwritten).
59
+ * Returns a new Metadata object; the input is not mutated.
60
+ */
61
+ export declare function enrichLegacyMetadata(m: Metadata, info: DeliveryInfo): Metadata;
62
+ /**
63
+ * MetadataFromHeaders extracts CloudEvents metadata from message headers
64
+ * into a Metadata struct. Invalid (non-RFC3339) timestamps return empty string.
65
+ */
66
+ export declare function metadataFromHeaders(h: Headers): Metadata;
67
+ /**
68
+ * ValidateCEHeaders checks that all required CloudEvents 1.0 attributes
69
+ * are present and are strings. Returns a list of warnings for any
70
+ * missing or non-string attributes.
71
+ */
72
+ export declare function validateCEHeaders(h: Headers): string[];
73
+ //# sourceMappingURL=cloudevents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudevents.d.ts","sourceRoot":"","sources":["../src/cloudevents.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElE,0FAA0F;AAC1F,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAC9C,eAAO,MAAM,MAAM,YAAY,CAAC;AAChC,eAAO,MAAM,QAAQ,cAAc,CAAC;AACpC,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,MAAM,YAAY,CAAC;AAChC,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,6BAA6B;AAC7B,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AACtD,eAAO,MAAM,SAAS,eAAe,CAAC;AACtC,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,0CAA0C;AAC1C,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAElD,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AACvD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,UAMhC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAYtD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAWhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,QAAQ,EACX,IAAI,EAAE,YAAY,GACjB,QAAQ,CAUV;AAcD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,CAYxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAYtD"}
@@ -0,0 +1,148 @@
1
+ // MIT License
2
+ // Copyright (c) 2026 sparetimecoders
3
+ /** CloudEvents attribute header keys for binary content mode (canonical "ce-" prefix). */
4
+ export const CESpecVersion = "ce-specversion";
5
+ export const CEType = "ce-type";
6
+ export const CESource = "ce-source";
7
+ export const CEID = "ce-id";
8
+ export const CETime = "ce-time";
9
+ export const CESpecVersionValue = "1.0";
10
+ /** Optional CE attributes */
11
+ export const CEDataContentType = "ce-datacontenttype";
12
+ export const CESubject = "ce-subject";
13
+ export const CEDataSchema = "ce-dataschema";
14
+ /** Extension attribute for correlation */
15
+ export const CECorrelationID = "ce-correlationid";
16
+ /** Bare CE attribute names (without prefix). */
17
+ export const CEAttrSpecVersion = "specversion";
18
+ export const CEAttrType = "type";
19
+ export const CEAttrSource = "source";
20
+ export const CEAttrID = "id";
21
+ export const CEAttrTime = "time";
22
+ export const CEAttrDataContentType = "datacontenttype";
23
+ export const CEAttrSubject = "subject";
24
+ export const CEAttrCorrelationID = "correlationid";
25
+ /** CERequiredAttributes lists header keys required by CE 1.0. */
26
+ export const CERequiredAttributes = [
27
+ CESpecVersion,
28
+ CEType,
29
+ CESource,
30
+ CEID,
31
+ CETime,
32
+ ];
33
+ /**
34
+ * AMQPCEHeaderKey returns the AMQP application-properties key for a bare
35
+ * CloudEvents attribute name, using the "cloudEvents:" prefix per the
36
+ * CloudEvents AMQP Protocol Binding specification.
37
+ * Example: AMQPCEHeaderKey("specversion") -> "cloudEvents:specversion"
38
+ */
39
+ export function AMQPCEHeaderKey(attr) {
40
+ return "cloudEvents:" + attr;
41
+ }
42
+ /**
43
+ * NormalizeCEHeaders rewrites incoming transport headers so that all
44
+ * CloudEvents attributes use the canonical "ce-" prefix. This allows
45
+ * consumers to accept messages with any known prefix variant:
46
+ * - "cloudEvents:specversion" -> "ce-specversion"
47
+ * - "cloudEvents_specversion" -> "ce-specversion" (JMS compat)
48
+ * - "ce-specversion" -> unchanged
49
+ *
50
+ * Non-CE headers are preserved unchanged. A new object is returned.
51
+ */
52
+ export function normalizeCEHeaders(h) {
53
+ const out = {};
54
+ for (const [k, v] of Object.entries(h)) {
55
+ if (k.startsWith("cloudEvents:")) {
56
+ out["ce-" + k.slice("cloudEvents:".length)] = v;
57
+ }
58
+ else if (k.startsWith("cloudEvents_")) {
59
+ out["ce-" + k.slice("cloudEvents_".length)] = v;
60
+ }
61
+ else {
62
+ out[k] = v;
63
+ }
64
+ }
65
+ return out;
66
+ }
67
+ /**
68
+ * HasCEHeaders reports whether h contains at least one CE required attribute,
69
+ * checking for "ce-", "cloudEvents:", and "cloudEvents_" prefixes.
70
+ * Use this to distinguish legacy (pre-CloudEvents) messages from malformed CE messages.
71
+ */
72
+ export function hasCEHeaders(h) {
73
+ for (const key of Object.keys(h)) {
74
+ if (key.startsWith("ce-") ||
75
+ key.startsWith("cloudEvents:") ||
76
+ key.startsWith("cloudEvents_")) {
77
+ return true;
78
+ }
79
+ }
80
+ return false;
81
+ }
82
+ /**
83
+ * EnrichLegacyMetadata populates empty Metadata fields with synthetic
84
+ * CloudEvents attributes derived from transport delivery information.
85
+ *
86
+ * Fields set when empty: id (randomUUID), timestamp (now), type (from key),
87
+ * source (from source), dataContentType ("application/json"), specVersion ("1.0").
88
+ *
89
+ * Fields NOT set: correlationId, subject (cannot be inferred).
90
+ * Any non-empty fields in m are preserved (not overwritten).
91
+ * Returns a new Metadata object; the input is not mutated.
92
+ */
93
+ export function enrichLegacyMetadata(m, info) {
94
+ return {
95
+ ...m,
96
+ id: m.id || crypto.randomUUID(),
97
+ timestamp: m.timestamp || new Date().toISOString(),
98
+ type: m.type || info.key,
99
+ source: m.source || info.source,
100
+ dataContentType: m.dataContentType || "application/json",
101
+ specVersion: m.specVersion || CESpecVersionValue,
102
+ };
103
+ }
104
+ /** RFC 3339 regex for timestamp validation. */
105
+ const RFC3339_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
106
+ function headerString(h, key) {
107
+ const v = h[key];
108
+ if (typeof v === "string") {
109
+ return v;
110
+ }
111
+ return "";
112
+ }
113
+ /**
114
+ * MetadataFromHeaders extracts CloudEvents metadata from message headers
115
+ * into a Metadata struct. Invalid (non-RFC3339) timestamps return empty string.
116
+ */
117
+ export function metadataFromHeaders(h) {
118
+ const timeStr = headerString(h, CETime);
119
+ return {
120
+ id: headerString(h, CEID),
121
+ source: headerString(h, CESource),
122
+ type: headerString(h, CEType),
123
+ subject: headerString(h, CESubject),
124
+ dataContentType: headerString(h, CEDataContentType),
125
+ specVersion: headerString(h, CESpecVersion),
126
+ correlationId: headerString(h, CECorrelationID),
127
+ timestamp: RFC3339_RE.test(timeStr) ? timeStr : "",
128
+ };
129
+ }
130
+ /**
131
+ * ValidateCEHeaders checks that all required CloudEvents 1.0 attributes
132
+ * are present and are strings. Returns a list of warnings for any
133
+ * missing or non-string attributes.
134
+ */
135
+ export function validateCEHeaders(h) {
136
+ const warnings = [];
137
+ for (const key of CERequiredAttributes) {
138
+ if (!(key in h)) {
139
+ warnings.push(`missing required attribute "${key}"`);
140
+ continue;
141
+ }
142
+ if (typeof h[key] !== "string") {
143
+ warnings.push(`attribute "${key}" is not a string`);
144
+ }
145
+ }
146
+ return warnings;
147
+ }
148
+ //# sourceMappingURL=cloudevents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudevents.js","sourceRoot":"","sources":["../src/cloudevents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type { Transport, EndpointDirection, ExchangeKind, Pattern, Headers, Metadata, DeliveryInfo, ConsumableEvent, Endpoint, Topology, EventHandler, RequestResponseEventHandler, NotificationSource, Notification, ErrorNotification, NotificationHandler, ErrorNotificationHandler, } from "./types.js";
2
+ export { ErrParseJSON } from "./types.js";
3
+ export { DefaultEventExchangeName, KindTopic, KindDirect, KindHeaders, topicExchangeName, serviceEventQueueName, serviceRequestExchangeName, serviceResponseExchangeName, serviceRequestQueueName, serviceResponseQueueName, natsStreamName, natsSubject, translateWildcard, } from "./naming.js";
4
+ export { CESpecVersion, CEType, CESource, CEID, CETime, CESpecVersionValue, CEDataContentType, CESubject, CEDataSchema, CECorrelationID, CEAttrSpecVersion, CEAttrType, CEAttrSource, CEAttrID, CEAttrTime, CEAttrDataContentType, CEAttrSubject, CEAttrCorrelationID, CERequiredAttributes, AMQPCEHeaderKey, normalizeCEHeaders, hasCEHeaders, enrichLegacyMetadata, metadataFromHeaders, validateCEHeaders, } from "./cloudevents.js";
5
+ export { matchRoutingKey, routingKeyOverlaps } from "./routing.js";
6
+ export { validate, validateTopologies } from "./validate.js";
7
+ export { mermaid } from "./visualize.js";
8
+ export {} from "./topology.js";
9
+ export type { MetricsRecorder, RoutingKeyMapper, MetricsOptions } from "./metrics.js";
10
+ export { mapRoutingKey } from "./metrics.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,2BAA2B,EAC3B,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EACL,wBAAwB,EACxB,SAAS,EACT,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,aAAa,EACb,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG7D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,OAAO,EAAE,MAAM,eAAe,CAAC;AAG/B,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ // MIT License
2
+ // Copyright (c) 2026 sparetimecoders
3
+ export { ErrParseJSON } from "./types.js";
4
+ // Naming
5
+ export { DefaultEventExchangeName, KindTopic, KindDirect, KindHeaders, topicExchangeName, serviceEventQueueName, serviceRequestExchangeName, serviceResponseExchangeName, serviceRequestQueueName, serviceResponseQueueName, natsStreamName, natsSubject, translateWildcard, } from "./naming.js";
6
+ // CloudEvents
7
+ export { CESpecVersion, CEType, CESource, CEID, CETime, CESpecVersionValue, CEDataContentType, CESubject, CEDataSchema, CECorrelationID, CEAttrSpecVersion, CEAttrType, CEAttrSource, CEAttrID, CEAttrTime, CEAttrDataContentType, CEAttrSubject, CEAttrCorrelationID, CERequiredAttributes, AMQPCEHeaderKey, normalizeCEHeaders, hasCEHeaders, enrichLegacyMetadata, metadataFromHeaders, validateCEHeaders, } from "./cloudevents.js";
8
+ // Routing
9
+ export { matchRoutingKey, routingKeyOverlaps } from "./routing.js";
10
+ // Validation
11
+ export { validate, validateTopologies } from "./validate.js";
12
+ // Visualization
13
+ export { mermaid } from "./visualize.js";
14
+ export { mapRoutingKey } from "./metrics.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,qCAAqC;AAsBrC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,SAAS;AACT,OAAO,EACL,wBAAwB,EACxB,SAAS,EACT,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,cAAc;AACd,OAAO,EACL,aAAa,EACb,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEnE,aAAa;AACb,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE7D,gBAAgB;AAChB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAOzC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pluggable metrics interface for messaging adapters.
3
+ *
4
+ * Users wire this to any metrics backend (prom-client, OpenTelemetry,
5
+ * StatsD, etc.) by implementing MetricsRecorder and passing it to
6
+ * ConnectionOptions.
7
+ */
8
+ /** Records messaging metrics. Implement this interface to wire any metrics backend. */
9
+ export interface MetricsRecorder {
10
+ /** An event was received from the broker. */
11
+ eventReceived(queue: string, routingKey: string): void;
12
+ /** An event was received but no handler matched its routing key. */
13
+ eventWithoutHandler(queue: string, routingKey: string): void;
14
+ /** An event could not be parsed (invalid JSON). */
15
+ eventNotParsable(queue: string, routingKey: string): void;
16
+ /** An event was acknowledged (successfully processed). */
17
+ eventAck(queue: string, routingKey: string, durationMs: number): void;
18
+ /** An event was negatively acknowledged (handler failed). */
19
+ eventNack(queue: string, routingKey: string, durationMs: number): void;
20
+ /** A message was published successfully. */
21
+ publishSucceed(exchange: string, routingKey: string, durationMs: number): void;
22
+ /** A message failed to publish. */
23
+ publishFailed(exchange: string, routingKey: string, durationMs: number): void;
24
+ }
25
+ /**
26
+ * Maps a routing key before it is passed to metrics.
27
+ * Use this to normalize or redact dynamic segments (e.g. UUIDs)
28
+ * to prevent unbounded label cardinality.
29
+ */
30
+ export type RoutingKeyMapper = (key: string) => string;
31
+ /** Options for configuring metrics behavior. */
32
+ export interface MetricsOptions {
33
+ routingKeyMapper?: RoutingKeyMapper;
34
+ }
35
+ /**
36
+ * Apply a routing key mapper, defaulting to identity.
37
+ * Empty mapped values are replaced with "unknown".
38
+ */
39
+ export declare function mapRoutingKey(key: string, mapper?: RoutingKeyMapper): string;
40
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvD,oEAAoE;IACpE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7D,mDAAmD;IACnD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1D,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtE,6DAA6D;IAC7D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvE,4CAA4C;IAC5C,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/E,mCAAmC;IACnC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/E;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEvD,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,gBAAgB,GACxB,MAAM,CAGR"}
@@ -0,0 +1,11 @@
1
+ // MIT License
2
+ // Copyright (c) 2026 sparetimecoders
3
+ /**
4
+ * Apply a routing key mapper, defaulting to identity.
5
+ * Empty mapped values are replaced with "unknown".
6
+ */
7
+ export function mapRoutingKey(key, mapper) {
8
+ const mapped = mapper ? mapper(key) : key;
9
+ return mapped === "" ? "unknown" : mapped;
10
+ }
11
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,qCAAqC;AA8CrC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAW,EACX,MAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1C,OAAO,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,54 @@
1
+ /** DefaultEventExchangeName is the default exchange name used for event streaming. */
2
+ export declare const DefaultEventExchangeName = "events";
3
+ /** Exchange kind constants matching AMQP exchange types. */
4
+ export declare const KindTopic = "topic";
5
+ export declare const KindDirect = "direct";
6
+ export declare const KindHeaders = "headers";
7
+ /**
8
+ * TopicExchangeName returns the topic exchange name for the given name.
9
+ * Format: `<name>.topic.exchange`
10
+ */
11
+ export declare function topicExchangeName(name: string): string;
12
+ /**
13
+ * ServiceEventQueueName returns the durable event queue name for a service.
14
+ * Format: `<exchangeName>.queue.<service>`
15
+ */
16
+ export declare function serviceEventQueueName(exchangeName: string, service: string): string;
17
+ /**
18
+ * ServiceRequestExchangeName returns the direct exchange name for requests to a service.
19
+ * Format: `<service>.direct.exchange.request`
20
+ */
21
+ export declare function serviceRequestExchangeName(service: string): string;
22
+ /**
23
+ * ServiceResponseExchangeName returns the headers exchange name for responses from a service.
24
+ * Format: `<service>.headers.exchange.response`
25
+ */
26
+ export declare function serviceResponseExchangeName(service: string): string;
27
+ /**
28
+ * ServiceRequestQueueName returns the queue name for requests to a service.
29
+ * Format: `<service>.direct.exchange.request.queue`
30
+ */
31
+ export declare function serviceRequestQueueName(service: string): string;
32
+ /**
33
+ * ServiceResponseQueueName returns the queue name for responses from targetService to serviceName.
34
+ * Format: `<targetService>.headers.exchange.response.queue.<serviceName>`
35
+ */
36
+ export declare function serviceResponseQueueName(targetService: string, serviceName: string): string;
37
+ /**
38
+ * NATSStreamName extracts the base stream name from a logical name.
39
+ * If the name follows the AMQP convention `<name>.topic.exchange`, the prefix is extracted.
40
+ * Otherwise the name is returned as-is.
41
+ */
42
+ export declare function natsStreamName(name: string): string;
43
+ /**
44
+ * NATSSubject builds a NATS subject from a stream name and routing key.
45
+ * Format: `<stream>.<routingKey>`
46
+ */
47
+ export declare function natsSubject(stream: string, routingKey: string): string;
48
+ /**
49
+ * TranslateWildcard converts AMQP-style wildcards to NATS-style wildcards.
50
+ * AMQP "#" (multi-level) -> NATS ">" (multi-level)
51
+ * AMQP "*" (single-level) stays "*" in NATS.
52
+ */
53
+ export declare function translateWildcard(routingKey: string): string;
54
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAGA,sFAAsF;AACtF,eAAO,MAAM,wBAAwB,WAAW,CAAC;AAEjD,4DAA4D;AAC5D,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D"}
package/dist/naming.js ADDED
@@ -0,0 +1,78 @@
1
+ // MIT License
2
+ // Copyright (c) 2026 sparetimecoders
3
+ /** DefaultEventExchangeName is the default exchange name used for event streaming. */
4
+ export const DefaultEventExchangeName = "events";
5
+ /** Exchange kind constants matching AMQP exchange types. */
6
+ export const KindTopic = "topic";
7
+ export const KindDirect = "direct";
8
+ export const KindHeaders = "headers";
9
+ /**
10
+ * TopicExchangeName returns the topic exchange name for the given name.
11
+ * Format: `<name>.topic.exchange`
12
+ */
13
+ export function topicExchangeName(name) {
14
+ return `${name}.${KindTopic}.exchange`;
15
+ }
16
+ /**
17
+ * ServiceEventQueueName returns the durable event queue name for a service.
18
+ * Format: `<exchangeName>.queue.<service>`
19
+ */
20
+ export function serviceEventQueueName(exchangeName, service) {
21
+ return `${exchangeName}.queue.${service}`;
22
+ }
23
+ /**
24
+ * ServiceRequestExchangeName returns the direct exchange name for requests to a service.
25
+ * Format: `<service>.direct.exchange.request`
26
+ */
27
+ export function serviceRequestExchangeName(service) {
28
+ return `${service}.${KindDirect}.exchange.request`;
29
+ }
30
+ /**
31
+ * ServiceResponseExchangeName returns the headers exchange name for responses from a service.
32
+ * Format: `<service>.headers.exchange.response`
33
+ */
34
+ export function serviceResponseExchangeName(service) {
35
+ return `${service}.${KindHeaders}.exchange.response`;
36
+ }
37
+ /**
38
+ * ServiceRequestQueueName returns the queue name for requests to a service.
39
+ * Format: `<service>.direct.exchange.request.queue`
40
+ */
41
+ export function serviceRequestQueueName(service) {
42
+ return `${serviceRequestExchangeName(service)}.queue`;
43
+ }
44
+ /**
45
+ * ServiceResponseQueueName returns the queue name for responses from targetService to serviceName.
46
+ * Format: `<targetService>.headers.exchange.response.queue.<serviceName>`
47
+ */
48
+ export function serviceResponseQueueName(targetService, serviceName) {
49
+ return `${serviceResponseExchangeName(targetService)}.queue.${serviceName}`;
50
+ }
51
+ /**
52
+ * NATSStreamName extracts the base stream name from a logical name.
53
+ * If the name follows the AMQP convention `<name>.topic.exchange`, the prefix is extracted.
54
+ * Otherwise the name is returned as-is.
55
+ */
56
+ export function natsStreamName(name) {
57
+ const suffix = ".topic.exchange";
58
+ if (name.endsWith(suffix)) {
59
+ return name.slice(0, -suffix.length);
60
+ }
61
+ return name;
62
+ }
63
+ /**
64
+ * NATSSubject builds a NATS subject from a stream name and routing key.
65
+ * Format: `<stream>.<routingKey>`
66
+ */
67
+ export function natsSubject(stream, routingKey) {
68
+ return `${stream}.${routingKey}`;
69
+ }
70
+ /**
71
+ * TranslateWildcard converts AMQP-style wildcards to NATS-style wildcards.
72
+ * AMQP "#" (multi-level) -> NATS ">" (multi-level)
73
+ * AMQP "*" (single-level) stays "*" in NATS.
74
+ */
75
+ export function translateWildcard(routingKey) {
76
+ return routingKey.replaceAll("#", ">");
77
+ }
78
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,qCAAqC;AAErC,sFAAsF;AACtF,MAAM,CAAC,MAAM,wBAAwB,GAAG,QAAQ,CAAC;AAEjD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AACnC,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,GAAG,IAAI,IAAI,SAAS,WAAW,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,YAAoB,EACpB,OAAe;IAEf,OAAO,GAAG,YAAY,UAAU,OAAO,EAAE,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAe;IACxD,OAAO,GAAG,OAAO,IAAI,UAAU,mBAAmB,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAAe;IACzD,OAAO,GAAG,OAAO,IAAI,WAAW,oBAAoB,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,QAAQ,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,aAAqB,EACrB,WAAmB;IAEnB,OAAO,GAAG,2BAA2B,CAAC,aAAa,CAAC,UAAU,WAAW,EAAE,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,MAAM,GAAG,iBAAiB,CAAC;IACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,UAAkB;IAC5D,OAAO,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC"}