@drarzter/kafka-client 0.9.3 → 0.10.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 (170) hide show
  1. package/README.md +625 -8
  2. package/dist/chunk-CMO7SMVK.mjs +4814 -0
  3. package/dist/chunk-CMO7SMVK.mjs.map +1 -0
  4. package/dist/cli/dlq.d.ts +119 -0
  5. package/dist/cli/dlq.d.ts.map +1 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/{chunk-TPIP5VV7.mjs → cli/index.js} +965 -265
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/index.mjs +355 -0
  11. package/dist/cli/index.mjs.map +1 -0
  12. package/dist/client/config/from-env.d.ts +188 -0
  13. package/dist/client/config/from-env.d.ts.map +1 -0
  14. package/dist/client/config/index.d.ts +2 -0
  15. package/dist/client/config/index.d.ts.map +1 -0
  16. package/dist/client/errors.d.ts +67 -0
  17. package/dist/client/errors.d.ts.map +1 -0
  18. package/dist/client/kafka.client/admin/ops.d.ts +114 -0
  19. package/dist/client/kafka.client/admin/ops.d.ts.map +1 -0
  20. package/dist/client/kafka.client/consumer/features/delayed.d.ts +24 -0
  21. package/dist/client/kafka.client/consumer/features/delayed.d.ts.map +1 -0
  22. package/dist/client/kafka.client/consumer/features/dlq-replay.d.ts +52 -0
  23. package/dist/client/kafka.client/consumer/features/dlq-replay.d.ts.map +1 -0
  24. package/dist/client/kafka.client/consumer/features/routed.d.ts +4 -0
  25. package/dist/client/kafka.client/consumer/features/routed.d.ts.map +1 -0
  26. package/dist/client/kafka.client/consumer/features/snapshot.d.ts +10 -0
  27. package/dist/client/kafka.client/consumer/features/snapshot.d.ts.map +1 -0
  28. package/dist/client/kafka.client/consumer/features/window.d.ts +5 -0
  29. package/dist/client/kafka.client/consumer/features/window.d.ts.map +1 -0
  30. package/dist/client/kafka.client/consumer/handler.d.ts +149 -0
  31. package/dist/client/kafka.client/consumer/handler.d.ts.map +1 -0
  32. package/dist/client/kafka.client/consumer/ops.d.ts +51 -0
  33. package/dist/client/kafka.client/consumer/ops.d.ts.map +1 -0
  34. package/dist/client/kafka.client/consumer/pipeline.d.ts +167 -0
  35. package/dist/client/kafka.client/consumer/pipeline.d.ts.map +1 -0
  36. package/dist/client/kafka.client/consumer/queue.d.ts +37 -0
  37. package/dist/client/kafka.client/consumer/queue.d.ts.map +1 -0
  38. package/dist/client/kafka.client/consumer/retry-topic.d.ts +65 -0
  39. package/dist/client/kafka.client/consumer/retry-topic.d.ts.map +1 -0
  40. package/dist/client/kafka.client/consumer/setup.d.ts +63 -0
  41. package/dist/client/kafka.client/consumer/setup.d.ts.map +1 -0
  42. package/dist/client/kafka.client/consumer/start.d.ts +7 -0
  43. package/dist/client/kafka.client/consumer/start.d.ts.map +1 -0
  44. package/dist/client/kafka.client/consumer/stop.d.ts +19 -0
  45. package/dist/client/kafka.client/consumer/stop.d.ts.map +1 -0
  46. package/dist/client/kafka.client/consumer/subscribe-retry.d.ts +4 -0
  47. package/dist/client/kafka.client/consumer/subscribe-retry.d.ts.map +1 -0
  48. package/dist/client/kafka.client/context.d.ts +72 -0
  49. package/dist/client/kafka.client/context.d.ts.map +1 -0
  50. package/dist/client/kafka.client/index.d.ts +155 -0
  51. package/dist/client/kafka.client/index.d.ts.map +1 -0
  52. package/dist/client/kafka.client/infra/circuit-breaker.manager.d.ts +61 -0
  53. package/dist/client/kafka.client/infra/circuit-breaker.manager.d.ts.map +1 -0
  54. package/dist/client/kafka.client/infra/dedup.store.d.ts +28 -0
  55. package/dist/client/kafka.client/infra/dedup.store.d.ts.map +1 -0
  56. package/dist/client/kafka.client/infra/inflight.tracker.d.ts +22 -0
  57. package/dist/client/kafka.client/infra/inflight.tracker.d.ts.map +1 -0
  58. package/dist/client/kafka.client/infra/metrics.manager.d.ts +67 -0
  59. package/dist/client/kafka.client/infra/metrics.manager.d.ts.map +1 -0
  60. package/dist/client/kafka.client/producer/lifecycle.d.ts +41 -0
  61. package/dist/client/kafka.client/producer/lifecycle.d.ts.map +1 -0
  62. package/dist/client/kafka.client/producer/ops.d.ts +70 -0
  63. package/dist/client/kafka.client/producer/ops.d.ts.map +1 -0
  64. package/dist/client/kafka.client/producer/send.d.ts +21 -0
  65. package/dist/client/kafka.client/producer/send.d.ts.map +1 -0
  66. package/dist/client/kafka.client/validate-options.d.ts +11 -0
  67. package/dist/client/kafka.client/validate-options.d.ts.map +1 -0
  68. package/dist/client/message/envelope.d.ts +105 -0
  69. package/dist/client/message/envelope.d.ts.map +1 -0
  70. package/dist/client/message/schema-registry.d.ts +105 -0
  71. package/dist/client/message/schema-registry.d.ts.map +1 -0
  72. package/dist/client/message/topic.d.ts +138 -0
  73. package/dist/client/message/topic.d.ts.map +1 -0
  74. package/dist/client/message/versioned-schema.d.ts +53 -0
  75. package/dist/client/message/versioned-schema.d.ts.map +1 -0
  76. package/dist/client/outbox/index.d.ts +4 -0
  77. package/dist/client/outbox/index.d.ts.map +1 -0
  78. package/dist/client/outbox/outbox.relay.d.ts +90 -0
  79. package/dist/client/outbox/outbox.relay.d.ts.map +1 -0
  80. package/dist/client/outbox/outbox.store.d.ts +42 -0
  81. package/dist/client/outbox/outbox.store.d.ts.map +1 -0
  82. package/dist/client/outbox/outbox.types.d.ts +144 -0
  83. package/dist/client/outbox/outbox.types.d.ts.map +1 -0
  84. package/dist/client/security/acl.d.ts +108 -0
  85. package/dist/client/security/acl.d.ts.map +1 -0
  86. package/dist/client/security/index.d.ts +5 -0
  87. package/dist/client/security/index.d.ts.map +1 -0
  88. package/dist/client/security/providers.d.ts +88 -0
  89. package/dist/client/security/providers.d.ts.map +1 -0
  90. package/dist/client/security/resolve-security.d.ts +19 -0
  91. package/dist/client/security/resolve-security.d.ts.map +1 -0
  92. package/dist/client/security/security.types.d.ts +76 -0
  93. package/dist/client/security/security.types.d.ts.map +1 -0
  94. package/dist/client/transport/confluent.transport.d.ts +32 -0
  95. package/dist/client/transport/confluent.transport.d.ts.map +1 -0
  96. package/dist/client/transport/transport.interface.d.ts +216 -0
  97. package/dist/client/transport/transport.interface.d.ts.map +1 -0
  98. package/dist/client/types/admin.interface.d.ts +174 -0
  99. package/dist/client/types/admin.interface.d.ts.map +1 -0
  100. package/dist/client/types/admin.types.d.ts +140 -0
  101. package/dist/client/types/admin.types.d.ts.map +1 -0
  102. package/dist/client/types/client.d.ts +21 -0
  103. package/dist/client/types/client.d.ts.map +1 -0
  104. package/dist/client/types/common.d.ts +84 -0
  105. package/dist/client/types/common.d.ts.map +1 -0
  106. package/dist/client/types/config.types.d.ts +150 -0
  107. package/dist/client/types/config.types.d.ts.map +1 -0
  108. package/dist/client/types/consumer.interface.d.ts +115 -0
  109. package/dist/client/types/consumer.interface.d.ts.map +1 -0
  110. package/dist/{consumer.types-fFCag3VJ.d.mts → client/types/consumer.types.d.ts} +62 -383
  111. package/dist/client/types/consumer.types.d.ts.map +1 -0
  112. package/dist/client/types/dedup.types.d.ts +50 -0
  113. package/dist/client/types/dedup.types.d.ts.map +1 -0
  114. package/dist/client/types/lifecycle.interface.d.ts +72 -0
  115. package/dist/client/types/lifecycle.interface.d.ts.map +1 -0
  116. package/dist/client/types/producer.interface.d.ts +52 -0
  117. package/dist/client/types/producer.interface.d.ts.map +1 -0
  118. package/dist/client/types/producer.types.d.ts +90 -0
  119. package/dist/client/types/producer.types.d.ts.map +1 -0
  120. package/dist/client/types.d.ts +8 -0
  121. package/dist/client/types.d.ts.map +1 -0
  122. package/dist/core.d.ts +10 -314
  123. package/dist/core.d.ts.map +1 -0
  124. package/dist/core.js +1326 -74
  125. package/dist/core.js.map +1 -1
  126. package/dist/core.mjs +39 -3
  127. package/dist/index.d.ts +7 -128
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +1343 -74
  130. package/dist/index.js.map +1 -1
  131. package/dist/index.mjs +56 -3
  132. package/dist/index.mjs.map +1 -1
  133. package/dist/nest/kafka.constants.d.ts +5 -0
  134. package/dist/nest/kafka.constants.d.ts.map +1 -0
  135. package/dist/nest/kafka.decorator.d.ts +49 -0
  136. package/dist/nest/kafka.decorator.d.ts.map +1 -0
  137. package/dist/nest/kafka.explorer.d.ts +17 -0
  138. package/dist/nest/kafka.explorer.d.ts.map +1 -0
  139. package/dist/nest/kafka.health.d.ts +7 -0
  140. package/dist/nest/kafka.health.d.ts.map +1 -0
  141. package/dist/nest/kafka.module.d.ts +61 -0
  142. package/dist/nest/kafka.module.d.ts.map +1 -0
  143. package/dist/otel.d.ts +83 -5
  144. package/dist/otel.d.ts.map +1 -0
  145. package/dist/otel.js +100 -6
  146. package/dist/otel.js.map +1 -1
  147. package/dist/otel.mjs +98 -5
  148. package/dist/otel.mjs.map +1 -1
  149. package/dist/testing/client.mock.d.ts +47 -0
  150. package/dist/testing/client.mock.d.ts.map +1 -0
  151. package/dist/testing/index.d.ts +4 -0
  152. package/dist/testing/index.d.ts.map +1 -0
  153. package/dist/testing/test.container.d.ts +63 -0
  154. package/dist/testing/test.container.d.ts.map +1 -0
  155. package/dist/{testing.d.mts → testing/transport.fake.d.ts} +7 -111
  156. package/dist/testing/transport.fake.d.ts.map +1 -0
  157. package/dist/testing.d.ts +2 -318
  158. package/dist/testing.d.ts.map +1 -0
  159. package/dist/testing.js +28 -2
  160. package/dist/testing.js.map +1 -1
  161. package/dist/testing.mjs +28 -2
  162. package/dist/testing.mjs.map +1 -1
  163. package/package.json +22 -9
  164. package/dist/chunk-TPIP5VV7.mjs.map +0 -1
  165. package/dist/client-CBBUDDtu.d.ts +0 -751
  166. package/dist/client-D-SxYV2b.d.mts +0 -751
  167. package/dist/consumer.types-fFCag3VJ.d.ts +0 -958
  168. package/dist/core.d.mts +0 -314
  169. package/dist/index.d.mts +0 -128
  170. package/dist/otel.d.mts +0 -27
