@walkeros/server-destination-kafka 3.4.0-next-1776749829492

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/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # @walkeros/server-destination-kafka
2
+
3
+ Apache Kafka server destination for
4
+ [walkerOS](https://github.com/elbwalker/walkerOS). Forwards events to Kafka
5
+ topics via [kafkajs](https://kafka.js.org/) with JSON serialization and
6
+ configurable compression.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @walkeros/server-destination-kafka
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```json
17
+ {
18
+ "destinations": {
19
+ "kafka": {
20
+ "package": "@walkeros/server-destination-kafka",
21
+ "config": {
22
+ "settings": {
23
+ "kafka": {
24
+ "brokers": ["kafka1:9092", "kafka2:9092"],
25
+ "topic": "walkeros-events"
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ ## Settings
35
+
36
+ | Setting | Type | Required | Default | Description |
37
+ | ------------------------ | ---------------- | -------- | ------------ | ------------------------------------------------------------ |
38
+ | `brokers` | string[] | Yes | -- | Kafka broker addresses (host:port) |
39
+ | `topic` | string | Yes | -- | Target Kafka topic |
40
+ | `clientId` | string | No | `'walkeros'` | Kafka client identifier |
41
+ | `ssl` | boolean / object | No | -- | TLS config (`true` for default TLS) |
42
+ | `sasl` | object | No | -- | SASL auth (plain, scram, aws, oauthbearer) |
43
+ | `acks` | number | No | `-1` | `-1` all replicas, `0` fire-and-forget, `1` leader |
44
+ | `compression` | string | No | `'gzip'` | `none`, `gzip`, `snappy`, `lz4`, `zstd` |
45
+ | `key` | string | No | event name | Mapping path for message key derivation |
46
+ | `headers` | Record | No | -- | Static headers on every message |
47
+ | `idempotent` | boolean | No | `false` | Exactly-once delivery |
48
+ | `allowAutoTopicCreation` | boolean | No | `false` | Auto-create topics |
49
+ | `retry` | object | No | -- | Retry config (`retries`, `maxRetryTime`, `initialRetryTime`) |
50
+
51
+ ## Per-rule mapping settings
52
+
53
+ | Setting | Description |
54
+ | ------- | ----------------------------------------------------------------- |
55
+ | `key` | Override message key mapping path for this rule |
56
+ | `topic` | Route this rule to a different topic than the destination default |
57
+
58
+ ## Authentication
59
+
60
+ ### Confluent Cloud
61
+
62
+ ```json
63
+ {
64
+ "kafka": {
65
+ "brokers": ["pkc-xxxxx.us-east-1.aws.confluent.cloud:9092"],
66
+ "topic": "walkeros-events",
67
+ "ssl": true,
68
+ "sasl": {
69
+ "mechanism": "plain",
70
+ "username": "$env.CONFLUENT_API_KEY",
71
+ "password": "$env.CONFLUENT_API_SECRET"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### AWS MSK (IAM)
78
+
79
+ ```json
80
+ {
81
+ "kafka": {
82
+ "brokers": ["broker.msk.us-east-1.amazonaws.com:9098"],
83
+ "topic": "walkeros-events",
84
+ "ssl": true,
85
+ "sasl": {
86
+ "mechanism": "aws",
87
+ "accessKeyId": "$env.AWS_ACCESS_KEY",
88
+ "secretAccessKey": "$env.AWS_SECRET_KEY"
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Message format
95
+
96
+ Events are serialized as JSON. When a mapping transforms `data`, only the mapped
97
+ payload is sent; otherwise the full walkerOS event is sent. The message key
98
+ defaults to the event name (spaces replaced with `_`) for partition-based
99
+ ordering. Configure `key` (destination-level) or `mapping.settings.key`
100
+ (per-rule) to use any event property path.
101
+
102
+ ## Shutdown
103
+
104
+ The destination implements `destroy()` calling `producer.disconnect()` to close
105
+ persistent TCP connections on flow hot-swap or server shutdown.
package/dist/dev.d.mts ADDED
@@ -0,0 +1,276 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ declare const KafkaSettingsSchema: z.ZodObject<{
7
+ brokers: z.ZodArray<z.ZodString>;
8
+ clientId: z.ZodOptional<z.ZodString>;
9
+ ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
10
+ sasl: z.ZodOptional<z.ZodObject<{
11
+ mechanism: z.ZodEnum<{
12
+ plain: "plain";
13
+ "scram-sha-256": "scram-sha-256";
14
+ "scram-sha-512": "scram-sha-512";
15
+ aws: "aws";
16
+ oauthbearer: "oauthbearer";
17
+ }>;
18
+ username: z.ZodOptional<z.ZodString>;
19
+ password: z.ZodOptional<z.ZodString>;
20
+ accessKeyId: z.ZodOptional<z.ZodString>;
21
+ secretAccessKey: z.ZodOptional<z.ZodString>;
22
+ sessionToken: z.ZodOptional<z.ZodString>;
23
+ authorizationIdentity: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>>;
25
+ connectionTimeout: z.ZodOptional<z.ZodNumber>;
26
+ requestTimeout: z.ZodOptional<z.ZodNumber>;
27
+ topic: z.ZodString;
28
+ acks: z.ZodOptional<z.ZodNumber>;
29
+ timeout: z.ZodOptional<z.ZodNumber>;
30
+ compression: z.ZodOptional<z.ZodEnum<{
31
+ none: "none";
32
+ gzip: "gzip";
33
+ snappy: "snappy";
34
+ lz4: "lz4";
35
+ zstd: "zstd";
36
+ }>>;
37
+ idempotent: z.ZodOptional<z.ZodBoolean>;
38
+ allowAutoTopicCreation: z.ZodOptional<z.ZodBoolean>;
39
+ key: z.ZodOptional<z.ZodString>;
40
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
41
+ retry: z.ZodOptional<z.ZodObject<{
42
+ maxRetryTime: z.ZodOptional<z.ZodNumber>;
43
+ initialRetryTime: z.ZodOptional<z.ZodNumber>;
44
+ retries: z.ZodOptional<z.ZodNumber>;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ declare const SettingsSchema: z.ZodObject<{
48
+ kafka: z.ZodObject<{
49
+ brokers: z.ZodArray<z.ZodString>;
50
+ clientId: z.ZodOptional<z.ZodString>;
51
+ ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
52
+ sasl: z.ZodOptional<z.ZodObject<{
53
+ mechanism: z.ZodEnum<{
54
+ plain: "plain";
55
+ "scram-sha-256": "scram-sha-256";
56
+ "scram-sha-512": "scram-sha-512";
57
+ aws: "aws";
58
+ oauthbearer: "oauthbearer";
59
+ }>;
60
+ username: z.ZodOptional<z.ZodString>;
61
+ password: z.ZodOptional<z.ZodString>;
62
+ accessKeyId: z.ZodOptional<z.ZodString>;
63
+ secretAccessKey: z.ZodOptional<z.ZodString>;
64
+ sessionToken: z.ZodOptional<z.ZodString>;
65
+ authorizationIdentity: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ connectionTimeout: z.ZodOptional<z.ZodNumber>;
68
+ requestTimeout: z.ZodOptional<z.ZodNumber>;
69
+ topic: z.ZodString;
70
+ acks: z.ZodOptional<z.ZodNumber>;
71
+ timeout: z.ZodOptional<z.ZodNumber>;
72
+ compression: z.ZodOptional<z.ZodEnum<{
73
+ none: "none";
74
+ gzip: "gzip";
75
+ snappy: "snappy";
76
+ lz4: "lz4";
77
+ zstd: "zstd";
78
+ }>>;
79
+ idempotent: z.ZodOptional<z.ZodBoolean>;
80
+ allowAutoTopicCreation: z.ZodOptional<z.ZodBoolean>;
81
+ key: z.ZodOptional<z.ZodString>;
82
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
83
+ retry: z.ZodOptional<z.ZodObject<{
84
+ maxRetryTime: z.ZodOptional<z.ZodNumber>;
85
+ initialRetryTime: z.ZodOptional<z.ZodNumber>;
86
+ retries: z.ZodOptional<z.ZodNumber>;
87
+ }, z.core.$strip>>;
88
+ }, z.core.$strip>;
89
+ }, z.core.$strip>;
90
+ type Settings$1 = z.infer<typeof SettingsSchema>;
91
+
92
+ declare const MappingSchema: z.ZodObject<{
93
+ key: z.ZodOptional<z.ZodString>;
94
+ topic: z.ZodOptional<z.ZodString>;
95
+ }, z.core.$strip>;
96
+ type Mapping = z.infer<typeof MappingSchema>;
97
+
98
+ declare const settings: _walkeros_core_dev.JSONSchema;
99
+ declare const mapping: _walkeros_core_dev.JSONSchema;
100
+
101
+ declare const index$1_KafkaSettingsSchema: typeof KafkaSettingsSchema;
102
+ type index$1_Mapping = Mapping;
103
+ declare const index$1_MappingSchema: typeof MappingSchema;
104
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
105
+ declare const index$1_mapping: typeof mapping;
106
+ declare const index$1_settings: typeof settings;
107
+ declare namespace index$1 {
108
+ export { index$1_KafkaSettingsSchema as KafkaSettingsSchema, type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
109
+ }
110
+
111
+ /**
112
+ * Mock-friendly Producer interface used by the destination.
113
+ * Tests provide this via env.Kafka; production creates a real
114
+ * kafkajs Producer and adapts it through settings._producer.
115
+ */
116
+ interface KafkaProducerMock {
117
+ connect: () => Promise<void>;
118
+ disconnect: () => Promise<void>;
119
+ send: (record: ProducerRecord) => Promise<unknown>;
120
+ }
121
+ /**
122
+ * Mock-friendly Kafka client interface (subset of kafkajs.Kafka).
123
+ */
124
+ interface KafkaClientMock {
125
+ producer: (config?: ProducerConfig) => KafkaProducerMock;
126
+ }
127
+ /**
128
+ * Constructor signature for the Kafka client. Accepts a config
129
+ * object and returns a client with producer() factory.
130
+ */
131
+ type KafkaClientConstructor = new (config: KafkaClientConfig) => KafkaClientMock;
132
+ interface KafkaClientConfig {
133
+ clientId?: string;
134
+ brokers: string[];
135
+ ssl?: boolean | Record<string, unknown>;
136
+ sasl?: SASLConfig;
137
+ connectionTimeout?: number;
138
+ requestTimeout?: number;
139
+ retry?: RetryConfig;
140
+ }
141
+ interface ProducerConfig {
142
+ allowAutoTopicCreation?: boolean;
143
+ idempotent?: boolean;
144
+ }
145
+ interface ProducerRecord {
146
+ topic: string;
147
+ messages: ProducerMessage[];
148
+ acks?: number;
149
+ compression?: number;
150
+ timeout?: number;
151
+ }
152
+ interface ProducerMessage {
153
+ key?: string;
154
+ value: string;
155
+ headers?: Record<string, string>;
156
+ timestamp?: string;
157
+ partition?: number;
158
+ }
159
+ interface CompressionTypesMap {
160
+ None: number;
161
+ GZIP: number;
162
+ Snappy: number;
163
+ LZ4: number;
164
+ ZSTD: number;
165
+ }
166
+ type CompressionType = 'none' | 'gzip' | 'snappy' | 'lz4' | 'zstd';
167
+ interface SASLConfig {
168
+ mechanism: 'plain' | 'scram-sha-256' | 'scram-sha-512' | 'aws' | 'oauthbearer';
169
+ username?: string;
170
+ password?: string;
171
+ accessKeyId?: string;
172
+ secretAccessKey?: string;
173
+ sessionToken?: string;
174
+ authorizationIdentity?: string;
175
+ }
176
+ interface RetryConfig {
177
+ maxRetryTime?: number;
178
+ initialRetryTime?: number;
179
+ retries?: number;
180
+ }
181
+ interface KafkaSettings {
182
+ brokers: string[];
183
+ clientId?: string;
184
+ ssl?: boolean | Record<string, unknown>;
185
+ sasl?: SASLConfig;
186
+ connectionTimeout?: number;
187
+ requestTimeout?: number;
188
+ topic: string;
189
+ acks?: number;
190
+ timeout?: number;
191
+ compression?: CompressionType;
192
+ idempotent?: boolean;
193
+ allowAutoTopicCreation?: boolean;
194
+ key?: string;
195
+ headers?: Record<string, string>;
196
+ retry?: RetryConfig;
197
+ _producer?: KafkaProducerMock;
198
+ }
199
+ interface Settings {
200
+ kafka: KafkaSettings;
201
+ }
202
+ /**
203
+ * Env -- optional Kafka SDK override. Production leaves this undefined
204
+ * and the destination creates real Kafka client instances. Tests provide
205
+ * mocks via env.Kafka.
206
+ */
207
+ interface Env extends DestinationServer.Env {
208
+ Kafka?: {
209
+ Kafka: KafkaClientConstructor;
210
+ CompressionTypes: CompressionTypesMap;
211
+ };
212
+ }
213
+
214
+ declare const push: Env;
215
+ declare const simulation: string[];
216
+
217
+ declare const env_push: typeof push;
218
+ declare const env_simulation: typeof simulation;
219
+ declare namespace env {
220
+ export { env_push as push, env_simulation as simulation };
221
+ }
222
+
223
+ /**
224
+ * Extended step example that may carry destination-level settings overrides.
225
+ */
226
+ type KafkaStepExample = Flow.StepExample & {
227
+ settings?: Partial<Settings>;
228
+ };
229
+ /**
230
+ * Default event -- full WalkerOS.Event serialized as JSON to the configured
231
+ * topic. Message key defaults to entity_action when no key path is set.
232
+ */
233
+ declare const defaultEvent: KafkaStepExample;
234
+ /**
235
+ * Mapped event name -- rule.name renames the event, which also changes the
236
+ * default message key when no key mapping is configured.
237
+ */
238
+ declare const mappedEventName: KafkaStepExample;
239
+ /**
240
+ * Mapped data -- data.map transforms the event payload. Value is the mapped
241
+ * object serialized as JSON.
242
+ */
243
+ declare const mappedData: KafkaStepExample;
244
+ /**
245
+ * Key from user -- settings.kafka.key path resolves the message key from
246
+ * the event (here user.id).
247
+ */
248
+ declare const keyFromUser: KafkaStepExample;
249
+ /**
250
+ * Topic override -- rule.settings.topic routes this rule to a different
251
+ * topic than the destination default.
252
+ */
253
+ declare const topicOverride: KafkaStepExample;
254
+ /**
255
+ * Ignored event -- mapping.ignore: true produces no producer.send call.
256
+ */
257
+ declare const ignoredEvent: KafkaStepExample;
258
+
259
+ type step_KafkaStepExample = KafkaStepExample;
260
+ declare const step_defaultEvent: typeof defaultEvent;
261
+ declare const step_ignoredEvent: typeof ignoredEvent;
262
+ declare const step_keyFromUser: typeof keyFromUser;
263
+ declare const step_mappedData: typeof mappedData;
264
+ declare const step_mappedEventName: typeof mappedEventName;
265
+ declare const step_topicOverride: typeof topicOverride;
266
+ declare namespace step {
267
+ export { type step_KafkaStepExample as KafkaStepExample, step_defaultEvent as defaultEvent, step_ignoredEvent as ignoredEvent, step_keyFromUser as keyFromUser, step_mappedData as mappedData, step_mappedEventName as mappedEventName, step_topicOverride as topicOverride };
268
+ }
269
+
270
+ declare const index_env: typeof env;
271
+ declare const index_step: typeof step;
272
+ declare namespace index {
273
+ export { index_env as env, index_step as step };
274
+ }
275
+
276
+ export { index as examples, index$1 as schemas };
package/dist/dev.d.ts ADDED
@@ -0,0 +1,276 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ declare const KafkaSettingsSchema: z.ZodObject<{
7
+ brokers: z.ZodArray<z.ZodString>;
8
+ clientId: z.ZodOptional<z.ZodString>;
9
+ ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
10
+ sasl: z.ZodOptional<z.ZodObject<{
11
+ mechanism: z.ZodEnum<{
12
+ plain: "plain";
13
+ "scram-sha-256": "scram-sha-256";
14
+ "scram-sha-512": "scram-sha-512";
15
+ aws: "aws";
16
+ oauthbearer: "oauthbearer";
17
+ }>;
18
+ username: z.ZodOptional<z.ZodString>;
19
+ password: z.ZodOptional<z.ZodString>;
20
+ accessKeyId: z.ZodOptional<z.ZodString>;
21
+ secretAccessKey: z.ZodOptional<z.ZodString>;
22
+ sessionToken: z.ZodOptional<z.ZodString>;
23
+ authorizationIdentity: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>>;
25
+ connectionTimeout: z.ZodOptional<z.ZodNumber>;
26
+ requestTimeout: z.ZodOptional<z.ZodNumber>;
27
+ topic: z.ZodString;
28
+ acks: z.ZodOptional<z.ZodNumber>;
29
+ timeout: z.ZodOptional<z.ZodNumber>;
30
+ compression: z.ZodOptional<z.ZodEnum<{
31
+ none: "none";
32
+ gzip: "gzip";
33
+ snappy: "snappy";
34
+ lz4: "lz4";
35
+ zstd: "zstd";
36
+ }>>;
37
+ idempotent: z.ZodOptional<z.ZodBoolean>;
38
+ allowAutoTopicCreation: z.ZodOptional<z.ZodBoolean>;
39
+ key: z.ZodOptional<z.ZodString>;
40
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
41
+ retry: z.ZodOptional<z.ZodObject<{
42
+ maxRetryTime: z.ZodOptional<z.ZodNumber>;
43
+ initialRetryTime: z.ZodOptional<z.ZodNumber>;
44
+ retries: z.ZodOptional<z.ZodNumber>;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ declare const SettingsSchema: z.ZodObject<{
48
+ kafka: z.ZodObject<{
49
+ brokers: z.ZodArray<z.ZodString>;
50
+ clientId: z.ZodOptional<z.ZodString>;
51
+ ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
52
+ sasl: z.ZodOptional<z.ZodObject<{
53
+ mechanism: z.ZodEnum<{
54
+ plain: "plain";
55
+ "scram-sha-256": "scram-sha-256";
56
+ "scram-sha-512": "scram-sha-512";
57
+ aws: "aws";
58
+ oauthbearer: "oauthbearer";
59
+ }>;
60
+ username: z.ZodOptional<z.ZodString>;
61
+ password: z.ZodOptional<z.ZodString>;
62
+ accessKeyId: z.ZodOptional<z.ZodString>;
63
+ secretAccessKey: z.ZodOptional<z.ZodString>;
64
+ sessionToken: z.ZodOptional<z.ZodString>;
65
+ authorizationIdentity: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ connectionTimeout: z.ZodOptional<z.ZodNumber>;
68
+ requestTimeout: z.ZodOptional<z.ZodNumber>;
69
+ topic: z.ZodString;
70
+ acks: z.ZodOptional<z.ZodNumber>;
71
+ timeout: z.ZodOptional<z.ZodNumber>;
72
+ compression: z.ZodOptional<z.ZodEnum<{
73
+ none: "none";
74
+ gzip: "gzip";
75
+ snappy: "snappy";
76
+ lz4: "lz4";
77
+ zstd: "zstd";
78
+ }>>;
79
+ idempotent: z.ZodOptional<z.ZodBoolean>;
80
+ allowAutoTopicCreation: z.ZodOptional<z.ZodBoolean>;
81
+ key: z.ZodOptional<z.ZodString>;
82
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
83
+ retry: z.ZodOptional<z.ZodObject<{
84
+ maxRetryTime: z.ZodOptional<z.ZodNumber>;
85
+ initialRetryTime: z.ZodOptional<z.ZodNumber>;
86
+ retries: z.ZodOptional<z.ZodNumber>;
87
+ }, z.core.$strip>>;
88
+ }, z.core.$strip>;
89
+ }, z.core.$strip>;
90
+ type Settings$1 = z.infer<typeof SettingsSchema>;
91
+
92
+ declare const MappingSchema: z.ZodObject<{
93
+ key: z.ZodOptional<z.ZodString>;
94
+ topic: z.ZodOptional<z.ZodString>;
95
+ }, z.core.$strip>;
96
+ type Mapping = z.infer<typeof MappingSchema>;
97
+
98
+ declare const settings: _walkeros_core_dev.JSONSchema;
99
+ declare const mapping: _walkeros_core_dev.JSONSchema;
100
+
101
+ declare const index$1_KafkaSettingsSchema: typeof KafkaSettingsSchema;
102
+ type index$1_Mapping = Mapping;
103
+ declare const index$1_MappingSchema: typeof MappingSchema;
104
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
105
+ declare const index$1_mapping: typeof mapping;
106
+ declare const index$1_settings: typeof settings;
107
+ declare namespace index$1 {
108
+ export { index$1_KafkaSettingsSchema as KafkaSettingsSchema, type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
109
+ }
110
+
111
+ /**
112
+ * Mock-friendly Producer interface used by the destination.
113
+ * Tests provide this via env.Kafka; production creates a real
114
+ * kafkajs Producer and adapts it through settings._producer.
115
+ */
116
+ interface KafkaProducerMock {
117
+ connect: () => Promise<void>;
118
+ disconnect: () => Promise<void>;
119
+ send: (record: ProducerRecord) => Promise<unknown>;
120
+ }
121
+ /**
122
+ * Mock-friendly Kafka client interface (subset of kafkajs.Kafka).
123
+ */
124
+ interface KafkaClientMock {
125
+ producer: (config?: ProducerConfig) => KafkaProducerMock;
126
+ }
127
+ /**
128
+ * Constructor signature for the Kafka client. Accepts a config
129
+ * object and returns a client with producer() factory.
130
+ */
131
+ type KafkaClientConstructor = new (config: KafkaClientConfig) => KafkaClientMock;
132
+ interface KafkaClientConfig {
133
+ clientId?: string;
134
+ brokers: string[];
135
+ ssl?: boolean | Record<string, unknown>;
136
+ sasl?: SASLConfig;
137
+ connectionTimeout?: number;
138
+ requestTimeout?: number;
139
+ retry?: RetryConfig;
140
+ }
141
+ interface ProducerConfig {
142
+ allowAutoTopicCreation?: boolean;
143
+ idempotent?: boolean;
144
+ }
145
+ interface ProducerRecord {
146
+ topic: string;
147
+ messages: ProducerMessage[];
148
+ acks?: number;
149
+ compression?: number;
150
+ timeout?: number;
151
+ }
152
+ interface ProducerMessage {
153
+ key?: string;
154
+ value: string;
155
+ headers?: Record<string, string>;
156
+ timestamp?: string;
157
+ partition?: number;
158
+ }
159
+ interface CompressionTypesMap {
160
+ None: number;
161
+ GZIP: number;
162
+ Snappy: number;
163
+ LZ4: number;
164
+ ZSTD: number;
165
+ }
166
+ type CompressionType = 'none' | 'gzip' | 'snappy' | 'lz4' | 'zstd';
167
+ interface SASLConfig {
168
+ mechanism: 'plain' | 'scram-sha-256' | 'scram-sha-512' | 'aws' | 'oauthbearer';
169
+ username?: string;
170
+ password?: string;
171
+ accessKeyId?: string;
172
+ secretAccessKey?: string;
173
+ sessionToken?: string;
174
+ authorizationIdentity?: string;
175
+ }
176
+ interface RetryConfig {
177
+ maxRetryTime?: number;
178
+ initialRetryTime?: number;
179
+ retries?: number;
180
+ }
181
+ interface KafkaSettings {
182
+ brokers: string[];
183
+ clientId?: string;
184
+ ssl?: boolean | Record<string, unknown>;
185
+ sasl?: SASLConfig;
186
+ connectionTimeout?: number;
187
+ requestTimeout?: number;
188
+ topic: string;
189
+ acks?: number;
190
+ timeout?: number;
191
+ compression?: CompressionType;
192
+ idempotent?: boolean;
193
+ allowAutoTopicCreation?: boolean;
194
+ key?: string;
195
+ headers?: Record<string, string>;
196
+ retry?: RetryConfig;
197
+ _producer?: KafkaProducerMock;
198
+ }
199
+ interface Settings {
200
+ kafka: KafkaSettings;
201
+ }
202
+ /**
203
+ * Env -- optional Kafka SDK override. Production leaves this undefined
204
+ * and the destination creates real Kafka client instances. Tests provide
205
+ * mocks via env.Kafka.
206
+ */
207
+ interface Env extends DestinationServer.Env {
208
+ Kafka?: {
209
+ Kafka: KafkaClientConstructor;
210
+ CompressionTypes: CompressionTypesMap;
211
+ };
212
+ }
213
+
214
+ declare const push: Env;
215
+ declare const simulation: string[];
216
+
217
+ declare const env_push: typeof push;
218
+ declare const env_simulation: typeof simulation;
219
+ declare namespace env {
220
+ export { env_push as push, env_simulation as simulation };
221
+ }
222
+
223
+ /**
224
+ * Extended step example that may carry destination-level settings overrides.
225
+ */
226
+ type KafkaStepExample = Flow.StepExample & {
227
+ settings?: Partial<Settings>;
228
+ };
229
+ /**
230
+ * Default event -- full WalkerOS.Event serialized as JSON to the configured
231
+ * topic. Message key defaults to entity_action when no key path is set.
232
+ */
233
+ declare const defaultEvent: KafkaStepExample;
234
+ /**
235
+ * Mapped event name -- rule.name renames the event, which also changes the
236
+ * default message key when no key mapping is configured.
237
+ */
238
+ declare const mappedEventName: KafkaStepExample;
239
+ /**
240
+ * Mapped data -- data.map transforms the event payload. Value is the mapped
241
+ * object serialized as JSON.
242
+ */
243
+ declare const mappedData: KafkaStepExample;
244
+ /**
245
+ * Key from user -- settings.kafka.key path resolves the message key from
246
+ * the event (here user.id).
247
+ */
248
+ declare const keyFromUser: KafkaStepExample;
249
+ /**
250
+ * Topic override -- rule.settings.topic routes this rule to a different
251
+ * topic than the destination default.
252
+ */
253
+ declare const topicOverride: KafkaStepExample;
254
+ /**
255
+ * Ignored event -- mapping.ignore: true produces no producer.send call.
256
+ */
257
+ declare const ignoredEvent: KafkaStepExample;
258
+
259
+ type step_KafkaStepExample = KafkaStepExample;
260
+ declare const step_defaultEvent: typeof defaultEvent;
261
+ declare const step_ignoredEvent: typeof ignoredEvent;
262
+ declare const step_keyFromUser: typeof keyFromUser;
263
+ declare const step_mappedData: typeof mappedData;
264
+ declare const step_mappedEventName: typeof mappedEventName;
265
+ declare const step_topicOverride: typeof topicOverride;
266
+ declare namespace step {
267
+ export { type step_KafkaStepExample as KafkaStepExample, step_defaultEvent as defaultEvent, step_ignoredEvent as ignoredEvent, step_keyFromUser as keyFromUser, step_mappedData as mappedData, step_mappedEventName as mappedEventName, step_topicOverride as topicOverride };
268
+ }
269
+
270
+ declare const index_env: typeof env;
271
+ declare const index_step: typeof step;
272
+ declare namespace index {
273
+ export { index_env as env, index_step as step };
274
+ }
275
+
276
+ export { index as examples, index$1 as schemas };
package/dist/dev.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r=(e,a)=>{for(var o in a)t(e,o,{get:a[o],enumerable:!0})},i={};r(i,{examples:()=>f,schemas:()=>n}),module.exports=(e=i,((e,r,i,n)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of o(r))s.call(e,c)||c===i||t(e,c,{get:()=>r[c],enumerable:!(n=a(r,c))||n.enumerable});return e})(t({},"__esModule",{value:!0}),e));var n={};r(n,{KafkaSettingsSchema:()=>l,MappingSchema:()=>b,SettingsSchema:()=>u,mapping:()=>v,settings:()=>k});var c=require("@walkeros/core/dev"),p=require("@walkeros/core/dev"),m=p.z.object({mechanism:p.z.enum(["plain","scram-sha-256","scram-sha-512","aws","oauthbearer"]).describe("SASL authentication mechanism."),username:p.z.string().optional().describe("Username for plain/scram mechanisms."),password:p.z.string().optional().describe("Password for plain/scram mechanisms."),accessKeyId:p.z.string().optional().describe("AWS access key ID for IAM auth (mechanism: aws)."),secretAccessKey:p.z.string().optional().describe("AWS secret access key for IAM auth (mechanism: aws)."),sessionToken:p.z.string().optional().describe("AWS session token for temporary credentials (mechanism: aws)."),authorizationIdentity:p.z.string().optional().describe("AWS authorization identity (mechanism: aws).")}),d=p.z.object({maxRetryTime:p.z.number().int().positive().optional().describe("Max total retry wait in ms. Default: 30000."),initialRetryTime:p.z.number().int().positive().optional().describe("First retry delay in ms. Default: 300."),retries:p.z.number().int().min(0).optional().describe("Max retry count. Default: 5.")}),l=p.z.object({brokers:p.z.array(p.z.string().min(1)).min(1).describe("Kafka broker addresses (host:port). At least one required."),clientId:p.z.string().optional().describe("Kafka client ID. Default: walkeros."),ssl:p.z.union([p.z.boolean(),p.z.record(p.z.string(),p.z.unknown())]).optional().describe("TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS."),sasl:m.optional().describe("SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc."),connectionTimeout:p.z.number().int().positive().optional().describe("Connection timeout in ms. Default: 1000."),requestTimeout:p.z.number().int().positive().optional().describe("Request timeout in ms. Default: 30000."),topic:p.z.string().min(1).describe("Target Kafka topic name."),acks:p.z.number().int().min(-1).max(1).optional().describe("Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1."),timeout:p.z.number().int().positive().optional().describe("Broker response timeout in ms. Default: 30000."),compression:p.z.enum(["none","gzip","snappy","lz4","zstd"]).optional().describe("Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages."),idempotent:p.z.boolean().optional().describe("Enable idempotent producer for exactly-once delivery. Default: false."),allowAutoTopicCreation:p.z.boolean().optional().describe("Allow auto-creation of topics on the broker. Default: false."),key:p.z.string().optional().describe("Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action."),headers:p.z.record(p.z.string(),p.z.string()).optional().describe("Static headers added to every message."),retry:d.optional().describe("Retry configuration for transient failures.")}),u=p.z.object({kafka:l.describe("Kafka connection and producer settings.")}),g=require("@walkeros/core/dev"),b=g.z.object({key:g.z.string().optional().describe("Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key."),topic:g.z.string().optional().describe("Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.")}),k=(0,c.zodToSchema)(u),v=(0,c.zodToSchema)(b),f={};r(f,{env:()=>y,step:()=>T});var y={};r(y,{push:()=>j,simulation:()=>D});var z=()=>Promise.resolve(),h=()=>Promise.resolve(),w=()=>Promise.resolve([]);var S=()=>({connect:z,disconnect:h,send:w}),j={Kafka:{Kafka:class{constructor(e){}producer(e){return S()}},CompressionTypes:{None:0,GZIP:1,Snappy:2,LZ4:3,ZSTD:4}}},D=["call:producer.send"],T={};r(T,{defaultEvent:()=>O,ignoredEvent:()=>q,keyFromUser:()=>I,mappedData:()=>K,mappedEventName:()=>E,topicOverride:()=>M});var A=require("@walkeros/core"),O={in:(0,A.getEvent)("page view",{timestamp:1700000100}),out:[["producer.send",{topic:"walkeros-events",messages:[{key:"page_view",value:"json:event",headers:{"content-type":"application/json"},timestamp:"1700000100"}],acks:-1,compression:1}]]},E={in:(0,A.getEvent)("order complete",{timestamp:1700000101}),mapping:{name:"purchase"},out:[["producer.send",{topic:"walkeros-events",messages:[{key:"purchase",value:"json:event",headers:{"content-type":"application/json"},timestamp:"1700000101"}],acks:-1,compression:1}]]},K={in:(0,A.getEvent)("order complete",{timestamp:1700000102,data:{id:"ORD-400",total:99.99,currency:"EUR"}}),mapping:{name:"purchase",data:{map:{order_id:"data.id",revenue:"data.total",currency:"data.currency"}}},out:[["producer.send",{topic:"walkeros-events",messages:[{key:"purchase",value:"json:data",headers:{"content-type":"application/json"},timestamp:"1700000102"}],acks:-1,compression:1}]]},I={in:(0,A.getEvent)("user signup",{timestamp:1700000103,user:{id:"usr-789"},data:{plan:"pro"}}),settings:{kafka:{brokers:["localhost:9092"],topic:"walkeros-events",key:"user.id"}},out:[["producer.send",{topic:"walkeros-events",messages:[{key:"usr-789",value:"json:event",headers:{"content-type":"application/json"},timestamp:"1700000103"}],acks:-1,compression:1}]]},M={in:(0,A.getEvent)("order complete",{timestamp:1700000104,data:{id:"ORD-500",total:42}}),mapping:{settings:{topic:"orders-stream"}},out:[["producer.send",{topic:"orders-stream",messages:[{key:"order_complete",value:"json:event",headers:{"content-type":"application/json"},timestamp:"1700000104"}],acks:-1,compression:1}]]},q={in:(0,A.getEvent)("debug noise",{timestamp:1700000105}),mapping:{ignore:!0},out:[]};//# sourceMappingURL=dev.js.map