@@ -0,0 +1,144 @@
1
+ import type { MessageHeaders, TopicMapConstraint } from "../types";
2
+ import type { TransactionContext } from "../types/consumer.types";
3
+ /**
4
+ * A single row from the application's transactional-outbox table.
5
+ *
6
+ * Application code inserts one of these into the outbox table inside the **same
7
+ * database transaction** as its business writes. The relay ({@link startOutboxRelay})
8
+ * later reads unpublished rows and publishes them to Kafka.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // Inside a DB transaction, alongside your business INSERT/UPDATE:
13
+ * await tx.query(
14
+ * `INSERT INTO outbox (id, topic, payload, key, correlation_id, event_id)
15
+ * VALUES ($1, $2, $3, $4, $5, $6)`,
16
+ * [randomUUID(), 'orders.created', JSON.stringify(order), order.id, corrId, eventId],
17
+ * );
18
+ * ```
19
+ */
20
+ export interface OutboxMessage {
21
+ /**
22
+ * Unique row identifier. Used purely for idempotent marking — the relay passes
23
+ * these ids to {@link OutboxStore.markPublished} after Kafka acks the batch.
24
+ * This is **not** the Kafka `eventId` (use {@link OutboxMessage.eventId} for that).
25
+ */
26
+ id: string;
27
+ /** Destination Kafka topic. */
28
+ topic: string;
29
+ /** JSON-serialisable message body. Published as the Kafka message value. */
30
+ payload: unknown;
31
+ /** Optional Kafka partition key (guarantees per-key ordering). */
32
+ key?: string;
33
+ /** Optional custom Kafka headers merged with the auto-generated envelope headers. */
34
+ headers?: MessageHeaders;
35
+ /** Optional correlation id propagated to the Kafka `x-correlation-id` header. */
36
+ correlationId?: string;
37
+ /**
38
+ * Optional stable Kafka `x-event-id`. Persist this on the outbox row so that a
39
+ * re-published duplicate (see {@link startOutboxRelay} at-least-once semantics)
40
+ * carries the **same** event id, letting consumers deduplicate.
41
+ */
42
+ eventId?: string;
43
+ }
44
+ /**
45
+ * DB-agnostic contract the application implements to back the outbox relay.
46
+ *
47
+ * The library never touches your database directly — you own the schema and the
48
+ * queries. The relay only needs to (1) read unpublished rows oldest-first and
49
+ * (2) durably mark rows published once Kafka has acked them.
50
+ *
51
+ * A ready-made in-memory implementation ({@link InMemoryOutboxStore}) is provided
52
+ * for tests and as executable documentation.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * // Pseudo-Postgres store:
57
+ * const store: OutboxStore = {
58
+ * async fetchUnpublished(limit) {
59
+ * const { rows } = await pool.query(
60
+ * `SELECT id, topic, payload, key, correlation_id AS "correlationId",
61
+ * event_id AS "eventId", headers
62
+ * FROM outbox
63
+ * WHERE published_at IS NULL
64
+ * ORDER BY created_at ASC
65
+ * LIMIT $1`,
66
+ * [limit],
67
+ * );
68
+ * return rows;
69
+ * },
70
+ * async markPublished(ids) {
71
+ * await pool.query(
72
+ * `UPDATE outbox SET published_at = now() WHERE id = ANY($1)`,
73
+ * [ids],
74
+ * );
75
+ * },
76
+ * };
77
+ * ```
78
+ */
79
+ export interface OutboxStore {
80
+ /**
81
+ * Fetch up to `limit` unpublished messages, **oldest first**.
82
+ *
83
+ * Must be safe to call concurrently with inserts from application code. The
84
+ * relay calls this once per poll tick; returning an empty array signals there
85
+ * is nothing to publish and the relay simply waits for the next tick.
86
+ */
87
+ fetchUnpublished(limit: number): Promise<OutboxMessage[]>;
88
+ /**
89
+ * Durably mark these ids as published. Called **only after** Kafka has acked
90
+ * the entire batch (i.e. the publishing transaction committed).
91
+ *
92
+ * This write should be durable and idempotent — a crash between the Kafka
93
+ * commit and this call causes the batch to be re-published on the next poll
94
+ * (at-least-once, see {@link startOutboxRelay}).
95
+ */
96
+ markPublished(ids: string[]): Promise<void>;
97
+ }
98
+ /**
99
+ * Tuning and observability options for {@link startOutboxRelay}.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * startOutboxRelay(kafka, store, {
104
+ * pollIntervalMs: 500,
105
+ * batchSize: 200,
106
+ * onPublished: (n) => metrics.increment('outbox.published', n),
107
+ * onError: (err, batch) =>
108
+ * logger.error(`outbox batch of ${batch.length} failed`, err),
109
+ * });
110
+ * ```
111
+ */
112
+ export interface OutboxRelayOptions {
113
+ /** Interval between poll ticks in ms. Default: `1000`. */
114
+ pollIntervalMs?: number;
115
+ /** Maximum rows fetched (and published in one transaction) per tick. Default: `100`. */
116
+ batchSize?: number;
117
+ /**
118
+ * Called when a poll iteration fails — either the publishing transaction
119
+ * threw or the store threw. The failed `batch` is **not** marked published and
120
+ * is retried on the next tick. The relay keeps running regardless.
121
+ *
122
+ * Default: log the error via the client logger.
123
+ */
124
+ onError?: (error: Error, batch: OutboxMessage[]) => void;
125
+ /** Called after a batch is successfully published and marked, with the batch size. */
126
+ onPublished?: (count: number) => void;
127
+ }
128
+ /**
129
+ * The narrowest producer surface the outbox relay needs: the ability to run an
130
+ * atomic Kafka transaction. Both `KafkaClient<T>` and the public
131
+ * `IKafkaProducer<T>` interface satisfy this.
132
+ */
133
+ export interface OutboxProducer<T extends TopicMapConstraint<T>> {
134
+ transaction(fn: (ctx: TransactionContext<T>) => Promise<void>): Promise<void>;
135
+ }
136
+ /** Handle returned by {@link startOutboxRelay}. */
137
+ export interface OutboxRelayHandle {
138
+ /**
139
+ * Stop the relay: halt the timer and wait for any in-flight iteration to
140
+ * finish before resolving. Idempotent.
141
+ */
142
+ stop(): Promise<void>;
143
+ }
144
+ //# sourceMappingURL=outbox.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.types.d.ts","sourceRoot":"","sources":["../../../src/client/outbox/outbox.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1D;;;;;;;OAOG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACzD,sFAAsF;IACtF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,kBAAkB,CAAC,CAAC,CAAC;IAC7D,WAAW,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E;AAED,mDAAmD;AACnD,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * ACL requirement calculator for the topics, consumer groups, and
3
+ * transactional ids this library derives from your configuration.
4
+ *
5
+ * Features like retry topics, DLQ, delayed delivery, deduplication routing,
6
+ * DLQ replay, snapshots, and clock recovery all create extra topics
7
+ * (`<topic>.retry.N`, `<topic>.dlq`, `<topic>.delayed`, `<topic>.duplicates`)
8
+ * and consumer groups (`<groupId>-retry.N`, `<groupId>-delayed-relay`, plus
9
+ * timestamped ephemeral groups). On a locked-down cluster every one of them
10
+ * needs an ACL — `describeRequiredAcls()` enumerates them so nothing is
11
+ * discovered in production at 3 a.m.
12
+ */
13
+ /** One ACL requirement on a Kafka resource. */
14
+ export interface AclResource {
15
+ resourceType: "topic" | "group" | "transactional-id" | "cluster";
16
+ /**
17
+ * `literal` — exact name match. `prefixed` — Kafka prefixed ACL pattern;
18
+ * required for the timestamped ephemeral groups this library creates.
19
+ */
20
+ patternType: "literal" | "prefixed";
21
+ name: string;
22
+ /** Kafka operations: READ, WRITE, DESCRIBE, CREATE, DELETE. */
23
+ operations: string[];
24
+ /** Which feature requires this resource. */
25
+ reason: string;
26
+ }
27
+ /** Input describing how a service uses its `KafkaClient`. */
28
+ export interface AclRequirementsInput {
29
+ clientId: string;
30
+ /** Default/typical consumer group ids used by this service. */
31
+ groupIds?: string[];
32
+ /** Topics this service produces to. */
33
+ produceTopics?: string[];
34
+ /** Topics this service consumes from. */
35
+ consumeTopics?: string[];
36
+ features?: {
37
+ /** `retryTopics: true` — adds `.retry.N` topics, `-retry.N` groups, and per-level tx ids. */
38
+ retryTopics?: {
39
+ maxRetries: number;
40
+ };
41
+ /** `dlq: true` — adds `.dlq` produce rights on consumed topics. */
42
+ dlq?: boolean;
43
+ /** `deliverAfterMs` / `startDelayedRelay` — adds `.delayed` topics, relay group, relay tx id. */
44
+ delayedDelivery?: boolean;
45
+ /** `deduplication.strategy: 'topic'` — adds `.duplicates` produce rights (or the custom topic). */
46
+ duplicatesTopic?: boolean | string;
47
+ /** `replayDlq()` usage — adds prefixed ephemeral replay groups + group deletion. */
48
+ dlqReplay?: boolean;
49
+ /** `readSnapshot` / `checkpointOffsets` / `restoreFromCheckpoint` — prefixed ephemeral groups. */
50
+ snapshots?: boolean;
51
+ /** `clockRecovery.topics` configured — prefixed ephemeral recovery groups. */
52
+ clockRecovery?: boolean;
53
+ /** `transaction()` usage — base transactional id. */
54
+ transactions?: boolean;
55
+ /** `autoCreateTopics: true` — cluster CREATE (avoid in production). */
56
+ autoCreateTopics?: boolean;
57
+ };
58
+ }
59
+ /**
60
+ * Enumerate every Kafka resource (with required operations) a service
61
+ * principal needs for the given usage profile — including all derived
62
+ * topics, companion groups, ephemeral groups, and transactional ids.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const acls = describeRequiredAcls({
67
+ * clientId: 'billing-svc',
68
+ * groupIds: ['billing-svc-group'],
69
+ * produceTopics: ['invoices.created'],
70
+ * consumeTopics: ['orders.created'],
71
+ * features: { retryTopics: { maxRetries: 3 }, dlq: true, dlqReplay: true },
72
+ * });
73
+ * console.log(toKafkaAclCommands(acls, 'User:billing-svc'));
74
+ * ```
75
+ */
76
+ export declare function describeRequiredAcls(input: AclRequirementsInput): AclResource[];
77
+ /**
78
+ * Render ACL requirements as `kafka-acls.sh` commands for a principal.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * toKafkaAclCommands(acls, 'User:billing-svc', 'broker:9092')
83
+ * // kafka-acls.sh --bootstrap-server broker:9092 --add --allow-principal User:billing-svc \
84
+ * // --operation READ --operation DESCRIBE --topic orders.created
85
+ * ```
86
+ */
87
+ export declare function toKafkaAclCommands(resources: AclResource[], principal: string, bootstrapServer?: string): string[];
88
+ /** Cluster coordinates for building MSK resource ARNs. */
89
+ export interface MskClusterCoordinates {
90
+ region: string;
91
+ accountId: string;
92
+ clusterName: string;
93
+ /** The UUID segment of the cluster ARN. */
94
+ clusterUuid: string;
95
+ }
96
+ /**
97
+ * Render ACL requirements as an AWS IAM policy document for MSK IAM auth.
98
+ *
99
+ * Prefixed patterns become `name*` wildcards in the resource ARN. The
100
+ * generated policy always includes `kafka-cluster:Connect` on the cluster.
101
+ * **Review before use** — validate against current AWS documentation and
102
+ * your organisation's least-privilege standards.
103
+ */
104
+ export declare function toMskIamPolicy(resources: AclResource[], cluster: MskClusterCoordinates): {
105
+ Version: string;
106
+ Statement: unknown[];
107
+ };
108
+ //# sourceMappingURL=acl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl.d.ts","sourceRoot":"","sources":["../../../src/client/security/acl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,OAAO,GAAG,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACjE;;;OAGG;IACH,WAAW,EAAE,SAAS,GAAG,UAAU,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,uCAAuC;IACvC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE;QACT,6FAA6F;QAC7F,WAAW,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC;QACrC,mEAAmE;QACnE,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,iGAAiG;QACjG,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,mGAAmG;QACnG,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;QACnC,oFAAoF;QACpF,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,kGAAkG;QAClG,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,8EAA8E;QAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,qDAAqD;QACrD,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,uEAAuE;QACvE,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAkBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,GAC1B,WAAW,EAAE,CAgMf;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAuB,GACrC,MAAM,EAAE,CAmBV;AAED,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;CACrB;AAsBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,WAAW,EAAE,EACxB,OAAO,EAAE,qBAAqB,GAC7B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,EAAE,CAAA;CAAE,CA4C3C"}
@@ -0,0 +1,5 @@
1
+ export * from "./security.types";
2
+ export * from "./resolve-security";
3
+ export * from "./providers";
4
+ export * from "./acl";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/security/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC"}
@@ -0,0 +1,88 @@
1
+ import type { OAuthBearerProvider } from "./security.types";
2
+ /** Injectable dynamic-import function — overridable in tests. */
3
+ type ImportFn = (specifier: string) => Promise<any>;
4
+ /** Options for {@link awsMskIamProvider}. */
5
+ export interface AwsMskIamProviderOptions {
6
+ /** AWS region of the MSK cluster, e.g. `"eu-west-1"`. */
7
+ region: string;
8
+ /**
9
+ * Optional AWS credentials profile / role logic is resolved by the signer
10
+ * library from the standard provider chain (env vars, ECS/EKS metadata,
11
+ * shared config). Nothing to configure here for IRSA / task roles.
12
+ */
13
+ /** @internal Injectable import for tests. */
14
+ importFn?: ImportFn;
15
+ }
16
+ /**
17
+ * OAUTHBEARER token provider for **AWS MSK IAM authentication**.
18
+ *
19
+ * Delegates token signing to the official `aws-msk-iam-sasl-signer-js`
20
+ * package (an optional dependency — install it alongside this library):
21
+ *
22
+ * ```bash
23
+ * npm install aws-msk-iam-sasl-signer-js
24
+ * ```
25
+ *
26
+ * Credentials are resolved from the standard AWS provider chain, so EKS
27
+ * IRSA, ECS task roles, and env credentials all work with no extra config.
28
+ * Authorisation is then governed by IAM policies (`kafka-cluster:*` actions) —
29
+ * see `describeRequiredAcls()` + `toMskIamPolicy()` to generate one covering
30
+ * every topic/group this library derives.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const kafka = new KafkaClient(id, group, brokers, {
35
+ * security: {
36
+ * sasl: {
37
+ * mechanism: 'oauthbearer',
38
+ * oauthBearerProvider: awsMskIamProvider({ region: 'eu-west-1' }),
39
+ * },
40
+ * },
41
+ * });
42
+ * ```
43
+ */
44
+ export declare function awsMskIamProvider(options: AwsMskIamProviderOptions): OAuthBearerProvider;
45
+ /** Options for {@link gcpAccessTokenProvider}. */
46
+ export interface GcpTokenProviderOptions {
47
+ /** OAuth scopes. Default: `["https://www.googleapis.com/auth/cloud-platform"]`. */
48
+ scopes?: string[];
49
+ /** Principal reported to the broker. Default: `"gcp"`. */
50
+ principal?: string;
51
+ /**
52
+ * Token validity reported to the driver (refresh margin), epoch-relative ms.
53
+ * GCP access tokens live ~1 h; default refresh window is 50 minutes.
54
+ */
55
+ tokenTtlMs?: number;
56
+ /** @internal Injectable import for tests. */
57
+ importFn?: ImportFn;
58
+ }
59
+ /**
60
+ * OAUTHBEARER token provider for **Google Cloud Managed Service for Apache
61
+ * Kafka** (and any broker accepting Google OAuth access tokens).
62
+ *
63
+ * Delegates to the official `google-auth-library` (optional dependency):
64
+ *
65
+ * ```bash
66
+ * npm install google-auth-library
67
+ * ```
68
+ *
69
+ * Uses Application Default Credentials, so GKE Workload Identity, attached
70
+ * service accounts, and `GOOGLE_APPLICATION_CREDENTIALS` all work unchanged.
71
+ * Verify the exact token format expected by your cluster against current
72
+ * Google documentation — this provider supplies a raw ADC access token.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const kafka = new KafkaClient(id, group, brokers, {
77
+ * security: {
78
+ * sasl: {
79
+ * mechanism: 'oauthbearer',
80
+ * oauthBearerProvider: gcpAccessTokenProvider(),
81
+ * },
82
+ * },
83
+ * });
84
+ * ```
85
+ */
86
+ export declare function gcpAccessTokenProvider(options?: GcpTokenProviderOptions): OAuthBearerProvider;
87
+ export {};
88
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../../src/client/security/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,kBAAkB,CAAC;AAE9E,iEAAiE;AACjE,KAAK,QAAQ,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAIpD,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,wBAAwB,GAChC,mBAAmB,CAsBrB;AAED,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,mBAAmB,CA6BrB"}
@@ -0,0 +1,19 @@
1
+ import type { KafkaLogger } from "../types";
2
+ import type { KafkaSecurityOptions } from "./security.types";
3
+ /**
4
+ * Apply the secure-by-default rules to a user-supplied security config:
5
+ *
6
+ * 1. `sasl` present + `ssl` unset → `ssl: true`. Credentials never travel
7
+ * over plaintext by accident; opting out requires an explicit `ssl: false`
8
+ * (which logs a warning).
9
+ * 2. No `ssl`/`sasl` at all while any broker is non-local → one warning per
10
+ * client, silenceable via `allowInsecure: true`.
11
+ *
12
+ * Never throws and never blocks a connection — the defaults protect, the
13
+ * user stays in control.
14
+ *
15
+ * @returns The effective options passed to the transport (may be `undefined`
16
+ * when no security was configured).
17
+ */
18
+ export declare function resolveSecurityOptions(security: KafkaSecurityOptions | undefined, brokers: string[], logger: KafkaLogger): KafkaSecurityOptions | undefined;
19
+ //# sourceMappingURL=resolve-security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-security.d.ts","sourceRoot":"","sources":["../../../src/client/security/resolve-security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAe7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,EAC1C,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,WAAW,GAClB,oBAAoB,GAAG,SAAS,CA0BlC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * OAuth bearer token returned by an {@link OAuthBearerProvider}.
3
+ * Mirrors the shape expected by librdkafka's OAUTHBEARER mechanism.
4
+ */
5
+ export interface OAuthBearerToken {
6
+ /** The raw token value presented to the broker. */
7
+ value: string;
8
+ /** Kafka principal name associated with the token. Default: `"kafka-client"`. */
9
+ principal?: string;
10
+ /**
11
+ * Absolute token expiry as epoch milliseconds. The driver refreshes the
12
+ * token before this deadline. Default: now + 15 minutes.
13
+ */
14
+ lifetimeMs?: number;
15
+ /** Optional SASL extensions forwarded to the broker. */
16
+ extensions?: Record<string, string>;
17
+ }
18
+ /**
19
+ * Async factory that produces a fresh OAuth bearer token.
20
+ * Called by the driver on connect and before each token expiry.
21
+ */
22
+ export type OAuthBearerProvider = () => Promise<OAuthBearerToken>;
23
+ /** SASL configuration — username/password mechanisms or OAUTHBEARER. */
24
+ export type KafkaSaslOptions = {
25
+ mechanism: "plain" | "scram-sha-256" | "scram-sha-512";
26
+ username: string;
27
+ password: string;
28
+ } | {
29
+ mechanism: "oauthbearer";
30
+ oauthBearerProvider: OAuthBearerProvider;
31
+ };
32
+ /**
33
+ * Transport security configuration for `KafkaClientOptions.security`.
34
+ *
35
+ * Secure-by-default behaviour (see `resolveSecurityOptions`):
36
+ * - When `sasl` is set and `ssl` is not, TLS is enabled automatically —
37
+ * credentials never travel over plaintext unless you explicitly opt out
38
+ * with `ssl: false` (which logs a warning).
39
+ * - Connecting to non-local brokers with no security at all logs a one-time
40
+ * warning. Set `allowInsecure: true` to acknowledge and silence it
41
+ * (e.g. a trusted private network or an mTLS-terminating service mesh).
42
+ *
43
+ * @example SASL/SCRAM over TLS (ssl auto-enabled)
44
+ * ```ts
45
+ * const kafka = new KafkaClient(id, group, brokers, {
46
+ * security: {
47
+ * sasl: { mechanism: 'scram-sha-512', username: 'svc', password: process.env.KAFKA_PASSWORD! },
48
+ * },
49
+ * });
50
+ * ```
51
+ *
52
+ * @example AWS MSK IAM
53
+ * ```ts
54
+ * import { awsMskIamProvider } from '@drarzter/kafka-client/core';
55
+ *
56
+ * const kafka = new KafkaClient(id, group, brokers, {
57
+ * security: {
58
+ * sasl: { mechanism: 'oauthbearer', oauthBearerProvider: awsMskIamProvider({ region: 'eu-west-1' }) },
59
+ * },
60
+ * });
61
+ * ```
62
+ */
63
+ export interface KafkaSecurityOptions {
64
+ /**
65
+ * Enable TLS. Defaults to `true` when `sasl` is configured, otherwise `false`.
66
+ */
67
+ ssl?: boolean;
68
+ /** SASL authentication. */
69
+ sasl?: KafkaSaslOptions;
70
+ /**
71
+ * Acknowledge an intentionally insecure setup (plaintext to non-local
72
+ * brokers) and silence the warning. Has no effect when `ssl`/`sasl` are set.
73
+ */
74
+ allowInsecure?: boolean;
75
+ }
76
+ //# sourceMappingURL=security.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.types.d.ts","sourceRoot":"","sources":["../../../src/client/security/security.types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAElE,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GACxB;IACE,SAAS,EAAE,OAAO,GAAG,eAAe,GAAG,eAAe,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,SAAS,EAAE,aAAa,CAAC;IACzB,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,2BAA2B;IAC3B,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -0,0 +1,32 @@
1
+ import { KafkaJS } from "@confluentinc/kafka-javascript";
2
+ import type { KafkaTransport, IProducer, IConsumer, IAdmin, IProducerCreationOptions, IConsumerCreationOptions, ITopicPartition, ITopicPartitions, ITopicPartitionOffset, IConsumerRunConfig } from "./transport.interface";
3
+ export declare class ConfluentConsumer implements IConsumer {
4
+ private readonly consumer;
5
+ constructor(consumer: KafkaJS.Consumer);
6
+ /** Returns the underlying KafkaJS.Consumer — used by ConfluentTransaction.sendOffsets. */
7
+ getNative(): KafkaJS.Consumer;
8
+ connect(): Promise<void>;
9
+ disconnect(): Promise<void>;
10
+ subscribe(options: {
11
+ topics: (string | RegExp)[];
12
+ }): Promise<void>;
13
+ run(config: IConsumerRunConfig): Promise<void>;
14
+ pause(assignments: ITopicPartitions[]): void;
15
+ resume(assignments: ITopicPartitions[]): void;
16
+ seek(options: ITopicPartitionOffset): void;
17
+ assignment(): ITopicPartition[];
18
+ commitOffsets(offsets: ITopicPartitionOffset[]): Promise<void>;
19
+ stop(): Promise<void>;
20
+ }
21
+ /**
22
+ * `KafkaTransport` implementation backed by `@confluentinc/kafka-javascript`.
23
+ * Wraps the KafkaJS-compatibility layer from librdkafka.
24
+ */
25
+ export declare class ConfluentTransport implements KafkaTransport {
26
+ private readonly kafka;
27
+ constructor(clientId: string, brokers: string[], security?: import("../security/security.types").KafkaSecurityOptions);
28
+ producer(options?: IProducerCreationOptions): IProducer;
29
+ consumer(options: IConsumerCreationOptions): IConsumer;
30
+ admin(): IAdmin;
31
+ }
32
+ //# sourceMappingURL=confluent.transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluent.transport.d.ts","sourceRoot":"","sources":["../../../src/client/transport/confluent.transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAGzD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EAGN,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAMnB,MAAM,uBAAuB,CAAC;AAuE/B,qBAAa,iBAAkB,YAAW,SAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAEvD,0FAA0F;IAC1F,SAAS,IAAI,OAAO,CAAC,QAAQ;IAIvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,SAAS,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,GAAG,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,KAAK,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAI5C,MAAM,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAI7C,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAI1C,UAAU,IAAI,eAAe,EAAE;IAIzB,aAAa,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AA0ED;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAGpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,CAAC,EAAE,OAAO,4BAA4B,EAAE,oBAAoB;IA0BtE,QAAQ,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,SAAS;IAgBvD,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,SAAS;IAsCtD,KAAK,IAAI,MAAM;CAGhB"}